diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml index be2ed8fc097..f203996b541 100644 --- a/addons/procurement/procurement_view.xml +++ b/addons/procurement/procurement_view.xml @@ -77,6 +77,34 @@ + + + Procurement for Groups + procurement.order + form + tree,form + [('group_id','=',active_id)] + + + + procurement.group.form + procurement.group + +
+ +
+
+ + + + + +
+
+
+
+ procurement.order.select procurement.order @@ -97,7 +125,7 @@ - + Procurement Orders ir.actions.act_window @@ -121,7 +149,7 @@

- + Procurements ir.actions.act_window diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index d7977652805..4e656649349 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -832,6 +832,7 @@ class purchase_order(osv.osv): @return: new purchase order id """ + #TOFIX: merged order line should be unlink def make_key(br, fields): list_key = [] @@ -854,14 +855,15 @@ class purchase_order(osv.osv): context = {} # Compute what the new orders should contain - new_orders = {} + order_lines_to_move = [] for porder in [order for order in self.browse(cr, uid, ids, context=context) if order.state == 'draft']: order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id')) new_order = new_orders.setdefault(order_key, ({}, [])) new_order[1].append(porder.id) order_infos = new_order[0] + if not order_infos: order_infos.update({ 'origin': porder.origin, @@ -885,21 +887,7 @@ class purchase_order(osv.osv): order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin for order_line in porder.order_line: - line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'product_id', 'move_dest_id', 'account_analytic_id')) - o_line = order_infos['order_line'].setdefault(line_key, {}) - if o_line: - # merge the line with an existing line - o_line['product_qty'] += order_line.product_qty * order_line.product_uom.factor / o_line['uom_factor'] - else: - # append a new "standalone" line - for field in ('product_qty', 'product_uom'): - field_val = getattr(order_line, field) - if isinstance(field_val, browse_record): - field_val = field_val.id - o_line[field] = field_val - o_line['uom_factor'] = order_line.product_uom and order_line.product_uom.factor or 1.0 - - + order_lines_to_move += [order_line.id] allorders = [] orders_info = {} @@ -913,7 +901,7 @@ class purchase_order(osv.osv): for key, value in order_data['order_line'].iteritems(): del value['uom_factor'] value.update(dict(key)) - order_data['order_line'] = [(0, 0, value) for value in order_data['order_line'].itervalues()] + order_data['order_line'] = [(6, 0, order_lines_to_move)] # create the new order context.update({'mail_create_nolog': True}) @@ -925,7 +913,8 @@ class purchase_order(osv.osv): # make triggers pointing to the old orders point to the new order for old_id in old_ids: self.redirect_workflow(cr, uid, [(old_id, neworder_id)]) - self.signal_purchase_cancel(cr, uid, [old_id]) # TODO Is it necessary to interleave the calls? + self.signal_purchase_cancel(cr, uid, [old_id]) + return orders_info diff --git a/addons/purchase/wizard/purchase_order_group.py b/addons/purchase/wizard/purchase_order_group.py index 243f27efea4..70a6b3240ab 100644 --- a/addons/purchase/wizard/purchase_order_group.py +++ b/addons/purchase/wizard/purchase_order_group.py @@ -66,12 +66,7 @@ class purchase_order_group(osv.osv_memory): id = mod_obj.read(cr, uid, result, ['res_id']) allorders = order_obj.do_merge(cr, uid, context.get('active_ids',[]), context) - for new_order in allorders: - proc_ids = proc_obj.search(cr, uid, [('purchase_id', 'in', allorders[new_order])], context=context) - for proc in proc_obj.browse(cr, uid, proc_ids, context=context): - if proc.purchase_id: - proc_obj.write(cr, uid, [proc.id], {'purchase_id': new_order}, context) - + return { 'domain': "[('id','in', [" + ','.join(map(str, allorders.keys())) + "])]", 'name': _('Purchase Orders'), diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index f2044fa88a2..3402aa6a8b7 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -90,7 +90,7 @@ class procurement_rule(osv.osv): class procurement_order(osv.osv): _inherit = "procurement.order" _columns = { - 'location_id': fields.many2one('stock.location', 'Procurement Location'), + 'location_id': fields.many2one('stock.location', 'Procurement Location', required=True), 'move_ids': fields.one2many('stock.move', 'procurement_id', 'Moves', help="Moves created by the procurement"), 'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Move which caused (created) the procurement"), } diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 3651a55aad8..29d2f863017 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -477,7 +477,13 @@ class stock_picking(osv.osv): _name = "stock.picking" _inherit = ['mail.thread'] _description = "Picking List" - _order = "id desc" + _order = "priority desc, date desc, id desc" + + def _set_min_date(self, cr, uid, id, field, value, arg, context=None): + move_obj = self.pool.get("stock.move") + move_ids = [move.id for move in self.browse(cr, uid, id, context=context).move_lines] + move_obj.write(cr, uid, move_ids, {'date_expected': value}, context=context) + def get_min_max_date(self, cr, uid, ids, field_name, arg, context=None): """ Finds minimum and maximum dates for picking. @return: Dictionary of values @@ -551,6 +557,15 @@ class stock_picking(osv.osv): res[pick.id] = True return res + def _get_quant_reserved_exist(self, cr, uid, ids, field_name, arg, context=None): + res = {} + for pick in self.browse(cr, uid, ids, context=context): + res[pick.id] = False + for move in pick.move_lines: + if move.reserved_quant_ids: + res[pick.id] = True + continue + return res def _get_group_id(self, cr, uid, ids, field_name, args, context=None): res = {} @@ -586,13 +601,15 @@ class stock_picking(osv.osv): * Transferred: has been processed, can't be modified or cancelled anymore\n * Cancelled: has been cancelled, can't be confirmed anymore""" ), - 'min_date': fields.function(get_min_max_date, multi="min_max_date", + 'priority': fields.selection([('0', 'Low'), ('1', 'Normal'), ('2', 'High')], string='Priority', required=True), + 'min_date': fields.function(get_min_max_date, multi="min_max_date", fnct_inv=_set_min_date, store={'stock.move': (_get_pickings, ['state', 'date_expected'], 20)}, type='datetime', string='Scheduled Date', select=1, help="Scheduled time for the first part of the shipment to be processed"), 'max_date': fields.function(get_min_max_date, multi="min_max_date", store={'stock.move': (_get_pickings, ['state', 'date_expected'], 20)}, type='datetime', string='Max. Expected Date', select=2, help="Scheduled time for the last part of the shipment to be processed"), 'date': fields.datetime('Commitment Date', help="Date promised for the completion of the transfer order, usually set the time of the order and revised later on.", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'date_done': fields.datetime('Date of Transfer', help="Date of Completion", states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'move_lines': fields.one2many('stock.move', 'picking_id', 'Internal Moves', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}), + 'quant_reserved_exist': fields.function(_get_quant_reserved_exist, type='boolean', string='Quant already reserved ?', help='technical field used to know if there is already at least one quant reserved on moves of a given picking'), 'partner_id': fields.many2one('res.partner', 'Partner', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'company_id': fields.many2one('res.company', 'Company', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'pack_operation_ids': fields.one2many('stock.pack.operation', 'picking_id', string='Related Packing Operations'), @@ -610,6 +627,7 @@ class stock_picking(osv.osv): 'name': lambda self, cr, uid, context: '/', 'state': 'draft', 'move_type': 'one', + 'priority' : '1', #normal 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.picking', context=c) } @@ -813,8 +831,17 @@ class stock_picking(osv.osv): ''' self.rereserve(cr, uid, picking_ids, context=context) - - + def do_unreserve(self,cr,uid,picking_ids, context=None): + """ + Will remove all quants for picking in picking_ids + """ + ids_to_free = [] + quant_obj = self.pool.get("stock.quant") + for picking in self.browse(cr, uid, picking_ids, context=context): + for move in picking.move_lines: + ids_to_free += [quant.id for quant in move.reserved_quant_ids] + if ids_to_free: + quant_obj.write(cr, uid, ids_to_free, {'reservation_id' : False, 'reservation_op_id': False }, context = context) def _reserve_quants_ops_move(self, cr, uid, ops, move, qty, create=False, context=None): """ @@ -1244,6 +1271,7 @@ class stock_move(osv.osv): 'move_orig_ids': fields.one2many('stock.move', 'move_dest_id', 'Original Move', help="Optional: previous stock move when chaining them", select=True), 'picking_id': fields.many2one('stock.picking', 'Reference', select=True,states={'done': [('readonly', True)]}), + 'picking_priority': fields.related('picking_id','priority', type='selection', selection=[('0','Low'),('1','Normal'),('2','High')], string='Picking Priority'), 'note': fields.text('Notes'), 'state': fields.selection([('draft', 'New'), ('cancel', 'Cancelled'), @@ -2115,7 +2143,7 @@ class stock_warehouse(osv.osv): 'company_id': fields.many2one('res.company', 'Company', required=True, select=True), 'partner_id': fields.many2one('res.partner', 'Address'), 'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True, domain=[('usage', '=', 'internal')]), - 'code': fields.char('Warehouse Unique Identifier', size=5, required=True, help="Short name used to identify your warehouse"), + 'code': fields.char('Short Name', size=5, required=True, help="Short name used to identify your warehouse"), } def _default_stock_id(self, cr, uid, context=None): diff --git a/addons/stock/stock_data.xml b/addons/stock/stock_data.xml index d189f70fa54..1a43bf8e867 100644 --- a/addons/stock/stock_data.xml +++ b/addons/stock/stock_data.xml @@ -154,9 +154,6 @@ watch your stock valuation, and track production lots upstream and downstream (b - - - diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index e3eaad45abc..acfc0629ba3 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -574,6 +574,7 @@ + @@ -594,6 +595,7 @@