# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 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 . # ############################################################################## import time import wizard import netsvc import pooler from osv.orm import browse_record, browse_null merge_form = """
""" merge_fields = { } ack_form = """
""" ack_fields = {} def _merge_orders(self, cr, uid, data, context): pool = pooler.get_pool(cr.dbname) order_obj = pool.get('purchase.order') mod_obj = pool.get('ir.model.data') result = mod_obj._get_id(cr, uid, 'purchase', 'view_purchase_order_filter') id = mod_obj.read(cr, uid, result, ['res_id']) def make_key(br, fields): list_key = [] for field in fields: field_val = getattr(br, field) if field in ('product_id', 'move_dest_id', 'account_analytic_id'): if not field_val: field_val = False if isinstance(field_val, browse_record): field_val = field_val.id elif isinstance(field_val, browse_null): field_val = False elif isinstance(field_val, list): field_val = ((6, 0, tuple([v.id for v in field_val])),) list_key.append((field, field_val)) list_key.sort() return tuple(list_key) # compute what the new orders should contain new_orders = {} for porder in [order for order in order_obj.browse(cr, uid, data['ids']) 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, 'date_order': time.strftime('%Y-%m-%d'), 'partner_id': porder.partner_id.id, 'partner_address_id': porder.partner_address_id.id, 'dest_address_id': porder.dest_address_id.id, 'warehouse_id': porder.warehouse_id.id, 'location_id': porder.location_id.id, 'pricelist_id': porder.pricelist_id.id, 'state': 'draft', 'order_line': {}, 'notes': '%s' % (porder.notes or '',), }) else: #order_infos['name'] += ', %s' % porder.name if porder.notes: order_infos['notes'] = (order_infos['notes'] or '') + ('\n%s' % (porder.notes,)) if porder.origin: 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', 'notes', '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 wf_service = netsvc.LocalService("workflow") allorders = [] for order_key, (order_data, old_ids) in new_orders.iteritems(): # skip merges with only one order if len(old_ids) < 2: allorders += (old_ids or []) continue # cleanup order line data 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()] # create the new order neworder_id = order_obj.create(cr, uid, order_data) allorders.append(neworder_id) # make triggers pointing to the old orders point to the new order for old_id in old_ids: wf_service.trg_redirect(uid, 'purchase.order', old_id, neworder_id, cr) wf_service.trg_validate(uid, 'purchase.order', old_id, 'purchase_cancel', cr) return { 'domain': "[('id','in', [" + ','.join(map(str, allorders)) + "])]", 'name': 'Purchase Orders', 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'purchase.order', 'view_id': False, 'type': 'ir.actions.act_window', 'search_view_id': id['res_id'] } class merge_orders(wizard.interface): states = { 'init': { 'actions': [], 'result': {'type': 'form', 'arch': merge_form, 'fields' : merge_fields, 'state' : [('end', 'Cancel'), ('merge', 'Merge orders') ]} }, 'merge': { 'actions': [], 'result': {'type': 'action', 'action': _merge_orders, 'state': 'end'} }, } merge_orders("purchase.order.merge")