Active Record
This commit is contained in:
1 parent
e7a05236a7
commit
83d9c368f7
6 files changed
+1237
-1435
No files matched your search
+30
@@ -1,7 +1,37 @@
|
||||
#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 trytond.pool import Pool
|
||||
from .payment_term import *
|
||||
from .invoice import *
|
||||
from .party import *
|
||||
from .account import *
|
||||
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
PaymentTerm,
|
||||
PaymentTermLine,
|
||||
Invoice,
|
||||
InvoicePaymentLine,
|
||||
InvoiceLine,
|
||||
InvoiceLineTax,
|
||||
InvoiceTax,
|
||||
PrintInvoiceWarning,
|
||||
PayInvoiceStart,
|
||||
PayInvoiceAsk,
|
||||
CreditInvoiceStart,
|
||||
Address,
|
||||
Party,
|
||||
FiscalYear,
|
||||
Period,
|
||||
Reconciliation,
|
||||
module='account_invoice', type_='model')
|
||||
Pool.register(
|
||||
PrintInvoice,
|
||||
PayInvoice,
|
||||
CreditInvoice,
|
||||
module='account_invoice', type_='wizard')
|
||||
Pool.register(
|
||||
InvoiceReport,
|
||||
module='account_invoice', type_='report')
|
||||
+96
-105
@@ -1,12 +1,15 @@
|
||||
#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 trytond.model import Model, ModelView, ModelSQL, fields
|
||||
from trytond.model import fields
|
||||
from trytond.pyson import Eval
|
||||
from trytond.pool import Pool
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
|
||||
__all__ = ['FiscalYear', 'Period', 'Reconciliation']
|
||||
__metaclass__ = PoolMeta
|
||||
|
||||
|
||||
class FiscalYear(ModelSQL, ModelView):
|
||||
_name = 'account.fiscalyear'
|
||||
class FiscalYear:
|
||||
__name__ = 'account.fiscalyear'
|
||||
out_invoice_sequence = fields.Many2One('ir.sequence.strict',
|
||||
'Customer Invoice Sequence', required=True,
|
||||
domain=[
|
||||
@@ -62,12 +65,13 @@ class FiscalYear(ModelSQL, ModelView):
|
||||
'company': Eval('company'),
|
||||
}, depends=['company'])
|
||||
|
||||
def __init__(self):
|
||||
super(FiscalYear, self).__init__()
|
||||
self._constraints += [
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(FiscalYear, cls).__setup__()
|
||||
cls._constraints += [
|
||||
('check_invoice_sequences', 'different_invoice_sequence'),
|
||||
]
|
||||
self._error_messages.update({
|
||||
]
|
||||
cls._error_messages.update({
|
||||
'change_invoice_sequence': 'You can not change ' \
|
||||
'the invoice sequence if there is already ' \
|
||||
'an invoice opened in the fiscalyear',
|
||||
@@ -75,44 +79,41 @@ class FiscalYear(ModelSQL, ModelView):
|
||||
'invoice sequences per fiscal year!',
|
||||
})
|
||||
|
||||
def check_invoice_sequences(self, ids):
|
||||
for fiscalyear in self.browse(ids):
|
||||
for sequence in ('out_invoice_sequence', 'in_invoice_sequence',
|
||||
'out_credit_note_sequence', 'in_credit_note_sequence'):
|
||||
if self.search([
|
||||
(sequence, '=', fiscalyear[sequence].id),
|
||||
('id', '!=', fiscalyear.id),
|
||||
]):
|
||||
return False
|
||||
def check_invoice_sequences(self):
|
||||
for sequence in ('out_invoice_sequence', 'in_invoice_sequence',
|
||||
'out_credit_note_sequence', 'in_credit_note_sequence'):
|
||||
if self.search([
|
||||
(sequence, '=', getattr(self, sequence).id),
|
||||
('id', '!=', self.id),
|
||||
]):
|
||||
return False
|
||||
return True
|
||||
|
||||
def write(self, ids, vals):
|
||||
invoice_obj = Pool().get('account.invoice')
|
||||
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
@classmethod
|
||||
def write(cls, fiscalyears, vals):
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
for sequence in ('out_invoice_sequence', 'in_invoice_sequence',
|
||||
'out_credit_note_sequence', 'in_credit_note_sequence'):
|
||||
if vals.get(sequence):
|
||||
for fiscalyear in self.browse(ids):
|
||||
if fiscalyear[sequence] and \
|
||||
fiscalyear[sequence].id != \
|
||||
vals[sequence]:
|
||||
if invoice_obj.search([
|
||||
('invoice_date', '>=', fiscalyear.start_date),
|
||||
('invoice_date', '<=', fiscalyear.end_date),
|
||||
('number', '!=', None),
|
||||
('type', '=', sequence[:-9]),
|
||||
]):
|
||||
self.raise_user_error('change_invoice_sequence')
|
||||
return super(FiscalYear, self).write(ids, vals)
|
||||
|
||||
FiscalYear()
|
||||
for fiscalyear in fiscalyears:
|
||||
if (getattr(fiscalyear, sequence)
|
||||
and (getattr(fiscalyear, sequence).id !=
|
||||
vals[sequence])):
|
||||
if Invoice.search([
|
||||
('invoice_date', '>=',
|
||||
fiscalyear.start_date),
|
||||
('invoice_date', '<=',
|
||||
fiscalyear.end_date),
|
||||
('number', '!=', None),
|
||||
('type', '=', sequence[:-9]),
|
||||
]):
|
||||
cls.raise_user_error('change_invoice_sequence')
|
||||
super(FiscalYear, cls).write(fiscalyears, vals)
|
||||
|
||||
|
||||
class Period(ModelSQL, ModelView):
|
||||
_name = 'account.period'
|
||||
class Period:
|
||||
__name__ = 'account.period'
|
||||
out_invoice_sequence = fields.Many2One('ir.sequence.strict',
|
||||
'Customer Invoice Sequence',
|
||||
domain=[('code', '=', 'account.invoice')],
|
||||
@@ -150,12 +151,13 @@ class Period(ModelSQL, ModelView):
|
||||
},
|
||||
depends=['type'])
|
||||
|
||||
def __init__(self):
|
||||
super(Period, self).__init__()
|
||||
self._constraints += [
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Period, cls).__setup__()
|
||||
cls._constraints += [
|
||||
('check_invoice_sequences', 'check_invoice_sequences'),
|
||||
]
|
||||
self._error_messages.update({
|
||||
]
|
||||
cls._error_messages.update({
|
||||
'change_invoice_sequence': 'You can not change ' \
|
||||
'the invoice sequence if there is already ' \
|
||||
'an invoice opened in the period',
|
||||
@@ -164,86 +166,75 @@ class Period(ModelSQL, ModelView):
|
||||
'in the same company!',
|
||||
})
|
||||
|
||||
def check_invoice_sequences(self, ids):
|
||||
for period in self.browse(ids):
|
||||
for sequence in ('out_invoice_sequence', 'in_invoice_sequence',
|
||||
'out_credit_note_sequence', 'in_credit_note_sequence'):
|
||||
if self.search([
|
||||
(sequence, '=', period[sequence].id),
|
||||
('fiscalyear', '!=', period.fiscalyear.id),
|
||||
]):
|
||||
return False
|
||||
if period[sequence].company \
|
||||
and period[sequence].company.id != \
|
||||
period.fiscalyear.company.id:
|
||||
return False
|
||||
def check_invoice_sequences(self):
|
||||
for sequence_name in ('out_invoice_sequence', 'in_invoice_sequence',
|
||||
'out_credit_note_sequence', 'in_credit_note_sequence'):
|
||||
sequence = getattr(self, sequence_name)
|
||||
if self.search([
|
||||
(sequence_name, '=', sequence.id),
|
||||
('fiscalyear', '!=', self.fiscalyear.id),
|
||||
]):
|
||||
return False
|
||||
if (sequence.company
|
||||
and sequence.company != self.fiscalyear.company):
|
||||
return False
|
||||
return True
|
||||
|
||||
def create(self, vals):
|
||||
fiscalyear_obj = Pool().get('account.fiscalyear')
|
||||
@classmethod
|
||||
def create(cls, vals):
|
||||
FiscalYear = Pool().get('account.fiscalyear')
|
||||
vals = vals.copy()
|
||||
if vals.get('fiscalyear'):
|
||||
fiscalyear = fiscalyear_obj.browse(vals['fiscalyear'])
|
||||
fiscalyear = FiscalYear(vals['fiscalyear'])
|
||||
for sequence in ('out_invoice_sequence', 'in_invoice_sequence',
|
||||
'out_credit_note_sequence', 'in_credit_note_sequence'):
|
||||
if not vals.get(sequence):
|
||||
vals[sequence] = fiscalyear[sequence].id
|
||||
return super(Period, self).create(vals)
|
||||
vals[sequence] = getattr(fiscalyear, sequence).id
|
||||
return super(Period, cls).create(vals)
|
||||
|
||||
def write(self, ids, vals):
|
||||
invoice_obj = Pool().get('account.invoice')
|
||||
@classmethod
|
||||
def write(cls, periods, vals):
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
|
||||
for sequence in ('out_invoice_sequence', 'in_invoice_sequence',
|
||||
for sequence_name in ('out_invoice_sequence', 'in_invoice_sequence',
|
||||
'out_credit_note_sequence', 'in_credit_note_sequence'):
|
||||
if vals.get(sequence):
|
||||
for period in self.browse(ids):
|
||||
if period[sequence] and \
|
||||
period[sequence].id != \
|
||||
vals[sequence]:
|
||||
if invoice_obj.search([
|
||||
('invoice_date', '>=', period.start_date),
|
||||
('invoice_date', '<=', period.end_date),
|
||||
('number', '!=', None),
|
||||
('type', '=', sequence[:-9]),
|
||||
]):
|
||||
self.raise_user_error('change_invoice_sequence')
|
||||
return super(Period, self).write(ids, vals)
|
||||
|
||||
Period()
|
||||
if vals.get(sequence_name):
|
||||
for period in periods:
|
||||
sequence = getattr(period, sequence_name)
|
||||
if (sequence and
|
||||
sequence.id != vals[sequence]):
|
||||
if Invoice.search([
|
||||
('invoice_date', '>=', period.start_date),
|
||||
('invoice_date', '<=', period.end_date),
|
||||
('number', '!=', None),
|
||||
('type', '=', sequence_name[:-9]),
|
||||
]):
|
||||
cls.raise_user_error('change_invoice_sequence')
|
||||
super(Period, cls).write(periods, vals)
|
||||
|
||||
|
||||
class Reconciliation(Model):
|
||||
_name = 'account.move.reconciliation'
|
||||
class Reconciliation:
|
||||
__name__ = 'account.move.reconciliation'
|
||||
|
||||
def create(self, values):
|
||||
pool = Pool()
|
||||
invoice_obj = pool.get('account.invoice')
|
||||
@classmethod
|
||||
def create(cls, values):
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
result = super(Reconciliation, self).create(values)
|
||||
reconciliation = self.browse(result)
|
||||
reconciliation = super(Reconciliation, cls).create(values)
|
||||
move_ids = set(l.move.id for l in reconciliation.lines)
|
||||
invoice_ids = invoice_obj.search([
|
||||
invoices = Invoice.search([
|
||||
('move', 'in', list(move_ids)),
|
||||
])
|
||||
invoice_obj.process(invoice_ids)
|
||||
return result
|
||||
Invoice.process(invoices)
|
||||
return reconciliation
|
||||
|
||||
def delete(self, ids):
|
||||
pool = Pool()
|
||||
invoice_obj = pool.get('account.invoice')
|
||||
@classmethod
|
||||
def delete(cls, reconciliations):
|
||||
Invoice = Pool().get('account.invoice')
|
||||
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
reconciliations = self.browse(ids)
|
||||
move_ids = set(l.move.id for r in reconciliations for l in r.lines)
|
||||
invoice_ids = invoice_obj.search([
|
||||
invoices = Invoice.search([
|
||||
('move', 'in', list(move_ids)),
|
||||
])
|
||||
result = super(Reconciliation, self).delete(ids)
|
||||
invoice_obj.process(invoice_ids)
|
||||
return result
|
||||
|
||||
Reconciliation()
|
||||
super(Reconciliation, cls).delete(reconciliations)
|
||||
Invoice.process(invoices)
|
||||
+1000
-1206
File diff suppressed because it is too large.
Load diff
@@ -1,37 +1,37 @@
|
||||
#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 trytond.model import ModelView, ModelSQL, fields
|
||||
from trytond.pool import Pool
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
|
||||
__all__ = ['Address', 'Party']
|
||||
__metaclass__ = PoolMeta
|
||||
|
||||
|
||||
class Address(ModelSQL, ModelView):
|
||||
_name = 'party.address'
|
||||
class Address:
|
||||
__name__ = 'party.address'
|
||||
invoice = fields.Boolean('Invoice')
|
||||
|
||||
Address()
|
||||
|
||||
|
||||
class Party(ModelSQL, ModelView):
|
||||
_name = 'party.party'
|
||||
__name__ = 'party.party'
|
||||
customer_payment_term = fields.Property(fields.Many2One(
|
||||
'account.invoice.payment_term', string='Customer Payment Term'))
|
||||
supplier_payment_term = fields.Property(fields.Many2One(
|
||||
'account.invoice.payment_term', string='Supplier Payment Term'))
|
||||
|
||||
def init(self, module_name):
|
||||
ir_model_field_obj = Pool().get('ir.model.field')
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
ModelField = Pool().get('ir.model.field')
|
||||
|
||||
# Migration from 2.2: property field payment_term renamed
|
||||
# to customer_payment_term
|
||||
field_ids = ir_model_field_obj.search([
|
||||
fields = ModelField.search([
|
||||
('name', '=', 'payment_term'),
|
||||
('model.model', '=', 'party.party')
|
||||
])
|
||||
if field_ids:
|
||||
ir_model_field_obj.write(field_ids, {
|
||||
if fields:
|
||||
ModelField.write(fields, {
|
||||
'name': 'customer_payment_term',
|
||||
})
|
||||
|
||||
super(Party, self).init(module_name)
|
||||
|
||||
Party()
|
||||
super(Party, cls).__register__(module_name)
|
||||
+92
-103
@@ -8,11 +8,12 @@ from trytond.pyson import Eval
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.pool import Pool
|
||||
|
||||
__all__ = ['PaymentTerm', 'PaymentTermLine']
|
||||
|
||||
|
||||
class PaymentTerm(ModelSQL, ModelView):
|
||||
'Payment Term'
|
||||
_name = 'account.invoice.payment_term'
|
||||
_description = __doc__
|
||||
__name__ = 'account.invoice.payment_term'
|
||||
name = fields.Char('Payment Term', size=None, required=True,
|
||||
translate=True)
|
||||
active = fields.Boolean('Active')
|
||||
@@ -20,41 +21,39 @@ class PaymentTerm(ModelSQL, ModelView):
|
||||
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({
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(PaymentTerm, cls).__setup__()
|
||||
cls._order.insert(0, ('name', 'ASC'))
|
||||
cls._error_messages.update({
|
||||
'invalid_line': 'Invalid payment term line!',
|
||||
'missing_remainder': 'Payment term missing a remainder line!',
|
||||
})
|
||||
|
||||
def default_active(self):
|
||||
@staticmethod
|
||||
def default_active():
|
||||
return True
|
||||
|
||||
def compute(self, amount, currency, payment_term, date=None):
|
||||
def compute(self, amount, currency, date=None):
|
||||
"""Calculate payment terms and return a list of tuples
|
||||
with (date, amount) for each payment term line.
|
||||
|
||||
amount must be a Decimal used for the calculation and
|
||||
both currency and payment_term must be BrowseRecord. If
|
||||
specified, date will be used as the start date, otherwise
|
||||
current date will be used.
|
||||
amount must be a Decimal used for the calculation.
|
||||
If specified, date will be used as the start date, otherwise current
|
||||
date will be used.
|
||||
"""
|
||||
#TODO implement business_days
|
||||
# http://pypi.python.org/pypi/BusinessHours/
|
||||
pool = Pool()
|
||||
line_obj = pool.get('account.invoice.payment_term.line')
|
||||
currency_obj = pool.get('currency.currency')
|
||||
date_obj = pool.get('ir.date')
|
||||
Date = Pool().get('ir.date')
|
||||
|
||||
sign = 1 if amount >= Decimal('0.0') else -1
|
||||
res = []
|
||||
if date is None:
|
||||
date = date_obj.today()
|
||||
date = Date.today()
|
||||
remainder = amount
|
||||
for line in payment_term.lines:
|
||||
value = line_obj.get_value(line, remainder, amount, currency)
|
||||
value_date = line_obj.get_date(line, date)
|
||||
for line in self.lines:
|
||||
value = line.get_value(remainder, amount, currency)
|
||||
value_date = line.get_date(date)
|
||||
if not value or not value_date:
|
||||
if (not remainder) and line.amount:
|
||||
self.raise_user_error('invalid_line')
|
||||
@@ -66,17 +65,14 @@ class PaymentTerm(ModelSQL, ModelView):
|
||||
res.append((value_date, value))
|
||||
remainder -= value
|
||||
|
||||
if not currency_obj.is_zero(currency, remainder):
|
||||
if not currency.is_zero(remainder):
|
||||
self.raise_user_error('missing_remainder')
|
||||
return res
|
||||
|
||||
PaymentTerm()
|
||||
|
||||
|
||||
class PaymentTermLine(ModelSQL, ModelView):
|
||||
'Payment Term Line'
|
||||
_name = 'account.invoice.payment_term.line'
|
||||
_description = __doc__
|
||||
__name__ = 'account.invoice.payment_term.line'
|
||||
sequence = fields.Integer('Sequence',
|
||||
order_field='(%(table)s.sequence IS NULL) %(order)s, '
|
||||
'%(table)s.sequence %(order)s',
|
||||
@@ -111,7 +107,7 @@ class PaymentTermLine(ModelSQL, ModelView):
|
||||
'required': Eval('type') == 'fixed',
|
||||
}, depends=['type'])
|
||||
currency_digits = fields.Function(fields.Integer('Currency Digits',
|
||||
on_change_with=['currency']), 'get_currency_digits')
|
||||
on_change_with=['currency']), 'on_change_with_currency_digits')
|
||||
day = fields.Integer('Day of Month')
|
||||
month = fields.Selection([
|
||||
(None, ''),
|
||||
@@ -142,132 +138,126 @@ class PaymentTermLine(ModelSQL, ModelView):
|
||||
weeks = fields.Integer('Number of Weeks', required=True)
|
||||
days = fields.Integer('Number of Days', required=True)
|
||||
|
||||
def __init__(self):
|
||||
super(PaymentTermLine, self).__init__()
|
||||
self._order.insert(0, ('sequence', 'ASC'))
|
||||
self._sql_constraints += [
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(PaymentTermLine, cls).__setup__()
|
||||
cls._order.insert(0, ('sequence', 'ASC'))
|
||||
cls._sql_constraints += [
|
||||
('day', 'CHECK(day BETWEEN 1 AND 31)',
|
||||
'Day of month must be between 1 and 31.'),
|
||||
]
|
||||
self._constraints += [
|
||||
cls._constraints += [
|
||||
('check_percentage_and_divisor', 'invalid_percentage_and_divisor'),
|
||||
]
|
||||
self._error_messages.update({
|
||||
cls._error_messages.update({
|
||||
'invalid_percentage_and_divisor': 'Percentage and '
|
||||
'Divisor values are not consistent.',
|
||||
})
|
||||
|
||||
def init(self, module_name):
|
||||
super(PaymentTermLine, self).init(module_name)
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
super(PaymentTermLine, cls).__register__(module_name)
|
||||
cursor = Transaction().cursor
|
||||
table = TableHandler(cursor, self, module_name)
|
||||
table = TableHandler(cursor, cls, module_name)
|
||||
|
||||
# Migration from 1.0 percent change into percentage
|
||||
if table.column_exist('percent'):
|
||||
cursor.execute('UPDATE "' + self._table + '" ' \
|
||||
cursor.execute('UPDATE "' + cls._table + '" ' \
|
||||
'SET percentage = percent * 100')
|
||||
table.drop_column('percent', exception=True)
|
||||
|
||||
# Migration from 2.2
|
||||
if table.column_exist('delay'):
|
||||
cursor.execute('UPDATE "' + self._table + '" SET day = 31 '
|
||||
cursor.execute('UPDATE "' + cls._table + '" SET day = 31 '
|
||||
"WHERE delay = 'end_month'")
|
||||
table.drop_column('delay', exception=True)
|
||||
ids = self.search([])
|
||||
for line in self.browse(ids):
|
||||
lines = cls.search([])
|
||||
for line in lines:
|
||||
if line.percentage:
|
||||
self.write(line.id, {
|
||||
'divisor': self.round(Decimal('100.0') /
|
||||
line.percentage, self.divisor.digits[1]),
|
||||
cls.write([line], {
|
||||
'divisor': cls.round(Decimal('100.0') /
|
||||
line.percentage, cls.divisor.digits[1]),
|
||||
})
|
||||
|
||||
# Migration from 2.4: drop required on sequence
|
||||
table.not_null_action('sequence', action='remove')
|
||||
|
||||
def default_currency_digits(self):
|
||||
@staticmethod
|
||||
def default_currency_digits():
|
||||
return 2
|
||||
|
||||
def default_type(self):
|
||||
@staticmethod
|
||||
def default_type():
|
||||
return 'remainder'
|
||||
|
||||
def default_months(self):
|
||||
@staticmethod
|
||||
def default_months():
|
||||
return 0
|
||||
|
||||
def default_weeks(self):
|
||||
@staticmethod
|
||||
def default_weeks():
|
||||
return 0
|
||||
|
||||
def default_days(self):
|
||||
@staticmethod
|
||||
def default_days():
|
||||
return 0
|
||||
|
||||
def on_change_type(self, vals):
|
||||
if not 'type' in vals:
|
||||
return {}
|
||||
def on_change_type(self):
|
||||
res = {}
|
||||
if vals['type'] != 'fixed':
|
||||
if self.type != 'fixed':
|
||||
res['amount'] = Decimal('0.0')
|
||||
res['currency'] = None
|
||||
if vals['type'] not in ('percent', 'percent_on_total'):
|
||||
if self.type not in ('percent', 'percent_on_total'):
|
||||
res['percentage'] = Decimal('0.0')
|
||||
res['divisor'] = Decimal('0.0')
|
||||
return res
|
||||
|
||||
def on_change_percentage(self, value):
|
||||
if not value.get('percentage'):
|
||||
def on_change_percentage(self):
|
||||
if not self.percentage:
|
||||
return {'divisor': 0.0}
|
||||
return {
|
||||
'divisor': self.round(Decimal('100.0') / value['percentage'],
|
||||
self.divisor.digits[1]),
|
||||
'divisor': self.round(Decimal('100.0') / self.percentage,
|
||||
self.__class__.divisor.digits[1]),
|
||||
}
|
||||
|
||||
def on_change_divisor(self, value):
|
||||
if not value.get('divisor'):
|
||||
def on_change_divisor(self):
|
||||
if not self.divisor:
|
||||
return {'percentage': 0.0}
|
||||
return {
|
||||
'percentage': self.round(Decimal('100.0') / value['divisor'],
|
||||
self.percentage.digits[1]),
|
||||
'percentage': self.round(Decimal('100.0') / self.divisor,
|
||||
self.__class__.percentage.digits[1]),
|
||||
}
|
||||
|
||||
def on_change_with_currency_digits(self, vals):
|
||||
currency_obj = Pool().get('currency.currency')
|
||||
if vals.get('currency'):
|
||||
currency = currency_obj.browse(vals['currency'])
|
||||
return currency.digits
|
||||
def on_change_with_currency_digits(self, name=None):
|
||||
if self.currency:
|
||||
return self.currency.digits
|
||||
return 2
|
||||
|
||||
def get_currency_digits(self, ids, name):
|
||||
res = {}
|
||||
for line in self.browse(ids):
|
||||
if line.currency:
|
||||
res[line.id] = line.currency.digits
|
||||
else:
|
||||
res[line.id] = 2
|
||||
return res
|
||||
|
||||
def get_delta(self, line):
|
||||
def get_delta(self):
|
||||
return {
|
||||
'day': line.day,
|
||||
'month': int(line.month) if line.month else None,
|
||||
'days': line.days,
|
||||
'weeks': line.weeks,
|
||||
'months': line.months,
|
||||
'weekday': int(line.weekday) if line.weekday else None,
|
||||
'day': self.day,
|
||||
'month': int(self.month) if self.month else None,
|
||||
'days': self.days,
|
||||
'weeks': self.weeks,
|
||||
'months': self.months,
|
||||
'weekday': int(self.weekday) if self.weekday else None,
|
||||
}
|
||||
|
||||
def get_date(self, line, date):
|
||||
return date + relativedelta(**self.get_delta(line))
|
||||
def get_date(self, date):
|
||||
return date + relativedelta(**self.get_delta())
|
||||
|
||||
def get_value(self, line, remainder, amount, currency):
|
||||
currency_obj = Pool().get('currency.currency')
|
||||
if line.type == 'fixed':
|
||||
return currency_obj.compute(line.currency, line.amount, currency)
|
||||
elif line.type == 'percent':
|
||||
return currency_obj.round(currency,
|
||||
remainder * line.percentage / Decimal('100'))
|
||||
elif line.type == 'percent_on_total':
|
||||
return currency_obj.round(currency,
|
||||
amount * line.percentage / Decimal('100'))
|
||||
elif line.type == 'remainder':
|
||||
return currency_obj.round(currency, remainder)
|
||||
def get_value(self, remainder, amount, currency):
|
||||
Currency = Pool().get('currency.currency')
|
||||
if self.type == 'fixed':
|
||||
return Currency.compute(self.currency, self.amount, currency)
|
||||
elif self.type == 'percent':
|
||||
return currency.round(
|
||||
remainder * self.percentage / Decimal('100'))
|
||||
elif self.type == 'percent_on_total':
|
||||
return currency.round(
|
||||
amount * self.percentage / Decimal('100'))
|
||||
elif self.type == 'remainder':
|
||||
return currency.round(remainder)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
@@ -275,11 +265,12 @@ class PaymentTermLine(ModelSQL, ModelView):
|
||||
quantize = Decimal(10) ** -Decimal(digits)
|
||||
return Decimal(number).quantize(quantize)
|
||||
|
||||
def check_percentage_and_divisor(self, ids):
|
||||
@classmethod
|
||||
def check_percentage_and_divisor(cls, lines):
|
||||
"Check consistency between percentage and divisor"
|
||||
percentage_digits = self.percentage.digits[1]
|
||||
divisor_digits = self.divisor.digits[1]
|
||||
for line in self.browse(ids):
|
||||
percentage_digits = cls.percentage.digits[1]
|
||||
divisor_digits = cls.divisor.digits[1]
|
||||
for line in lines:
|
||||
if line.type not in ('percent', 'percent_on_total'):
|
||||
continue
|
||||
if line.percentage is None or line.divisor is None:
|
||||
@@ -288,14 +279,12 @@ class PaymentTermLine(ModelSQL, ModelView):
|
||||
continue
|
||||
percentage = line.percentage
|
||||
divisor = line.divisor
|
||||
calc_percentage = self.round(Decimal('100.0') / divisor,
|
||||
calc_percentage = cls.round(Decimal('100.0') / divisor,
|
||||
percentage_digits)
|
||||
calc_divisor = self.round(Decimal('100.0') / percentage,
|
||||
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):
|
||||
return False
|
||||
return True
|
||||
|
||||
PaymentTermLine()
|
||||
@@ -45,14 +45,13 @@ class AccountInvoiceTestCase(unittest.TestCase):
|
||||
Test payment_term.
|
||||
'''
|
||||
with Transaction().start(DB_NAME, USER, context=CONTEXT):
|
||||
cu1_id = self.currency.create({
|
||||
cu1 = self.currency.create({
|
||||
'name': 'cu1',
|
||||
'symbol': 'cu1',
|
||||
'code': 'cu1'
|
||||
})
|
||||
cu1 = self.currency.browse(cu1_id)
|
||||
|
||||
term_id = self.payment_term.create({
|
||||
term = self.payment_term.create({
|
||||
'name': '30 days, 1 month, 1 month + 15 days',
|
||||
'lines': [
|
||||
('create', {
|
||||
@@ -75,7 +74,7 @@ class AccountInvoiceTestCase(unittest.TestCase):
|
||||
'months': 1,
|
||||
'days': 30,
|
||||
'amount': Decimal('396.84'),
|
||||
'currency': cu1_id,
|
||||
'currency': cu1.id,
|
||||
}),
|
||||
('create', {
|
||||
'sequence': 3,
|
||||
@@ -85,9 +84,8 @@ class AccountInvoiceTestCase(unittest.TestCase):
|
||||
'day': 15,
|
||||
})]
|
||||
})
|
||||
term = self.payment_term.browse(term_id)
|
||||
terms = term.compute(Decimal('1587.35'), cu1, term,
|
||||
date=datetime.date(2011, 10, 1))
|
||||
terms = term.compute(Decimal('1587.35'), cu1,
|
||||
date=datetime.date(2011, 10, 1))
|
||||
self.assertEqual(terms, [
|
||||
(datetime.date(2011, 10, 31), Decimal('396.84')),
|
||||
(datetime.date(2011, 11, 01), Decimal('396.84')),
|
||||
|
||||
Reference in new issue
Block a user