Files
tryton/payment_term.py
T

214 lines
7.5 KiB
Python
Raw Normal View History

2009-01-02 17:54:34 +01:00
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
from decimal import Decimal
2009-01-04 14:37:44 +01:00
import datetime
import time
from dateutil.relativedelta import relativedelta
2010-08-19 22:02:49 +02:00
from trytond.model import ModelView, ModelSQL, fields
from trytond.backend import TableHandler
2011-08-21 11:20:30 +02:00
from trytond.pyson import Eval
2010-08-19 22:02:49 +02:00
from trytond.transaction import Transaction
2011-07-03 13:18:43 +02:00
from trytond.pool import Pool
2009-01-02 17:54:34 +01:00
2009-02-28 16:57:26 +01:00
class PaymentTerm(ModelSQL, ModelView):
2009-01-02 17:54:34 +01:00
'Payment Term'
_name = 'account.invoice.payment_term'
_description = __doc__
name = fields.Char('Payment Term', size=None, required=True, translate=True)
active = fields.Boolean('Active')
description = fields.Text('Description', translate=True)
lines = fields.One2Many('account.invoice.payment_term.line', 'payment',
'Lines')
def __init__(self):
super(PaymentTerm, self).__init__()
self._order.insert(0, ('name', 'ASC'))
self._error_messages.update({
'invalid_line': 'Invalid payment term line!',
'missing_remainder': 'Payment term missing a remainder line!',
})
2010-08-19 22:02:49 +02:00
def default_active(self):
2009-01-02 17:54:34 +01:00
return True
2010-08-19 22:02:49 +02:00
def compute(self, amount, currency, payment_term, date=None):
2009-01-02 17:54:34 +01:00
'''
Return list with (date, amount) for each payment term lines
'''
#TODO implement business_days
# http://pypi.python.org/pypi/BusinessHours/
2011-07-03 13:18:43 +02:00
pool = Pool()
type_obj = pool.get('account.invoice.payment_term.line.type')
delay_obj = pool.get(
2009-01-02 17:54:34 +01:00
'account.invoice.payment_term.line.delay')
2011-07-03 13:18:43 +02:00
currency_obj = pool.get('currency.currency')
date_obj = pool.get('ir.date')
2009-01-02 17:54:34 +01:00
res = []
if date is None:
2010-08-19 22:02:49 +02:00
date = date_obj.today()
2009-01-02 17:54:34 +01:00
remainder = amount
for line in payment_term.lines:
2010-08-19 22:02:49 +02:00
value = type_obj.get_value(line, remainder, currency)
value_date = delay_obj.get_date(line, date)
2009-01-02 17:54:34 +01:00
if not value or not value_date:
if (not remainder) and line.amount:
2010-08-19 22:02:49 +02:00
self.raise_user_error('invalid_line')
2009-01-02 17:54:34 +01:00
else:
continue
res.append((value_date, value))
remainder -= value
2010-08-19 22:02:49 +02:00
if not currency_obj.is_zero(currency, remainder):
self.raise_user_error('missing_remainder')
2009-01-02 17:54:34 +01:00
return res
PaymentTerm()
2009-02-28 16:57:26 +01:00
class PaymentTermLineType(ModelSQL, ModelView):
2009-01-02 17:54:34 +01:00
'Payment Term Line Type'
_name = 'account.invoice.payment_term.line.type'
_description = __doc__
name = fields.Char('Name', size=None, translate=True, required=True)
code = fields.Char('Code', size=None, required=True)
def __init__(self):
super(PaymentTermLineType, self).__init__()
self._sql_constraints += [
2009-03-20 13:02:41 +01:00
('code_uniq', 'UNIQUE(code)', 'The code must be unique!'),
2009-01-02 17:54:34 +01:00
]
self._order.insert(0, ('name', 'ASC'))
2010-08-19 22:02:49 +02:00
def get_value(self, line, amount, currency):
2011-07-03 13:18:43 +02:00
currency_obj = Pool().get('currency.currency')
2009-01-02 17:54:34 +01:00
if line.type == 'fixed':
2010-08-19 22:02:49 +02:00
return currency_obj.compute(line.currency, line.amount, currency)
2009-01-02 17:54:34 +01:00
elif line.type == 'percent':
2010-08-19 22:02:49 +02:00
return currency_obj.round(currency,
amount * line.percentage / Decimal('100'))
2009-01-02 17:54:34 +01:00
elif line.type == 'remainder':
2010-08-19 22:02:49 +02:00
return currency_obj.round(currency, amount)
2009-01-02 17:54:34 +01:00
return None
PaymentTermLineType()
2009-02-28 16:57:26 +01:00
class PaymentTermLineDelay(ModelSQL, ModelView):
2009-01-02 17:54:34 +01:00
'Payment Term Line Delay'
_name = 'account.invoice.payment_term.line.delay'
_description = __doc__
name = fields.Char('Name', size=None, translate=True, required=True)
code = fields.Char('Code', size=None, required=True)
def __init__(self):
super(PaymentTermLineDelay, self).__init__()
self._sql_constraints += [
2009-03-20 13:02:41 +01:00
('code_uniq', 'UNIQUE(code)', 'The code must be unique!'),
2009-01-02 17:54:34 +01:00
]
self._order.insert(0, ('name', 'ASC'))
2010-08-19 22:02:49 +02:00
def get_date(self, line, date):
2009-01-02 17:54:34 +01:00
value = None
if line.delay in ('net_days', 'end_month'):
value = date + relativedelta(days=line.days)
if line.delay == 'end_month':
value += relativedelta(day=31)
return value
2009-01-02 17:54:34 +01:00
PaymentTermLineDelay()
2009-02-28 16:57:26 +01:00
class PaymentTermLine(ModelSQL, ModelView):
2009-01-02 17:54:34 +01:00
'Payment Term Line'
_name = 'account.invoice.payment_term.line'
_description = __doc__
sequence = fields.Integer('Sequence',
help='Use to order lines in ascending order')
payment = fields.Many2One('account.invoice.payment_term', 'Payment Term',
required=True, ondelete="CASCADE")
type = fields.Selection('get_type', 'Type', required=True,
on_change=['type'])
percentage = fields.Numeric('Percentage', digits=(16, 8),
2011-08-04 16:57:16 +02:00
states={
2011-08-21 11:20:30 +02:00
'invisible': Eval('type') != 'percent',
'required': Eval('type') == 'percent',
2011-08-04 16:57:16 +02:00
}, depends=['type'], help='In %')
2010-01-20 10:57:08 +01:00
amount = fields.Numeric('Amount', digits=(16, Eval('currency_digits', 2)),
2011-08-04 16:57:16 +02:00
states={
2011-08-21 11:20:30 +02:00
'invisible': Eval('type') != 'fixed',
'required': Eval('type') == 'fixed',
2011-08-04 16:57:16 +02:00
}, depends=['type', 'currency_digits'])
2009-01-02 17:54:34 +01:00
currency = fields.Many2One('currency.currency', 'Currency',
2011-08-04 16:57:16 +02:00
states={
2011-08-21 11:20:30 +02:00
'invisible': Eval('type') != 'fixed',
'required': Eval('type') == 'fixed',
2011-08-04 16:57:16 +02:00
}, depends=['type'])
2010-03-11 16:45:42 +01:00
currency_digits = fields.Function(fields.Integer('Currency Digits',
on_change_with=['currency']), 'get_currency_digits')
2009-01-02 17:54:34 +01:00
days = fields.Integer('Number of Days')
delay = fields.Selection('get_delay', 'Condition', required=True)
def __init__(self):
super(PaymentTermLine, self).__init__()
self._order.insert(0, ('sequence', 'ASC'))
2010-08-19 22:02:49 +02:00
def init(self, module_name):
super(PaymentTermLine, self).init(module_name)
cursor = Transaction().cursor
2009-03-17 22:39:26 +01:00
table = TableHandler(cursor, self, module_name)
# Migration from 1.0 percent change into percentage
2009-02-04 13:30:48 +01:00
if table.column_exist('percent'):
cursor.execute('UPDATE "' + self._table + '" ' \
'SET percentage = percent * 100')
2009-02-04 13:30:48 +01:00
table.drop_column('percent', exception=True)
2010-08-19 22:02:49 +02:00
def default_type(self):
2009-01-02 17:54:34 +01:00
return 'remainder'
2010-08-19 22:02:49 +02:00
def default_delay(self):
2009-01-02 17:54:34 +01:00
return 'net_days'
2010-08-19 22:02:49 +02:00
def get_type(self):
2011-07-03 13:18:43 +02:00
type_obj = Pool().get('account.invoice.payment_term.line.type')
2010-08-19 22:02:49 +02:00
type_ids = type_obj.search([])
types = type_obj.browse(type_ids)
2009-01-02 17:54:34 +01:00
return [(x.code, x.name) for x in types]
2010-08-19 22:02:49 +02:00
def get_delay(self):
2011-07-03 13:18:43 +02:00
delay_obj = Pool().get('account.invoice.payment_term.line.delay')
2010-08-19 22:02:49 +02:00
delay_ids = delay_obj.search([])
delays = delay_obj.browse(delay_ids)
2009-01-02 17:54:34 +01:00
return [(x.code, x.name) for x in delays]
2010-08-19 22:02:49 +02:00
def on_change_type(self, vals):
2009-01-02 17:54:34 +01:00
if not 'type' in vals:
return {}
res = {}
if vals['type'] != 'fixed':
res['amount'] = Decimal('0.0')
res['currency'] = False
if vals['type'] != 'percent':
res['percentage'] = Decimal('0.0')
2009-01-02 17:54:34 +01:00
return res
2010-08-19 22:02:49 +02:00
def on_change_with_currency_digits(self, vals):
2011-07-03 13:18:43 +02:00
currency_obj = Pool().get('currency.currency')
2009-01-02 17:54:34 +01:00
if vals.get('currency'):
2010-08-19 22:02:49 +02:00
currency = currency_obj.browse(vals['currency'])
2009-01-02 17:54:34 +01:00
return currency.digits
return 2
2010-08-19 22:02:49 +02:00
def get_currency_digits(self, ids, name):
2009-01-02 17:54:34 +01:00
res = {}
2010-08-19 22:02:49 +02:00
for line in self.browse(ids):
2009-01-02 17:54:34 +01:00
if line.currency:
res[line.id] = line.currency.digits
else:
res[line.id] = 2
return res
PaymentTermLine()