Change payment term percentage into ratio

issue5286
review15951002
This commit is contained in:
Cédric Krier
2016-02-03 21:26:47 +01:00
parent 41a3efd067
commit c3b6648204
9 changed files with 54 additions and 47 deletions
+2
View File
@@ -1,3 +1,5 @@
* Change payment term percentage into ratio
Version 3.8.0 - 2015-11-02
* Bug fixes (see mercurial logs for details)
* Don't set default unit price on invoice line
+4 -4
View File
@@ -104,13 +104,13 @@ It defines the maximum dates of how an due amount should be paid.
- *Percentage on Remainder*:
- Percentage: The percentage to use on the remainder amount.
- Divisor: The reversed percentage.
- Ratio: The ratio to use on the remainder amount.
- Divisor: The reversed ratio.
- *Percentage on Total*:
- Percentage: The percentage to use on the total amount.
- Divisor: The reversed percentage.
- Ratio: The ratio to use on the total amount.
- Divisor: The reversed ratio.
- *Remainder*
+33 -35
View File
@@ -105,12 +105,12 @@ class PaymentTermLine(ModelSQL, ModelView):
('percent_on_total', 'Percentage on Total'),
('remainder', 'Remainder'),
], 'Type', required=True)
percentage = fields.Numeric('Percentage', digits=(16, 8),
ratio = fields.Numeric('Ratio', digits=(14, 10),
states={
'invisible': ~Eval('type').in_(['percent', 'percent_on_total']),
'required': Eval('type').in_(['percent', 'percent_on_total']),
}, depends=['type'])
divisor = fields.Numeric('Divisor', digits=(16, 8),
divisor = fields.Numeric('Divisor', digits=(10, 14),
states={
'invisible': ~Eval('type').in_(['percent', 'percent_on_total']),
'required': Eval('type').in_(['percent', 'percent_on_total']),
@@ -135,7 +135,7 @@ class PaymentTermLine(ModelSQL, ModelView):
super(PaymentTermLine, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC'))
cls._error_messages.update({
'invalid_percentage_and_divisor': ('Percentage and '
'invalid_ratio_and_divisor': ('Ratio and '
'Divisor values are not consistent in line "%(line)s" '
'of payment term "%(term)s".'),
})
@@ -173,6 +173,13 @@ class PaymentTermLine(ModelSQL, ModelView):
# Migration from 2.4: drop required on sequence
table.not_null_action('sequence', action='remove')
# Migration from 3.8: rename percentage into ratio
if table.column_exist('percentage'):
cursor.execute(*sql_table.update(
columns=[sql_table.ratio],
values=[sql_table.percentage / 100]))
table.drop_column('percentage')
@staticmethod
def order_sequence(tables):
table, _ = tables[None]
@@ -192,24 +199,24 @@ class PaymentTermLine(ModelSQL, ModelView):
self.amount = Decimal('0.0')
self.currency = None
if self.type not in ('percent', 'percent_on_total'):
self.percentage = Decimal('0.0')
self.ratio = Decimal('0.0')
self.divisor = Decimal('0.0')
@fields.depends('percentage')
def on_change_percentage(self):
if not self.percentage:
self.divisor = 0.0
@fields.depends('ratio')
def on_change_ratio(self):
if not self.ratio:
self.divisor = Decimal('0.0')
else:
self.divisor = self.round(Decimal('100.0') / self.percentage,
self.divisor = self.round(1 / self.ratio,
self.__class__.divisor.digits[1])
@fields.depends('divisor')
def on_change_divisor(self):
if not self.divisor:
self.percentage = 0.0
self.ratio = Decimal('0.0')
else:
self.percentage = self.round(Decimal('100.0') / self.divisor,
self.__class__.percentage.digits[1])
self.ratio = self.round(1 / self.divisor,
self.__class__.ratio.digits[1])
@fields.depends('currency')
def on_change_with_currency_digits(self, name=None):
@@ -237,11 +244,9 @@ class PaymentTermLine(ModelSQL, ModelView):
if self.type == 'fixed':
return Currency.compute(self.currency, self.amount, currency)
elif self.type == 'percent':
return currency.round(
remainder * self.percentage / Decimal('100'))
return currency.round(remainder * self.ratio)
elif self.type == 'percent_on_total':
return currency.round(
amount * self.percentage / Decimal('100'))
return currency.round(amount * self.ratio)
elif self.type == 'remainder':
return currency.round(remainder)
return None
@@ -254,33 +259,26 @@ class PaymentTermLine(ModelSQL, ModelView):
@classmethod
def validate(cls, lines):
super(PaymentTermLine, cls).validate(lines)
cls.check_percentage_and_divisor(lines)
cls.check_ratio_and_divisor(lines)
@classmethod
def check_percentage_and_divisor(cls, lines):
"Check consistency between percentage and divisor"
percentage_digits = cls.percentage.digits[1]
divisor_digits = cls.divisor.digits[1]
for line in lines:
def check_ratio_and_divisor(cls, lines):
"Check consistency between ratio and divisor"
# Use a copy because on_change will change the records
for line in cls.browse(lines):
if line.type not in ('percent', 'percent_on_total'):
continue
if line.percentage is None or line.divisor is None:
cls.raise_user_error('invalid_percentage_and_divisor', {
if line.ratio is None or line.divisor is None:
cls.raise_user_error('invalid_ratio_and_divisor', {
'line': line.rec_name,
'term': line.payment.rec_name,
})
if line.percentage == line.divisor == Decimal('0.0'):
continue
percentage = line.percentage
ratio = line.ratio
divisor = line.divisor
calc_percentage = cls.round(Decimal('100.0') / divisor,
percentage_digits)
calc_divisor = cls.round(Decimal('100.0') / percentage,
divisor_digits)
if (percentage == Decimal('0.0') or divisor == Decimal('0.0')
or percentage != calc_percentage
and divisor != calc_divisor):
cls.raise_user_error('invalid_percentage_and_divisor', {
line.on_change_ratio()
line.on_change_divisor()
if (line.divisor != divisor) or (line.ratio != ratio):
cls.raise_user_error('invalid_ratio_and_divisor', {
'line': line.rec_name,
'term': line.payment.rec_name,
})
+1 -1
View File
@@ -89,7 +89,7 @@ Create payment term::
>>> PaymentTerm = Model.get('account.invoice.payment_term')
>>> payment_term = PaymentTerm(name='Term')
>>> line = payment_term.lines.new(type='percent', percentage=Decimal(50))
>>> line = payment_term.lines.new(type='percent', ratio=Decimal('.5'))
>>> delta = line.relativedeltas.new(days=20)
>>> line = payment_term.lines.new(type='remainder')
>>> delta = line.relativedeltas.new(days=40)
@@ -91,7 +91,7 @@ Create payment term::
>>> PaymentTerm = Model.get('account.invoice.payment_term')
>>> payment_term = PaymentTerm(name='Term')
>>> line = payment_term.lines.new(type='percent', percentage=Decimal(50))
>>> line = payment_term.lines.new(type='percent', ratio=Decimal('.5'))
>>> delta = line.relativedeltas.new(days=20)
>>> line = payment_term.lines.new(type='remainder')
>>> delta = line.relativedeltas.new(days=40)
+2 -2
View File
@@ -36,7 +36,7 @@ class AccountInvoiceTestCase(ModuleTestCase):
'sequence': 0,
'type': 'percent',
'divisor': 4,
'percentage': 25,
'ratio': Decimal('.25'),
'relativedeltas': [('create', [{
'days': 30,
},
@@ -46,7 +46,7 @@ class AccountInvoiceTestCase(ModuleTestCase):
'sequence': 1,
'type': 'percent_on_total',
'divisor': 4,
'percentage': 25,
'ratio': Decimal('.25'),
'relativedeltas': [('create', [{
'months': 1,
},
+5 -2
View File
@@ -10,8 +10,11 @@ this repository contains the full copyright notices and license terms. -->
<field name="amount"/>
<label name="currency"/>
<field name="currency"/>
<label name="percentage"/>
<field name="percentage"/>
<label name="ratio"/>
<group col="2" id="ratio">
<field name="ratio" factor="100" xexpand="0"/>
<label name="ratio" string="%" xalign="0.0" xexpand="1"/>
</group>
<label name="divisor"/>
<field name="divisor"/>
<field name="relativedeltas" mode="form,tree" colspan="4"
+3 -1
View File
@@ -4,7 +4,9 @@ this repository contains the full copyright notices and license terms. -->
<tree string="Payment Term Line">
<field name="payment"/>
<field name="type"/>
<field name="percentage"/>
<field name="ratio" factor="100">
<suffix string="%" name="ratio"/>
</field>
<field name="amount"/>
<field name="currency"/>
</tree>
+3 -1
View File
@@ -3,7 +3,9 @@
this repository contains the full copyright notices and license terms. -->
<tree string="Payment Term Line" sequence="sequence">
<field name="type"/>
<field name="percentage"/>
<field name="ratio" factor="100">
<suffix string="%" name="ratio"/>
</field>
<field name="amount"/>
<field name="currency"/>
</tree>