Some fixes and improvements

This commit is contained in:
Guillem Barba 2015-01-19 19:16:09 +01:00
parent 0cd91d1a19
commit 2b32fa46c3
12 changed files with 608 additions and 391 deletions

View File

@ -1,3 +1,6 @@
Version 3.4.1 - 2015-01-19
* Some fix and improvements
Version 3.4.0 - 2014-11-03
Version 3.2.0 - 2014-06-02

View File

@ -1,4 +1,4 @@
Copyright (C) 2013 NaN·tic
Copyright (C) 2014-15 NaN·tic
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -10,6 +10,26 @@ msgstr ""
"No podeu eliminar el cost \"%(cost)s\" del pla \"%(plan)s\" perquè està "
"gestionat pel sistema."
msgctxt "error:product.cost.plan:"
msgid "A bom already exists for cost plan \"%s\"."
msgstr "Ja existeix una LdM pel pla de cost \"%s\"."
msgctxt "error:product.cost.plan:"
msgid "It will remove the existing Product Lines in this plan."
msgstr "S'eliminaran les línies de producte d'aquest pla."
msgctxt "error:product.cost.plan:"
msgid ""
"Product \"%(product)s\" in Cost Plan \"%(plan)s\" has different units of "
"measure."
msgstr ""
"El producte \"%(product)s\" del pla de cost \"%(plan)s\" té una unitat de "
"mesura diferent."
msgctxt "error:product.cost.plan:"
msgid "Product \"%s\" already has a BOM assigned."
msgstr "El producte \"%s\" ja té una LdM assignada."
msgctxt "field:product.cost.plan,active:"
msgid "Active"
msgstr "Actiu"
@ -42,6 +62,10 @@ msgctxt "field:product.cost.plan,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:product.cost.plan,name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:product.cost.plan,notes:"
msgid "Notes"
msgstr "Notes"
@ -54,10 +78,6 @@ msgctxt "field:product.cost.plan,product:"
msgid "Product"
msgstr "Producte"
msgctxt "field:product.cost.plan,product_cost:"
msgid "Product Cost"
msgstr "Cost del producte"
msgctxt "field:product.cost.plan,product_uom_category:"
msgid "Product UoM Category"
msgstr "Categoria UdM del producte"
@ -66,18 +86,30 @@ msgctxt "field:product.cost.plan,products:"
msgid "Products"
msgstr "Productes"
msgctxt "field:product.cost.plan,products_cost:"
msgid "Products Cost"
msgstr "Cost dels materials"
msgctxt "field:product.cost.plan,products_tree:"
msgid "Products"
msgstr "Productes"
msgctxt "field:product.cost.plan,quantity:"
msgid "Quantity"
msgstr "Quantitat"
msgctxt "field:product.cost.plan,rec_name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:product.cost.plan,state:"
msgid "State"
msgstr "Estat"
msgctxt "field:product.cost.plan,uom:"
msgid "UoM"
msgstr "UdM"
msgctxt "field:product.cost.plan,uom_digits:"
msgid "UoM Digits"
msgstr "Digits UdM"
msgctxt "field:product.cost.plan,write_date:"
msgid "Write Date"
msgstr "Data modificació"
@ -138,6 +170,10 @@ msgctxt "field:product.cost.plan.cost,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:product.cost.plan.cost,internal_cost:"
msgid "Cost (Internal Use)"
msgstr "Cost (ús intern)"
msgctxt "field:product.cost.plan.cost,plan:"
msgid "Plan"
msgstr "Pla"
@ -146,6 +182,10 @@ msgctxt "field:product.cost.plan.cost,rec_name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:product.cost.plan.cost,sequence:"
msgid "Sequence"
msgstr "Seqüència"
msgctxt "field:product.cost.plan.cost,system:"
msgid "System Managed"
msgstr "Gestionat pel sistema"
@ -178,10 +218,18 @@ msgctxt "field:product.cost.plan.cost.type,name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:product.cost.plan.cost.type,plan_field_name:"
msgid "Plan Field Name"
msgstr "Nom camp del pla"
msgctxt "field:product.cost.plan.cost.type,rec_name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:product.cost.plan.cost.type,system:"
msgid "System Managed"
msgstr "Gestionat pel sistema"
msgctxt "field:product.cost.plan.cost.type,write_date:"
msgid "Write Date"
msgstr "Data modificació"
@ -194,14 +242,14 @@ msgctxt "field:product.cost.plan.create_bom.start,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:product.cost.plan.create_bom.start,inputs:"
msgid "Inputs"
msgstr "Entrades"
msgctxt "field:product.cost.plan.create_bom.start,name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:product.cost.plan.product_line,children:"
msgid "Children"
msgstr "Fills"
msgctxt "field:product.cost.plan.product_line,cost_price:"
msgid "Cost Price"
msgstr "Preu de cost"
@ -218,14 +266,14 @@ msgctxt "field:product.cost.plan.product_line,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:product.cost.plan.product_line,last_purchase_price:"
msgid "Last Purchase Price"
msgstr "Últim preu de compra"
msgctxt "field:product.cost.plan.product_line,name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:product.cost.plan.product_line,parent:"
msgid "Parent"
msgstr "Pare"
msgctxt "field:product.cost.plan.product_line,plan:"
msgid "Plan"
msgstr "Pla"
@ -250,10 +298,14 @@ msgctxt "field:product.cost.plan.product_line,sequence:"
msgid "Sequence"
msgstr "Seqüència"
msgctxt "field:product.cost.plan.product_line,total:"
msgctxt "field:product.cost.plan.product_line,total_cost:"
msgid "Total Cost"
msgstr "Cost total"
msgctxt "field:product.cost.plan.product_line,unit_cost:"
msgid "Unit Cost"
msgstr "Cost unitari"
msgctxt "field:product.cost.plan.product_line,uom:"
msgid "UoM"
msgstr "UdM"
@ -278,6 +330,14 @@ msgctxt "field:production.configuration,product_cost_plan_sequence:"
msgid "Product Cost Plan Sequence"
msgstr "Seqüencia pla de costsos de producte"
msgctxt "help:product.cost.plan.product_line,total_cost:"
msgid "The cost of this product for total plan's quantity."
msgstr "El cost d'aquest producte per la quantitat total del pla."
msgctxt "help:product.cost.plan.product_line,unit_cost:"
msgid "The cost of this product for each unit of plan's product."
msgstr "El cost d'aquest producte per cada unitat del producte del pla."
msgctxt "model:ir.action,name:act_product_cost_plan"
msgid "Product Cost Plan"
msgstr "Pla de costos de producte"
@ -354,14 +414,6 @@ msgctxt "model:res.group,name:group_product_cost_plan_admin"
msgid "Product Cost Plan Administration"
msgstr "Administració Pla de costos de producte"
msgctxt "selection:product.cost.plan,state:"
msgid "Computed"
msgstr "Calculat"
msgctxt "selection:product.cost.plan,state:"
msgid "Draft"
msgstr "Esborrany"
msgctxt "view:product.cost.plan.bom_line:"
msgid "Product Cost Plan BOM"
msgstr "LdM Pla de costos de producte"
@ -394,10 +446,6 @@ msgctxt "view:product.cost.plan:"
msgid "Costs"
msgstr "Costos"
msgctxt "view:product.cost.plan:"
msgid "General"
msgstr "General"
msgctxt "view:product.cost.plan:"
msgid "Notes"
msgstr "Notes"
@ -407,8 +455,12 @@ msgid "Product Cost Plan"
msgstr "Pla de costos de producte"
msgctxt "view:product.cost.plan:"
msgid "Reset"
msgstr "Reinicialitza"
msgid "Products"
msgstr "Productes"
msgctxt "view:product.cost.plan:"
msgid "Update Product's Prices"
msgstr "Actualitza preus del producte"
msgctxt "wizard_button:product.cost.plan.create_bom,start,bom:"
msgid "Ok"

View File

@ -10,6 +10,26 @@ msgstr ""
"No se puede eliminar el coste \"%(cost)s\" del plan \"%(plan)s\" porqué esta"
" gestionado por el sistema."
msgctxt "error:product.cost.plan:"
msgid "A bom already exists for cost plan \"%s\"."
msgstr "Ya existe una LdM para el plan de costes \"%s\"."
msgctxt "error:product.cost.plan:"
msgid "It will remove the existing Product Lines in this plan."
msgstr "Se eliminaran las líneas de producto de este plan."
msgctxt "error:product.cost.plan:"
msgid ""
"Product \"%(product)s\" in Cost Plan \"%(plan)s\" has different units of "
"measure."
msgstr ""
"El producto \"%(product)s\" del plan de costes \"%(plan)s\" tiene unidades "
"de medida diferentes.¡"
msgctxt "error:product.cost.plan:"
msgid "Product \"%s\" already has a BOM assigned."
msgstr "El producto \"%s\" ya tiene una LdM asociada."
msgctxt "field:product.cost.plan,active:"
msgid "Active"
msgstr "Activo"
@ -42,6 +62,10 @@ msgctxt "field:product.cost.plan,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:product.cost.plan,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:product.cost.plan,notes:"
msgid "Notes"
msgstr "Notas"
@ -54,10 +78,6 @@ msgctxt "field:product.cost.plan,product:"
msgid "Product"
msgstr "Producto"
msgctxt "field:product.cost.plan,product_cost:"
msgid "Product Cost"
msgstr "Coste del producto"
msgctxt "field:product.cost.plan,product_uom_category:"
msgid "Product UoM Category"
msgstr "Categoría UdM del producto"
@ -66,18 +86,30 @@ msgctxt "field:product.cost.plan,products:"
msgid "Products"
msgstr "Productos"
msgctxt "field:product.cost.plan,products_cost:"
msgid "Products Cost"
msgstr "Coste materiales"
msgctxt "field:product.cost.plan,products_tree:"
msgid "Products"
msgstr "Productos"
msgctxt "field:product.cost.plan,quantity:"
msgid "Quantity"
msgstr "Cantidad"
msgctxt "field:product.cost.plan,rec_name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:product.cost.plan,state:"
msgid "State"
msgstr "Estado"
msgctxt "field:product.cost.plan,uom:"
msgid "UoM"
msgstr "UdM"
msgctxt "field:product.cost.plan,uom_digits:"
msgid "UoM Digits"
msgstr "Dígitos UdM"
msgctxt "field:product.cost.plan,write_date:"
msgid "Write Date"
msgstr "Fecha modificación"
@ -138,6 +170,10 @@ msgctxt "field:product.cost.plan.cost,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:product.cost.plan.cost,internal_cost:"
msgid "Cost (Internal Use)"
msgstr "Coste (uso interno)"
msgctxt "field:product.cost.plan.cost,plan:"
msgid "Plan"
msgstr "Plan"
@ -146,6 +182,10 @@ msgctxt "field:product.cost.plan.cost,rec_name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:product.cost.plan.cost,sequence:"
msgid "Sequence"
msgstr "Secuencia"
msgctxt "field:product.cost.plan.cost,system:"
msgid "System Managed"
msgstr "Gestinado por el sistema"
@ -178,10 +218,18 @@ msgctxt "field:product.cost.plan.cost.type,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:product.cost.plan.cost.type,plan_field_name:"
msgid "Plan Field Name"
msgstr "Nombre campo del plan"
msgctxt "field:product.cost.plan.cost.type,rec_name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:product.cost.plan.cost.type,system:"
msgid "System Managed"
msgstr "Gestinado por el sistema"
msgctxt "field:product.cost.plan.cost.type,write_date:"
msgid "Write Date"
msgstr "Fecha modificación"
@ -194,14 +242,14 @@ msgctxt "field:product.cost.plan.create_bom.start,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:product.cost.plan.create_bom.start,inputs:"
msgid "Inputs"
msgstr "Entradas"
msgctxt "field:product.cost.plan.create_bom.start,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:product.cost.plan.product_line,children:"
msgid "Children"
msgstr "Hijos"
msgctxt "field:product.cost.plan.product_line,cost_price:"
msgid "Cost Price"
msgstr "Precio de coste"
@ -218,14 +266,14 @@ msgctxt "field:product.cost.plan.product_line,id:"
msgid "ID"
msgstr "Identificador"
msgctxt "field:product.cost.plan.product_line,last_purchase_price:"
msgid "Last Purchase Price"
msgstr "Último precio de compra"
msgctxt "field:product.cost.plan.product_line,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:product.cost.plan.product_line,parent:"
msgid "Parent"
msgstr "Padre"
msgctxt "field:product.cost.plan.product_line,plan:"
msgid "Plan"
msgstr "Plan"
@ -250,10 +298,14 @@ msgctxt "field:product.cost.plan.product_line,sequence:"
msgid "Sequence"
msgstr "Secuencia"
msgctxt "field:product.cost.plan.product_line,total:"
msgctxt "field:product.cost.plan.product_line,total_cost:"
msgid "Total Cost"
msgstr "Coste total"
msgctxt "field:product.cost.plan.product_line,unit_cost:"
msgid "Unit Cost"
msgstr "Coste unitario"
msgctxt "field:product.cost.plan.product_line,uom:"
msgid "UoM"
msgstr "UdM"
@ -278,6 +330,14 @@ msgctxt "field:production.configuration,product_cost_plan_sequence:"
msgid "Product Cost Plan Sequence"
msgstr "Sequencia plan de coste del producto"
msgctxt "help:product.cost.plan.product_line,total_cost:"
msgid "The cost of this product for total plan's quantity."
msgstr "El coste de este producto por la cantidad total del plan."
msgctxt "help:product.cost.plan.product_line,unit_cost:"
msgid "The cost of this product for each unit of plan's product."
msgstr "El coste de este producto por cada unidad del producto del plan."
msgctxt "model:ir.action,name:act_product_cost_plan"
msgid "Product Cost Plan"
msgstr "Plan de coste del producto"
@ -354,14 +414,6 @@ msgctxt "model:res.group,name:group_product_cost_plan_admin"
msgid "Product Cost Plan Administration"
msgstr "Administración Plan de coste del producto"
msgctxt "selection:product.cost.plan,state:"
msgid "Computed"
msgstr "Calculado"
msgctxt "selection:product.cost.plan,state:"
msgid "Draft"
msgstr "Borrador"
msgctxt "view:product.cost.plan.bom_line:"
msgid "Product Cost Plan BOM"
msgstr "LdM Plan de coste del producto"
@ -394,10 +446,6 @@ msgctxt "view:product.cost.plan:"
msgid "Costs"
msgstr "Costes"
msgctxt "view:product.cost.plan:"
msgid "General"
msgstr "General"
msgctxt "view:product.cost.plan:"
msgid "Notes"
msgstr "Notas"
@ -407,8 +455,12 @@ msgid "Product Cost Plan"
msgstr "Plan de coste del producto"
msgctxt "view:product.cost.plan:"
msgid "Reset"
msgstr "Reiniciar"
msgid "Products"
msgstr "Productos"
msgctxt "view:product.cost.plan:"
msgid "Update Product's Prices"
msgstr "Actualizar precios producto"
msgctxt "wizard_button:product.cost.plan.create_bom,start,bom:"
msgid "Ok"

359
plan.py
View File

@ -1,10 +1,14 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from decimal import Decimal
from trytond.config import config
from trytond.model import ModelSQL, ModelView, fields
from trytond.pool import Pool
from trytond.pyson import Eval, Bool, If
from trytond.transaction import Transaction
from trytond.wizard import Wizard, StateView, StateAction, Button
from trytond.config import config
DIGITS = int(config.get('digits', 'unit_price_digits', 4))
__all__ = ['PlanCostType', 'Plan', 'PlanBOM', 'PlanProductLine', 'PlanCost',
@ -15,6 +19,8 @@ class PlanCostType(ModelSQL, ModelView):
'Plan Cost Type'
__name__ = 'product.cost.plan.cost.type'
name = fields.Char('Name', required=True, translate=True)
system = fields.Boolean('System Managed', readonly=True)
plan_field_name = fields.Char('Plan Field Name', readonly=True)
class Plan(ModelSQL, ModelView):
@ -25,21 +31,21 @@ class Plan(ModelSQL, ModelView):
name = fields.Char('Name', select=True)
active = fields.Boolean('Active')
product = fields.Many2One('product.product', 'Product')
product_uom_category = fields.Function(
fields.Many2One('product.uom.category', 'Product UoM Category'),
'on_change_with_product_uom_category')
quantity = fields.Float('Quantity', digits=(16, Eval('uom_digits', 2)),
required=True, depends=['uom_digits'])
uom = fields.Many2One('product.uom', 'UoM', required=True, domain=[
If(Bool(Eval('product_uom_category')),
If(Bool(Eval('product')),
('category', '=', Eval('product_uom_category')),
('id', '!=', -1),
)],
states={
'readonly': Bool(Eval('product')),
}, depends=['product_uom_category', 'product'])
}, depends=['product', 'product_uom_category'])
uom_digits = fields.Function(fields.Integer('UoM Digits'),
'on_change_with_uom_digits')
product_uom_category = fields.Function(
fields.Many2One('product.uom.category', 'Product UoM Category'),
'on_change_with_product_uom_category')
bom = fields.Many2One('production.bom', 'BOM',
depends=['product'], domain=[
('output_products', '=', Eval('product', 0)),
@ -57,13 +63,13 @@ class Plan(ModelSQL, ModelView):
},
depends=['costs']),
'get_products_tree', setter='set_products_tree')
product_cost = fields.Function(fields.Numeric('Product Cost',
products_cost = fields.Function(fields.Numeric('Products Cost',
digits=(16, DIGITS)),
'on_change_with_product_cost')
'get_products_cost')
costs = fields.One2Many('product.cost.plan.cost', 'plan', 'Costs')
cost_price = fields.Function(fields.Numeric('Unit Cost Price',
digits=(16, DIGITS)),
'on_change_with_cost_price')
'get_cost_price')
notes = fields.Text('Notes')
@classmethod
@ -73,14 +79,19 @@ class Plan(ModelSQL, ModelView):
'compute': {
'icon': 'tryton-spreadsheet',
},
'update_product_prices': {
'icon': 'tryton-refresh',
},
})
cls._error_messages.update({
'bom_already_exists': ('A bom already exists for cost plan '
'"%s".'),
'product_lines_will_be_removed': (
'It will remove the existing Product Lines in this plan.'),
'bom_already_exists': (
'A bom already exists for cost plan "%s".'),
'cannot_mix_input_uoms': ('Product "%(product)s" in Cost Plan '
'"%(plan)s" has different units of measure.'),
'product_already_has_bom': ('Product "%s" already has a BOM '
'assigned.'),
'product_already_has_bom': (
'Product "%s" already has a BOM assigned.'),
})
@ -119,10 +130,12 @@ class Plan(ModelSQL, ModelView):
def on_change_with_uom_digits(self, name=None):
return self.uom.digits if self.uom else 2
@fields.depends('product')
@fields.depends('product', 'uom')
def on_change_with_product_uom_category(self, name=None):
if self.product:
return self.product.default_uom_category.id
if self.uom:
return self.uom.category.id
@fields.depends('product')
def on_change_with_bom(self):
@ -168,44 +181,15 @@ class Plan(ModelSQL, ModelView):
'products': value,
})
@fields.depends('quantity', 'products', 'products_tree')
def on_change_with_product_cost(self, name=None):
def get_products_cost(self, name):
if not self.quantity:
return Decimal('0.0')
cost = sum(p.total for p in self.products_tree if p.total)
cost = sum(p.get_total_cost(None, round=False) for p in self.products)
cost /= Decimal(str(self.quantity))
digits = self.__class__.product_cost.digits[1]
digits = self.__class__.products_cost.digits[1]
return cost.quantize(Decimal(str(10 ** -digits)))
@fields.depends('product_cost', 'costs', methods=['product_cost'])
def on_change_with_costs(self):
self.product_cost = self.on_change_with_product_cost()
return self._on_change_with_costs_cost_type('product_cost_plan',
'raw_materials', self.product_cost)
def _on_change_with_costs_cost_type(self, module, cost_type_xml_id, value):
"""
Updates the cost line for type_ with value of field
"""
pool = Pool()
CostType = pool.get('product.cost.plan.cost.type')
ModelData = pool.get('ir.model.data')
type_ = CostType(ModelData.get_id(module, cost_type_xml_id))
to_update = []
for cost in self.costs:
if cost.type == type_ and cost.system:
to_update.append(cost.update_cost_values(value))
cost.cost = value
if to_update:
return {
'update': to_update,
}
return {}
@fields.depends('costs', methods=['costs'])
def on_change_with_cost_price(self, name=None):
self.on_change_with_costs()
def get_cost_price(self, name):
return sum(c.cost for c in self.costs if c.cost)
@classmethod
@ -214,20 +198,19 @@ class Plan(ModelSQL, ModelView):
ProductLine = pool.get('product.cost.plan.product_line')
CostLine = pool.get('product.cost.plan.cost')
types = [x[0]for x in cls.get_cost_types()]
to_delete = []
costs_to_delete = []
for plan in plans:
to_delete.extend(plan.products)
for line in plan.costs:
if line.type in types:
costs_to_delete.append(line)
product_lines = ProductLine.search([
('plan', 'in', [p.id for p in plans]),
])
if product_lines:
cls.raise_user_warning('remove_product_lines',
'product_lines_will_be_removed')
ProductLine.delete(product_lines)
if to_delete:
ProductLine.delete(to_delete)
if costs_to_delete:
with Transaction().set_context(reset_costs=True):
CostLine.delete(costs_to_delete)
with Transaction().set_context(reset_costs=True):
CostLine.delete(CostLine.search([
('plan', 'in', [p.id for p in plans]),
('system', '=', True),
]))
@classmethod
@ModelView.button
@ -251,37 +234,6 @@ class Plan(ModelSQL, ModelView):
if to_create:
CostLine.create(to_create)
def get_costs(self):
"Returns the cost lines to be created on compute"
ret = []
for cost_type, field_name in self.get_cost_types():
ret.append(self.get_cost_line(cost_type, field_name))
return ret
def get_cost_line(self, cost_type, field_name):
cost = getattr(self, field_name, 0.0)
return {
'type': cost_type.id,
'cost': Decimal(str(cost)),
'plan': self.id,
'system': True,
}
@classmethod
def get_cost_types(cls):
"""
Returns a list of values with the cost types and the field to get
their cost.
"""
pool = Pool()
CostType = pool.get('product.cost.plan.cost.type')
ModelData = pool.get('ir.model.data')
ret = []
type_ = CostType(ModelData.get_id('product_cost_plan',
'raw_materials'))
ret.append((type_, 'product_cost'))
return ret
def explode_bom(self, product, bom, quantity, uom):
"Returns products for the especified products"
pool = Pool()
@ -323,11 +275,15 @@ class Plan(ModelSQL, ModelView):
cost_factor = Decimal(UoM.compute_qty(input_.product.default_uom, 1,
input_.uom))
digits = ProductLine.product_cost_price.digits[1]
product_cost_price = (input_.product.cost_price /
cost_factor).quantize(Decimal(str(10 ** -digits)))
digits = ProductLine.cost_price.digits[1]
cost_price = (input_.product.cost_price /
cost_factor).quantize(Decimal(str(10 ** -digits)))
if cost_factor == Decimal('0.0'):
product_cost_price = Decimal('0.0')
cost_price = Decimal('0.0')
else:
product_cost_price = (input_.product.cost_price /
cost_factor).quantize(Decimal(str(10 ** -digits)))
digits = ProductLine.cost_price.digits[1]
cost_price = (input_.product.cost_price /
cost_factor).quantize(Decimal(str(10 ** -digits)))
return {
'name': input_.product.rec_name,
@ -338,6 +294,52 @@ class Plan(ModelSQL, ModelView):
'cost_price': cost_price,
}
def get_costs(self):
"Returns the cost lines to be created on compute"
pool = Pool()
CostType = pool.get('product.cost.plan.cost.type')
ret = []
system_cost_types = CostType.search([
('system', '=', True),
])
for cost_type in system_cost_types:
ret.append(self._get_cost_line(cost_type))
return ret
def _get_cost_line(self, cost_type):
return {
'plan': self.id,
'type': cost_type.id,
'system': True,
}
@classmethod
@ModelView.button
def update_product_prices(cls, plans):
for plan in plans:
if not plan.product:
continue
plan._update_product_prices()
plan.product.save()
plan.product.template.save()
def _update_product_prices(self):
pool = Pool()
Uom = pool.get('product.uom')
assert self.product
cost_price = Uom.compute_price(self.uom, self.cost_price,
self.product.default_uom)
if hasattr(self.product.__class__, 'cost_price'):
digits = self.product.__class__.cost_price.digits[1]
cost_price = cost_price.quantize(Decimal(str(10 ** -digits)))
self.product.cost_price = cost_price
else:
digits = self.product.template.__class__.cost_price.digits[1]
cost_price = cost_price.quantize(Decimal(str(10 ** -digits)))
self.product.template.cost_price = cost_price
def create_bom(self, name):
pool = Pool()
BOM = pool.get('production.bom')
@ -371,7 +373,7 @@ class Plan(ModelSQL, ModelView):
if self.product:
output = BOMOutput()
output.product = self.product
output.uom = self.product.default_uom
output.uom = self.uom
output.quantity = self.quantity
outputs.append(output)
return outputs
@ -477,21 +479,22 @@ class PlanProductLine(ModelSQL, ModelView):
'Children')
plan = fields.Many2One('product.cost.plan', 'Plan', required=True,
ondelete='CASCADE')
product = fields.Many2One('product.product', 'Product',
domain=[
product = fields.Many2One('product.product', 'Product', domain=[
('type', '!=', 'service'),
])
If(Bool(Eval('children')),
('default_uom.category', '=', Eval('uom_category')),
()),
], depends=['children', 'uom_category'])
quantity = fields.Float('Quantity', required=True,
digits=(16, Eval('uom_digits', 2)), depends=['uom_digits'])
uom_category = fields.Function(fields.Many2One('product.uom.category',
'UoM Category'),
'on_change_with_uom_category')
uom = fields.Many2One('product.uom', 'UoM', required=True,
domain=[
If(Bool(Eval('product', 0)),
uom = fields.Many2One('product.uom', 'UoM', required=True, domain=[
If(Bool(Eval('children')) | Bool(Eval('product')),
('category', '=', Eval('uom_category')),
('id', '!=', 0)),
], depends=['uom_category', 'product'])
()),
], depends=['children', 'product', 'uom_category'])
uom_digits = fields.Function(fields.Integer('UoM Digits'),
'on_change_with_uom_digits')
product_cost_price = fields.Numeric('Product Cost Price',
@ -501,12 +504,14 @@ class PlanProductLine(ModelSQL, ModelView):
}, depends=['product'])
cost_price = fields.Numeric('Cost Price', required=True,
digits=(16, DIGITS))
total = fields.Function(fields.Numeric('Total Cost',
digits=(16, DIGITS)),
'on_change_with_total')
total_unit = fields.Function(fields.Numeric('Total Unit Cost',
digits=(16, DIGITS)),
'on_change_with_total_unit')
unit_cost = fields.Function(fields.Numeric('Unit Cost',
digits=(16, DIGITS),
help="The cost of this product for each unit of plan's product."),
'get_unit_cost')
total_cost = fields.Function(fields.Numeric('Total Cost',
digits=(16, DIGITS),
help="The cost of this product for total plan's quantity."),
'get_total_cost')
@classmethod
def __setup__(cls):
@ -536,49 +541,75 @@ class PlanProductLine(ModelSQL, ModelView):
res['product_cost_price'] = None
return res
@fields.depends('product')
@fields.depends('children', '_parent_plan.uom' 'product', 'uom')
def on_change_with_uom_category(self, name=None):
if self.children:
# If product line has children, it must be have computable
# quantities of plan product
return self.plan.uom.category.id
if self.product:
return self.product.default_uom.category.id
@fields.depends('product', 'uom')
def on_change_with_product_cost_price(self):
UoM = Pool().get('product.uom')
if not self.product or not self.uom:
return
cost = Decimal(UoM.compute_qty(self.product.default_uom,
float(self.product.cost_price), self.uom, round=False))
digits = self.__class__.product_cost_price.digits[1]
return cost.quantize(Decimal(str(10 ** -digits)))
@fields.depends('quantity', 'cost_price', 'uom', 'product', 'children')
def on_change_with_total(self, name=None):
quantity = self.quantity
if not quantity:
return Decimal('0.0')
total = Decimal(str(quantity)) * (self.cost_price or Decimal('0.0'))
for child in self.children:
total += Decimal(str(quantity)) * (child.on_change_with_total()
or Decimal('0.0'))
digits = self.__class__.total.digits[1]
return total.quantize(Decimal(str(10 ** -digits)))
@fields.depends('_parent_plan.quantity', methods=['total'])
def on_change_with_total_unit(self, name=None):
total = self.on_change_with_total(None)
if total and self.plan and self.plan.quantity:
total /= Decimal(str(self.plan.quantity))
else:
total = Decimal('0.0')
digits = self.__class__.total_unit.digits[1]
return total.quantize(Decimal(str(10 ** -digits)))
@fields.depends('uom')
def on_change_with_uom_digits(self, name=None):
if self.uom:
return self.uom.digits
return 2
@fields.depends('product', 'uom', 'cost_price')
def on_change_with_cost_price(self):
UoM = Pool().get('product.uom')
if (not self.product or not self.uom
or (self.cost_price
and self.cost_price != self.product.cost_price)):
cost = self.cost_price
else:
cost = UoM.compute_price(self.product.default_uom,
self.product.cost_price, self.uom)
if cost:
digits = self.__class__.cost_price.digits[1]
return cost.quantize(Decimal(str(10 ** -digits)))
return cost
@fields.depends('product', 'uom')
def on_change_with_product_cost_price(self):
UoM = Pool().get('product.uom')
if not self.product:
return
if not self.uom:
cost = self.product.cost_price
else:
cost = UoM.compute_price(self.product.default_uom,
self.product.cost_price, self.uom)
digits = self.__class__.product_cost_price.digits[1]
return cost.quantize(Decimal(str(10 ** -digits)))
def get_unit_cost(self, name):
unit_cost = self.total_cost
if unit_cost and self.plan and self.plan.quantity:
unit_cost /= Decimal(str(self.plan.quantity))
digits = self.__class__.unit_cost.digits[1]
return unit_cost.quantize(Decimal(str(10 ** -digits)))
def get_total_cost(self, name, round=True):
if not self.cost_price:
return Decimal('0.0')
# Quantity is the quantity of this line for all plan's quantity
quantity = self.quantity
line = self
while quantity and line.parent:
quantity *= line.parent.quantity
line = line.parent
if not quantity:
return Decimal('0.0')
total_cost = Decimal(str(quantity)) * self.cost_price
if not round:
return total_cost
digits = self.__class__.total_cost.digits[1]
return total_cost.quantize(Decimal(str(10 ** -digits)))
@classmethod
def copy(cls, lines, default=None):
if default is None:
@ -612,10 +643,15 @@ class PlanCost(ModelSQL, ModelView):
plan = fields.Many2One('product.cost.plan', 'Plan', required=True,
ondelete='CASCADE')
sequence = fields.Integer('Sequence')
type = fields.Many2One('product.cost.plan.cost.type', 'Type',
type = fields.Many2One('product.cost.plan.cost.type', 'Type', domain=[
('system', '=', Eval('system')),
],
required=True, states=STATES, depends=DEPENDS)
cost = fields.Numeric('Cost', required=True, states=STATES,
depends=DEPENDS, digits=(16, DIGITS))
internal_cost = fields.Numeric('Cost (Internal Use)', digits=(16, DIGITS),
readonly=True)
cost = fields.Function(fields.Numeric('Cost', digits=(16, DIGITS),
required=True, states=STATES, depends=DEPENDS),
'get_cost', setter='set_cost')
system = fields.Boolean('System Managed', readonly=True)
@classmethod
@ -627,10 +663,6 @@ class PlanCost(ModelSQL, ModelView):
'from plan "%(plan)s" because it\'s managed by system.'),
})
@staticmethod
def default_system():
return False
@staticmethod
def order_sequence(tables):
table, _ = tables[None]
@ -643,6 +675,25 @@ class PlanCost(ModelSQL, ModelView):
def search_rec_name(cls, name, clause):
return [('type.name',) + tuple(clause[1:])]
@staticmethod
def default_system():
return False
def get_cost(self, name):
if self.system:
cost = getattr(self.plan, self.type.plan_field_name)
else:
cost = self.internal_cost
digits = self.__class__.cost.digits[1]
return cost.quantize(Decimal(str(10 ** -digits)))
@classmethod
def set_cost(cls, records, name, value):
records_todo = [r for r in records if not r.system]
cls.write(records, {
'internal_cost': value,
})
@classmethod
def delete(cls, costs):
if not Transaction().context.get('reset_costs', False):
@ -654,12 +705,6 @@ class PlanCost(ModelSQL, ModelView):
})
super(PlanCost, cls).delete(costs)
def update_cost_values(self, value):
return {
'cost': value,
'id': self.id,
}
class CreateBomStart(ModelView):
'Create BOM Start'

386
plan.xml
View File

@ -1,18 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<tryton>
<data>
<record model="res.group" id="group_product_cost_plan_admin">
<field name="name">Product Cost Plan Administration</field>
</record>
<record model="res.user-res.group" id="user_admin_group_product_cost_plan_admin">
<record model="res.user-res.group"
id="user_admin_group_product_cost_plan_admin">
<field name="user" ref="res.user_admin"/>
<field name="group" ref="group_product_cost_plan_admin"/>
</record>
<record model="res.user-res.group" id="user_trigger_group_product_cost_plan_admin">
<record model="res.user-res.group"
id="user_trigger_group_product_cost_plan_admin">
<field name="user" ref="res.user_trigger"/>
<field name="group" ref="group_product_cost_plan_admin"/>
</record>
<record model="res.group" id="group_product_cost_plan">
<field name="name">Product Cost Plan</field>
</record>
@ -45,16 +47,19 @@
<field name="code">product_cost_plan</field>
</record>
<!-- product.cost.plan -->
<record model="ir.ui.view" id="product_cost_plan_view_form">
<field name="model">product.cost.plan</field>
<field name="type">form</field>
<field name="name">cost_plan_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_view_list">
<field name="model">product.cost.plan</field>
<field name="type">tree</field>
<field name="name">cost_plan_list</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan">
<field name="name">Product Cost Plan</field>
<field name="res_model">product.cost.plan</field>
@ -69,6 +74,7 @@
<field name="view" ref="product_cost_plan_view_form"/>
<field name="act_window" ref="act_product_cost_plan"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan">
<field name="model" search="[('model', '=', 'product.cost.plan')]"/>
<field name="perm_read" eval="True"/>
@ -76,6 +82,7 @@
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_admin">
<field name="model" search="[('model', '=', 'product.cost.plan')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
@ -84,163 +91,6 @@
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="product_cost_plan_bom_line_view_form">
<field name="model">product.cost.plan.bom_line</field>
<field name="type">form</field>
<field name="name">cost_plan_bom_line_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_bom_line_view_list">
<field name="model">product.cost.plan.bom_line</field>
<field name="type">tree</field>
<field name="name">cost_plan_bom_line_list</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan_bom_line">
<field name="name">Product Cost Plan BOM</field>
<field name="res_model">product.cost.plan.bom_line</field>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_bom_line_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="product_cost_plan_bom_line_view_list"/>
<field name="act_window" ref="act_product_cost_plan_bom_line"/>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_bom_line_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="product_cost_plan_bom_line_view_form"/>
<field name="act_window" ref="act_product_cost_plan_bom_line"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_bom_line">
<field name="model" search="[('model', '=', 'product.cost.plan.bom_line')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_bom_line_admin">
<field name="model" search="[('model', '=', 'product.cost.plan.bom_line')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="product_cost_plan_product_line_view_form">
<field name="model">product.cost.plan.product_line</field>
<field name="type">form</field>
<field name="name">cost_plan_product_line_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_product_line_view_list">
<field name="model">product.cost.plan.product_line</field>
<field name="type">tree</field>
<field name="name">cost_plan_product_line_list</field>
<field name="field_childs">children</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan_product_line">
<field name="name">Product Cost Plan Product Line</field>
<field name="res_model">product.cost.plan.product_line</field>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_product_line_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="product_cost_plan_product_line_view_list"/>
<field name="act_window" ref="act_product_cost_plan_product_line"/>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_product_line_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="product_cost_plan_product_line_view_form"/>
<field name="act_window" ref="act_product_cost_plan_product_line"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_product_line">
<field name="model" search="[('model', '=', 'product.cost.plan.product_line')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_product_line_admin">
<field name="model" search="[('model', '=', 'product.cost.plan.product_line')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="product_cost_plan_cost_view_form">
<field name="model">product.cost.plan.cost</field>
<field name="type">form</field>
<field name="name">plan_cost_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_cost_view_list">
<field name="model">product.cost.plan.cost</field>
<field name="type">tree</field>
<field name="name">plan_cost_list</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan_cost">
<field name="name">Plan Costs</field>
<field name="res_model">product.cost.plan.cost</field>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_cost_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="product_cost_plan_cost_view_list"/>
<field name="act_window" ref="act_product_cost_plan_cost"/>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_cost_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="product_cost_plan_cost_view_form"/>
<field name="act_window" ref="act_product_cost_plan_cost"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_cost">
<field name="model" search="[('model', '=', 'product.cost.plan.cost')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_cost_admin">
<field name="model" search="[('model', '=', 'product.cost.plan.cost')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="product_cost_plan_cost_type_view_form">
<field name="model">product.cost.plan.cost.type</field>
<field name="type">form</field>
<field name="name">plan_cost_type_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_cost_type_view_list">
<field name="model">product.cost.plan.cost.type</field>
<field name="type">tree</field>
<field name="name">plan_cost_type_list</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan_cost_type">
<field name="name">Plan Cost Type</field>
<field name="res_model">product.cost.plan.cost.type</field>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_cost_type_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="product_cost_plan_cost_type_view_list"/>
<field name="act_window" ref="act_product_cost_plan_cost_type"/>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_cost_type_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="product_cost_plan_cost_type_view_form"/>
<field name="act_window" ref="act_product_cost_plan_cost_type"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_cost_type">
<field name="model" search="[('model', '=', 'product.cost.plan.cost.type')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_cost_type_admin">
<field name="model" search="[('model', '=', 'product.cost.plan.cost.type')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.model.button" id="plan_compute_button">
<field name="name">compute</field>
@ -251,6 +101,212 @@
<field name="group" ref="group_product_cost_plan"/>
</record>
<record model="ir.model.button" id="plan_update_product_prices_button">
<field name="name">update_product_prices</field>
<field name="model" search="[('model', '=', 'product.cost.plan')]"/>
</record>
<record model="ir.model.button-res.group"
id="plan_update_product_prices_button_group_product_admin">
<field name="button" ref="plan_compute_button"/>
<field name="group" ref="product.group_product_admin"/>
</record>
<!-- product.cost.plan.bom_line -->
<record model="ir.ui.view" id="product_cost_plan_bom_line_view_form">
<field name="model">product.cost.plan.bom_line</field>
<field name="type">form</field>
<field name="name">cost_plan_bom_line_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_bom_line_view_list">
<field name="model">product.cost.plan.bom_line</field>
<field name="type">tree</field>
<field name="name">cost_plan_bom_line_list</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan_bom_line">
<field name="name">Product Cost Plan BOM</field>
<field name="res_model">product.cost.plan.bom_line</field>
</record>
<record model="ir.action.act_window.view"
id="act_product_cost_plan_bom_line_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="product_cost_plan_bom_line_view_list"/>
<field name="act_window" ref="act_product_cost_plan_bom_line"/>
</record>
<record model="ir.action.act_window.view"
id="act_product_cost_plan_bom_line_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="product_cost_plan_bom_line_view_form"/>
<field name="act_window" ref="act_product_cost_plan_bom_line"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_bom_line">
<field name="model" search="[('model', '=', 'product.cost.plan.bom_line')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_bom_line_admin">
<field name="model" search="[('model', '=', 'product.cost.plan.bom_line')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<!-- product.cost.plan.product_line -->
<record model="ir.ui.view" id="product_cost_plan_product_line_view_form">
<field name="model">product.cost.plan.product_line</field>
<field name="type">form</field>
<field name="name">cost_plan_product_line_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_product_line_view_list">
<field name="model">product.cost.plan.product_line</field>
<field name="type">tree</field>
<field name="name">cost_plan_product_line_list</field>
<field name="field_childs">children</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan_product_line">
<field name="name">Product Cost Plan Product Line</field>
<field name="res_model">product.cost.plan.product_line</field>
</record>
<record model="ir.action.act_window.view"
id="act_product_cost_plan_product_line_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="product_cost_plan_product_line_view_list"/>
<field name="act_window" ref="act_product_cost_plan_product_line"/>
</record>
<record model="ir.action.act_window.view"
id="act_product_cost_plan_product_line_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="product_cost_plan_product_line_view_form"/>
<field name="act_window" ref="act_product_cost_plan_product_line"/>
</record>
<record model="ir.model.access"
id="access_product_cost_plan_product_line">
<field name="model"
search="[('model', '=', 'product.cost.plan.product_line')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access"
id="access_product_cost_plan_product_line_admin">
<field name="model"
search="[('model', '=', 'product.cost.plan.product_line')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<!-- product.cost.plan.cost -->
<record model="ir.ui.view" id="product_cost_plan_cost_view_form">
<field name="model">product.cost.plan.cost</field>
<field name="type">form</field>
<field name="name">plan_cost_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_cost_view_list">
<field name="model">product.cost.plan.cost</field>
<field name="type">tree</field>
<field name="name">plan_cost_list</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan_cost">
<field name="name">Plan Costs</field>
<field name="res_model">product.cost.plan.cost</field>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_cost_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="product_cost_plan_cost_view_list"/>
<field name="act_window" ref="act_product_cost_plan_cost"/>
</record>
<record model="ir.action.act_window.view" id="act_product_cost_plan_cost_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="product_cost_plan_cost_view_form"/>
<field name="act_window" ref="act_product_cost_plan_cost"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_cost">
<field name="model" search="[('model', '=', 'product.cost.plan.cost')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_cost_admin">
<field name="model" search="[('model', '=', 'product.cost.plan.cost')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<!-- product.cost.plan.cost.type -->
<record model="ir.ui.view" id="product_cost_plan_cost_type_view_form">
<field name="model">product.cost.plan.cost.type</field>
<field name="type">form</field>
<field name="name">plan_cost_type_form</field>
</record>
<record model="ir.ui.view" id="product_cost_plan_cost_type_view_list">
<field name="model">product.cost.plan.cost.type</field>
<field name="type">tree</field>
<field name="name">plan_cost_type_list</field>
</record>
<record model="ir.action.act_window" id="act_product_cost_plan_cost_type">
<field name="name">Plan Cost Type</field>
<field name="res_model">product.cost.plan.cost.type</field>
</record>
<record model="ir.action.act_window.view"
id="act_product_cost_plan_cost_type_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="product_cost_plan_cost_type_view_list"/>
<field name="act_window" ref="act_product_cost_plan_cost_type"/>
</record>
<record model="ir.action.act_window.view"
id="act_product_cost_plan_cost_type_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="product_cost_plan_cost_type_view_form"/>
<field name="act_window" ref="act_product_cost_plan_cost_type"/>
</record>
<record model="ir.model.access" id="access_product_cost_plan_cost_type">
<field name="model"
search="[('model', '=', 'product.cost.plan.cost.type')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access"
id="access_product_cost_plan_cost_type_admin">
<field name="model"
search="[('model', '=', 'product.cost.plan.cost.type')]"/>
<field name="group" ref="group_product_cost_plan_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<!-- product.cost.plan.create_bom -->
<record model="ir.ui.view" id="create_bom_start_view_form">
<field name="model">product.cost.plan.create_bom.start</field>
<field name="type">form</field>
@ -276,13 +332,13 @@
<menuitem action="act_product_cost_plan" id="menu_product_cost_plan"
parent="product.menu_main_product" sequence="50"
name="Product Cost Plan"/>
<record model="ir.ui.menu-res.group" id="menu_product_cost_plan_group_product_cost_plan">
<record model="ir.ui.menu-res.group"
id="menu_product_cost_plan_group_product_cost_plan">
<field name="menu" ref="menu_product_cost_plan"/>
<field name="group" ref="group_product_cost_plan"/>
</record>
<record model="ir.ui.menu-res.group" id="menu_product_cost_plan_group_product_cost_plan_admin">
<record model="ir.ui.menu-res.group"
id="menu_product_cost_plan_group_product_cost_plan_admin">
<field name="menu" ref="menu_product_cost_plan"/>
<field name="group" ref="group_product_cost_plan"/>
</record>
@ -296,6 +352,8 @@
<record model="product.cost.plan.cost.type" id="raw_materials">
<field name="name">Raw materials</field>
<field name="system" eval="True"/>
<field name="plan_field_name">products_cost</field>
</record>
</data>
</tryton>

View File

@ -1,5 +1,5 @@
[tryton]
version=3.4.0
version=3.4.1
depends:
production
xml:

View File

@ -21,8 +21,8 @@
<notebook colspan="6">
<page string="Products" id="products">
<field name="products_tree" colspan="4"/>
<label name="product_cost"/>
<field name="product_cost"/>
<label name="products_cost"/>
<field name="products_cost"/>
</page>
<page id="costs" string="Costs">
<field name="costs" colspan="4"/>
@ -36,4 +36,6 @@
</notebook>
<label name="cost_price"/>
<field name="cost_price"/>
<button name="update_product_prices" string="Update Product's Prices"
colspan="2"/>
</form>

View File

@ -20,6 +20,8 @@
<field name="product_cost_price"/>
<label name="cost_price"/>
<field name="cost_price"/>
<label name="total"/>
<field name="total"/>
<label name="unit_cost"/>
<field name="unit_cost"/>
<label name="total_cost"/>
<field name="total_cost"/>
</form>

View File

@ -9,8 +9,8 @@
<field name="uom"/>
<field name="cost_price"/>
<field name="product_cost_price"/>
<field name="total"/>
<field name="total_unit"/>
<field name="unit_cost"/>
<field name="total_cost"/>
<field name="parent" tree_invisible="1"/>
<field name="children" tree_invisible="1"/>
</tree>

View File

@ -4,4 +4,6 @@
<form string="Plan Cost Type">
<label name="name"/>
<field name="name"/>
<label name="system"/>
<field name="system"/>
</form>

View File

@ -3,4 +3,5 @@
copyright notices and license terms. -->
<tree string="Plan Cost Type">
<field name="name"/>
<field name="system"/>
</tree>