Unstable fix
This commit is contained in:
parent
5dcbc05fab
commit
a57f01d456
|
@ -18,6 +18,7 @@ def register():
|
||||||
production.Production,
|
production.Production,
|
||||||
production.ProductionDetailedStart,
|
production.ProductionDetailedStart,
|
||||||
production.ProcessProductionAsyncStart,
|
production.ProcessProductionAsyncStart,
|
||||||
|
production.ProductionCost,
|
||||||
account.Move,
|
account.Move,
|
||||||
stock.Move,
|
stock.Move,
|
||||||
ir.Cron,
|
ir.Cron,
|
||||||
|
|
11
bom.py
11
bom.py
|
@ -5,14 +5,13 @@ from datetime import datetime, date
|
||||||
|
|
||||||
from trytond.pool import Pool, PoolMeta
|
from trytond.pool import Pool, PoolMeta
|
||||||
from trytond.modules.product import round_price
|
from trytond.modules.product import round_price
|
||||||
from trytond.transaction import Transaction
|
|
||||||
from trytond.model import fields, ModelSQL, ModelView
|
from trytond.model import fields, ModelSQL, ModelView
|
||||||
|
|
||||||
|
|
||||||
class BOM(metaclass=PoolMeta):
|
class BOM(metaclass=PoolMeta):
|
||||||
__name__ = 'production.bom'
|
__name__ = 'production.bom'
|
||||||
direct_costs = fields.One2Many('production.bom.direct_cost',
|
direct_costs = fields.One2Many('production.bom.direct_cost', 'bom',
|
||||||
'bom', 'Direct Costs')
|
'Direct Costs')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def calc_cost_ldm(cls):
|
def calc_cost_ldm(cls):
|
||||||
|
@ -65,12 +64,12 @@ class BOMDirectCost(ModelSQL, ModelView):
|
||||||
product = fields.Many2One('product.product', 'Product', required=True,
|
product = fields.Many2One('product.product', 'Product', required=True,
|
||||||
domain=[('type', '!=', 'active')])
|
domain=[('type', '!=', 'active')])
|
||||||
uom = fields.Many2One('product.uom', 'UoM')
|
uom = fields.Many2One('product.uom', 'UoM')
|
||||||
quantity = fields.Float('Quantity', required=True, digits=(16,2))
|
quantity = fields.Float('Quantity', required=True, digits=(16, 2))
|
||||||
notes = fields.Char('Notes')
|
notes = fields.Char('Notes')
|
||||||
kind = fields.Selection([
|
kind = fields.Selection([
|
||||||
('labour', 'Labour'),
|
('labour', 'Labour'),
|
||||||
('imc', 'IMC'),
|
('indirect', 'Indirect'),
|
||||||
('', ''),
|
('service', 'Service'),
|
||||||
], 'Kind')
|
], 'Kind')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
235
production.py
235
production.py
|
@ -3,15 +3,15 @@
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from trytond.pool import PoolMeta, Pool
|
from trytond.pool import PoolMeta, Pool
|
||||||
from trytond.model import fields, ModelView
|
from trytond.model import fields, ModelView, ModelSQL
|
||||||
from trytond.pyson import Eval
|
from trytond.pyson import Eval
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
from trytond.wizard import Wizard, StateTransition, StateReport, StateView, Button
|
from trytond.wizard import (
|
||||||
|
Wizard, StateTransition, StateReport, StateView, Button)
|
||||||
from trytond.modules.company import CompanyReport
|
from trytond.modules.company import CompanyReport
|
||||||
from trytond.i18n import gettext
|
from trytond.i18n import gettext
|
||||||
from trytond.exceptions import UserError
|
from trytond.exceptions import UserError
|
||||||
from trytond.report import Report
|
from trytond.report import Report
|
||||||
from trytond.modules.product import price_digits, round_price
|
|
||||||
|
|
||||||
ZERO = Decimal(0)
|
ZERO = Decimal(0)
|
||||||
|
|
||||||
|
@ -24,6 +24,14 @@ def round_dec(number):
|
||||||
|
|
||||||
class Production(metaclass=PoolMeta):
|
class Production(metaclass=PoolMeta):
|
||||||
__name__ = 'production'
|
__name__ = 'production'
|
||||||
|
_analytic_dom = [
|
||||||
|
('type', 'in', ['normal', 'distribution']),
|
||||||
|
('company', '=', Eval('context', {}).get('company', -1)),
|
||||||
|
('parent', '=', Eval('analytic_account')),
|
||||||
|
]
|
||||||
|
_states = {
|
||||||
|
'readonly': ~Eval('state').in_(['draft', 'request']),
|
||||||
|
}
|
||||||
in_account_move = fields.Many2One('account.move', 'In Account Move',
|
in_account_move = fields.Many2One('account.move', 'In Account Move',
|
||||||
states={'readonly': True})
|
states={'readonly': True})
|
||||||
out_account_move = fields.Many2One('account.move', 'Out Account Move',
|
out_account_move = fields.Many2One('account.move', 'Out Account Move',
|
||||||
|
@ -33,19 +41,32 @@ class Production(metaclass=PoolMeta):
|
||||||
warehouse_target = fields.Many2One('stock.location', 'Warehouse Target',
|
warehouse_target = fields.Many2One('stock.location', 'Warehouse Target',
|
||||||
domain=[('type', '=', 'warehouse')])
|
domain=[('type', '=', 'warehouse')])
|
||||||
warehouse_moves = fields.One2Many('stock.move', 'origin', 'Warehouse Moves')
|
warehouse_moves = fields.One2Many('stock.move', 'origin', 'Warehouse Moves')
|
||||||
|
costs = fields.One2Many('production.cost', 'production', 'Costs')
|
||||||
material_costs = fields.Numeric('Material Costs', digits=(16, 2),
|
material_costs = fields.Numeric('Material Costs', digits=(16, 2),
|
||||||
readonly=True)
|
states={'readonly': True})
|
||||||
labour_costs = fields.Numeric('Labour Costs', digits=(16, 2), readonly=True)
|
labour_costs = fields.Numeric('Labour Costs', digits=(16, 2),
|
||||||
imc_costs = fields.Numeric('IMC Costs', digits=(16, 2), readonly=True)
|
states={'readonly': True})
|
||||||
total_cost = fields.Numeric('Total Cost', digits=(16, 2), readonly=True)
|
indirect_costs = fields.Numeric('Indirect Costs', digits=(16, 2),
|
||||||
perfomance = fields.Function(fields.Numeric('Perfomance', digits=(16, 2)), 'get_perfomance')
|
states={'readonly': True})
|
||||||
|
services_costs = fields.Numeric('Services Costs', digits=(16, 2),
|
||||||
|
states={'readonly': True})
|
||||||
|
total_cost = fields.Function(fields.Numeric('Total Cost', digits=(16, 2)),
|
||||||
|
'get_total_cost')
|
||||||
|
perfomance = fields.Function(fields.Numeric('Perfomance', digits=(16, 2)),
|
||||||
|
'get_perfomance')
|
||||||
analytic_account = fields.Many2One('analytic_account.account',
|
analytic_account = fields.Many2One('analytic_account.account',
|
||||||
'Analytic Account', domain=[
|
'Analytic Account Main', domain=[
|
||||||
('type', 'in', ['normal', 'distribution']),
|
('type', '=', 'view'),
|
||||||
('company', '=', Eval('context', {}).get('company', -1))
|
('company', '=', Eval('context', {}).get('company', -1))
|
||||||
], states={
|
], states=_states)
|
||||||
'readonly': ~Eval('state').in_(['draft', 'request']),
|
analytic_account_materials = fields.Many2One('analytic_account.account',
|
||||||
})
|
'Analytic Account Materials', domain=_analytic_dom)
|
||||||
|
analytic_account_labour = fields.Many2One('analytic_account.account',
|
||||||
|
'Analytic Account Labour', domain=_analytic_dom)
|
||||||
|
analytic_account_indirect = fields.Many2One('analytic_account.account',
|
||||||
|
'Analytic Account Indirect', domain=_analytic_dom)
|
||||||
|
analytic_account_services = fields.Many2One('analytic_account.account',
|
||||||
|
'Analytic Account Services', domain=_analytic_dom)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def default_warehouse_origin():
|
def default_warehouse_origin():
|
||||||
|
@ -64,17 +85,18 @@ class Production(metaclass=PoolMeta):
|
||||||
@classmethod
|
@classmethod
|
||||||
def wait(cls, records):
|
def wait(cls, records):
|
||||||
super(Production, cls).wait(records)
|
super(Production, cls).wait(records)
|
||||||
# for rec in records:
|
for rec in records:
|
||||||
# cls.create_account_move(rec, 'wait', 'in_account_move')
|
# cls.create_account_move(rec, 'wait', 'in_account_move')
|
||||||
# FIXME
|
# FIXME
|
||||||
# rec.create_stock_move('in')
|
# rec.create_stock_move('in')
|
||||||
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def done(cls, records):
|
def done(cls, records):
|
||||||
Move = Pool().get('stock.move')
|
Move = Pool().get('stock.move')
|
||||||
super(Production, cls).done(records)
|
super(Production, cls).done(records)
|
||||||
for rec in records:
|
for rec in records:
|
||||||
# cls.create_account_move(rec, 'done', 'out_account_move')
|
cls.create_account_move(rec, 'done', 'out_account_move')
|
||||||
for output in rec.outputs:
|
for output in rec.outputs:
|
||||||
unit_price = rec._compute_unit_cost()
|
unit_price = rec._compute_unit_cost()
|
||||||
Move.write([output], {'unit_price': unit_price})
|
Move.write([output], {'unit_price': unit_price})
|
||||||
|
@ -90,10 +112,18 @@ class Production(metaclass=PoolMeta):
|
||||||
new_cost_price = round_dec(total_cost / Decimal(self.quantity))
|
new_cost_price = round_dec(total_cost / Decimal(self.quantity))
|
||||||
return new_cost_price
|
return new_cost_price
|
||||||
|
|
||||||
|
def get_total_cost(self, name=None):
|
||||||
|
return sum([
|
||||||
|
self.material_costs or 0,
|
||||||
|
self.indirect_costs or 0,
|
||||||
|
self.services_costs or 0,
|
||||||
|
self.labour_costs or 0,
|
||||||
|
])
|
||||||
|
|
||||||
def get_perfomance(self, name=None):
|
def get_perfomance(self, name=None):
|
||||||
res = Decimal(0)
|
res = Decimal(0)
|
||||||
if self.bom:
|
if self.bom:
|
||||||
origin = sum(p.quantity for p in self.bom.outputs ) * self.quantity
|
origin = sum(p.quantity for p in self.bom.outputs) * self.quantity
|
||||||
result = sum(p.quantity for p in self.outputs)
|
result = sum(p.quantity for p in self.outputs)
|
||||||
if result != 0 and origin != 0:
|
if result != 0 and origin != 0:
|
||||||
res = Decimal(str(round(result*100/origin, 2)))
|
res = Decimal(str(round(result*100/origin, 2)))
|
||||||
|
@ -108,56 +138,51 @@ class Production(metaclass=PoolMeta):
|
||||||
ProductCost.write(products, {'cost_price': new_cost})
|
ProductCost.write(products, {'cost_price': new_cost})
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_production_lines(cls, bom, materials_cost, date_, factor, args=None):
|
def get_production_lines(cls, rec, date_, factor, args=None):
|
||||||
""" Get Production Account Move Lines """
|
""" Get Production Account Move Lines """
|
||||||
lines = []
|
|
||||||
cost_finished_production = []
|
cost_finished_production = []
|
||||||
values = {}
|
values = {}
|
||||||
output = bom.outputs[0]
|
output = rec.bom.outputs[0]
|
||||||
|
|
||||||
account_expense = output.product.account_expense_used
|
account_expense = output.product.account_expense_used
|
||||||
|
analytic_materials = args.get('analytic_materials', None)
|
||||||
materials_line = {
|
materials_line = {
|
||||||
'description': '',
|
'description': '',
|
||||||
'account': account_expense.id,
|
'account': account_expense.id,
|
||||||
'debit': 0,
|
'debit': 0,
|
||||||
'credit': materials_cost,
|
'credit': rec.material_costs,
|
||||||
}
|
}
|
||||||
analytic = args.get('analytic', None)
|
cls.set_analytic_lines(materials_line, date_, analytic_materials)
|
||||||
cls.set_analytic_lines(materials_line, date_, analytic)
|
|
||||||
lines.append(materials_line)
|
lines.append(materials_line)
|
||||||
cost_finished_production.append(materials_cost)
|
cost_finished_production.append(rec.materials_cost)
|
||||||
|
|
||||||
values = {
|
account_id = None
|
||||||
'total_labour': [],
|
lines = []
|
||||||
'total_imc': [],
|
for cost in rec.costs:
|
||||||
}
|
amount = rec.amount
|
||||||
|
if cost.kind == 'labour':
|
||||||
for dc in bom.direct_costs:
|
account_id = cost.product.account_expense_used.id
|
||||||
account_id = dc.product.account_expense_used.id
|
values['total_labour'].append(rec.labour_costs)
|
||||||
amount = Decimal(dc.quantity * factor) * dc.product.cost_price
|
line_ = {
|
||||||
amount = Decimal(round(amount, 2))
|
'description': '',
|
||||||
line_ = {
|
'account': account_id,
|
||||||
'description': '',
|
'debit': 0,
|
||||||
'account': account_id,
|
'credit': rec.amount,
|
||||||
'debit': 0,
|
}
|
||||||
'credit': amount,
|
cls.set_analytic_lines(line_, date_, analytic_work_force)
|
||||||
}
|
lines.append(line_)
|
||||||
|
|
||||||
cls.set_analytic_lines(line_, date_, analytic)
|
|
||||||
lines.append(line_)
|
lines.append(line_)
|
||||||
cost_finished_production.append(amount)
|
cost_finished_production.append(amount)
|
||||||
if dc.kind == 'labour':
|
#
|
||||||
values['total_labour'].append(amount)
|
# account_stock = output.product.account_stock_used
|
||||||
elif dc.kind == 'imc':
|
# lines.append({
|
||||||
values['total_imc'].append(amount)
|
# 'description': '',
|
||||||
|
# 'account': account_stock.id,
|
||||||
account_stock = output.product.account_stock_used
|
# 'debit': sum(cost_finished_production),
|
||||||
lines.append({
|
# 'credit': 0,
|
||||||
'description': '',
|
# })
|
||||||
'account': account_stock.id,
|
# return lines, values
|
||||||
'debit': sum(cost_finished_production),
|
|
||||||
'credit': 0,
|
|
||||||
})
|
|
||||||
return lines, values
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_consumption_lines(cls, inputs, factor, date_, args=None):
|
def get_consumption_lines(cls, inputs, factor, date_, args=None):
|
||||||
|
@ -227,32 +252,39 @@ class Production(metaclass=PoolMeta):
|
||||||
raise UserError(
|
raise UserError(
|
||||||
gettext('production_accounting.msg_planned_date_required')
|
gettext('production_accounting.msg_planned_date_required')
|
||||||
)
|
)
|
||||||
analytic_ctx = {'analytic': rec.analytic_account}
|
analytic_ctx = {
|
||||||
|
'analytic_materials': rec.analytic_account_materials,
|
||||||
|
'analytic_labour': rec.analytic_account_labour,
|
||||||
|
'analytic_indirect': rec.analytic_account_indirect,
|
||||||
|
'analytic_services': rec.analytic_account_services,
|
||||||
|
}
|
||||||
to_update = {}
|
to_update = {}
|
||||||
output = rec.outputs[0]
|
output = rec.outputs[0]
|
||||||
factor = rec.quantity / output.quantity
|
factor = rec.quantity / output.quantity
|
||||||
if kind == 'wait':
|
# if kind == 'wait':
|
||||||
date_ = rec.planned_date
|
# date_ = rec.planned_date
|
||||||
lines, values = cls.get_consumption_lines(
|
# lines, values = cls.get_consumption_lines(
|
||||||
rec.inputs, factor, date_, analytic_ctx
|
# rec.inputs, factor, date_, analytic_ctx
|
||||||
)
|
# )
|
||||||
to_update['material_costs'] = values['material_costs']
|
# to_update['material_costs'] = values['material_costs']
|
||||||
|
|
||||||
if kind == 'done':
|
if kind == 'done':
|
||||||
date_ = rec.effective_date
|
date_ = rec.effective_date
|
||||||
lines, values = cls.get_production_lines(
|
lines, values = cls.get_production_lines(
|
||||||
rec.bom,
|
rec,
|
||||||
rec.material_costs,
|
|
||||||
date_,
|
date_,
|
||||||
factor,
|
factor,
|
||||||
analytic_ctx
|
analytic_ctx
|
||||||
)
|
)
|
||||||
total_labour = sum(values['total_labour'])
|
# total_labour = sum(values['total_labour'])
|
||||||
total_imc = sum(values['total_imc'])
|
# total_indirect = sum(values['total_indirect'])
|
||||||
to_update['material_costs'] = round_dec(rec.cost)
|
# total_services = sum(values['total_services'])
|
||||||
to_update['labour_costs'] = round_dec(total_labour)
|
# to_update['material_costs'] = round_dec(rec.cost)
|
||||||
to_update['imc_costs'] = round_dec(total_imc)
|
# to_update['labour_costs'] = round_dec(total_labour)
|
||||||
to_update['total_cost'] = round_dec(total_imc + total_labour + rec.cost)
|
# to_update['indirect_costs'] = round_dec(total_indirect)
|
||||||
|
# to_update['services_costs'] = round_dec(total_services)
|
||||||
|
# to_update['total_cost'] = round_dec(
|
||||||
|
# total_indirect + total_labour + rec.cost)
|
||||||
|
|
||||||
period_id = Period.find(rec.company.id, date=date_)
|
period_id = Period.find(rec.company.id, date=date_)
|
||||||
|
|
||||||
|
@ -267,8 +299,8 @@ class Production(metaclass=PoolMeta):
|
||||||
}])
|
}])
|
||||||
|
|
||||||
Move.post([move])
|
Move.post([move])
|
||||||
to_update[field] = move.id
|
# to_update[field] = move.id
|
||||||
cls.write([rec], to_update)
|
# cls.write([rec], to_update)
|
||||||
|
|
||||||
def create_stock_move(self, kind, field=None):
|
def create_stock_move(self, kind, field=None):
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
|
@ -321,6 +353,67 @@ class Production(metaclass=PoolMeta):
|
||||||
lines.append(analytic_line)
|
lines.append(analytic_line)
|
||||||
line['analytic_lines'] = [('create', lines)]
|
line['analytic_lines'] = [('create', lines)]
|
||||||
|
|
||||||
|
@fields.depends('inputs', 'material_costs')
|
||||||
|
def on_change_inputs(self, name=None):
|
||||||
|
res = []
|
||||||
|
for _input in self.inputs:
|
||||||
|
res.append(Decimal(_input.quantity) * _input.product.cost_price)
|
||||||
|
self.material_costs = sum(res)
|
||||||
|
|
||||||
|
@fields.depends('costs', 'indirect_costs', 'services_costs', 'labour_costs')
|
||||||
|
def on_change_costs(self, name=None):
|
||||||
|
indirect_costs = []
|
||||||
|
services_costs = []
|
||||||
|
labour_costs = []
|
||||||
|
for cost in self.costs:
|
||||||
|
if cost.kind == 'indirect':
|
||||||
|
indirect_costs.append(cost.amount)
|
||||||
|
elif cost.kind == 'labour':
|
||||||
|
labour_costs.append(cost.amount)
|
||||||
|
elif cost.kind == 'service':
|
||||||
|
services_costs.append(cost.amount)
|
||||||
|
|
||||||
|
self.indirect_costs = sum(indirect_costs)
|
||||||
|
self.services_costs = sum(services_costs)
|
||||||
|
self.labour_costs = sum(labour_costs)
|
||||||
|
|
||||||
|
|
||||||
|
class ProductionCost(ModelSQL, ModelView):
|
||||||
|
"Production Cost"
|
||||||
|
__name__ = "production.cost"
|
||||||
|
production = fields.Many2One('production', 'Production', required=True,
|
||||||
|
ondelete='CASCADE')
|
||||||
|
product = fields.Many2One('product.product', 'Product', required=True,
|
||||||
|
domain=[('type', '!=', 'active')])
|
||||||
|
unit = fields.Many2One('product.uom', 'UoM')
|
||||||
|
effective_date = fields.Date('Effective Date')
|
||||||
|
quantity = fields.Float('Quantity', required=True, digits=(16, 2))
|
||||||
|
unit_price = fields.Numeric('Unit Price', required=True, digits=(16, 2))
|
||||||
|
amount = fields.Numeric('Amount', digits=(16, 2), states={'readonly': True})
|
||||||
|
analytic_account = fields.Many2One('analytic_account.account',
|
||||||
|
'Analytic Account', domain=[
|
||||||
|
('type', 'in', ['normal', 'distribution']),
|
||||||
|
('company', '=', Eval('context', {}).get('company', -1)),
|
||||||
|
('parent', '=', Eval('_parent_production', {}).get('analytic_account')),
|
||||||
|
])
|
||||||
|
kind = fields.Selection([
|
||||||
|
('labour', 'Labour'),
|
||||||
|
('indirect', 'Indirect'),
|
||||||
|
('service', 'Service'),
|
||||||
|
], 'Kind', required=True)
|
||||||
|
notes = fields.Text('Notes')
|
||||||
|
|
||||||
|
@fields.depends('product', 'unit', 'unit_price')
|
||||||
|
def on_change_product(self, name=None):
|
||||||
|
if self.product:
|
||||||
|
self.unit = self.product.default_uom.id
|
||||||
|
self.unit_price = self.product.cost_price
|
||||||
|
|
||||||
|
@fields.depends('unit_price', 'amount', 'quantity')
|
||||||
|
def on_change_with_amount(self, name=None):
|
||||||
|
if self.unit_price and self.quantity:
|
||||||
|
return round(self.unit_price * Decimal(self.quantity), 2)
|
||||||
|
|
||||||
|
|
||||||
class ProductionReport(CompanyReport):
|
class ProductionReport(CompanyReport):
|
||||||
'Production Report'
|
'Production Report'
|
||||||
|
|
|
@ -72,5 +72,15 @@ this repository contains the full copyright notices and license terms. -->
|
||||||
sequence="2" id="menu_process_production_async"
|
sequence="2" id="menu_process_production_async"
|
||||||
action="wizard_process_production_async"/>
|
action="wizard_process_production_async"/>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="production_cost_view_form">
|
||||||
|
<field name="model">production.cost</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">production_cost_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="production_cost_view_tree">
|
||||||
|
<field name="model">production.cost</field>
|
||||||
|
<field name="type">tree</field>
|
||||||
|
<field name="name">production_cost_tree</field>
|
||||||
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<form>
|
||||||
|
<label name="kind"/>
|
||||||
|
<field name="kind"/>
|
||||||
|
<label name="effective_date"/>
|
||||||
|
<field name="effective_date"/>
|
||||||
|
<label name="product"/>
|
||||||
|
<field name="product"/>
|
||||||
|
<label name="unit"/>
|
||||||
|
<field name="unit" widget="selection"/>
|
||||||
|
<label name="unit_price"/>
|
||||||
|
<field name="unit_price"/>
|
||||||
|
<label name="quantity"/>
|
||||||
|
<field name="quantity"/>
|
||||||
|
<label name="amount"/>
|
||||||
|
<field name="amount"/>
|
||||||
|
<label name="analytic_account" widget="selection"/>
|
||||||
|
<field name="analytic_account" widget="selection"/>
|
||||||
|
<newline />
|
||||||
|
<field name="notes" colspan="4"/>
|
||||||
|
</form>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<tree editable="1">
|
||||||
|
<field name="kind"/>
|
||||||
|
<field name="effective_date"/>
|
||||||
|
<field name="product"/>
|
||||||
|
<field name="quantity"/>
|
||||||
|
<field name="unit" widget="selection"/>
|
||||||
|
<field name="unit_price"/>
|
||||||
|
<field name="amount"/>
|
||||||
|
<field name="analytic_account" widget="selection" expand="1"/>
|
||||||
|
</tree>
|
|
@ -2,14 +2,6 @@
|
||||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
this repository contains the full copyright notices and license terms. -->
|
this repository contains the full copyright notices and license terms. -->
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="/form/notebook/page[@id='other']/field[@name='effective_date']" position="replace">
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page[@id='other']/label[@name='effective_date']" position="replace">
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page[@id='other']/field[@name='effective_start_date']" position="replace">
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page[@id='other']/label[@name='effective_start_date']" position="replace">
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page[@id='other']/field[@name='cost']" position="after">
|
<xpath expr="/form/notebook/page[@id='other']/field[@name='cost']" position="after">
|
||||||
<newline />
|
<newline />
|
||||||
<label name="warehouse_origin"/>
|
<label name="warehouse_origin"/>
|
||||||
|
@ -20,30 +12,37 @@ this repository contains the full copyright notices and license terms. -->
|
||||||
<field name="in_account_move"/>
|
<field name="in_account_move"/>
|
||||||
<label name="out_account_move"/>
|
<label name="out_account_move"/>
|
||||||
<field name="out_account_move"/>
|
<field name="out_account_move"/>
|
||||||
<label name="material_costs"/>
|
|
||||||
<field name="material_costs"/>
|
|
||||||
<label name="labour_costs"/>
|
|
||||||
<field name="labour_costs"/>
|
|
||||||
<label name="imc_costs"/>
|
|
||||||
<field name="imc_costs"/>
|
|
||||||
<label name="total_cost"/>
|
|
||||||
<field name="total_cost"/>
|
|
||||||
<label name="perfomance"/>
|
<label name="perfomance"/>
|
||||||
<field name="perfomance"/>
|
<field name="perfomance"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="/form/field[@name='uom']" position="after">
|
<xpath expr="/form/field[@name='uom']" position="after">
|
||||||
<label name="analytic_account"/>
|
<label name="analytic_account" widget="selection"/>
|
||||||
<field name="analytic_account"/>
|
<field name="analytic_account" widget="selection"/>
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/field[@name='planned_start_date']" position="after">
|
|
||||||
<label name="effective_date"/>
|
|
||||||
<field name="effective_date"/>
|
|
||||||
<label name="effective_start_date"/>
|
|
||||||
<field name="effective_start_date"/>
|
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="/form/notebook/page[@id='other']" position="after">
|
<xpath expr="/form/notebook/page[@id='other']" position="after">
|
||||||
<page string="Stock Moves" id="warehouse_stock_moves">
|
<page string="Stock Moves" id="warehouse_stock_moves">
|
||||||
<field name="warehouse_moves" colspan="4"/>
|
<field name="warehouse_moves" colspan="4"/>
|
||||||
</page>
|
</page>
|
||||||
|
<page string="Costs" id="production_costs">
|
||||||
|
<label name="analytic_account_materials"/>
|
||||||
|
<field name="analytic_account_materials" widget="selection"/>
|
||||||
|
<label name="analytic_account_labour"/>
|
||||||
|
<field name="analytic_account_labour" widget="selection"/>
|
||||||
|
<label name="analytic_account_indirect"/>
|
||||||
|
<field name="analytic_account_indirect" widget="selection"/>
|
||||||
|
<label name="analytic_account_services"/>
|
||||||
|
<field name="analytic_account_services" widget="selection"/>
|
||||||
|
<field name="costs" colspan="4"/>
|
||||||
|
<group col="8" string="Costs Summary" colspan="4" id="costs_summary">
|
||||||
|
<label name="material_costs"/>
|
||||||
|
<field name="material_costs"/>
|
||||||
|
<label name="labour_costs"/>
|
||||||
|
<field name="labour_costs"/>
|
||||||
|
<label name="indirect_costs"/>
|
||||||
|
<field name="indirect_costs"/>
|
||||||
|
<label name="total_cost"/>
|
||||||
|
<field name="total_cost"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
|
Loading…
Reference in New Issue