diff --git a/addons/stock/stock_demo.yml b/addons/stock/stock_demo.yml index 64be92f8d06..d925ba4dc8e 100644 --- a/addons/stock/stock_demo.yml +++ b/addons/stock/stock_demo.yml @@ -44,7 +44,7 @@ valuation: real_time cost_method: average property_stock_account_input: account.conf_o_income - property_stock_account_output: account.conf_o_expense + property_stock_account_output: account.a_expense - Stock user can handled production lot,inventory and picking, so let's check data with giving the access rights of user - diff --git a/addons/stock/test/shipment.yml b/addons/stock/test/shipment.yml index 4c715584756..909050d0483 100644 --- a/addons/stock/test/shipment.yml +++ b/addons/stock/test/shipment.yml @@ -1,3 +1,6 @@ +- + !context + uid: 'res_users_stock_manager' - I confirm outgoing shipment of 130 unit 15” LCD Monitor. - @@ -16,29 +19,68 @@ - !python {model: product.product}: | product = self.browse(cr, uid, ref('product_product_6'), context=context) - product.virtual_available == -30, "Vitual stock is not updated." + assert product.virtual_available == -30, "Vitual stock is not updated." - I confirm incomming shipment of 50 unit 15” LCD Monitor. - !workflow {model: stock.picking, action: button_confirm, ref: incomming_shipment} +- + I split incomming shipment into lots. each lot contain 10 unit 15” LCD Monitor. +- + !python {model: stock.picking}: | + shipment = self.browse(cr, uid, ref("incomming_shipment")) + move_ids = [x.id for x in shipment.move_lines] + context.update({'active_model': 'stock.move', 'active_id': move_ids[0], 'active_ids': move_ids}) +- + !record {model: stock.move.split, id: split_lot_incomming}: + line_ids: + - name: incoming_lot0 + quantity: 10 + - name: incoming_lot1 + quantity: 10 + - name: incoming_lot2 + quantity: 10 + - name: incoming_lot3 + quantity: 10 +- + !python {model: stock.move.split }: | + self.split_lot(cr, uid, [ref('split_lot_incomming')], context=context) +- + I check move lines after spliting +- + !python {model: stock.move}: | + mm = self.browse(cr, uid, ref("incomming_shipment_monitor")) + lot = self.pool.get('stock.move.split').browse(cr, uid, ref('split_lot_incomming'), context=context) + lot_ids = self.pool.get('stock.production.lot').search(cr, uid, [('name','in',[x.name for x in lot.line_ids])]) + assert len(lot_ids) == 4, 'lots of incomming shipment are not correspond.' + move_ids = self.search(cr, uid, [('location_dest_id','=',ref('location_monitor')),('prodlot_id','in',lot_ids)]) + assert len(move_ids) == 4, 'move lines are not correspond per prodcution lot after splited.' + for move in self.browse(cr, uid, move_ids, context=context): + assert move.prodlot_id.name in ['incoming_lot0', 'incoming_lot1', 'incoming_lot2', 'incoming_lot3'], "lot does not correspond." + assert move.product_qty == 10, "qty does not correspond per production lot." - I receive 40 unit 15” LCD Monitor so I make backorder of incomming shipment for 40 unit. - !python {model: stock.partial.picking}: | context.update({'active_model': 'stock.picking', 'active_id': ref('incomming_shipment'), 'active_ids': [ref('incomming_shipment')]}) - - !record {model: stock.partial.picking, id: partial_incomming}: - move_ids: - - quantity: 40 - product_id: product_product_6 - product_uom: product.product_uom_unit - move_id: incomming_shipment_monitor - location_id: stock_location_3 - location_dest_id: location_monitor -- - !python {model: stock.partial.picking }: | - self.do_partial(cr, uid, [ref('partial_incomming')], context=context) + !python {model: stock.partial.picking}: | + partial = [] + for move in self.pool.get('stock.picking').browse(cr, uid, ref("incomming_shipment")).move_lines: + if move.prodlot_id: + partial.append((0, 0, { + 'quantity': move.product_qty, + 'product_id': move.product_id.id, + 'product_uom': move.product_uom.id, + 'move_id': move.id, + 'location_id': move.location_id.id, + 'location_dest_id': move.location_dest_id.id, + 'prodlot_id': move.prodlot_id.id, + 'cost': move.product_id.standard_price + })) + partial_id = self.create(cr, uid, {'move_ids': partial}, context=context) + self.do_partial(cr, uid, [partial_id], context=context) - I check backorder shipment after received partial shipment. - @@ -46,10 +88,12 @@ shipment = self.browse(cr, uid, ref("incomming_shipment")) backorder = shipment.backorder_id assert backorder, "Backorder should be created after partial shipment." - assert backorder.state == 'done', "Backorder should be close after received." + assert backorder.state == 'done', "Backorder should be closed after received." + qty = 0 for move_line in backorder.move_lines: - assert move_line.product_qty == 40, "Qty in backorder does not correspond." assert move_line.state == 'done', "Move line of backorder should be closed." + qty += move_line.product_qty + assert qty == 40, "Qty in backorder does not correspond." - I receive another 10 unit 15” LCD Monitor. - @@ -64,18 +108,16 @@ - !python {model: stock.partial.picking }: | self.do_partial(cr, uid, [ref('partial_incomming')], context=context) - - - I check incomming shipment after received. + I check incomming shipment after receiving it. - !python {model: stock.picking}: | shipment = self.browse(cr, uid, ref("incomming_shipment")) - assert shipment.state == 'done', "shipment should be close after received." + assert shipment.state == 'done', "shipment should be closed after receiving." for move_line in shipment.move_lines: assert move_line.product_qty == 10, "Qty does not correspond." assert move_line.product_id.virtual_available == 20, "Virtual stock does not correspond." assert move_line.state == 'done', "Move line should be closed." - - I return last incomming shipment for 10 unit 15” LCD Monitor. - @@ -91,7 +133,7 @@ !python {model: stock.picking}: | # the cancel is not on the return, but on the incomming shipment (which now has a quantity of 10, thanks to the # backorder). This situation is a little weird as we returned a move that we finally cancelled... As result, only - # 30Kg from the original 50Kg will be counted in the stock (50 - 10 (cancelled quantity) - 10 (returned quantity)) + # 30Unit from the original 50Unit will be counted in the stock (50 - 10 (cancelled quantity) - 10 (returned quantity)) self.action_cancel(cr, uid, [ref("incomming_shipment")], context=context) - I make invoice of backorder of incomming shipment. @@ -118,41 +160,6 @@ product = self.browse(cr, uid, ref('product_product_6'), context=context) assert product.qty_available == 140, "Stock does not correspond." assert product.virtual_available == 0, "Vitual stock does not correspond." -- - I split incomming shipment into lots. each lot contain 10 unit 15” LCD Monitor. -- - !python {model: stock.picking}: | - shipment = self.browse(cr, uid, ref("incomming_shipment")) - move_ids = [x.id for x in shipment.backorder_id.move_lines] - context.update({'active_model': 'stock.move', 'active_id': move_ids[0], 'active_ids': move_ids}) -- - !record {model: stock.move.split, id: split_lot_incomming}: - line_ids: - - name: incoming_lot0 - quantity: 10 - - name: incoming_lot1 - quantity: 10 - - name: incoming_lot2 - quantity: 10 - - name: incoming_lot3 - quantity: 10 - -- - !python {model: stock.move.split }: | - self.split_lot(cr, uid, [ref('split_lot_incomming')], context=context) -- - I check move lines after spliting -- - !python {model: stock.move}: | - lot = self.pool.get('stock.move.split').browse(cr, uid, ref('split_lot_incomming'), context=context) - lot_ids = self.pool.get('stock.production.lot').search(cr, uid, [('name','in',[x.name for x in lot.line_ids])]) - assert len(lot_ids) == 4, 'lots of incomming shipment are not correspond.' - move_ids = self.search(cr, uid, [('location_dest_id','=',ref('location_monitor')),('prodlot_id','in',lot_ids)]) - assert len(move_ids) == 4, 'move lines are not correspond per prodcution lot after splited.' - for move in self.browse(cr, uid, move_ids, context=context): - assert move.prodlot_id.name in ['incoming_lot0', 'incoming_lot1', 'incoming_lot2', 'incoming_lot3'], "lot does not correspond." - assert move.product_qty == 10, "qty does not correspond per production lot." - context.update({'active_model':'stock.move', 'active_id':move_ids[0],'active_ids': move_ids}) - I check the stock valuation account entries. - @@ -165,45 +172,11 @@ for account_move_line in account_move.line_id: for stock_move in incomming_shipment.move_lines: if account_move_line.account_id.id == stock_move.product_id.property_stock_account_input.id: - assert account_move_line.credit == 10000.0, "Credit amount does not correspond." + assert account_move_line.credit == 14000.0, "Credit amount does not correspond." assert account_move_line.debit == 0.0, "Debit amount does not correspond." else: assert account_move_line.credit == 0.0, "Credit amount does not correspond." - assert account_move_line.debit == 10000.0, "Debit amount does not correspond." -- - I consume 1 unit 15” LCD Monitor from each incoming lots into internal production. -- - !record {model: stock.move.consume, id: consume_lot_incomming}: - product_qty: 1 - location_id: location_monitor -- - !python {model: stock.move.consume}: | - self.do_move_consume(cr, uid, [ref('consume_lot_incomming')], context=context) -- - I scrap 1 unit 15” LCD Monitor from each incoming lots into scrap location. -- - !record {model: stock.move.scrap, id: scrap_lot_incomming}: - product_qty: 1 -- - !python {model: stock.move.scrap}: | - self.move_scrap(cr, uid, [ref('scrap_lot_incomming')], context=context) -- - I check stock in scrap location and stock location shop0. -- - !python {model: stock.location}: | - ctx = {'product_id': ref('product_product_6')} - monitor_location = self.pool.get('stock.location').browse(cr, uid, ref('location_monitor'), context=ctx) - assert monitor_location.stock_real == 132.0, 'stock does not correspond in stock location shop0.' - scrapped_location = self.browse(cr, uid, ref('stock_location_scrapped'), context=ctx) - assert scrapped_location.stock_real == 1*4, 'scraped stock does not correspond in scrap location.' - -- - I check availabile stock after consumed and scraped. -- - !python {model: product.product}: | - product = self.browse(cr, uid, ref('product_product_6'), context=context) - assert product.qty_available == 132.0, "Stock does not correspond." - assert round(product.virtual_available, 2) == -8.00, "Vitual stock does not correspond." + assert account_move_line.debit == 14000.0, "Debit amount does not correspond." - I trace all incoming lots. - @@ -221,6 +194,40 @@ for move_line in shipment.move_lines: assert move_line.state == "assigned", "Move should be assigned." self.force_assign(cr, uid, [shipment.id]) + context.update({'active_model':'stock.move', 'active_id':shipment.move_lines[0].id,'active_ids': [shipment.move_lines[0].id]}) +- + I scrap 4 units of 15” LCD Monitor into scrap location. +- + !record {model: stock.move.scrap, id: scrap_monitor1}: + product_qty: 4 +- + !python {model: stock.move.scrap}: | + self.move_scrap(cr, uid, [ref('scrap_monitor1')], context=context) +- + I consume 4 units of 15” LCD Monitor. +- + !record {model: stock.move.consume, id: consume_monitor1}: + product_qty: 4 + location_id: location_monitor +- + !python {model: stock.move.consume}: | + self.do_move_consume(cr, uid, [ref('consume_monitor1')], context=context) +- + I check stock in scrap location and stock location shop0. +- + !python {model: stock.location}: | + ctx = {'product_id': ref('product_product_6')} + monitor_location = self.pool.get('stock.location').browse(cr, uid, ref('location_monitor'), context=ctx) + assert monitor_location.stock_real == 132.0, 'stock does not correspond in stock location shop0.' + scrapped_location = self.browse(cr, uid, ref('stock_location_scrapped'), context=ctx) + assert scrapped_location.stock_real == 4, 'scraped stock does not correspond in scrap location.' +- + I check availabile stock after consumed and scraped. +- + !python {model: product.product}: | + product = self.browse(cr, uid, ref('product_product_6'), context=context) + assert product.qty_available == 132.0, "Stock does not correspond." + assert round(product.virtual_available, 2) == -4.00, "Vitual stock does not correspond." - I deliver 5 unit 15” LCD Monitor to customer so I make partial deliver - @@ -277,5 +284,5 @@ - !python {model: product.product}: | product = self.browse(cr, uid, ref('product_product_6'), context=context) - assert round(product.qty_available, 2) == 2, "Stock does not correspond." - assert round(product.virtual_available, 2) == -8.00, "Vitual stock does not correspond." + assert round(product.qty_available, 2) == 6, "Stock does not correspond." + assert round(product.virtual_available, 2) == -4.00, "Vitual stock does not correspond."