1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# Copyright (C) 2011 Associazione OpenERP Italia
5
# (<http://www.openerp-italia.org>).
7
# Thanks to Cecchi s.r.l http://www.cecchi.com/
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU Affero General Public License as published by
11
# the Free Software Foundation, either version 3 of the License, or
12
# (at your option) any later version.
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
19
# You should have received a copy of the GNU Affero General Public License
20
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
##############################################################################
26
from osv import osv, fields
28
from tools.translate import _
33
class riba_mode(osv.osv):
35
_description= 'Presentacion Bank'
37
'name': fields.char('Bank of Presentacion', size=64, required=True, help='Banca di Presentazione'),
38
'bank_id': fields.many2one('res.partner.bank', "Bank Account for the Riba Mode",
39
required=True,help='Presentacion bank account for the RiBa'),
40
'journal': fields.many2one('account.journal', 'Journal', required=True,
41
domain=[('type', '=', 'bank')], help='Bank Journal for the Mode RiBa'),
42
'company_id': fields.many2one('res.company', 'Company',required=True),
43
'partner_id':fields.related('company_id','partner_id',type='many2one',relation='res.partner',string='Partner',store=True,),
47
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id
50
def suitable_bank_types(self, cr, uid, payment_code=None, context=None):
51
"""Return the codes of the bank type that are suitable
52
for the given payment type code"""
53
"""ID's Creditor Banks"""
56
cr.execute(""" SELECT pb.state
57
FROM res_partner_bank pb
58
JOIN riba_mode rm ON (rm.bank_id = pb.id)
59
WHERE rm.id = %s """, [payment_code])
60
return [x[0] for x in cr.fetchall()]
62
def onchange_company_id (self, cr, uid, ids, company_id=False, context=None):
65
partner_id = self.pool.get('res.company').browse(cr, uid, company_id, context=context).partner_id.id
66
result['partner_id'] = partner_id
67
return {'value': result}
72
class riba_order(osv.osv):
74
_description = 'Riba Order'
75
_rec_name = 'reference'
77
def get_wizard(self, type):
78
logger = netsvc.Logger()
79
logger.notifyChannel("warning", netsvc.LOG_WARNING,
80
"No wizard found for the RiBa type '%s'." % type)
83
def _total(self, cursor, user, ids, name, args, context=None):
87
for order in self.browse(cursor, user, ids, context=context):
89
res[order.id] = reduce(lambda x, y: x + y.amount, order.line_ids, 0.0)
95
'date_scheduled': fields.date('Scheduled date if fixed', states={'done':[('readonly', True)]}, help='Select a date if you have chosen Preferred Date to be fixed.'),
96
'reference': fields.char('Reference', size=128, required=1, states={'done': [('readonly', True)]}),
97
'mode': fields.many2one('riba.mode', 'Riba mode', select=True, required=1, states={'done': [('readonly', True)]}, help='Select the Riba Mode to be applied.'),
98
'state': fields.selection([
100
('open', 'Confirmed'),
101
('cancel', 'Cancelled'),
102
('done', 'Done')], 'State', select=True,
103
help='When an order is placed the state is \'Draft\'.\n Once the bank is confirmed the state is set to \'Confirmed\'.\n Then the order is paid the state is \'Done\'.'),
104
'line_ids': fields.one2many('riba.line', 'order_id', 'Riba lines', states={'done': [('readonly', True)]}),
105
'total': fields.function(_total, string="Total", method=True, type='float'),
106
'user_id': fields.many2one('res.users', 'User', required=True, states={'done': [('readonly', True)]}),
107
'date_prefered': fields.selection([
110
('fixed', 'Fixed date')
111
], "Preferred date", change_default=True, required=True, states={'done': [('readonly', True)]}, help="Choose an option for the Riba Order:'Fixed' stands for a date specified by you.'Directly' stands for the direct execution.'Due date' stands for the scheduled date of execution."),
112
'date_created': fields.date('Creation date', readonly=True),
113
'date_done': fields.date('Execution date', readonly=True),
114
'company_id': fields.related('mode', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
118
'user_id': lambda self,cr,uid,context: uid,
120
'date_prefered': 'due',
121
'date_created': lambda *a: time.strftime('%Y-%m-%d'),
122
'reference': lambda self,cr,uid,context: self.pool.get('ir.sequence').get(cr, uid, 'riba.order'),
125
def set_to_draft(self, cr, uid, ids, *args):
126
self.write(cr, uid, ids, {'state': 'draft'})
127
wf_service = netsvc.LocalService("workflow")
129
wf_service.trg_create(uid, 'riba.order', id, cr)
132
def action_open(self, cr, uid, ids, *args):
133
ir_seq_obj = self.pool.get('ir.sequence')
135
for order in self.read(cr, uid, ids, ['reference']):
136
if not order['reference']:
137
reference = ir_seq_obj.get(cr, uid, 'riba.order')
138
self.write(cr, uid, order['id'], {'reference':reference})
141
def set_done(self, cr, uid, ids, *args):
142
wf_service = netsvc.LocalService("workflow")
143
self.write(cr, uid, ids, {'date_done': time.strftime('%Y-%m-%d')})
144
wf_service.trg_validate(uid, 'riba.order', ids[0], 'done', cr)
147
def copy(self, cr, uid, id, default={}, context=None):
151
'reference': self.pool.get('ir.sequence').get(cr, uid, 'riba.order')
153
return super(riba_order, self).copy(cr, uid, id, default, context=context)
155
def write(self, cr, uid, ids, vals, context=None):
158
riba_line_obj = self.pool.get('riba.line')
161
if (vals.get('date_prefered', False) == 'fixed' and not vals.get('date_scheduled', False)) or vals.get('date_scheduled', False):
162
for order in self.browse(cr, uid, ids, context=context):
163
for line in order.line_ids:
164
riba_line_ids.append(line.id)
165
riba_line_obj.write(cr, uid, riba_line_ids, {'date': vals.get('date_scheduled', False)}, context=context)
166
elif vals.get('date_prefered', False) == 'due':
167
vals.update({'date_scheduled': False})
168
for order in self.browse(cr, uid, ids, context=context):
169
for line in order.line_ids:
170
riba_line_obj.write(cr, uid, [line.id], {'date': line.ml_maturity_date}, context=context)
171
elif vals.get('date_prefered', False) == 'now':
172
vals.update({'date_scheduled': False})
173
for order in self.browse(cr, uid, ids, context=context):
174
for line in order.line_ids:
175
riba_line_ids.append(line.id)
176
riba_line_obj.write(cr, uid, riba_line_ids, {'date': False}, context=context)
177
return super(riba_order, self).write(cr, uid, ids, vals, context=context)
181
class riba_line(osv.osv):
183
_description = 'Riba Line'
185
def translate(self, orig):
187
"due_date": "date_maturity",
188
"reference": "ref"}.get(orig, orig)
190
def info_owner(self, cr, uid, ids, name=None, args=None, context=None):
191
if not ids: return {}
192
partner_address_obj = self.pool.get('res.partner.address')
196
for line in self.browse(cr, uid, ids, context=context):
197
owner = line.order_id.mode.bank_id.partner_id
198
result[line.id] = False
200
for ads in owner.address:
201
if ads.type == 'default':
202
st = ads.street and ads.street or ''
203
st1 = ads.street2 and ads.street2 or ''
205
zip_city = ads.zip_id and partner_address_obj.name_get(cr, uid, [ads.zip_id.id])[0][1] or ''
207
zip = ads.zip and ads.zip or ''
208
city = ads.city and ads.city or ''
209
zip_city = zip + ' ' + city
210
cntry = ads.country_id and ads.country_id.name or ''
211
info = owner.name + "\n" + st + " " + st1 + "\n" + zip_city + "\n" +cntry
212
result[line.id] = info
216
def info_partner(self, cr, uid, ids, name=None, args=None, context=None):
217
if not ids: return {}
218
partner_address_obj = self.pool.get('res.partner.address')
222
for line in self.browse(cr, uid, ids, context=context):
223
result[line.id] = False
224
if not line.partner_id:
226
partner = line.partner_id.name or ''
227
if line.partner_id.address:
228
for ads in line.partner_id.address:
229
if ads.type == 'default':
230
st = ads.street and ads.street or ''
231
st1 = ads.street2 and ads.street2 or ''
233
zip_city = ads.zip_id and partner_address_obj.name_get(cr, uid, [ads.zip_id.id])[0][1] or ''
235
zip = ads.zip and ads.zip or ''
236
city = ads.city and ads.city or ''
237
zip_city = zip + ' ' + city
238
cntry = ads.country_id and ads.country_id.name or ''
239
info = partner + "\n" + st + " " + st1 + "\n" + zip_city + "\n" +cntry
240
result[line.id] = info
245
def s_bank_types(self, cr, uid, payment_code=None, context=None):
246
"""Return the codes of the bank type that are suitable
247
for the given bank payment of riba line"""
248
"""ID's Debitor's Banks"""
251
cr.execute(""" SELECT pb.name
252
FROM res_partner_bank pb
253
JOIN riba_line rl ON (rl.bank_id = pb.id)
254
WHERE rl.id = %s """, [payment_code])
255
return [x[0] for x in cr.fetchall()]
257
def select_by_name(self, cr, uid, ids, name, args, context=None):
258
if not ids: return {}
259
partner_obj = self.pool.get('res.partner')
261
cr.execute("""SELECT rl.id, ml.%s
262
FROM account_move_line ml
263
INNER JOIN riba_line rl
264
ON (ml.id = rl.move_line_id)
265
WHERE rl.id IN %%s"""% self.translate(name),
267
res = dict(cr.fetchall())
269
if name == 'partner_id':
271
for p_id, p_name in partner_obj.name_get(cr, uid,
272
filter(lambda x:x and x != 0,res.values()), context=context):
273
partner_name[p_id] = p_name
276
if id in res and partner_name:
277
res[id] = (res[id],partner_name[res[id]])
279
res[id] = (False,False)
282
res.setdefault(id, (False, ""))
285
def _amount(self, cursor, user, ids, name, args, context=None):
288
currency_obj = self.pool.get('res.currency')
293
for line in self.browse(cursor, user, ids, context=context):
295
ctx['date'] = line.order_id.date_done or time.strftime('%Y-%m-%d')
296
res[line.id] = currency_obj.compute(cursor, user, line.currency.id,
297
line.company_currency.id,
298
line.amount_currency, context=ctx)
301
def _get_currency(self, cr, uid, context=None):
302
user_obj = self.pool.get('res.users')
303
currency_obj = self.pool.get('res.currency')
304
user = user_obj.browse(cr, uid, uid, context=context)
307
return user.company_id.currency_id.id
309
return currency_obj.search(cr, uid, [('rate', '=', 1.0)])[0]
311
def _get_date(self, cr, uid, context=None):
314
riba_order_obj = self.pool.get('riba.order')
317
if context.get('order_id') and context['order_id']:
318
order = riba_order_obj.browse(cr, uid, context['order_id'], context=context)
319
if order.date_prefered == 'fixed':
320
date = order.date_scheduled
322
date = time.strftime('%Y-%m-%d')
325
def _get_ml_inv_ref(self, cr, uid, ids, *a):
327
for id in self.browse(cr, uid, ids):
330
if id.move_line_id.invoice:
331
res[id.id] = id.move_line_id.invoice.id
334
def _get_ml_maturity_date(self, cr, uid, ids, *a):
336
for id in self.browse(cr, uid, ids):
338
res[id.id] = id.move_line_id.date_maturity
343
def _get_ml_created_date(self, cr, uid, ids, *a):
345
for id in self.browse(cr, uid, ids):
347
res[id.id] = id.move_line_id.date_created
353
'name': fields.char('Your Reference', size=64),
354
'communication': fields.char('Communication', size=64, required=True, help="Used as the message between ordering customer and current company. Depicts 'What do you want to say to the recipient about this order?'"),
355
'communication2': fields.char('Communication 2', size=64, help='The successor message of Communication.'),
356
'move_line_id': fields.many2one('account.move.line', 'Entry line', domain=[('account_id.type', '=', 'receivable'), ('account_id.type', '=', 'receivable')], help='This Entry Line will be referred for the information of the ordering customer.'),
357
'amount_currency': fields.float('Amount in Partner Currency', digits=(16, 2),
358
required=True, help='Payment amount in the partner currency'),
359
'currency': fields.many2one('res.currency','Partner Currency'),
360
'company_currency': fields.many2one('res.currency', 'Company Currency', readonly=True),
361
'bank_id': fields.many2one('res.partner.bank', 'Debitor Bank'),
362
'order_id': fields.many2one('riba.order', 'Order', required=True,
363
ondelete='cascade', select=True),
364
'partner_id': fields.many2one('res.partner', string="Partner", required=True, help='The Ordering Customer'),
365
'amount': fields.function(_amount, string='Amount in Company Currency',
366
method=True, type='float',
367
help='Payment amount in the company currency'),
368
'ml_date_created': fields.function(_get_ml_created_date, string="Effective Date",
369
method=True, type='date', help="Invoice Effective Date"),
370
'ml_maturity_date': fields.function(_get_ml_maturity_date, method=True, type='date', string='Due Date'),
371
'ml_inv_ref': fields.function(_get_ml_inv_ref, method=True, type='many2one', relation='account.invoice', string='Invoice Ref.'),
372
'info_owner': fields.function(info_owner, string="Owner Account", method=True, type="text", help='Address of the Main Partner'),
373
'info_partner': fields.function(info_partner, string="Destination Account", method=True, type="text", help='Address of the Customer.'),
374
'date': fields.date('Payment Date', help="If no payment date is specified, the bank will treat this riba line directly"),
375
'create_date': fields.datetime('Created', readonly=True),
376
'state': fields.selection([('normal','Free'), ('structured','Structured')], 'Communication Type', required=True),
377
'company_id': fields.related('order_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
380
'name': lambda obj, cursor, user, context: obj.pool.get('ir.sequence'
381
).get(cursor, user, 'riba.line'),
383
'currency': _get_currency,
384
'company_currency': _get_currency,
388
('name_uniq', 'UNIQUE(name)', 'The riba line name must be unique!'),
391
def onchange_move_line(self, cr, uid, ids, move_line_id, payment_type, date_prefered, date_scheduled, currency=False, company_currency=False, context=None):
393
move_line_obj = self.pool.get('account.move.line')
395
data['amount_currency'] = data['communication'] = data['partner_id'] = data['reference'] = data['date_created'] = data['bank_id'] = data['amount'] = False
398
line = move_line_obj.browse(cr, uid, move_line_id, context=context)
399
data['amount_currency'] = line.riba_amount_to_pay
401
res = self.onchange_amount(cr, uid, ids, data['amount_currency'], currency,
402
company_currency, context)
404
data['amount'] = res['value']['amount']
405
data['partner_id'] = line.partner_id.id
406
temp = line.currency_id and line.currency_id.id or False
409
data['currency'] = line.invoice.currency_id.id
411
data['currency'] = temp
413
# calling onchange of partner and updating data dictionary
414
temp_dict = self.onchange_partner(cr, uid, ids, line.partner_id.id, payment_type)
415
data.update(temp_dict['value'])
417
data['reference'] = line.ref
418
data['date_created'] = line.date_created
419
data['communication'] = line.ref
421
if date_prefered == 'now':
422
#no payment date => immediate payment
424
elif date_prefered == 'due':
425
data['date'] = line.date_maturity
426
elif date_prefered == 'fixed':
427
data['date'] = date_scheduled
428
return {'value': data}
430
def onchange_amount(self, cr, uid, ids, amount, currency, cmpny_currency, context=None):
431
if (not amount) or (not cmpny_currency):
432
return {'value': {'amount': False}}
434
currency_obj = self.pool.get('res.currency')
435
company_amount = currency_obj.compute(cr, uid, currency, cmpny_currency, amount)
436
res['amount'] = company_amount
437
return {'value': res}
439
def onchange_partner(self, cr, uid, ids, partner_id, payment_type, context=None):
441
partner_address_obj = self.pool.get('res.partner.address')
442
partner_obj = self.pool.get('res.partner')
443
data['info_partner'] = data['bank_id'] = False
446
part_obj = partner_obj.browse(cr, uid, partner_id, context=context)
447
partner = part_obj.name or ''
450
for ads in part_obj.address:
451
if ads.type == 'default':
452
st = ads.street and ads.street or ''
453
st1 = ads.street2 and ads.street2 or ''
456
zip_city = ads.zip_id and partner_address_obj.name_get(cr, uid, [ads.zip_id.id])[0][1] or ''
458
zip = ads.zip and ads.zip or ''
459
city = ads.city and ads.city or ''
460
zip_city = zip + ' ' + city
462
cntry = ads.country_id and ads.country_id.name or ''
463
info = partner + "\n" + st + " " + st1 + "\n" + zip_city + "\n" +cntry
465
data['info_partner'] = info
467
if part_obj.bank_ids and payment_type:
468
bank_type = self.s_bank_types(cr, uid, payment_type, context=context)
469
for bank in part_obj.bank_ids:
470
if bank.state in bank_type:
471
data['bank_id'] = bank.id
473
return {'value': data}
475
def fields_get(self, cr, uid, fields=None, context=None):
476
res = super(riba_line, self).fields_get(cr, uid, fields, context)
477
if 'communication2' in res:
478
res['communication2'].setdefault('states', {})
479
res['communication2']['states']['structured'] = [('readonly', True)]
480
res['communication2']['states']['normal'] = [('readonly', False)]
485
class account_payment_term(osv.osv):
486
# This OpenERP object inherits from account_payment_term
487
# to add a new boolean field
488
_inherit = 'account.payment.term'
490
'riba' : fields.boolean('Riba'),
495
# create an instance of account_payment_term_
496
# to migrate the objects in the system
497
account_payment_term()
499
class res_bank_add_field(osv.osv):
500
# This OpenERP object inherits from account_payment_term
501
# to add a new boolean field
502
_inherit = 'res.bank'
504
'banca_estera' : fields.boolean('Banca Estera'),
506
# create an instance of account_payment_term_
507
# to migrate the objects in the system
510
class res_partner_bank_add(osv.osv):
511
# This OpenERP object inherits from account_payment_term
512
# to add a new boolean field
513
_inherit = "res.partner.bank"
515
'codice_sia' : fields.char('Codice SIA', size=5, help="Identification Code of the Company in the System Interbank")
518
# create an instance of account_payment_term_
519
# to migrate the objects in the system
520
res_partner_bank_add()
522
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: