~unifield-team/unifield-wm/us-826

« back to all changes in this revision

Viewing changes to purchase_followup/purchase_followup.py

  • Committer: Quentin THEURET
  • Date: 2011-12-12 08:02:59 UTC
  • mto: This revision was merged to the branch mainline in revision 724.
  • Revision ID: qt@tempo-consulting.fr-20111212080259-oul1f0g37hcpubyc
UF-641 [ADD] Added the empty purchase_followup module

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
##############################################################################
3
 
#    
4
 
#    OpenERP, Open Source Management Solution
5
 
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6
 
#
7
 
#    This program is free software: you can redistribute it and/or modify
8
 
#    it under the terms of the GNU Affero General Public License as
9
 
#    published by the Free Software Foundation, either version 3 of the
10
 
#    License, or (at your option) any later version.
11
 
#
12
 
#    This program is distributed in the hope that it will be useful,
13
 
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
#    GNU Affero General Public License for more details.
16
 
#
17
 
#    You should have received a copy of the GNU Affero General Public License
18
 
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
19
 
#
20
 
##############################################################################
21
 
 
22
 
from osv import osv
23
 
from osv import fields
24
 
 
25
 
from tools.translate import _
26
 
 
27
 
from order_types import ORDER_PRIORITY, ORDER_CATEGORY
28
 
 
29
 
ORDER_TYPE = [('regular', 'Regular'), ('donation_exp', 'Donation before expiry'), 
30
 
              ('donation_st', 'Standard donation'), ('loan', 'Loan'), 
31
 
              ('in_kind', 'In Kind Donation'), ('purchase_list', 'Purchase List'),
32
 
              ('direct', 'Direct Purchase Order')]
33
 
 
34
 
class purchase_order_followup(osv.osv_memory):
35
 
    _name = 'purchase.order.followup'
36
 
    _description = 'Purchase Order Followup'
37
 
    
38
 
    def _shipped_rate(self, cr, uid, line, context=None):
39
 
        '''
40
 
        Return the shipped rate of a PO line
41
 
        '''
42
 
        uom_obj = self.pool.get('product.uom')
43
 
        line_value = line.price_subtotal
44
 
        move_value = 0.00
45
 
        for move in line.move_ids:
46
 
            if move.state == 'done':
47
 
                product_qty = uom_obj._compute_qty(cr, uid, move.product_uom.id, move.product_qty, line.product_uom.id)
48
 
                if move.type == 'out':
49
 
                    move_value -= product_qty*move.price_unit
50
 
                elif move.type == 'in':
51
 
                    move_value += product_qty*move.price_unit
52
 
            
53
 
        return round((move_value/line_value)*100, 2)
54
 
    
55
 
    def _get_move_state(self, cr, uid, move_state, context=None):
56
 
        return self.pool.get('ir.model.fields').get_selection(cr, uid, 'stock.move', 'state', move_state, context)
57
 
        
58
 
    def update_view(self, cr, uid, ids, context=None):
59
 
        '''
60
 
        Reload the view
61
 
        '''
62
 
        if context is None:
63
 
            context = {}
64
 
        if ids:
65
 
            order_id = self.browse(cr, uid, ids, context=context)[0].order_id.id
66
 
        else:
67
 
            raise osv.except_osv(_('Error'), _('Order followup not found !'))
68
 
        
69
 
        self.unlink(cr, uid, ids, context=context)
70
 
        
71
 
        context.update({'active_id': order_id, 
72
 
                        'active_ids': [order_id], 
73
 
                        'update': True})
74
 
        
75
 
        return self.start_order_followup(cr, uid, ids, context)
76
 
    
77
 
    def close_view(self, cr, uid, ids, context=None):
78
 
        '''
79
 
        Close the view
80
 
        '''
81
 
        return {'type': 'ir.actions.act_window_close'}
82
 
    
83
 
    def start_order_followup(self, cr, uid, ids, context=None):
84
 
        if context is None:
85
 
            context = {}
86
 
        if not context.get('lang'):
87
 
            context['lang'] = self.pool.get('res.users').read(cr, uid, uid, ['context_lang'])['context_lang']
88
 
        # openERP BUG ?
89
 
        ids = context.get('active_ids',[])
90
 
        split = True
91
 
        
92
 
        if not ids:
93
 
            raise osv.except_osv(_('Error'), _('No order found !'))
94
 
        if len(ids) != 1:
95
 
            raise osv.except_osv(_('Error'), 
96
 
                                 _('You should select one order to follow !'))
97
 
        
98
 
        order_obj = self.pool.get('purchase.order')
99
 
        line_obj = self.pool.get('purchase.order.followup.line')
100
 
        
101
 
        for order in order_obj.browse(cr, uid, ids, context=context):
102
 
            if order.state not in ('approved', 'done', 'confirmed_wait', 'split',
103
 
                                   'sourced', 'except_picking', 'except_invoice'):
104
 
                raise osv.except_osv(_('Error'), 
105
 
                       _('You cannot follow a non-confirmed Purchase order !'))
106
 
            
107
 
            followup_id = self.create(cr, uid, 
108
 
                                       {'order_id': order.id}, context=context)
109
 
            
110
 
            order_ids = order_obj.search(cr, uid, [('id', '!=', order.id), ('name', 'like', order.name)], context=context)
111
 
            if not order_ids:
112
 
                split = False
113
 
                order_ids = [order.id]
114
 
            
115
 
            for o in order_obj.browse(cr, uid, order_ids, context=context):
116
 
                for line in o.order_line:
117
 
                    # If the line has no moves
118
 
                    if not line.move_ids:
119
 
                        line_data = {'followup_id': followup_id,
120
 
                                     'order_id': line.order_id and line.order_id.id or False,
121
 
                                      'move_id': False,
122
 
                                      'line_id': line.id,
123
 
                                      'picking_id': False,
124
 
                                      'move_state': 'No move',
125
 
                                      'line_name': line.line_number,
126
 
                                      'line_product_id': line.product_id.id,
127
 
                                      'line_product_qty': line.product_qty,
128
 
                                      'line_uom_id': line.product_uom.id,
129
 
                                      'line_confirmed_date': line.confirmed_delivery_date,
130
 
                                      'line_shipped_rate': 0.0,
131
 
                                      'move_product_id': False,
132
 
                                      'move_product_qty': '',
133
 
                                      'move_uom_id': False,
134
 
                                      'move_delivery_date': False,
135
 
                                      'return_move': False,
136
 
                                      }
137
 
                        line_obj.create(cr, uid, line_data, context=context)
138
 
                    first_move = True
139
 
                    move_ids1 = []
140
 
                    move_ids2 = []
141
 
                    move_ids3 = []
142
 
                    move_ids4 = []
143
 
                    move_ids5 = []
144
 
                    move_ids6 = []
145
 
                    for move in line.move_ids:
146
 
                        if move.type == 'internal':
147
 
                            continue
148
 
                        elif move.type == 'out':
149
 
                            move_ids6.append(move)
150
 
                        elif move.state == 'done':
151
 
                            move_ids1.append(move)
152
 
                        elif move.product_id.id == line.product_id.id:
153
 
                            move_ids2.append(move)
154
 
                        elif move.product_uom.id == line.product_uom.id:
155
 
                            move_ids3.append(move)
156
 
                        elif move.date_expected == line.confirmed_delivery_date:
157
 
                            move_ids4.append(move)
158
 
                        else:
159
 
                            move_ids4.append(move)
160
 
                    for move_ids in [move_ids1, move_ids2, move_ids3, move_ids4, move_ids5, move_ids6]:
161
 
                        for move in move_ids:
162
 
                            line_shipped_rate = "no-progressbar"
163
 
                            if first_move:
164
 
                                line_shipped_rate = self._shipped_rate(cr, uid, line, context)
165
 
                            line_data = {'followup_id': followup_id,
166
 
                                         'order_id': line.order_id and line.order_id.id or False,
167
 
                                         'move_id': move.id,
168
 
                                         'line_id': line.id,
169
 
                                         'picking_id': move.picking_id.id,
170
 
                                         'move_state': self._get_move_state(cr, uid, move.state, context=context),
171
 
                                         'line_name': line.line_number,
172
 
                                         'line_product_id': first_move and line.product_id.id or False,
173
 
                                         'line_product_qty': first_move and line.product_qty or False,
174
 
                                         'line_uom_id': first_move and line.product_uom.id or False,
175
 
                                         'line_confirmed_date': first_move and line.confirmed_delivery_date or False,
176
 
                                         'line_shipped_rate': line_shipped_rate,
177
 
                                         'move_product_id': line.product_id.id != move.product_id.id and move.product_id.id or False,
178
 
                                         'move_product_qty': (line.product_qty != move.product_qty or line.product_id.id != move.product_id.id) and '%.2f' % move.product_qty or '',
179
 
                                         'move_uom_id': line.product_uom.id != move.product_uom.id and move.product_uom.id or False,
180
 
                                         'move_delivery_date': line.confirmed_delivery_date != move.date[:10] and move.date or False,
181
 
                                         'return_move': move.type == 'out',
182
 
                                         }
183
 
                            line_obj.create(cr, uid, line_data, context=context)
184
 
                            
185
 
                            # Unflag the first move
186
 
                            if first_move:
187
 
                                first_move = False
188
 
                                
189
 
        if split:
190
 
            view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase_followup', 'purchase_order_followup_split_form_view')[1]
191
 
        else:
192
 
            view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase_followup', 'purchase_order_followup_form_view')[1]
193
 
                        
194
 
        res = {'type': 'ir.actions.act_window',
195
 
               'res_model': 'purchase.order.followup',
196
 
               'view_type': 'form',
197
 
               'view_mode': 'form',
198
 
               'view_id': [view_id],
199
 
               'res_id': followup_id,
200
 
               'context': context,}
201
 
        
202
 
        # If update the view, return the view in the same screen
203
 
        if context.get('update'):
204
 
            res.update({'target': 'dummy'})
205
 
            
206
 
        return res
207
 
    
208
 
    _columns = {
209
 
        'order_id': fields.many2one('purchase.order', string='Order reference', readonly=True),
210
 
        'supplier_ref': fields.related('order_id', 'partner_ref', string='Supplier Reference', readonly=True, type='char'),
211
 
        'delivery_requested_date': fields.related('order_id', 'delivery_requested_date', string='Delivery requested date', type='date', readonly=True),
212
 
        'delivery_confirmed_date': fields.related('order_id', 'delivery_confirmed_date', string='Delivery confirmed date', type='date', readonly=True),
213
 
        'partner_id': fields.related('order_id', 'partner_id', string='Supplier', type='many2one', relation='res.partner', readonly=True),
214
 
        'partner_ref': fields.related('order_id', 'partner_ref', string='Supplier reference', type='char', readonly=True),
215
 
        'order_type': fields.related('order_id', 'order_type', string='Order Type', type='selection', selection=ORDER_TYPE, readonly=True),
216
 
        'priority': fields.related('order_id', 'priority', string='Priority', type='selection', selection=ORDER_PRIORITY, readonly=True),
217
 
        'categ': fields.related('order_id', 'categ', string='Order Category', type='selection', selection=ORDER_CATEGORY, readonly=True),
218
 
        'line_ids': fields.one2many('purchase.order.followup.line', 'followup_id', readonly=True),
219
 
        
220
 
    }
221
 
    
222
 
purchase_order_followup()
223
 
 
224
 
class purchase_order_followup_line(osv.osv_memory):
225
 
    _name = 'purchase.order.followup.line'
226
 
    _description = 'Purchase Order Followup Line'
227
 
    _rec_name = 'move_id'
228
 
    
229
 
    _columns = {
230
 
        'move_id': fields.many2one('stock.move', string='Move'),
231
 
        'order_id': fields.many2one('purchase.order', string='Order'),
232
 
        'line_id': fields.many2one('purchase.order.line', string='Order line'),
233
 
        'followup_id': fields.many2one('purchase.order.followup', string='Follow-up'),
234
 
        'line_name': fields.char(size=64, string='#'),
235
 
        'line_product_id': fields.many2one('product.product', string='Product'),
236
 
        'line_product_qty': fields.char(size=64, string='Qty'),
237
 
        'line_uom_id': fields.many2one('product.uom', string='UoM'),
238
 
        'line_confirmed_date': fields.date(string='Del. Conf. date'),
239
 
        'line_shipped_rate': fields.float(digits=(16,2), string='% of line received'),
240
 
        'picking_id': fields.many2one('stock.picking', string='Incoming shipment'),
241
 
        'move_product_id': fields.many2one('product.product', string='New product'),
242
 
        'move_product_qty': fields.char(size=64, string='New Qty'),
243
 
        'move_uom_id': fields.many2one('product.uom', string='New UoM'),
244
 
        'move_delivery_date': fields.date(string='New Del. date'),
245
 
        'move_state': fields.char(size=64, string='State'),
246
 
        'return_move': fields.boolean(string='Is a return move ?'),
247
 
    }
248
 
    
249
 
    def go_to_incoming(self, cr, uid, ids, context=None):
250
 
        '''
251
 
        Open the associated Incoming shipment
252
 
        '''
253
 
        for line in self.browse(cr, uid, ids, context=context):
254
 
            if not line.picking_id:
255
 
                raise osv.except_osv(_('Error'), _('This line has no incoming shipment !'))
256
 
            view_id = self.pool.get('stock.picking')._hook_picking_get_view(cr, uid, ids, context=context, pick=line.picking_id)[1]
257
 
            return {'type': 'ir.actions.act_window',
258
 
                    'res_model': 'stock.picking',
259
 
                    'res_id': line.picking_id.id,
260
 
                    'target': 'current',
261
 
                    'view_type': 'form',
262
 
                    'view_mode': 'form,tree',
263
 
                    'view_id': [view_id]}
264
 
            
265
 
purchase_order_followup_line()
266
 
 
267
 
class purchase_order_followup_from_menu(osv.osv_memory):
268
 
    _name = 'purchase.order.followup.from.menu'
269
 
    _description = 'Purchase order followup menu entry'
270
 
 
271
 
    _columns = {
272
 
        'order_id': fields.many2one('purchase.order', string='PO reference', required=True),
273
 
        'cust_order_id': fields.many2one('purchase.order', string='Supplier reference', required=True),
274
 
        'incoming_id': fields.many2one('stock.picking', string='Incoming shipment', required=True),
275
 
        'cust_order_id2': fields.many2one('purchase.order', string='Customer Name', required=True),
276
 
    }
277
 
 
278
 
    def go_to_followup(self, cr, uid, ids, context=None):
279
 
        if context is None:
280
 
            context = {}
281
 
        new_context = context.copy()
282
 
        new_ids = []
283
 
        for menu in self.browse(cr, uid, ids, context=context):
284
 
            if menu.order_id:
285
 
                new_ids.append(menu.order_id.id)
286
 
            elif menu.cust_order_id.id:
287
 
                new_ids.append(menu.cust_order_id.id)
288
 
            elif menu.cust_order_id2.id:
289
 
                new_ids.append(menu.cust_order_id2.id)
290
 
            else:
291
 
                new_ids.append(menu.incoming_id.purchase_id.id)
292
 
 
293
 
        new_context['active_ids'] = new_ids
294
 
 
295
 
        return self.pool.get('purchase.order.followup').start_order_followup(cr, uid, ids, context=new_context)
296
 
 
297
 
    def change_order_id(self, cr, uid, ids, order_id, cust_order_id, incoming_id, cust_order_id2, type='order_id'):
298
 
        res = {}
299
 
 
300
 
        if type == 'cust_order_id' and cust_order_id:
301
 
            res.update({'order_id': False, 'incoming_id': False, 'cust_order_id2': False})
302
 
        elif type == 'order_id' and order_id:
303
 
            res.update({'cust_order_id': False, 'incoming_id': False, 'cust_order_id2': False})
304
 
        elif type == 'incoming_id' and incoming_id:
305
 
            res.update({'cust_order_id': False, 'order_id': False, 'cust_order_id2': False})
306
 
        if type == 'cust_order_id2' and cust_order_id2:
307
 
            res.update({'cust_order_id': False, 'order_id': False, 'incoming_id': False})
308
 
        
309
 
        return {'value': res}
310
 
 
311
 
purchase_order_followup_from_menu()
312
 
 
313
 
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: