From 10f073edf1533779244301a018f5f4c988f55166 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Fri, 4 Apr 2014 09:45:39 +0200 Subject: [PATCH 1/8] [FIX] stock_account: typo in domain. Courtesy of hbto [Vauxoo] bzr revid: qdp-launchpad@openerp.com-20140404074539-03ivqk8jztynaicd --- addons/stock_account/product_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock_account/product_view.xml b/addons/stock_account/product_view.xml index 47b159d9c46..93570d50ee8 100644 --- a/addons/stock_account/product_view.xml +++ b/addons/stock_account/product_view.xml @@ -59,7 +59,7 @@
From e175a4b00b5cd922f96c0eb84fd5a6a85d2a7d10 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 4 Apr 2014 13:34:36 +0200 Subject: [PATCH 2/8] [IMP] Do prepare partial should not give default location of picking type, but of picking bzr revid: jco@openerp.com-20140404113436-sb188wlqz8g5m5na --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 9798c4e24fd..a33bf67f586 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1021,7 +1021,7 @@ class stock_picking(osv.osv): product_putaway_strats[product.id] = putaway_strat if putaway_strat: location = self._picking_putaway_resolution(cr, uid, picking, product, putaway_strat, context=context) - return location or picking.picking_type_id.default_location_dest_id.id or picking.location_dest_id.id + return location or picking.location_dest_id.id pack_obj = self.pool.get("stock.quant.package") quant_obj = self.pool.get("stock.quant") From 511d5b6cc49a69fc3aaff2ea06822e85ffe927dc Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 7 Apr 2014 13:33:31 +0200 Subject: [PATCH 3/8] [FIX] Fix report printing from barcode scanner bzr revid: jco@openerp.com-20140407113331-nlrfnd2iykktnfnn --- addons/report/static/src/js/qwebactionmanager.js | 2 +- addons/stock/stock.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/report/static/src/js/qwebactionmanager.js b/addons/report/static/src/js/qwebactionmanager.js index dac8dcacf25..e7222330ebb 100644 --- a/addons/report/static/src/js/qwebactionmanager.js +++ b/addons/report/static/src/js/qwebactionmanager.js @@ -64,7 +64,7 @@ openerp.report = function(instance) { self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \ system. The report will be shown in html.

\ wkhtmltopdf.org'), true); - window.open(report_url.substring(12), '_blank', 'height=768,width=1024'); + window.open(report_url.substring(11), '_blank', 'height=768,width=1024'); instance.web.unblockUI(); } else { if (presence == 'upgrade') { diff --git a/addons/stock/stock.py b/addons/stock/stock.py index a33bf67f586..6bb3f3f0bfc 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -839,6 +839,8 @@ class stock_picking(osv.osv): def do_print_picking(self, cr, uid, ids, context=None): '''This function prints the picking list''' + context = context or {} + context['active_ids'] = ids return self.pool.get("report").get_action(cr, uid, ids, 'stock.report_picking', context=context) def action_confirm(self, cr, uid, ids, context=None): From 6a50b1663b295acf1050a9eb8d6c7364af9acf57 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 7 Apr 2014 16:14:58 +0200 Subject: [PATCH 4/8] [IMP] group_id on orderpoint + copy of orderpoint/package should not copy procurements/quants child packages bzr revid: jco@openerp.com-20140407141458-xg1jbl2ctnfzs5eh --- addons/stock/procurement.py | 1 + addons/stock/stock.py | 10 ++++++++-- addons/stock/stock_view.xml | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index 3a95e3278ae..29afdffd19b 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -341,6 +341,7 @@ class procurement_order(osv.osv): 'origin': orderpoint.name, 'warehouse_id': orderpoint.warehouse_id.id, 'orderpoint_id': orderpoint.id, + 'group_id': orderpoint.group_id.id, } def _product_virtual_get(self, cr, uid, order_point): diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 6bb3f3f0bfc..83cbc8877a0 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -813,7 +813,7 @@ class stock_picking(osv.osv): _defaults = { 'name': lambda self, cr, uid, context: '/', 'state': 'draft', - 'move_type': 'one', + 'move_type': 'direct', 'priority': '1', # normal 'date': fields.datetime.now, 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.picking', context=c), @@ -834,6 +834,7 @@ class stock_picking(osv.osv): default['backorder_id'] = False default['pack_operation_ids'] = [] default['date_done'] = False + return super(stock_picking, self).copy(cr, uid, id, default, context) @@ -3610,6 +3611,8 @@ class stock_package(osv.osv): default = {} if not default.get('name'): default['name'] = self.pool.get('ir.sequence').get(cr, uid, 'stock.quant.package') or _('Unknown Pack') + default['quant_ids'] = [] + default['children_ids'] = [] return super(stock_package, self).copy(cr, uid, id, default, context=context) def copy_pack(self, cr, uid, id, default_pack_values=None, default=None, context=None): @@ -3917,7 +3920,8 @@ class stock_warehouse_orderpoint(osv.osv): 'qty_multiple': fields.integer('Qty Multiple', required=True, help="The procurement quantity will be rounded up to this multiple."), 'procurement_ids': fields.one2many('procurement.order', 'orderpoint_id', 'Created Procurements'), - 'company_id': fields.many2one('res.company', 'Company', required=True) + 'group_id': fields.many2one('procurement.group', 'Procurement Group', help="Moves created through this orderpoint will be put in this procurement group. If none is given, the moves generated by procurement rules will be grouped into one big picking. "), + 'company_id': fields.many2one('res.company', 'Company', required=True), } _defaults = { 'active': lambda *a: 1, @@ -3973,6 +3977,8 @@ class stock_warehouse_orderpoint(osv.osv): default = {} default.update({ 'name': self.pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint') or '', + 'procurement_ids': [], + 'group_id': False }) return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context=context) diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index c4c8cea461a..499bc57baee 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -1576,6 +1576,7 @@ + From 6a0011e87c4ce27c36e468c8b02bb0cae16ff62f Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 7 Apr 2014 18:06:24 +0200 Subject: [PATCH 5/8] [IMP] Remove auto_force_assign and change default source location in do_prepare_partial bzr revid: jco@openerp.com-20140407160624-rs4vkxjeef8eu2rw --- addons/stock/stock.py | 10 ++++------ addons/stock/stock_view.xml | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 83cbc8877a0..889f0bd15b0 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -848,7 +848,7 @@ class stock_picking(osv.osv): todo = [] todo_force_assign = [] for picking in self.browse(cr, uid, ids, context=context): - if picking.picking_type_id.auto_force_assign: + if picking.location_id.usage == 'supplier': todo_force_assign.append(picking.id) for r in picking.move_lines: if r.state == 'draft': @@ -1069,7 +1069,7 @@ class stock_picking(osv.osv): if qty <= 0: continue suggested_location_id = _picking_putaway_apply(product) - key = (product.id, False, False, False, picking.picking_type_id.default_location_src_id.id or picking.location_id.id, suggested_location_id) + key = (product.id, False, False, False, picking.location_id.id, suggested_location_id) if qtys_grouped.get(key): qtys_grouped[key] += qty else: @@ -2084,7 +2084,7 @@ class stock_move(osv.osv): for move in self.browse(cr, uid, ids, context=context): if move.state not in ('confirmed', 'waiting', 'assigned'): continue - if move.picking_type_id and move.picking_type_id.auto_force_assign: + if move.location_id.usage in ('supplier', 'inventory', 'production'): to_assign_moves.append(move.id) #in case the move is returned, we want to try to find quants before forcing the assignment if not move.origin_returned_move_id: @@ -2135,7 +2135,7 @@ class stock_move(osv.osv): quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty, domain=main_domain[move.id], prefered_domain=[], fallback_domain=[], restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) quant_obj.quants_reserve(cr, uid, quants, move, context=context) - #force assignation of consumable products and picking type auto_force_assign + #force assignation of consumable products and incoming from supplier/inventory/production if to_assign_moves: self.force_assign(cr, uid, to_assign_moves, context=context) @@ -3144,7 +3144,6 @@ class stock_warehouse(osv.osv): 'name': _('Receptions'), 'warehouse_id': new_id, 'code': 'incoming', - 'auto_force_assign': True, 'sequence_id': in_seq_id, 'default_location_src_id': supplier_loc.id, 'default_location_dest_id': input_loc.id, @@ -4107,7 +4106,6 @@ class stock_picking_type(osv.osv): _columns = { 'name': fields.char('Picking Type Name', translate=True, required=True), 'complete_name': fields.function(_get_name, type='char', string='Name'), - 'auto_force_assign': fields.boolean('Automatic Availability', help='This picking type does\'t need to check for the availability in source location.'), 'color': fields.integer('Color'), 'sequence': fields.integer('Sequence', help="Used to order the 'All Operations' kanban view"), 'sequence_id': fields.many2one('ir.sequence', 'Reference Sequence', required=True), diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 499bc57baee..ce3ef03d586 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -1393,7 +1393,6 @@ - From e55ac5a9de492a95a86352beba15d3f83695358f Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Tue, 8 Apr 2014 18:27:17 +0200 Subject: [PATCH 6/8] [WIP] In case the warehouse operator chooses other quants than foreseen that were reserved on another move bzr revid: jco@openerp.com-20140408162717-khax5gied2atr7gd --- addons/stock/__openerp__.py | 1 + addons/stock/stock.py | 40 +++++---- addons/stock/test/wiseoperator.yml | 120 ++++++++++++++++++++++++++ addons/stock_account/stock_account.py | 4 +- 4 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 addons/stock/test/wiseoperator.yml diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 3da1ccbcc8d..1b6e5aa1574 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -92,6 +92,7 @@ Dashboard / Reports for Warehouse Management will include: 'views/report_stockinventory.xml', ], 'test': [ + 'test/wiseoperator.yml', 'test/inventory.yml', 'test/move.yml', 'test/procrule.yml', diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 889f0bd15b0..f2d4e1204b6 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -338,7 +338,7 @@ class stock_quant(osv.osv): elif reserved_availability > 0 and not move.partially_available: self.pool.get('stock.move').write(cr, uid, [move.id], {'partially_available': True}, context=context) - def quants_move(self, cr, uid, quants, move, location_to, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, context=None): + def quants_move(self, cr, uid, quants, move, location_to, location_from=False, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, context=None): """Moves all given stock.quant in the given destination location. :param quants: list of tuple(browse record(stock.quant) or None, quantity to move) :param move: browse record (stock.move) @@ -354,7 +354,7 @@ class stock_quant(osv.osv): for quant, qty in quants: if not quant: #If quant is None, we will create a quant to move (and potentially a negative counterpart too) - quant = self._quant_create(cr, uid, qty, move, lot_id=lot_id, owner_id=owner_id, src_package_id=src_package_id, dest_package_id=dest_package_id, force_location=location_to, context=context) + quant = self._quant_create(cr, uid, qty, move, lot_id=lot_id, owner_id=owner_id, src_package_id=src_package_id, dest_package_id=dest_package_id, force_location=location_to, force_location_from=location_from, context=context) else: self._quant_split(cr, uid, quant, qty, context=context) quant.refresh() @@ -428,7 +428,8 @@ class stock_quant(osv.osv): raise osv.except_osv(_('Error!'), _('Removal strategy %s not implemented.' % (removal_strategy,))) return result - def _quant_create(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, force_location=False, context=None): + def _quant_create(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, + force_location=False, force_location_from=False, context=None): '''Create a quant in the destination location and create a negative quant in the source location if it's an internal location. ''' if context is None: @@ -449,10 +450,11 @@ class stock_quant(osv.osv): } if move.location_id.usage == 'internal': + location_from = force_location_from or move.location_id #if we were trying to move something from an internal location and reach here (quant creation), #it means that a negative quant has to be created as well. negative_vals = vals.copy() - negative_vals['location_id'] = move.location_id.id + negative_vals['location_id'] = location_from.id negative_vals['qty'] = -qty negative_vals['cost'] = price_unit negative_vals['negative_move_id'] = move.id @@ -486,7 +488,7 @@ class stock_quant(osv.osv): path.append((4, move.id)) self.write(cr, SUPERUSER_ID, solved_quant_ids, {'history_ids': path}, context=context) - def _quant_reconcile_negative(self, cr, uid, quant, move, context=None): + def _quant_reconcile_negative(self, cr, uid, quant, move, reserve_move=False, context=None): """ When new quant arrive in a location, try to reconcile it with negative quants. If it's possible, apply the cost of the new @@ -498,7 +500,8 @@ class stock_quant(osv.osv): dom += [('lot_id', '=', quant.lot_id.id)] dom += [('owner_id', '=', quant.owner_id.id)] dom += [('package_id', '=', quant.package_id.id)] - if move.move_dest_id: + + if not reserve_move and move.move_dest_id: dom += [('negative_move_id', '=', move.move_dest_id.id)] quants = self.quants_get(cr, uid, quant.location_id, quant.product_id, quant.qty, dom, context=context) for quant_neg, qty in quants: @@ -542,6 +545,13 @@ class stock_quant(osv.osv): self.pool.get('stock.picking').write(cr, uid, [move.picking_id.id], {'recompute_pack_op': True}, context=context) if move.partially_available: self.pool.get("stock.move").write(cr, uid, [move.id], {'partially_available': False}, context=context) + #TODO: or split from move with move_orig_ids? + if move.location_id.usage == 'internal' and not move.move_orig_ids: + if self.search(cr, uid, [('product_id', '=', move.product_id.id), ('qty','<', 0), ('location_id', 'child_of', move.location_id.id)], limit=1, context=context): + for quant in move.reserved_quant_ids: + self._quant_reconcile_negative(cr, uid, quant, move, reserve_move = True, context=context) + move.refresh() + related_quants = [x.id for x in move.reserved_quant_ids] return self.write(cr, SUPERUSER_ID, related_quants, {'reservation_id': False}, context=context) def _quants_get_order(self, cr, uid, location, product, quantity, domain=[], orderby='in_date', context=None): @@ -2200,14 +2210,14 @@ class stock_move(osv.osv): for record in ops.linked_move_operation_ids: move = record.move_id self.check_tracking(cr, uid, move, ops.package_id.id or ops.lot_id.id, context=context) - if record.reserved_quant_id: - quants = [(record.reserved_quant_id, record.qty)] - else: - prefered_domain = [('reservation_id', '=', move.id)] - fallback_domain = [('reservation_id', '=', False)] - dom = main_domain + self.pool.get('stock.move.operation.link').get_specific_domain(cr, uid, record, context=context) - quants = quant_obj.quants_get_prefered_domain(cr, uid, ops.location_id, move.product_id, record.qty, domain=dom, prefered_domain=prefered_domain, - fallback_domain=fallback_domain, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) +# if record.reserved_quant_id: +# quants = [(record.reserved_quant_id, record.qty)] +# else: + prefered_domain = [('reservation_id', '=', move.id)] + fallback_domain = [('reservation_id', '=', False)] + dom = main_domain + self.pool.get('stock.move.operation.link').get_specific_domain(cr, uid, record, context=context) + quants = quant_obj.quants_get_prefered_domain(cr, uid, ops.location_id, move.product_id, record.qty, domain=dom, prefered_domain=prefered_domain, + fallback_domain=fallback_domain, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) if ops.result_package_id.id: #if a result package is given, all quants go there @@ -2218,7 +2228,7 @@ class stock_move(osv.osv): else: #otherwise we keep the current pack of the quant, which may mean None quant_dest_package_id = ops.package_id.id - quant_obj.quants_move(cr, uid, quants, move, ops.location_dest_id, lot_id=ops.lot_id.id, owner_id=ops.owner_id.id, src_package_id=ops.package_id.id, dest_package_id=quant_dest_package_id, context=context) + quant_obj.quants_move(cr, uid, quants, move, ops.location_dest_id, location_from = ops.location_id, lot_id=ops.lot_id.id, owner_id=ops.owner_id.id, src_package_id=ops.package_id.id, dest_package_id=quant_dest_package_id, context=context) # Handle pack in pack if not ops.product_id and ops.package_id and ops.result_package_id.id != ops.package_id.parent_id.id: self.pool.get('stock.quant.package').write(cr, SUPERUSER_ID, [ops.package_id.id], {'parent_id': ops.result_package_id.id}, context=context) diff --git a/addons/stock/test/wiseoperator.yml b/addons/stock/test/wiseoperator.yml new file mode 100644 index 00000000000..7e0aa78a799 --- /dev/null +++ b/addons/stock/test/wiseoperator.yml @@ -0,0 +1,120 @@ +- + Create a new stockable product +- + !record {model: product.product, id: product_wise}: + name: Wise Unit + type: product + categ_id: product.product_category_1 + uom_id: product.product_uom_unit + uom_po_id: product.product_uom_unit +- + Create an incoming picking for this product of 10 PCE from suppliers to stock +- + !record {model: stock.picking, id: pick1}: + name: Incoming picking + partner_id: base.res_partner_2 + picking_type_id: picking_type_in + move_lines: + - product_id: product_wise + product_uom_qty: 10.00 + location_id: stock_location_suppliers + location_dest_id: stock_location_stock +- + Confirm and assign picking and prepare partial +- + !python {model: stock.picking}: | + self.action_confirm(cr, uid, [ref('pick1')], context=context) + self.do_prepare_partial(cr, uid, [ref('pick1')], context=context) +- + Put 6 pieces in shelf1 and 4 pieces in shelf2 +- + !python {model: stock.picking}: | + record = self.browse(cr, uid, ref('pick1'), context=context) + stock_pack = self.pool.get('stock.pack.operation') + stock_quant_pack = self.pool.get('stock.quant.package') + package1 = stock_quant_pack.create(cr, uid, {'name': 'Pack 1'}, context=context) + stock_pack.write(cr, uid, record.pack_operation_ids[0].id, {'result_package_id': package1, 'product_qty': 4, 'location_dest_id': ref('stock_location_components')}) + new_pack1 = stock_pack.create(cr, uid, {'product_id': ref('product_wise'), 'product_uom_id': ref('product.product_uom_unit'), 'picking_id': ref('pick1'), 'product_qty': 6.0, 'location_id': ref('stock_location_suppliers'), 'location_dest_id': ref('stock_location_14')}, context=context) +- + Transfer the reception +- + !python {model: stock.picking}: | + self.do_transfer(cr, uid, [ref('pick1')], context=context) +- + Check the system created 2 quants +- + !python {model: stock.quant}: | + reco_id = self.search(cr ,uid , [('product_id','=',ref('product_wise'))], context=context) + assert len(reco_id) == 2, "The number of quants created is not correct" +- + Make a delivery order of 5 pieces to the customer +- + !record {model: stock.picking, id: delivery_order1}: + name: outgoing picking + partner_id: base.res_partner_4 + picking_type_id: stock.picking_type_out + move_lines: + - product_id: product_wise + product_uom_qty: 5.0 + location_id: stock_location_stock + location_dest_id: stock_location_customers +- + Assign and confirm +- + !python {model: stock.picking}: | + self.action_confirm(cr, uid, [ref('delivery_order1')], context=context) + self.action_assign(cr, uid, [ref('delivery_order1')]) + self.do_prepare_partial(cr, uid, [ref('delivery_order1')]) +- + Make a delivery order of 5 pieces to the customer +- + !record {model: stock.picking, id: delivery_order2}: + name: outgoing picking + partner_id: base.res_partner_4 + picking_type_id: stock.picking_type_out + move_lines: + - product_id: product_wise + product_uom_qty: 5.0 + location_id: stock_location_stock + location_dest_id: stock_location_customers +- + Assign and confirm +- + !python {model: stock.picking}: | + self.action_confirm(cr, uid, [ref('delivery_order2')], context=context) + self.action_assign(cr, uid, [ref('delivery_order2')]) + self.do_prepare_partial(cr, uid, [ref('delivery_order2')]) +- + The operator is a wise guy and decides to do the opposite as OpenERP proposes. He uses the products reserved on picking 1 on picking 2 and vice versa +- + !python {model: stock.picking}: | + stock_pack = self.pool.get('stock.pack.operation') + picking1 = self.browse(cr, uid, ref('delivery_order1')) + picking2 = self.browse(cr, uid, ref('delivery_order2')) + pack_ids1 = [x.id for x in picking1.pack_operation_ids] + pack_ids2 = [x.id for x in picking2.pack_operation_ids] + stock_pack.write(cr, uid, pack_ids1, {'picking_id': picking2.id}) + stock_pack.write(cr, uid, pack_ids2, {'picking_id': picking1.id}) + picking1.refresh() +- + Process this picking +- + !python {model: stock.picking}: | + self.do_transfer(cr, uid, [ref('delivery_order1')], context=context) +- + Check a negative quant was created by this picking +- + !python {model: stock.quant}: | + reco_id = self.search(cr ,uid , [('product_id','=',ref('product_wise')), ('qty', '<', 0.0)], context=context) + assert len(reco_id) > 0, 'This should have created a negative quant' +- + Process the second picking +- + !python {model: stock.picking}: | + self.do_transfer(cr, uid, [ref('delivery_order2')], context=context) +- + Check all quants are in Customers and there are no negative quants anymore +- + !python {model: stock.quant}: | + reco_id = self.search(cr ,uid , [('product_id','=',ref('product_wise'))], context=context) + assert all([x.location_id.id==ref('stock_location_customers') and x.qty > 0.0 for x in self.browse(cr, uid, reco_id)]), "Negative quant or wrong location detected" diff --git a/addons/stock_account/stock_account.py b/addons/stock_account/stock_account.py index 9bbad8e52b4..b2076968188 100644 --- a/addons/stock_account/stock_account.py +++ b/addons/stock_account/stock_account.py @@ -128,8 +128,8 @@ class stock_quant(osv.osv): else: self._create_account_move_line(cr, uid, quants, move, acc_valuation, acc_dest, journal_id, context=ctx) - def _quant_create(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, force_location=False, context=None): - quant = super(stock_quant, self)._quant_create(cr, uid, qty, move, lot_id, owner_id, src_package_id, dest_package_id, force_location, context=context) + def _quant_create(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, force_location=False, force_location_from=False, context=None): + quant = super(stock_quant, self)._quant_create(cr, uid, qty, move, lot_id, owner_id, src_package_id, dest_package_id, force_location, force_location_from, context=context) if move.product_id.valuation == 'real_time': self._account_entry_move(cr, uid, [quant], move, context) return quant From 214f8ba4d47c01883439502ce936551288cb49c5 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Wed, 9 Apr 2014 10:22:19 +0200 Subject: [PATCH 7/8] [IMP] Easy solution in case of split from mto move bzr revid: jco@openerp.com-20140409082219-hap0oys1dfq2i81j --- addons/stock/stock.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index f2d4e1204b6..2afbf6776d3 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -545,8 +545,13 @@ class stock_quant(osv.osv): self.pool.get('stock.picking').write(cr, uid, [move.picking_id.id], {'recompute_pack_op': True}, context=context) if move.partially_available: self.pool.get("stock.move").write(cr, uid, [move.id], {'partially_available': False}, context=context) - #TODO: or split from move with move_orig_ids? - if move.location_id.usage == 'internal' and not move.move_orig_ids: + move_orig_ids = [] + move2 = move + while move2: + move_orig_ids += [x.id for x in move2.move_orig_ids] + #loop on the split_from to find the ancestor of split moves only if the move has not direct ancestor (priority goes to them) + move2 = not move2.move_orig_ids and move2.split_from or False + if move.location_id.usage == 'internal' and not move_orig_ids: if self.search(cr, uid, [('product_id', '=', move.product_id.id), ('qty','<', 0), ('location_id', 'child_of', move.location_id.id)], limit=1, context=context): for quant in move.reserved_quant_ids: self._quant_reconcile_negative(cr, uid, quant, move, reserve_move = True, context=context) From aeea3f8b4e0608e454427f74e4b5c3ffb9267628 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Fri, 11 Apr 2014 11:57:23 +0200 Subject: [PATCH 8/8] [FIX] Product_qty should not default to 1, but be calculated from product_uom_qty bzr revid: jco@openerp.com-20140411095723-wvr5hb1gpbi4lswt --- addons/stock/stock.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 2afbf6776d3..d5411f4d96c 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1733,7 +1733,6 @@ class stock_move(osv.osv): 'partner_id': _default_destination_address, 'state': 'draft', 'priority': '1', - 'product_qty': 1.0, 'product_uom_qty': 1.0, 'scrapped': False, 'date': fields.datetime.now,