1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ##############################################################################
28 from osv.orm import browse_record, browse_null
31 merge_form = """<?xml version="1.0"?>
32 <form string="Merge orders">
33 <separator string="Are you sure you want to merge these orders ?"/>
35 <label>Please note that:
36 - orders will only be merged if:
37 * their status is draft
38 * they belong to the same partner
39 * are going to the same location
40 * have the same pricelist
41 - lines will only be merged if:
42 * they are exactly the same except for the quantity and unit</label>
49 ack_form = """<?xml version="1.0"?>
50 <form string="Merge orders">
51 <separator string="Orders merged"/>
57 def _merge_orders(self, cr, uid, data, context):
58 order_obj = pooler.get_pool(cr.dbname).get('purchase.order')
60 def make_key(br, fields):
63 field_val = getattr(br, field)
64 if field in ('product_id', 'move_dest_id', 'account_analytic_id'):
67 if isinstance(field_val, browse_record):
68 field_val = field_val.id
69 elif isinstance(field_val, browse_null):
71 elif isinstance(field_val, list):
72 field_val = ((6, 0, tuple([v.id for v in field_val])),)
73 list_key.append((field, field_val))
75 return tuple(list_key)
77 # compute what the new orders should contain
79 for porder in [order for order in order_obj.browse(cr, uid, data['ids']) if order.state == 'draft']:
80 order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id'))
82 new_order = new_orders.setdefault(order_key, ({}, []))
83 new_order[1].append(porder.id)
84 order_infos = new_order[0]
87 'origin': porder.origin,
88 'date_order': time.strftime('%Y-%m-%d'),
89 'partner_id': porder.partner_id.id,
90 'partner_address_id': porder.partner_address_id.id,
91 'dest_address_id': porder.dest_address_id.id,
92 'warehouse_id': porder.warehouse_id.id,
93 'location_id': porder.location_id.id,
94 'pricelist_id': porder.pricelist_id.id,
97 'notes': '%s' % (porder.notes or '',),
100 #order_infos['name'] += ', %s' % porder.name
102 order_infos['notes'] = (order_infos['notes'] or '') + ('\n%s' % (porder.notes,))
104 order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin
106 for order_line in porder.order_line:
107 line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'notes', 'product_id', 'move_dest_id', 'account_analytic_id'))
108 o_line = order_infos['order_line'].setdefault(line_key, {})
110 # merge the line with an existing line
111 o_line['product_qty'] += order_line.product_qty * order_line.product_uom.factor / o_line['uom_factor']
113 # append a new "standalone" line
114 for field in ('product_qty', 'product_uom'):
115 field_val = getattr(order_line, field)
116 if isinstance(field_val, browse_record):
117 field_val = field_val.id
118 o_line[field] = field_val
119 o_line['uom_factor'] = order_line.product_uom and order_line.product_uom.factor or 1.0
121 wf_service = netsvc.LocalService("workflow")
124 for order_key, (order_data, old_ids) in new_orders.iteritems():
125 # skip merges with only one order
127 allorders += (old_ids or [])
130 # cleanup order line data
131 for key, value in order_data['order_line'].iteritems():
132 del value['uom_factor']
133 value.update(dict(key))
134 order_data['order_line'] = [(0, 0, value) for value in order_data['order_line'].itervalues()]
136 # create the new order
137 neworder_id = order_obj.create(cr, uid, order_data)
138 allorders.append(neworder_id)
140 # make triggers pointing to the old orders point to the new order
141 for old_id in old_ids:
142 wf_service.trg_redirect(uid, 'purchase.order', old_id, neworder_id, cr)
143 wf_service.trg_validate(uid, 'purchase.order', old_id, 'purchase_cancel', cr)
146 'domain': "[('id','in', [" + ','.join(map(str, allorders)) + "])]",
147 'name': 'Purchase Orders',
149 'view_mode': 'tree,form',
150 'res_model': 'purchase.order',
152 'type': 'ir.actions.act_window'
156 class merge_orders(wizard.interface):
160 'result': {'type': 'form', 'arch': merge_form, 'fields' : merge_fields, 'state' : [('end', 'Cancel'), ('merge', 'Merge orders') ]}
164 'result': {'type': 'action', 'action': _merge_orders, 'state': 'end'}
168 merge_orders("purchase.order.merge")