diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py index 0b8aa101a9d..d4e383bd702 100644 --- a/addons/mrp/__openerp__.py +++ b/addons/mrp/__openerp__.py @@ -73,6 +73,7 @@ Dashboard / Reports for MRP will include: 'report/mrp_production_order_view.xml', 'board_manufacturing_view.xml', 'res_config_view.xml', + 'wizard/stock_move_view.xml', ], 'demo': ['mrp_demo.xml'], 'test': [ diff --git a/addons/mrp/stock.py b/addons/mrp/stock.py index 8bd9d6b82d3..efe5a1a1c42 100644 --- a/addons/mrp/stock.py +++ b/addons/mrp/stock.py @@ -103,26 +103,50 @@ class StockMove(osv.osv): procurement_obj.signal_button_wait_done(cr, uid, procurement_ids) return processed_ids - def action_consume(self, cr, uid, ids, product_qty, location_id=False, restrict_lot_id = False, default_values = None, context=None): + + + def action_consume(self, cr, uid, ids, product_qty, location_id=False, restrict_lot_id = False, restrict_partner_id = False, + consumed_for = False, context=None): """ Consumed product with specific quantity from specific source location. @param product_qty: Consumed product quantity @param location_id: Source location @return: Consumed lines """ - if default_values is None: - default_values = {} res = [] production_obj = self.pool.get('mrp.production') + uom_obj = self.pool.get('product.uom') + + if product_qty <= 0: + raise osv.except_osv(_('Warning!'), _('Please provide proper quantity.')) for move in self.browse(cr, uid, ids, context=context): - self.action_confirm(cr, uid, [move.id], context=context) - new_moves = super(StockMove, self).action_consume(cr, uid, [move.id], product_qty, location_id, restrict_lot_id = restrict_lot_id, - default_values = default_values, context=context) + if move.state == 'draft': + self.action_confirm(cr, uid, [move.id], context=context) + move_qty = move.product_qty + uom_qty = uom_obj._compute_qty(cr, uid, move.product_id.uom_id.id, product_qty, move.product_uom.id) + if move_qty <= 0: + raise osv.except_osv(_('Error!'), _('Cannot consume a move with negative or zero quantity.')) + quantity_rest = move.product_qty - uom_qty + if quantity_rest > 0: + ctx = context.copy() + if location_id: + ctx['source_location_id'] = location_id + res.append(self.split(cr, uid, move, move_qty - quantity_rest, restrict_lot_id=restrict_lot_id, + restrict_partner_id=restrict_partner_id, context=ctx)) + #TODO need to add consumed_for here + else: + res.append(move.id) + if location_id: + self.write(cr, uid, [move.id], {'location_id': location_id, 'restrict_lot_id': restrict_lot_id, + 'restrict_partner_id': restrict_partner_id, + 'consumed_for': consumed_for}, context=context) + self.action_done(cr, uid, res, context=context) + production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])]) for prod in production_obj.browse(cr, uid, production_ids, context=context): if prod.state == 'confirmed': production_obj.force_production(cr, uid, [prod.id]) production_obj.signal_button_produce(cr, uid, production_ids) - for new_move in new_moves: + for new_move in res: if new_move != move.id: #This move is not already there in move lines of production order production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]}) diff --git a/addons/mrp/wizard/__init__.py b/addons/mrp/wizard/__init__.py index 83dd1971c5b..2f024506811 100644 --- a/addons/mrp/wizard/__init__.py +++ b/addons/mrp/wizard/__init__.py @@ -23,6 +23,7 @@ import mrp_product_produce import mrp_price import mrp_workcenter_load import change_production_qty +import stock_move #import mrp_change_standard_price # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 07a92744036..3ccbf3bca50 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1899,41 +1899,6 @@ class stock_move(osv.osv): self.action_done(cr, uid, res, context=context) return res - def action_consume(self, cr, uid, ids, quantity, location_id=False, restrict_lot_id=False, default_values = None, context=None): - """ Consumed product with specific quantity from specific source location. This correspond to a split of the move (or write if the quantity to consume is >= than the quantity of the move) followed by an action_done - @param ids: ids of stock move object to be consumed - @param quantity : specify consume quantity (given in move UoM) - @param location_id : specify source location - @return: Consumed lines - """ - if default_values is None: - default_values = {} - uom_obj = self.pool.get('product.uom') - if context is None: - context = {} - if quantity <= 0: - raise osv.except_osv(_('Warning!'), _('Please provide proper quantity.')) - res = [] - for move in self.browse(cr, uid, ids, context=context): - move_qty = move.product_qty - uom_qty = uom_obj._compute_qty(cr, uid, move.product_id.uom_id.id, quantity, move.product_uom.id) - if move_qty <= 0: - raise osv.except_osv(_('Error!'), _('Cannot consume a move with negative or zero quantity.')) - quantity_rest = move.product_qty - uom_qty - if quantity_rest > 0: - ctx = context.copy() - if location_id: - ctx['source_location_id'] = location_id - res.append(self.split(cr, uid, move, move_qty - quantity_rest, restrict_lot_id=restrict_lot_id, - default_values = default_values, context=ctx)) - else: - res.append(move.id) - if location_id: - vals = default_values.copy() - vals.update({'location_id': location_id, 'restrict_lot_id': restrict_lot_id}) - self.write(cr, uid, [move.id], vals, context=context) - self.action_done(cr, uid, res, context=context) - return res def split(self, cr, uid, move, qty, restrict_lot_id=False, default_values = None, context=None): """ Splits qty from move move into a new move diff --git a/addons/stock/wizard/__init__.py b/addons/stock/wizard/__init__.py index a29f3207ca1..4e2659f8218 100644 --- a/addons/stock/wizard/__init__.py +++ b/addons/stock/wizard/__init__.py @@ -20,8 +20,6 @@ ############################################################################## import stock_move -import stock_inventory_merge -import stock_inventory_line_split import stock_location_product import stock_return_picking import stock_change_product_qty diff --git a/addons/stock/wizard/stock_inventory_line_split.py b/addons/stock/wizard/stock_inventory_line_split.py deleted file mode 100644 index e06bf0d11e8..00000000000 --- a/addons/stock/wizard/stock_inventory_line_split.py +++ /dev/null @@ -1,112 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from openerp.osv import fields, osv - -class stock_inventory_line_split(osv.osv_memory): - _inherit = "stock.move.split" - _name = "stock.inventory.line.split" - _description = "Split inventory lines" - - _columns = { - 'line_ids': fields.one2many('stock.inventory.line.split.lines', 'wizard_id', 'Serial Numbers'), - 'line_exist_ids': fields.one2many('stock.inventory.line.split.lines', 'wizard_exist_id', 'Serial Numbers'), - } - - def default_get(self, cr, uid, fields, context=None): - if context is None: - context = {} - record_id = context and context.get('active_id',False) - res = {} - line = self.pool.get('stock.inventory.line').browse(cr, uid, record_id, context=context) - if 'product_id' in fields: - res.update({'product_id':line.product_id.id}) - if 'product_uom' in fields: - res.update({'product_uom': line.product_uom_id.id}) - if 'qty' in fields: - res.update({'qty': line.product_qty}) - return res - - def split(self, cr, uid, ids, line_ids, context=None): - """ To split stock inventory lines according to serial numbers. - - :param line_ids: the ID or list of IDs of inventory lines we want to split - """ - if context is None: - context = {} - assert context.get('active_model') == 'stock.inventory.line',\ - 'Incorrect use of the inventory line split wizard.' - prodlot_obj = self.pool.get('stock.production.lot') - ir_sequence_obj = self.pool.get('ir.sequence') - line_obj = self.pool.get('stock.inventory.line') - new_line = [] - for data in self.browse(cr, uid, ids, context=context): - for inv_line in line_obj.browse(cr, uid, line_ids, context=context): - line_qty = inv_line.product_qty - quantity_rest = inv_line.product_qty - new_line = [] - if data.use_exist: - lines = [l for l in data.line_exist_ids if l] - else: - lines = [l for l in data.line_ids if l] - for line in lines: - quantity = line.quantity - if quantity <= 0 or line_qty == 0: - continue - quantity_rest -= quantity - if quantity_rest < 0: - quantity_rest = quantity - break - default_val = { - 'product_qty': quantity, - } - if quantity_rest > 0: - current_line = line_obj.copy(cr, uid, inv_line.id, default_val) - new_line.append(current_line) - if quantity_rest == 0: - current_line = inv_line.id - lot_id = False - if data.use_exist: - lot_id = line.lot_id.id - if not lot_id: - lot_id = prodlot_obj.create(cr, uid, { - 'name': line.name, - 'product_id': inv_line.product_id.id}, - context=context) - line_obj.write(cr, uid, [current_line], {'prod_lot_id': lot_id}) - prodlot = prodlot_obj.browse(cr, uid, lot_id) - - update_val = {} - if quantity_rest > 0: - update_val['product_qty'] = quantity_rest - line_obj.write(cr, uid, [inv_line.id], update_val) - - return new_line - -class stock_inventory_split_lines(osv.osv_memory): - _inherit = "stock.move.split.lines" - _name = "stock.inventory.line.split.lines" - _description = "Inventory Split lines" - _columns = { - 'wizard_id': fields.many2one('stock.inventory.line.split', 'Parent Wizard'), - 'wizard_exist_id': fields.many2one('stock.inventory.line.split', 'Parent Wizard'), - } - diff --git a/addons/stock/wizard/stock_inventory_line_split_view.xml b/addons/stock/wizard/stock_inventory_line_split_view.xml deleted file mode 100644 index 1c41533c022..00000000000 --- a/addons/stock/wizard/stock_inventory_line_split_view.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - Split Inventory Line - stock.inventory.line.split - -
- - - - - - - - - - - - - - -
- - - - - -
- - - - -
-
-
-
- -
-
- - - Split inventory lines - ir.actions.act_window - stock.inventory.line.split - form - form - new - - -
-
diff --git a/addons/stock/wizard/stock_inventory_merge.py b/addons/stock/wizard/stock_inventory_merge.py deleted file mode 100644 index 9245628b040..00000000000 --- a/addons/stock/wizard/stock_inventory_merge.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from openerp.osv import fields, osv -from openerp.tools.translate import _ - -class stock_inventory_merge(osv.osv_memory): - _name = "stock.inventory.merge" - _description = "Merge Inventory" - - def fields_view_get(self, cr, uid, view_id=None, view_type='form', - context=None, toolbar=False, submenu=False): - """ - Changes the view dynamically - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param context: A standard dictionary - @return: New arch of view. - """ - if context is None: - context={} - res = super(stock_inventory_merge, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False) - if context.get('active_model','') == 'stock.inventory' and len(context['active_ids']) < 2: - raise osv.except_osv(_('Warning!'), - _('Please select multiple physical inventories to merge in the list view.')) - return res - - def do_merge(self, cr, uid, ids, context=None): - """ To merge selected Inventories. - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param ids: List of IDs selected - @param context: A standard dictionary - @return: - """ - invent_obj = self.pool.get('stock.inventory') - invent_line_obj = self.pool.get('stock.inventory.line') - invent_lines = {} - if context is None: - context = {} - for inventory in invent_obj.browse(cr, uid, context['active_ids'], context=context): - if inventory.state == "done": - raise osv.except_osv(_('Warning!'), - _('Merging is only allowed on draft inventories.')) - - for line in inventory.inventory_line_id: - key = (line.location_id.id, line.product_id.id, line.product_uom_id.id) - if key in invent_lines: - invent_lines[key] += line.product_qty - else: - invent_lines[key] = line.product_qty - - - new_invent = invent_obj.create(cr, uid, { - 'name': 'Merged inventory' - }, context=context) - - for key, quantity in invent_lines.items(): - invent_line_obj.create(cr, uid, { - 'inventory_id': new_invent, - 'location_id': key[0], - 'product_id': key[1], - 'product_uom_id': key[2], - 'product_qty': quantity, - }) - - return {'type': 'ir.actions.act_window_close'} - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/stock/wizard/stock_inventory_merge_view.xml b/addons/stock/wizard/stock_inventory_merge_view.xml deleted file mode 100644 index bf661b426a2..00000000000 --- a/addons/stock/wizard/stock_inventory_merge_view.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - stock.inventory.merge.form - stock.inventory.merge - -
- -
-
- - -
-
diff --git a/addons/stock/wizard/stock_move.py b/addons/stock/wizard/stock_move.py index 488e825a361..c0cb5dbcf2b 100644 --- a/addons/stock/wizard/stock_move.py +++ b/addons/stock/wizard/stock_move.py @@ -23,9 +23,11 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ import openerp.addons.decimal_precision as dp -class stock_move_consume(osv.osv_memory): - _name = "stock.move.consume" - _description = "Consume Products" + + +class stock_move_scrap(osv.osv_memory): + _name = "stock.move.scrap" + _description = "Scrap Products" _columns = { 'product_id': fields.many2one('product.product', 'Product', required=True, select=True), @@ -35,59 +37,6 @@ class stock_move_consume(osv.osv_memory): 'restrict_lot_id': fields.many2one('stock.production.lot', 'Lot'), } - #TOFIX: product_uom should not have differemt category of default UOM of product. Qty should be convert into UOM of original move line before going in consume and scrap - def default_get(self, cr, uid, fields, context=None): - """ Get default values - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param fields: List of fields for default value - @param context: A standard dictionary - @return: default values of fields - """ - if context is None: - context = {} - res = super(stock_move_consume, self).default_get(cr, uid, fields, context=context) - move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context) - if 'product_id' in fields: - res.update({'product_id': move.product_id.id}) - if 'product_uom' in fields: - res.update({'product_uom': move.product_uom.id}) - if 'product_qty' in fields: - res.update({'product_qty': move.product_qty}) - if 'location_id' in fields: - res.update({'location_id': move.location_id.id}) - - return res - - - - def do_move_consume(self, cr, uid, ids, context=None): - """ To move consumed products - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param ids: the ID or list of IDs if we want more than one - @param context: A standard dictionary - @return: - """ - if context is None: - context = {} - move_obj = self.pool.get('stock.move') - move_ids = context['active_ids'] - for data in self.browse(cr, uid, ids, context=context): - move_obj.action_consume(cr, uid, move_ids, - data.product_qty, data.location_id.id, restrict_lot_id=data.restrict_lot_id and data.restrict_lot_id.id or False, - context=context) - return {'type': 'ir.actions.act_window_close'} - - - -class stock_move_scrap(osv.osv_memory): - _name = "stock.move.scrap" - _description = "Scrap Products" - _inherit = "stock.move.consume" - _defaults = { 'location_id': lambda *x: False } @@ -103,8 +52,9 @@ class stock_move_scrap(osv.osv_memory): """ if context is None: context = {} - res = super(stock_move_consume, self).default_get(cr, uid, fields, context=context) + res = super(stock_move_scrap, self).default_get(cr, uid, fields, context=context) move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context) + location_obj = self.pool.get('stock.location') scrap_location_id = location_obj.search(cr, uid, [('scrap_location','=',True)]) @@ -139,7 +89,6 @@ class stock_move_scrap(osv.osv_memory): return {'type': 'ir.actions.act_window_close'} - class split_in_production_lot(osv.osv_memory): _name = "stock.move.split" _description = "Split in Serial Numbers" diff --git a/addons/stock/wizard/stock_move_view.xml b/addons/stock/wizard/stock_move_view.xml index 0a567be651e..a5dda8954c0 100644 --- a/addons/stock/wizard/stock_move_view.xml +++ b/addons/stock/wizard/stock_move_view.xml @@ -1,41 +1,7 @@ - - - - Consume Move - stock.move.consume - -
- - - -
-
-
-
-
- - - Consume Move - ir.actions.act_window - stock.move.consume - form - form - new - + Scrap Move