15
15
# GNU Affero General Public License for more details.
17
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/>.
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
20
##############################################################################
22
24
from osv import osv
23
25
from osv import fields
27
29
from order_types import ORDER_PRIORITY, ORDER_CATEGORY
29
ORDER_TYPE = [('regular', 'Regular'), ('donation_exp', 'Donation before expiry'),
30
('donation_st', 'Standard donation'), ('loan', 'Loan'),
31
ORDER_TYPE = [('regular', 'Regular'), ('donation_exp', 'Donation before expiry'),
32
('donation_st', 'Standard donation'), ('loan', 'Loan'),
31
33
('in_kind', 'In Kind Donation'), ('purchase_list', 'Purchase List'),
32
34
('direct', 'Direct Purchase Order')]
34
36
class purchase_order_followup(osv.osv_memory):
35
37
_name = 'purchase.order.followup'
36
38
_description = 'Purchase Order Followup'
38
40
def _shipped_rate(self, cr, uid, line, context=None):
40
42
Return the shipped rate of a PO line
49
51
move_value -= product_qty*move.price_unit
50
52
elif move.type == 'in':
51
53
move_value += product_qty*move.price_unit
53
55
return round((move_value/line_value)*100, 2)
55
57
def _get_move_state(self, cr, uid, move_state, context=None):
56
58
return self.pool.get('ir.model.fields').get_selection(cr, uid, 'stock.move', 'state', move_state, context)
58
60
def update_view(self, cr, uid, ids, context=None):
65
67
order_id = self.browse(cr, uid, ids, context=context)[0].order_id.id
67
69
raise osv.except_osv(_('Error'), _('Order followup not found !'))
69
71
self.unlink(cr, uid, ids, context=context)
71
context.update({'active_id': order_id,
72
'active_ids': [order_id],
73
context.update({'active_id': order_id,
74
'active_ids': [order_id],
75
77
return self.start_order_followup(cr, uid, ids, context)
77
79
def close_view(self, cr, uid, ids, context=None):
81
83
return {'type': 'ir.actions.act_window_close'}
83
85
def start_order_followup(self, cr, uid, ids, context=None):
84
86
if context is None:
89
91
ids = context.get('active_ids',[])
93
95
raise osv.except_osv(_('Error'), _('No order found !'))
95
raise osv.except_osv(_('Error'),
97
raise osv.except_osv(_('Error'),
96
98
_('You should select one order to follow !'))
98
100
order_obj = self.pool.get('purchase.order')
99
101
line_obj = self.pool.get('purchase.order.followup.line')
101
103
for order in order_obj.browse(cr, uid, ids, context=context):
102
104
if order.state not in ('approved', 'done', 'confirmed_wait', 'split',
103
105
'sourced', 'except_picking', 'except_invoice'):
104
raise osv.except_osv(_('Error'),
106
raise osv.except_osv(_('Error'),
105
107
_('You cannot follow a non-confirmed Purchase order !'))
107
followup_id = self.create(cr, uid,
109
followup_id = self.create(cr, uid,
108
110
{'order_id': order.id}, context=context)
110
112
order_ids = order_obj.search(cr, uid, [('id', '!=', order.id), ('name', 'like', order.name)], context=context)
111
113
if not order_ids:
113
115
order_ids = [order.id]
115
117
for o in order_obj.browse(cr, uid, order_ids, context=context):
116
118
for line in o.order_line:
117
119
# If the line has no moves
177
179
'move_product_id': line.product_id.id != move.product_id.id and move.product_id.id or False,
178
180
'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
181
'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,
182
'move_delivery_date': line.confirmed_delivery_date != move.date[:10] and move.date[:10] or False,
181
183
'return_move': move.type == 'out',
183
185
line_obj.create(cr, uid, line_data, context=context)
185
187
# Unflag the first move
187
189
first_move = False
190
192
view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase_followup', 'purchase_order_followup_split_form_view')[1]
192
194
view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase_followup', 'purchase_order_followup_form_view')[1]
194
196
res = {'type': 'ir.actions.act_window',
195
197
'res_model': 'purchase.order.followup',
196
198
'view_type': 'form',
198
200
'view_id': [view_id],
199
201
'res_id': followup_id,
200
202
'context': context,}
202
204
# If update the view, return the view in the same screen
203
205
if context.get('update'):
204
206
res.update({'target': 'dummy'})
210
def export_get_file_name(self, cr, uid, ids, prefix='PO_Follow_Up', context=None):
211
if isinstance(ids, (int, long)):
215
foup = self.browse(cr, uid, ids[0], context=context)
216
if not foup or not foup.order_id or not foup.order_id.name:
218
dt_now = datetime.datetime.now()
219
po_name = "%s_%s_%d_%02d_%02d" % (prefix,
220
foup.order_id.name.replace('/', '_'),
221
dt_now.year, dt_now.month, dt_now.day)
224
def export_xls(self, cr, uid, ids, context=None):
226
Print the report (Excel)
228
if isinstance(ids, (int, long)):
231
file_name = self.export_get_file_name(cr, uid, ids, context=context)
233
datas['target_filename'] = file_name
235
'type': 'ir.actions.report.xml',
236
'report_name': 'purchase.follow.up.report_xls',
242
def export_pdf(self, cr, uid, ids, context=None):
244
Print the report (PDF)
246
if isinstance(ids, (int, long)):
249
file_name = self.export_get_file_name(cr, uid, ids, context=context)
251
datas['target_filename'] = file_name
253
'type': 'ir.actions.report.xml',
254
'report_name': 'purchase.follow.up.report_pdf',
209
261
'order_id': fields.many2one('purchase.order', string='Order reference', readonly=True),
210
262
'supplier_ref': fields.related('order_id', 'partner_ref', string='Supplier Reference', readonly=True, type='char'),
216
268
'priority': fields.related('order_id', 'priority', string='Priority', type='selection', selection=ORDER_PRIORITY, readonly=True),
217
269
'categ': fields.related('order_id', 'categ', string='Order Category', type='selection', selection=ORDER_CATEGORY, readonly=True),
218
270
'line_ids': fields.one2many('purchase.order.followup.line', 'followup_id', readonly=True),
222
274
purchase_order_followup()
224
276
class purchase_order_followup_line(osv.osv_memory):
225
277
_name = 'purchase.order.followup.line'
226
278
_description = 'Purchase Order Followup Line'
227
279
_rec_name = 'move_id'
230
282
'move_id': fields.many2one('stock.move', string='Move'),
231
283
'order_id': fields.many2one('purchase.order', string='Order'),
245
297
'move_state': fields.char(size=64, string='State'),
246
298
'return_move': fields.boolean(string='Is a return move ?'),
301
def read(self, cr, uid, ids, fields, context=None, load='_classic_write'):
302
res = super(purchase_order_followup_line, self).read(cr, uid, ids, fields, context=context, load=load)
304
if context.get('export'):
306
if 'line_shipped_rate' in r and r['line_shipped_rate'] == 'no-progressbar':
307
r['line_shipped_rate'] = 0.00
249
311
def go_to_incoming(self, cr, uid, ids, context=None):
251
313
Open the associated Incoming shipment
272
334
'order_id': fields.many2one('purchase.order', string='PO reference', required=True),
273
335
'cust_order_id': fields.many2one('purchase.order', string='Supplier reference', required=True),
274
336
'incoming_id': fields.many2one('stock.picking', string='Incoming shipment', required=True),
337
'cust_order_id2': fields.many2one('purchase.order', string='Customer Name', required=True),
277
340
def go_to_followup(self, cr, uid, ids, context=None):
284
347
new_ids.append(menu.order_id.id)
285
348
elif menu.cust_order_id.id:
286
349
new_ids.append(menu.cust_order_id.id)
350
elif menu.cust_order_id2.id:
351
new_ids.append(menu.cust_order_id2.id)
288
353
new_ids.append(menu.incoming_id.purchase_id.id)
292
357
return self.pool.get('purchase.order.followup').start_order_followup(cr, uid, ids, context=new_context)
294
def change_order_id(self, cr, uid, ids, order_id, cust_order_id, incoming_id, type='order_id'):
359
def change_order_id(self, cr, uid, ids, order_id, cust_order_id, incoming_id, cust_order_id2, type='order_id'):
297
362
if type == 'cust_order_id' and cust_order_id:
298
res.update({'order_id': False, 'incoming_id': False})
363
res.update({'order_id': False, 'incoming_id': False, 'cust_order_id2': False})
299
364
elif type == 'order_id' and order_id:
300
res.update({'cust_order_id': False, 'incoming_id': False})
365
res.update({'cust_order_id': False, 'incoming_id': False, 'cust_order_id2': False})
301
366
elif type == 'incoming_id' and incoming_id:
302
res.update({'cust_order_id': False, 'order_id': False})
367
res.update({'cust_order_id': False, 'order_id': False, 'cust_order_id2': False})
368
if type == 'cust_order_id2' and cust_order_id2:
369
res.update({'cust_order_id': False, 'order_id': False, 'incoming_id': False})
304
371
return {'value': res}
306
373
purchase_order_followup_from_menu()
308
375
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: