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
30 merge_form = """<?xml version="1.0"?>
31 <form string="Merge orders">
32 <separator string="Are you sure you want to merge these orders ?"/>
34 <label string="Please note that orders will only be merged if they are to the same partner and going to the same location, and lines will only be merged if they are exactly the same except for the quantity and unit."/>
41 ack_form = """<?xml version="1.0"?>
42 <form string="Merge orders">
43 <separator string="Orders merged"/>
49 def _merge_orders(self, cr, uid, data, context):
50 order_obj = pooler.get_pool(cr.dbname).get('purchase.order')
52 def make_key(br, fields):
55 field_val = getattr(br, field)
56 if field in ('product_id', 'move_dest_id', 'account_analytic_id'):
59 if isinstance(field_val, browse_record):
60 field_val = field_val.id
61 elif isinstance(field_val, browse_null):
63 elif isinstance(field_val, list):
64 field_val = ((6, 0, tuple([v.id for v in field_val])),)
65 list_key.append((field, field_val))
67 return tuple(list_key)
69 # compute what the new orders should contain
71 for porder in [order for order in order_obj.browse(cr, uid, data['ids']) if order.state == 'draft']:
72 order_key = make_key(porder, ('partner_id', 'location_id'))
74 new_order = new_orders.setdefault(order_key, ({}, []))
75 new_order[1].append(porder.id)
76 order_infos = new_order[0]
79 'origin': porder.origin,
80 'date_order': time.strftime('%Y-%m-%d'),
81 'partner_id': porder.partner_id.id,
82 'partner_address_id': porder.partner_address_id.id,
83 'dest_address_id': porder.dest_address_id.id,
84 'warehouse_id': porder.warehouse_id.id,
85 'location_id': porder.location_id.id,
86 'pricelist_id': porder.pricelist_id.id,
89 'notes': '%s' % (porder.notes or '',),
92 #order_infos['name'] += ', %s' % porder.name
94 order_infos['notes'] += ('\n%s' % (porder.notes,))
96 order_infos['origin'] = order_infos['origin'] + ' ' + porder.origin
98 for order_line in porder.order_line:
99 line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'notes', 'product_id', 'move_dest_id', 'account_analytic_id'))
100 o_line = order_infos['order_line'].setdefault(line_key, {})
102 # merge the line with an existing line
103 o_line['product_qty'] += order_line.product_qty * order_line.product_uom.factor / o_line['uom_factor']
105 # append a new "standalone" line
106 for field in ('product_qty', 'product_uom'):
107 field_val = getattr(order_line, field)
108 if isinstance(field_val, browse_record):
109 field_val = field_val.id
110 o_line[field] = field_val
111 o_line['uom_factor'] = order_line.product_uom and order_line.product_uom.factor or 1.0
113 wf_service = netsvc.LocalService("workflow")
116 for order_key, (order_data, old_ids) in new_orders.iteritems():
117 # skip merges with only one order
119 allorders += (old_ids or [])
122 # cleanup order line data
123 for key, value in order_data['order_line'].iteritems():
124 del value['uom_factor']
125 value.update(dict(key))
126 order_data['order_line'] = [(0, 0, value) for value in order_data['order_line'].itervalues()]
128 # create the new order
129 neworder_id = order_obj.create(cr, uid, order_data)
130 allorders.append(neworder_id)
132 # make triggers pointing to the old orders point to the new order
133 for old_id in old_ids:
134 wf_service.trg_redirect(uid, 'purchase.order', old_id, neworder_id, cr)
135 wf_service.trg_validate(uid, 'purchase.order', old_id, 'purchase_cancel', cr)
138 'domain': "[('id','in', [" + ','.join(map(str, allorders)) + "])]",
139 'name': 'Purchase Orders',
141 'view_mode': 'tree,form',
142 'res_model': 'purchase.order',
144 'type': 'ir.actions.act_window'
148 class merge_orders(wizard.interface):
152 'result': {'type': 'form', 'arch' : merge_form, 'fields' : merge_fields, 'state' : [('end', 'Cancel'), ('merge', 'Merge orders') ]}
156 'result': {'type': 'action', 'action': _merge_orders, 'state': 'end'}
160 merge_orders("purchase.order.merge")