add encoding comment and vim comment
[odoo/odoo.git] / addons / purchase / wizard / wizard_group.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 # Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
5 #
6 # $Id$
7 #
8 # WARNING: This program as such is intended to be used by professional
9 # programmers who take the whole responsability of assessing all potential
10 # consequences resulting from its eventual inadequacies and bugs
11 # End users who are looking for a ready-to-use solution with commercial
12 # garantees and support are strongly adviced to contract a Free Software
13 # Service Company
14 #
15 # This program is Free Software; you can redistribute it and/or
16 # modify it under the terms of the GNU General Public License
17 # as published by the Free Software Foundation; either version 2
18 # of the License, or (at your option) any later version.
19 #
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28 #
29 ##############################################################################
30
31 import time
32
33 import wizard
34 import netsvc
35 import pooler
36 from osv.orm import browse_record
37
38 merge_form = """<?xml version="1.0"?>
39 <form string="Merge orders">
40     <separator string="Are you sure you want to merge these orders ?"/>
41     <newline/>
42     <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."/>
43 </form>
44 """
45
46 merge_fields = {
47 }
48
49 ack_form = """<?xml version="1.0"?>
50 <form string="Merge orders">
51     <separator string="Orders merged"/>
52 </form>"""
53
54 ack_fields = {}
55
56 def _mergeOrders(self, cr, uid, data, context):
57     order_obj = pooler.get_pool(cr.dbname).get('purchase.order')
58
59     def make_key(br, fields):
60         list_key = []
61         for field in fields:
62             field_val = getattr(br, field)
63             if field in ('product_id','move_dest_id', 'account_analytic_id'):
64                 if not field_val:
65                     field_val = False
66             if isinstance(field_val, browse_record):
67                 field_val = field_val.id
68             elif isinstance(field_val, list):
69                 field_val = ((6, 0, tuple([v.id for v in field_val])),)
70             list_key.append((field, field_val))
71         list_key.sort()
72         return tuple(list_key)
73         
74     # compute what the new orders should contain
75     new_orders = {}
76     for porder in [order for order in order_obj.browse(cr, uid, data['ids']) if order.state == 'draft']:
77         order_key = make_key(porder, ('partner_id', 'location_id'))
78         new_order = new_orders.setdefault(order_key, ({}, []))
79         new_order[1].append(porder.id)
80         order_infos = new_order[0]
81         if not order_infos:
82             order_infos.update({
83                 'origin': porder.origin,
84                 'date_order': time.strftime('%Y-%m-%d'),
85                 'partner_id': porder.partner_id.id,
86                 'partner_address_id': porder.partner_address_id.id,
87                 'dest_address_id': porder.dest_address_id.id,
88                 'warehouse_id': porder.warehouse_id.id,
89                 'location_id': porder.location_id.id,
90                 'pricelist_id': porder.pricelist_id.id,
91                 'state': 'draft',
92                 'order_line': {},
93                 'notes': '%s' % (porder.notes or '',),
94             })
95         else:
96             #order_infos['name'] += ', %s' % porder.name
97             if porder.notes:
98                 order_infos['notes'] += ('\n%s' % (porder.notes,))
99             if porder.origin:
100                 order_infos['origin'] = order_infos['origin'] +' '+ porder.origin
101
102         for order_line in porder.order_line:
103             line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'notes', 'product_id', 'move_dest_id', 'account_analytic_id'))
104             o_line = order_infos['order_line'].setdefault(line_key, {})
105             if o_line:
106                 # merge the line with an existing line
107                 o_line['product_qty'] += order_line.product_qty * order_line.product_uom.factor / o_line['uom_factor']
108             else:
109                 # append a new "standalone" line
110                 for field in ('product_qty', 'product_uom'):
111                     field_val = getattr(order_line, field)
112                     if isinstance(field_val, browse_record):
113                         field_val = field_val.id
114                     o_line[field] = field_val 
115                 o_line['uom_factor'] = order_line.product_uom and order_line.product_uom.factor or 1.0
116
117     wf_service = netsvc.LocalService("workflow")
118
119     allorders = []
120     for order_key, (order_data, old_ids) in new_orders.iteritems():
121         # skip merges with only one order
122         if len(old_ids) < 2:
123             allorders += (old_ids or [])
124             continue
125
126         # cleanup order line data
127         for key, value in order_data['order_line'].iteritems():
128             del value['uom_factor']
129             value.update(dict(key))
130         order_data['order_line'] = [(0, 0, value) for value in order_data['order_line'].itervalues()]
131         
132         # create the new order
133         neworder_id = order_obj.create(cr, uid, order_data)
134         allorders.append(neworder_id)
135
136         # make triggers pointing to the old orders point to the new order
137         for old_id in old_ids:
138             wf_service.trg_redirect(uid, 'purchase.order', old_id, neworder_id, cr)
139             wf_service.trg_validate(uid, 'purchase.order', old_id, 'purchase_cancel', cr)
140
141     return {
142         'domain': "[('id','in', ["+','.join(map(str,allorders))+"])]",
143         'name': 'Purchase orders',
144         'view_type': 'form',
145         'view_mode': 'tree,form',
146         'res_model': 'purchase.order',
147         'view_id': False,
148         'type': 'ir.actions.act_window'
149     }
150
151 class merge_orders(wizard.interface):
152     states = {
153         'init' : {
154             'actions' : [],
155             'result' : {'type' : 'form', 'arch' : merge_form, 'fields' : merge_fields, 'state' : [('end', 'Cancel'),('merge', 'Merge orders') ]}
156         },
157         'merge' : {
158             'actions' : [],
159             'result' : {'type':'action', 'action':_mergeOrders, 'state':'end'}
160         },
161     }
162 merge_orders("purchase.order.merge")
163
164 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
165