2 I compute the production order.
4 !python {model: mrp.production}: |
5 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"), context=context)
6 order.action_compute(context=context)
8 I check production lines after compute.
10 !python {model: mrp.production}: |
11 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"), context=context)
12 assert len(order.product_lines) == 5, "Production lines are not generated proper."
19 for line in order.product_lines:
20 if line.product_id.id == ref('product.product_product_sidepanel0'): #SIDEPAN 2 PCE
21 assert not sidepanel, "Production line is already generated for SIDEPAN."
22 assert line.product_qty == (2.0*factor), "Qty is not correspond."
23 assert line.product_uom.id == ref('product.product_uom_unit'), "UOM is not correspond"
25 elif line.product_id.id == ref('product.product_product_woodlintelm0'): #LIN40 4*0.25 Meter
26 assert not woodlintelm, "Production line is already generated for LIN40."
27 assert line.product_qty == (4*0.25*factor), "Qty is not correspond."
28 assert line.product_uom.id == ref('product.product_uom_meter'), "UOM is not correspond"
30 elif line.product_id.id == ref('product.product_product_woodmm0'): #WOOD002 0.25 m
31 assert not woodmm0, "Production line is already generated for WOOD002."
32 assert line.product_qty == (0.25*factor), "Qty is not correspond."
33 assert line.product_uom.id == ref('product.product_uom_meter'), "UOM is not correspond"
35 elif line.product_id.id == ref('product.product_product_metalcleats0'): #METC000 4*3 PCE
36 assert not metalcleats, "Production line is already generated for METC000."
37 assert line.product_qty == (4*3*factor), "Qty is not correspond."
38 assert line.product_uom.id == ref('product.product_uom_unit'), "UOM is not correspond"
40 elif line.product_id.id == ref('product.product_product_woodmm10'): #WOOD010 0.083*3 m
41 assert not woodmm10, "Production line is already generated for WOOD010."
42 assert line.product_qty == (0.083*3*factor), "Qty is not correspond."
43 assert line.product_uom.id == ref('product.product_uom_meter'), "UOM is not correspond"
46 raise AssertionError('unknown order line: %s' % line)
47 assert sidepanel, "Production line is not generated for SIDEPAN."
48 assert woodlintelm, "Production line is not generated for LIN40."
49 assert woodmm0, "Production line is not generated for WOOD002."
50 assert metalcleats, "Production line is not generated for METC000."
51 assert woodmm10, "Production line is not generated for WOOD010."
54 Now I check workcenter lines.
56 !python {model: mrp.production}: |
57 from tools import float_compare
58 def assert_equals(value1, value2, msg, float_compare=float_compare):
59 assert float_compare(value1, value2, precision_digits=2) == 0, msg
60 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"), context=context)
61 assert len(order.workcenter_lines), "Workcenter lines are not generated proper."
62 for line in order.workcenter_lines:
63 wc = line.workcenter_id
64 hours = ((wc.time_start or 0.0)+(wc.time_stop or 0.0)+line.cycle*(wc.time_cycle or 0.0)) * (wc.time_efficiency or 1.0)
66 d, m = divmod(factor, wc.capacity_per_cycle)
67 cycle = (d + (m and 1.0 or 0.0))
68 if line.name == "Short time assembly - Assembly Section":
69 assert_equals(line.cycle, (4*cycle), "Computed cycles mismatch: %s" % (line.name))
70 assert_equals(line.hour, (2*cycle*4 + hours), "Computed hours mismatch: %s"% (line.name))
71 elif line.name == "Short time assembly - Rear Panel SHE100":
72 assert_equals(line.cycle, (1*cycle), "Computed cycles mismatch: %s" % (line.name))
73 assert_equals(line.hour, (2*cycle + hours), "Computed hours mismatch: %s"% (line.name))
74 elif line.name == "long time assembly - Shelf of 100cm":
75 assert_equals(line.cycle, (2*cycle), "Computed cycles mismatch: %s" % (line.name))
76 assert_equals(line.hour, (5*cycle + hours), "Computed hours mismatch: %s"% (line.name))
77 elif line.name == "Testing - Shelf of 100cm":
78 assert_equals(line.cycle, (1*cycle), "Computed cycles mismatch: %s" % (line.name))
79 assert_equals(line.hour, (1*cycle + hours), "Computed hours mismatch: %s"% (line.name))
80 elif line.name == "Packing - Shelf of 100cm":
81 assert_equals(line.cycle, (1*cycle), "Computed cycles mismatch: %s" % (line.name))
82 assert_equals(line.hour, (0.5*cycle + hours), "Computed hours mismatch: %s"% (line.name))
84 raise AssertionError('unknown workcenter line: %s' % line)
86 I confirm the Production Order.
88 !workflow {model: mrp.production, action: button_confirm, ref: mrp_production_shelf100cm}
90 I check details of Produce Move of Production Order to trace Final Product.
92 !python {model: mrp.production}: |
93 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
94 assert order.state == 'confirmed', "Production order should be confirmed."
95 assert order.move_created_ids, "Trace Record is not created for Final Product."
96 move = order.move_created_ids[0]
97 source_location_id = order.product_id.product_tmpl_id.property_stock_production.id
98 assert move.date == order.date_planned, "Planned date is not correspond."
99 assert move.product_id.id == order.product_id.id, "Product is not correspond."
100 assert move.product_uom.id == order.product_uom.id, "UOM is not correspond."
101 assert move.product_qty == order.product_qty, "Qty is not correspond."
102 assert move.product_uos_qty == order.product_uos and order.product_uos_qty or order.product_qty, "UOS qty is not correspond."
103 if order.product_uos:
104 assert move.product_uos.id == order.product_uos.id, "UOS is not correspond."
105 assert move.location_id.id == source_location_id, "Source Location is not correspond."
106 assert move.location_dest_id.id == order.location_dest_id.id, "Destination Location is not correspond."
108 if order.bom_id.routing_id and order.bom_id.routing_id.location_id:
109 routing_loc = order.bom_id.routing_id.location_id.id
110 date_planned = order.date_planned
111 for move_line in order.move_lines:
112 for order_line in order.product_lines:
113 if move_line.product_id.type not in ('product', 'consu'):
115 if move_line.product_id.id == order_line.product_id.id:
116 assert move_line.date == date_planned, "Planned date is not correspond in 'To consume line'."
117 assert move_line.product_qty == order_line.product_qty, "Qty is not correspond in 'To consume line'."
118 assert move_line.product_uom.id == order_line.product_uom.id, "UOM is not correspond in 'To consume line'."
119 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'."
120 if order_line.product_uos:
121 assert move_line.product_uos.id == order_line.product_uos.id, "UOS is not correspond in 'To consume line'."
122 assert move_line.location_id.id == routing_loc or order.location_src_id.id, "Source location is not correspond in 'To consume line'."
123 assert move_line.location_dest_id.id == source_location_id, "Destination Location is not correspond in 'To consume line'."
126 I check details of an Internal Shipment after confirmed production order to bring components in Raw Materials Location.
128 !python {model: mrp.production}: |
129 procurement = self.pool.get('procurement.order')
130 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
131 assert order.picking_id, 'Internal Shipment should be created!'
134 pick_type = 'internal'
136 if order.bom_id.routing_id and order.bom_id.routing_id.location_id:
137 routing_loc = order.bom_id.routing_id.location_id
138 if routing_loc.usage <> 'internal':
140 address_id = routing_loc.address_id and routing_loc.address_id.id or False
141 routing_loc = routing_loc.id
142 assert order.picking_id.type == pick_type, "Shipment should be Internal."
143 assert order.picking_id.address_id.id == address_id, "Shipment Address is not correspond with Adderss of Routing Location."
144 date_planned = order.date_planned
145 for move_line in order.picking_id.move_lines:
146 for order_line in order.product_lines:
147 if move_line.product_id.type not in ('product', 'consu'):
149 if move_line.product_id.id == order_line.product_id.id:
150 assert move_line.date == date_planned, "Planned date is not correspond."
151 assert move_line.product_qty == order_line.product_qty, "Qty is not correspond."
152 assert move_line.product_uom.id == order_line.product_uom.id, "UOM is not correspond."
153 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."
154 if order_line.product_uos:
155 assert move_line.product_uos.id == order_line.product_uos.id, "UOS is not correspond."
156 assert move_line.location_id.id == order.location_src_id.id, "Source location is not correspond."
157 assert move_line.location_dest_id.id == routing_loc or order.location_src_id.id, "Destination Location is not correspond."
158 procurement_ids = procurement.search(cr, uid, [('move_id','=',move_line.id)])
159 assert procurement_ids, "Procurement should be created for shipment line of raw materials."
160 shipment_procurement = procurement.browse(cr, uid, procurement_ids[0], context=context)
161 assert shipment_procurement.date_planned == date_planned, "Planned date is not correspond in procurement."
162 assert shipment_procurement.product_id.id == order_line.product_id.id, "Product is not correspond in procurement."
163 assert shipment_procurement.product_qty == order_line.product_qty, "Qty is not correspond in procurement."
164 assert shipment_procurement.product_uom.id == order_line.product_uom.id, "UOM is not correspond in procurement."
165 assert shipment_procurement.product_uos_qty == order_line.product_uos and order_line.product_uos_qty or order_line.product_qty, "UOS qty is not correspond in procurement."
166 if order_line.product_uos:
167 assert shipment_procurement.product_uos.id == order_line.product_uos.id, "UOS is not correspond in procurement."
168 assert shipment_procurement.location_id.id == order.location_src_id.id, "Location is not correspond in procurement."
169 assert shipment_procurement.procure_method == order_line.product_id.procure_method, "Procure method is not correspond in procurement."
172 I change production qty with 3 Dozen Shelf 100cm.
174 !python {model: change.production.qty}: |
175 context.update({'active_id': ref('mrp_production_shelf100cm')})
177 !record {model: change.production.qty, id: mrp_production_qty}:
180 !python {model: change.production.qty}: |
181 self.change_prod_qty(cr, uid, [ref("mrp_production_qty")], context=context)
183 I check qty after changed in production order.
185 !python {model: mrp.production}: |
186 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
187 assert order.product_qty == 3, "Qty is not changed in order."
188 move = order.move_created_ids[0]
189 assert move.product_qty == order.product_qty, "Qty is not changed in move line."
193 !python {model: procurement.order}: |
194 self.run_scheduler(cr, uid)
196 The production order is Waiting Goods, I forcefully done internal shipment.
198 !python {model: mrp.production}: |
199 self.force_production(cr, uid, [ref("mrp_production_shelf100cm")])
201 I check that production order in ready state after forcefully done internal shipment.
203 !python {model: mrp.production}: |
204 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
205 assert order.state == 'ready', 'Production order should be in Ready State.'
206 assert order.picking_id.state == 'done', 'Internal shipment should be done.'
208 Now I start production.
210 !workflow {model: mrp.production, action: button_produce, ref: mrp_production_shelf100cm}
212 I check that production order in production state after start production.
214 !python {model: mrp.production}: |
215 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
216 assert order.state == 'in_production', 'Production order should be in production State.'
218 I consume raw materials and put one material in scrap location due to waste it.
220 !python {model: mrp.production}: |
221 scrap_location_ids = self.pool.get('stock.location').search(cr, uid, [('scrap_location','=',True)])
222 scrap_location_id = scrap_location_ids[0]
223 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
224 for move in order.move_lines:
225 move.action_consume(move.product_qty)
226 if move.product_id.id == ref("product.product_product_metalcleats0"):
227 move.action_scrap(5.0, scrap_location_id)
231 !python {model: mrp.product.produce}: |
232 context.update({'active_id': ref('mrp_production_shelf100cm')})
234 !record {model: mrp.product.produce, id: mrp_product_produce1}:
235 mode: 'consume_produce'
237 !python {model: mrp.product.produce}: |
238 self.do_produce(cr, uid, [ref('mrp_product_produce1')], context=context)
240 I check production order after produced.
242 !python {model: mrp.production}: |
243 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
244 assert order.state == 'done', "Production order should be closed."
246 I check Total Costs at End of Production.
248 !python {model: mrp.production}: |
249 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
250 account_analytic_line = self.pool.get('account.analytic.line')
255 return math.ceil(f / r) * r
257 for wc_line in order.workcenter_lines:
258 wc = wc_line.workcenter_id
259 accounts = [wc.costs_hour_account_id, wc.costs_cycle_account_id]
260 cost_per_cyle = wc_line.cycle * wc.costs_cycle
261 cost_per_hours = wc_line.hour * wc.costs_hour
262 if accounts and wc.costs_journal_id and wc.costs_general_account_id and (cost_per_cyle or cost_per_hours):
263 line_ids = account_analytic_line.search(cr, uid, [('name','ilike',wc_line.name)])
264 assert line_ids, 'Costs lines are not generated.'
265 for line in account_analytic_line.browse(cr, uid, line_ids, context=context):
266 if wc.costs_hour_account_id and line.account_id.id == wc.costs_hour_account_id.id:
267 assert rounding(line.unit_amount, 3) == rounding(wc_line.hour, 3), "Cost Unit Amount is not correspond."
268 assert rounding(line.amount, 3) == rounding(cost_per_hours, 3), "Cost amount is not correspond."
269 elif wc.costs_cycle_account_id and line.account_id.id == wc.costs_cycle_account_id.id:
270 assert rounding(line.unit_amount, 3) == rounding(wc_line.cycle, 3), "Cost Unit Amount is not correspond."
271 assert rounding(line.amount, 3) == rounding(cost_per_cyle, 3), "Cost Amount is not correspond."
273 raise AssertionError('unknown cost line: %s' % line)
274 assert line.general_account_id.id == wc.costs_general_account_id.id, "General Account is not correspond."
275 assert line.journal_id.id == wc.costs_journal_id.id, "Account Journal is not correspond."
276 assert line.product_id.id == wc.product_id.id, "Product is not correspond."
277 assert line.product_uom_id.id == wc.product_id.uom_id.id, "UOM is not correspond."
280 I print a "BOM Structure".
282 !python {model: mrp.production}: |
283 import netsvc, tools, os
284 order = self.browse(cr, uid, ref("mrp_production_shelf100cm"))
285 (data, format) = netsvc.LocalService('report.bom.structure').create(cr, uid, [order.bom_id.id], {}, {})
286 if tools.config['test_report_directory']:
287 file(os.path.join(tools.config['test_report_directory'], 'mrp-bom_structure_report.'+format), 'wb+').write(data)
290 I print "Production Order".
292 !python {model: mrp.production}: |
293 import netsvc, tools, os
294 (data, format) = netsvc.LocalService('report.mrp.production.order').create(cr, uid, [ref("mrp_production_shelf100cm")], {}, {})
295 if tools.config['test_report_directory']:
296 file(os.path.join(tools.config['test_report_directory'], 'mrp-production_order_report.'+format), 'wb+').write(data)
299 I print "Work Center Load Report".
301 !python {model: mrp.workcenter}: |
303 ctx.update({'model': 'mrp.workcenter','active_ids': [ref('mrp_workcenter_0'),ref('mrp_workcenter_1')]})
304 data_dict = {'time_unit': 'day', 'measure_unit': 'hours'}
305 from tools import test_reports
306 test_reports.try_report_action(cr, uid, 'action_mrp_workcenter_load_wizard',wiz_data=data_dict, context=ctx, our_module='mrp')