[IMP] mrp*: adaptation due to the new Sale module
Major changes: - No use of UoS anymore Reason: complete rewrite of the Sale module. Responsible: fp, dbo, nim
This commit is contained in:
+5
-53
@@ -62,7 +62,6 @@ class mrp_workcenter(osv.osv):
|
||||
'costs_cycle': fields.float('Cost per cycle', help="Specify Cost of Work Center per cycle."),
|
||||
'costs_cycle_account_id': fields.many2one('account.analytic.account', 'Cycle Account', domain=[('type','!=','view')],
|
||||
help="Fill this only if you want automatic analytic accounting entries on production orders."),
|
||||
'costs_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'),
|
||||
'costs_general_account_id': fields.many2one('account.account', 'General Account', domain=[('deprecated', '=', False)]),
|
||||
'resource_id': fields.many2one('resource.resource','Resource', ondelete='cascade', required=True),
|
||||
'product_id': fields.many2one('product.product','Work Center Product', help="Fill this product to easily track your production costs in the analytic accounting."),
|
||||
@@ -320,9 +319,7 @@ class mrp_bom(osv.osv):
|
||||
'name': bom_line_id.product_id.name,
|
||||
'product_id': bom_line_id.product_id.id,
|
||||
'product_qty': quantity,
|
||||
'product_uom': bom_line_id.product_uom.id,
|
||||
'product_uos_qty': bom_line_id.product_uos and _factor(bom_line_id.product_uos_qty * factor, bom_line_id.product_efficiency, bom_line_id.product_rounding) or False,
|
||||
'product_uos': bom_line_id.product_uos and bom_line_id.product_uos.id or False,
|
||||
'product_uom': bom_line_id.product_uom.id
|
||||
})
|
||||
elif bom_id:
|
||||
all_prod = [bom.product_tmpl_id.id] + (previous_products or [])
|
||||
@@ -410,8 +407,6 @@ class mrp_bom_line(osv.osv):
|
||||
"it will be directly replaced by the raw materials of its own BoM, without triggering"
|
||||
"an extra manufacturing order."),
|
||||
'product_id': fields.many2one('product.product', 'Product', required=True),
|
||||
'product_uos_qty': fields.float('Product UOS Qty'),
|
||||
'product_uos': fields.many2one('product.uom', 'Product UOS', help="Product UOS (Unit of Sale) is the unit of measurement for the invoicing and promotion of stock."),
|
||||
'product_qty': fields.float('Product Quantity', required=True, digits_compute=dp.get_precision('Product Unit of Measure')),
|
||||
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True,
|
||||
help="Unit of Measure (Unit of Measure) is the unit of measurement for the inventory control"),
|
||||
@@ -473,12 +468,7 @@ class mrp_bom_line(osv.osv):
|
||||
prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
|
||||
res['value'] = {
|
||||
'product_uom': prod.uom_id.id,
|
||||
'product_uos_qty': 0,
|
||||
'product_uos': False
|
||||
}
|
||||
if prod.uos_id.id:
|
||||
res['value']['product_uos_qty'] = product_qty * prod.uos_coeff
|
||||
res['value']['product_uos'] = prod.uos_id.id
|
||||
return res
|
||||
|
||||
class mrp_production(osv.osv):
|
||||
@@ -572,8 +562,6 @@ class mrp_production(osv.osv):
|
||||
domain=[('type', 'in', ['product', 'consu'])]),
|
||||
'product_qty': fields.float('Product Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'product_uos_qty': fields.float('Product UoS Quantity', readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'product_uos': fields.many2one('product.uom', 'Product UoS', readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'progress': fields.function(_get_progress, type='float',
|
||||
string='Production progress'),
|
||||
|
||||
@@ -698,8 +686,6 @@ class mrp_production(osv.osv):
|
||||
'product_uom': False,
|
||||
'bom_id': False,
|
||||
'routing_id': False,
|
||||
'product_uos_qty': 0,
|
||||
'product_uos': False,
|
||||
'product_tmpl_id': False
|
||||
}}
|
||||
bom_obj = self.pool.get('mrp.bom')
|
||||
@@ -710,10 +696,7 @@ class mrp_production(osv.osv):
|
||||
bom_point = bom_obj.browse(cr, uid, bom_id, context=context)
|
||||
routing_id = bom_point.routing_id.id or False
|
||||
product_uom_id = product.uom_id and product.uom_id.id or False
|
||||
result['value'] = {'product_uos_qty': 0, 'product_uos': False, 'product_uom': product_uom_id, 'bom_id': bom_id, 'routing_id': routing_id, 'product_tmpl_id': product.product_tmpl_id}
|
||||
if product.uos_id.id:
|
||||
result['value']['product_uos_qty'] = product_qty * product.uos_coeff
|
||||
result['value']['product_uos'] = product.uos_id.id
|
||||
result['value'] = {'product_uom': product_uom_id, 'bom_id': bom_id, 'routing_id': routing_id, 'product_tmpl_id': product.product_tmpl_id}
|
||||
return result
|
||||
|
||||
def bom_id_change(self, cr, uid, ids, bom_id, context=None):
|
||||
@@ -1065,7 +1048,7 @@ class mrp_production(osv.osv):
|
||||
analytic_line_obj = self.pool.get('account.analytic.line')
|
||||
for wc_line in production.workcenter_lines:
|
||||
wc = wc_line.workcenter_id
|
||||
if wc.costs_journal_id and wc.costs_general_account_id:
|
||||
if wc.costs_general_account_id:
|
||||
# Cost per hour
|
||||
value = wc_line.hour * wc.costs_hour
|
||||
account = wc.costs_hour_account_id.id
|
||||
@@ -1079,7 +1062,6 @@ class mrp_production(osv.osv):
|
||||
'amount': value,
|
||||
'account_id': account,
|
||||
'general_account_id': wc.costs_general_account_id.id,
|
||||
'journal_id': wc.costs_journal_id.id,
|
||||
'ref': wc.code,
|
||||
'product_id': wc.product_id.id,
|
||||
'unit_amount': wc_line.hour,
|
||||
@@ -1095,7 +1077,6 @@ class mrp_production(osv.osv):
|
||||
'amount': value,
|
||||
'account_id': account,
|
||||
'general_account_id': wc.costs_general_account_id.id,
|
||||
'journal_id': wc.costs_journal_id.id,
|
||||
'ref': wc.code,
|
||||
'product_id': wc.product_id.id,
|
||||
'unit_amount': wc_line.cycle,
|
||||
@@ -1138,8 +1119,6 @@ class mrp_production(osv.osv):
|
||||
'product_id': production.product_id.id,
|
||||
'product_uom': production.product_uom.id,
|
||||
'product_uom_qty': production.product_qty,
|
||||
'product_uos_qty': production.product_uos and production.product_uos_qty or False,
|
||||
'product_uos': production.product_uos and production.product_uos.id or False,
|
||||
'location_id': source_location_id,
|
||||
'location_dest_id': destination_location_id,
|
||||
'move_dest_id': production.move_prod_id.id,
|
||||
@@ -1214,7 +1193,7 @@ class mrp_production(osv.osv):
|
||||
}, context=context)
|
||||
return move
|
||||
|
||||
def _make_consume_line_from_data(self, cr, uid, production, product, uom_id, qty, uos_id, uos_qty, context=None):
|
||||
def _make_consume_line_from_data(self, cr, uid, production, product, uom_id, qty, context=None):
|
||||
stock_move = self.pool.get('stock.move')
|
||||
loc_obj = self.pool.get('stock.location')
|
||||
# Internal shipment is created for Stockable and Consumer Products
|
||||
@@ -1235,8 +1214,6 @@ class mrp_production(osv.osv):
|
||||
'product_id': product.id,
|
||||
'product_uom_qty': qty,
|
||||
'product_uom': uom_id,
|
||||
'product_uos_qty': uos_id and uos_qty or False,
|
||||
'product_uos': uos_id or False,
|
||||
'location_id': source_location_id,
|
||||
'location_dest_id': destination_location_id,
|
||||
'company_id': production.company_id.id,
|
||||
@@ -1256,27 +1233,7 @@ class mrp_production(osv.osv):
|
||||
return move_id
|
||||
|
||||
def _make_production_consume_line(self, cr, uid, line, context=None):
|
||||
return self._make_consume_line_from_data(cr, uid, line.production_id, line.product_id, line.product_uom.id, line.product_qty, line.product_uos.id, line.product_uos_qty, context=context)
|
||||
|
||||
|
||||
def _make_service_procurement(self, cr, uid, line, context=None):
|
||||
prod_obj = self.pool.get('product.product')
|
||||
if prod_obj.need_procurement(cr, uid, [line.product_id.id], context=context):
|
||||
vals = {
|
||||
'name': line.production_id.name,
|
||||
'origin': line.production_id.name,
|
||||
'company_id': line.production_id.company_id.id,
|
||||
'date_planned': line.production_id.date_planned,
|
||||
'product_id': line.product_id.id,
|
||||
'product_qty': line.product_qty,
|
||||
'product_uom': line.product_uom.id,
|
||||
'product_uos_qty': line.product_uos_qty,
|
||||
'product_uos': line.product_uos.id,
|
||||
}
|
||||
proc_obj = self.pool.get("procurement.order")
|
||||
proc = proc_obj.create(cr, uid, vals, context=context)
|
||||
proc_obj.run(cr, uid, [proc], context=context)
|
||||
|
||||
return self._make_consume_line_from_data(cr, uid, line.production_id, line.product_id, line.product_uom.id, line.product_qty, context=context)
|
||||
|
||||
def action_confirm(self, cr, uid, ids, context=None):
|
||||
""" Confirms production order.
|
||||
@@ -1288,14 +1245,11 @@ class mrp_production(osv.osv):
|
||||
self.action_compute(cr, uid, uncompute_ids, context=context)
|
||||
for production in self.browse(cr, uid, ids, context=context):
|
||||
self._make_production_produce_line(cr, uid, production, context=context)
|
||||
|
||||
stock_moves = []
|
||||
for line in production.product_lines:
|
||||
if line.product_id.type in ['product', 'consu']:
|
||||
stock_move_id = self._make_production_consume_line(cr, uid, line, context=context)
|
||||
stock_moves.append(stock_move_id)
|
||||
else:
|
||||
self._make_service_procurement(cr, uid, line, context=context)
|
||||
if stock_moves:
|
||||
self.pool.get('stock.move').action_confirm(cr, uid, stock_moves, context=context)
|
||||
production.write({'state': 'confirmed'})
|
||||
@@ -1356,7 +1310,5 @@ class mrp_production_product_line(osv.osv):
|
||||
'product_id': fields.many2one('product.product', 'Product', required=True),
|
||||
'product_qty': fields.float('Product Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
|
||||
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
|
||||
'product_uos_qty': fields.float('Product UOS Quantity'),
|
||||
'product_uos': fields.many2one('product.uom', 'Product UOS'),
|
||||
'production_id': fields.many2one('mrp.production', 'Production Order', select=True),
|
||||
}
|
||||
|
||||
@@ -12,13 +12,11 @@
|
||||
</record>
|
||||
|
||||
<record id="account_assembly_hours" model="account.analytic.account">
|
||||
<field name="type">normal</field>
|
||||
<field name="code">ASML - HOUR</field>
|
||||
<field name="name">Costing Account For Hours of Assembly.</field>
|
||||
</record>
|
||||
|
||||
<record id="account_assembly_cycle" model="account.analytic.account">
|
||||
<field name="type">normal</field>
|
||||
<field name="code">ASML - Cycle</field>
|
||||
<field name="name">Costing Account For Cycle of Assembly.</field>
|
||||
</record>
|
||||
@@ -49,7 +47,6 @@
|
||||
<field name="costs_hour_account_id" ref="account_assembly_hours"/>
|
||||
<field name="costs_cycle">0.05</field>
|
||||
<field name="costs_cycle_account_id" ref="account_assembly_cycle"/>
|
||||
<field name="costs_journal_id" ref="account.exp"/>
|
||||
<field name="calendar_id" ref="resource.timesheet_group1"/>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -204,7 +204,6 @@
|
||||
<field name="costs_hour_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="costs_cycle"/>
|
||||
<field name="costs_cycle_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="costs_journal_id" attrs="{'required':['|',('costs_hour_account_id', '=', True),('costs_cycle_account_id', '=', True)]}" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="costs_general_account_id" attrs="{ 'required':['|',('costs_cycle_account_id', '=', True),('costs_hour_account_id', '=', True)]}" groups="analytic.group_analytic_accounting"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -518,8 +517,6 @@
|
||||
<field name="product_rounding"/>
|
||||
<field name="product_efficiency"/>
|
||||
<field name="product_uom" options="{'no_open':True,'no_create':True}" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
|
||||
<field name="product_uos_qty" groups="product.group_uos"/>
|
||||
<field name="product_uos" groups="product.group_uos"/>
|
||||
<field name="date_start"/>
|
||||
<field name="date_stop"/>
|
||||
<field name="routing_id"/>
|
||||
@@ -611,11 +608,6 @@
|
||||
name="%(mrp.action_change_production_qty)d"
|
||||
string="Update" states="confirmed" class="oe_edit_only oe_link"/>
|
||||
</div>
|
||||
<label for="product_uos_qty" groups="product.group_uos"/>
|
||||
<div groups="product.group_uos" class="o_row">
|
||||
<field name="product_uos_qty"/>
|
||||
<field name="product_uos"/>
|
||||
</div>
|
||||
<field name="date_planned"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -941,8 +933,6 @@
|
||||
<field name="product_id"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="product_uom" options="{'no_open':True,'no_create':True}" groups="product.group_uom"/>
|
||||
<field name="product_uos_qty" groups="product.group_uos"/>
|
||||
<field name="product_uos" groups="product.group_uos"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
@@ -955,8 +945,6 @@
|
||||
<field name="product_id"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="product_uom" options="{'no_open':True,'no_create':True}" groups="product.group_uom"/>
|
||||
<field name="product_uos_qty" groups="product.group_uos"/>
|
||||
<field name="product_uos" groups="product.group_uos"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -77,8 +77,6 @@ class procurement_order(osv.osv):
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_qty': procurement.product_qty,
|
||||
'product_uom': procurement.product_uom.id,
|
||||
'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
|
||||
'product_uos': procurement.product_uos and procurement.product_uos.id or False,
|
||||
'location_src_id': procurement.location_id.id,
|
||||
'location_dest_id': procurement.location_id.id,
|
||||
'bom_id': bom_id,
|
||||
|
||||
@@ -21,7 +21,6 @@ access_stock_location_mrp_worker,stock.location mrp_worker,stock.model_stock_loc
|
||||
access_stock_move_mrp_worker,stock.move mrp_worker,stock.model_stock_move,mrp.group_mrp_user,1,1,1,0
|
||||
access_stock_picking_mrp_worker,stock.picking mrp_worker,stock.model_stock_picking,mrp.group_mrp_user,1,1,1,1
|
||||
access_stock_warehouse,stock.warehouse mrp_worker,stock.model_stock_warehouse,mrp.group_mrp_user,1,0,0,0
|
||||
access_account_analytic_journal_mrp_worker,account.analytic.journal mrp_worker,analytic.model_account_analytic_journal,mrp.group_mrp_user,1,0,0,0
|
||||
access_account_account,account.account mrp_worker,account.model_account_account,mrp.group_mrp_user,1,0,0,0
|
||||
access_hr_timesheet_group_mrp_worker,resource.calendar mrp_manager,resource.model_resource_calendar,mrp.group_mrp_manager,1,1,1,1
|
||||
access_procurement_user,procurement.order.user,model_procurement_order,base.group_user,1,1,1,1
|
||||
|
||||
|
+1
-5
@@ -53,8 +53,6 @@ class StockMove(osv.osv):
|
||||
'product_id': line['product_id'],
|
||||
'product_uom': line['product_uom'],
|
||||
'product_uom_qty': line['product_qty'],
|
||||
'product_uos': line['product_uos'],
|
||||
'product_uos_qty': line['product_uos_qty'],
|
||||
'state': 'draft', #will be confirmed below
|
||||
'name': line['name'],
|
||||
'procurement_id': move.procurement_id.id,
|
||||
@@ -63,7 +61,7 @@ class StockMove(osv.osv):
|
||||
mid = move_obj.copy(cr, uid, move.id, default=valdef, context=context)
|
||||
to_explode_again_ids.append(mid)
|
||||
else:
|
||||
if prod_obj.need_procurement(cr, uid, [product.id], context=context):
|
||||
if prod_obj.type in ('consu','product'):
|
||||
valdef = {
|
||||
'name': move.rule_id and move.rule_id.name or "/",
|
||||
'origin': move.origin,
|
||||
@@ -72,8 +70,6 @@ class StockMove(osv.osv):
|
||||
'product_id': line['product_id'],
|
||||
'product_qty': line['product_qty'],
|
||||
'product_uom': line['product_uom'],
|
||||
'product_uos_qty': line['product_uos_qty'],
|
||||
'product_uos': line['product_uos'],
|
||||
'group_id': move.group_id.id,
|
||||
'priority': move.priority,
|
||||
'partner_dest_id': move.partner_id.id,
|
||||
|
||||
@@ -42,9 +42,6 @@
|
||||
assert move.product_id.id == order.product_id.id, "Product does not correspond."
|
||||
assert move.product_uom.id == order.product_uom.id, "UOM does not correspond."
|
||||
assert move.product_qty == order.product_qty, "Qty does not correspond."
|
||||
assert move.product_uos_qty == order.product_uos and order.product_uos_qty or order.product_qty, "UOS qty does not correspond."
|
||||
if order.product_uos:
|
||||
assert move.product_uos.id == order.product_uos.id, "UOS does not correspond."
|
||||
assert move.location_id.id == source_location_id, "Source Location does not correspond."
|
||||
assert move.location_dest_id.id == order.location_dest_id.id, "Destination Location does not correspond."
|
||||
routing_loc = None
|
||||
@@ -59,9 +56,6 @@
|
||||
assert move_line.date == date_planned, "Planned date does not correspond in 'To consume line'."
|
||||
assert move_line.product_qty == order_line.product_qty, "Qty does not correspond in 'To consume line'."
|
||||
assert move_line.product_uom.id == order_line.product_uom.id, "UOM does not correspond in 'To consume line'."
|
||||
assert move_line.product_uos_qty == order_line.product_uos and order_line.product_uos_qty or order_line.product_qty, "UOS qty is not correspond in 'To consume line'."
|
||||
if order_line.product_uos:
|
||||
assert move_line.product_uos.id == order_line.product_uos.id, "UOS is not correspond in 'To consume line'."
|
||||
assert move_line.location_id.id == routing_loc or order.location_src_id.id, "Source location is not correspond in 'To consume line'."
|
||||
assert move_line.location_dest_id.id == source_location_id, "Destination Location is not correspond in 'To consume line'."
|
||||
-
|
||||
@@ -91,14 +85,11 @@
|
||||
assert proc.product_qty == order_line.product_qty, "Qty does not correspond"
|
||||
assert proc.location_id.id == order.location_src_id.id, "Input location and procurement location do not correspond"
|
||||
assert proc.product_uom.id == order_line.product_uom.id, "UOM does not correspond in procurement."
|
||||
assert proc.product_uos_qty == order_line.product_uos and order_line.product_uos_qty or order_line.product_qty, "UOS qty does not correspond in procurement."
|
||||
# procurement state should be `confirmed` at this stage, except if procurement_jit is installed, in which
|
||||
# case it could already be in `running` or `exception` state (not enough stock)
|
||||
expected_states = ('confirmed', 'running', 'exception')
|
||||
assert proc.state in expected_states, 'Procurement state is `%s` for %s, expected one of %s' % \
|
||||
(proc.state, proc.product_id.name, expected_states)
|
||||
if order_line.product_uos:
|
||||
assert proc.product_uos.id == order_line.product_uos.id, "UOS is not correspond in procurement."
|
||||
-
|
||||
I change production qty with 3 PC Assemble SC349.
|
||||
-
|
||||
@@ -184,7 +175,7 @@
|
||||
accounts = [wc.costs_hour_account_id, wc.costs_cycle_account_id]
|
||||
cost_per_cyle = wc_line.cycle * wc.costs_cycle
|
||||
cost_per_hours = wc_line.hour * wc.costs_hour
|
||||
if accounts and wc.costs_journal_id and wc.costs_general_account_id and (cost_per_cyle or cost_per_hours):
|
||||
if accounts and wc.costs_general_account_id and (cost_per_cyle or cost_per_hours):
|
||||
line_ids = account_analytic_line.search(cr, uid, [('name','ilike',wc_line.name)])
|
||||
assert line_ids, 'Costs lines are not generated.'
|
||||
for line in account_analytic_line.browse(cr, uid, line_ids, context=context):
|
||||
@@ -197,6 +188,5 @@
|
||||
else:
|
||||
raise AssertionError('unknown cost line: %s' % line)
|
||||
assert line.general_account_id.id == wc.costs_general_account_id.id, "General Account is not correspond."
|
||||
assert line.journal_id.id == wc.costs_journal_id.id, "Account Journal is not correspond."
|
||||
assert line.product_id.id == wc.product_id.id, "Product does not correspond."
|
||||
assert line.product_uom_id.id == wc.product_id.uom_id.id, "UOM does not correspond."
|
||||
|
||||
@@ -60,7 +60,7 @@ class stock_move_consume(osv.osv_memory):
|
||||
#consumed more in wizard than previously planned
|
||||
extra_more_qty = qty - consumed_qty
|
||||
#create new line for a remaining qty of the product
|
||||
extra_move_id = production_obj._make_consume_line_from_data(cr, uid, production, data.product_id, data.product_id.uom_id.id, extra_more_qty, False, 0, context=context)
|
||||
extra_move_id = production_obj._make_consume_line_from_data(cr, uid, production, data.product_id, data.product_id.uom_id.id, extra_more_qty, context=context)
|
||||
move_obj.write(cr, uid, [extra_move_id], {'restrict_lot_id': data.restrict_lot_id.id}, context=context)
|
||||
move_obj.action_done(cr, uid, [extra_move_id], context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
@@ -356,7 +356,7 @@ class mrp_repair(osv.osv):
|
||||
'account_id': account_id,
|
||||
'quantity': operation.product_uom_qty,
|
||||
'invoice_line_tax_ids': [(6, 0, [x.id for x in operation.tax_id])],
|
||||
'uos_id': operation.product_uom.id,
|
||||
'uom_id': operation.product_uom.id,
|
||||
'price_unit': operation.price_unit,
|
||||
'price_subtotal': operation.product_uom_qty * operation.price_unit,
|
||||
'product_id': operation.product_id and operation.product_id.id or False
|
||||
@@ -385,7 +385,7 @@ class mrp_repair(osv.osv):
|
||||
'account_id': account_id,
|
||||
'quantity': fee.product_uom_qty,
|
||||
'invoice_line_tax_ids': [(6, 0, [x.id for x in fee.tax_id])],
|
||||
'uos_id': fee.product_uom.id,
|
||||
'uom_id': fee.product_uom.id,
|
||||
'product_id': fee.product_id and fee.product_id.id or False,
|
||||
'price_unit': fee.price_unit,
|
||||
'price_subtotal': fee.product_uom_qty * fee.price_unit
|
||||
|
||||
Reference in New Issue
Block a user