Add optional credit type on account

issue11090
review372941002
This commit is contained in:
Cédric Krier committed 2022-01-23 13:03:06 +01:00
1 parent cc4333b810
commit 2bcb9da7c2
10 files changed
+110 -20

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Add optional credit type on account
* Always require a date to compute taxes
* Add support for Python 3.10
* Remove support for Python 3.6
+64 -10
View File
@@ -14,7 +14,7 @@ from sql.conditionals import Case, Coalesce
from trytond.i18n import gettext
from trytond.model import (
ModelSQL, ModelView, Unique, fields, sequence_ordered, tree)
Check, ModelSQL, ModelView, Unique, fields, sequence_ordered, tree)
from trytond.model.exceptions import AccessError
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
@@ -319,18 +319,24 @@ class Type(
accounts = Account.search([
('type', 'in', [t.id for t in childs]),
])
debit_accounts = Account.search([
debit_credit_accounts = Account.search([
('type', '!=', None),
('debit_type', 'in', [t.id for t in childs]),
['OR',
('debit_type', 'in', [t.id for t in childs]),
('credit_type', 'in', [t.id for t in childs]),
],
])
for account in accounts:
balance = account.credit - account.debit
if not account.debit_type or balance > 0:
if ((not account.debit_type or balance > 0)
and (not account.credit_type or balance < 0)):
type_sum[account.type.id] += balance
for account in debit_accounts:
for account in debit_credit_accounts:
balance = account.credit - account.debit
if balance < 0:
if account.debit_type and balance < 0:
type_sum[account.debit_type.id] += balance
elif account.credit_type and balance > 0:
type_sum[account.credit_type.id] += balance
for type_ in types:
childs = cls.search([
@@ -627,6 +633,8 @@ class AccountTemplate(
'account.account.type.template', "Type", ondelete="RESTRICT")
debit_type = fields.Many2One(
'account.account.type.template', "Debit Type", ondelete="RESTRICT")
credit_type = fields.Many2One(
'account.account.type.template', "Credit Type", ondelete="RESTRICT")
parent = fields.Many2One('account.account.template', 'Parent', select=True,
ondelete="RESTRICT")
childs = fields.One2Many('account.account.template', 'parent', 'Children')
@@ -644,6 +652,11 @@ class AccountTemplate(
super(AccountTemplate, cls).__setup__()
cls._order.insert(0, ('code', 'ASC'))
cls._order.insert(1, ('name', 'ASC'))
table = cls.__table__()
cls._sql_constraints.append(
('only_one_debit_credit_types', Check(
table, (table.debit_type + table.credit_type) == Null),
'account.msg_only_one_debit_credit_types'))
@classmethod
def __register__(cls, module_name):
@@ -721,6 +734,11 @@ class AccountTemplate(
template.debit_type.id)
else:
vals['debit_type'] = None
if template.credit_type:
vals['credit_type'] = template2type.get(
template.credit_type.id)
else:
vals['credit_type'] = None
values.append(vals)
created.append(template)
@@ -825,13 +843,28 @@ class Account(AccountMixin(), ActivePeriodMixin, tree(), ModelSQL, ModelView):
'account.account.type', "Debit Type", ondelete='RESTRICT',
states={
'readonly': _states['readonly'],
'invisible': ~Eval('type'),
'invisible': (
~Eval('type') | Eval('credit_type')
| (_states['readonly']) & ~Eval('debit_type')),
},
domain=[
('company', '=', Eval('company')),
],
depends=['company', 'type'],
depends=['company', 'type', 'credit_type'],
help="The type used if not empty and debit > credit.")
credit_type = fields.Many2One(
'account.account.type', "Credit Type", ondelete='RESTRICT',
states={
'readonly': _states['readonly'],
'invisible': (
~Eval('type') | Eval('debit_type')
| (_states['readonly']) & ~Eval('credit_type')),
},
domain=[
('company', '=', Eval('company')),
],
depends=['company', 'type', 'debit_type'],
help="The type used if not empty and debit < credit.")
parent = fields.Many2One(
'account.account', 'Parent', select=True,
left="left", right="right", ondelete="RESTRICT", states=_states)
@@ -899,6 +932,11 @@ class Account(AccountMixin(), ActivePeriodMixin, tree(), ModelSQL, ModelView):
}
cls._order.insert(0, ('code', 'ASC'))
cls._order.insert(1, ('name', 'ASC'))
table = cls.__table__()
cls._sql_constraints.append(
('only_one_debit_credit_types', Check(
table, (table.debit_type + table.credit_type) == Null),
'account.msg_only_one_debit_credit_types'))
@classmethod
def __register__(cls, module_name):
@@ -1094,7 +1132,7 @@ class Account(AccountMixin(), ActivePeriodMixin, tree(), ModelSQL, ModelView):
return values
__on_change_parent_fields = ['name', 'code', 'company', 'type',
'debit_type', 'reconcile', 'deferral', 'party_required',
'debit_type', 'credit_type', 'reconcile', 'deferral', 'party_required',
'general_ledger_balance', 'taxes']
@fields.depends('parent', *(__on_change_parent_fields
@@ -1231,6 +1269,16 @@ class Account(AccountMixin(), ActivePeriodMixin, tree(), ModelSQL, ModelView):
template_debit_type = None
if current_debit_type != template_debit_type:
vals['debit_type'] = template_debit_type
current_credit_type = (
child.credit_type.id if child.credit_type
else None)
if child.template.credit_type:
template_credit_type = template2type.get(
child.template.credit_type.id)
else:
template_credit_type = None
if current_credit_type != template_credit_type:
vals['credit_type'] = template_credit_type
if vals:
values.append([child])
values.append(vals)
@@ -1329,6 +1377,7 @@ class AccountParty(ActivePeriodMixin, ModelSQL):
company = fields.Many2One('company.company', "Company")
type = fields.Many2One('account.account.type', "Type")
debit_type = fields.Many2One('account.account.type', "Debit Type")
credit_type = fields.Many2One('account.account.type', "Credit Type")
closed = fields.Boolean("Closed")
balance = fields.Function(Monetary(
@@ -1854,6 +1903,7 @@ class GeneralLedgerAccount(_GeneralLedgerAccount):
type = fields.Many2One('account.account.type', "Type")
debit_type = fields.Many2One('account.account.type', "Debit Type")
credit_type = fields.Many2One('account.account.type', "Credit Type")
lines = fields.One2Many(
'account.general_ledger.line', 'account', "Lines", readonly=True)
general_ledger_balance = fields.Boolean("General Ledger Balance")
@@ -2595,6 +2645,7 @@ class AgedBalance(ModelSQL, ModelView):
account = Account.__table__()
type_ = Type.__table__()
debit_type = Type.__table__()
credit_type = Type.__table__()
company_id = context.get('company')
date = context.get('date')
@@ -2602,6 +2653,7 @@ class AgedBalance(ModelSQL, ModelView):
line_query, _ = MoveLine.query_get(line)
kind = cls.get_kind(type_)
debit_kind = cls.get_kind(debit_type)
credit_kind = cls.get_kind(credit_type)
columns = [
line.party.as_('id'),
Literal(0).as_('create_uid'),
@@ -2638,11 +2690,13 @@ class AgedBalance(ModelSQL, ModelView):
).join(type_, condition=account.type == type_.id
).join(debit_type, 'LEFT',
condition=account.debit_type == debit_type.id
).join(credit_type, 'LEFT',
condition=account.credit_type == credit_type.id
).join(reconciliation, 'LEFT',
condition=reconciliation.id == line.reconciliation
).select(*columns,
where=(line.party != Null)
& (kind | debit_kind)
& (kind | debit_kind | credit_kind)
& ((line.reconciliation == Null)
| (reconciliation.date > date))
& (move.date <= date)
+3
View File
@@ -83,6 +83,9 @@ this repository contains the full copyright notices and license terms. -->
<field name="text">You cannot erase party "%(party)s" while they have pending receivable/payable with company "%(company)s".</field>
</record>
<record model="ir.message" id="msg_only_one_debit_credit_types">
<field name="text">Account can have only one of the debit or credit type set.</field>
</record>
<record model="ir.message" id="msg_delete_account_with_move_lines">
<field name="text">You cannot delete account "%(account)s" because it has move lines.</field>
</record>
+20
View File
@@ -540,6 +540,7 @@ class AccountTestCase(
with Transaction().set_context(fiscalyear=fiscalyear.id):
debit_receivable_type, = Type.copy([receivable_type])
receivable.debit_type = debit_receivable_type
receivable.credit_type = None
receivable.save()
self.assertEqual(receivable_type.amount, Decimal(0))
self.assertEqual(debit_receivable_type.amount, Decimal(100))
@@ -548,10 +549,29 @@ class AccountTestCase(
with Transaction().set_context(fiscalyear=fiscalyear.id):
debit_revenue_type, = Type.copy([revenue_type])
revenue.debit_type = debit_revenue_type
revenue.credit_type = None
revenue.save()
self.assertEqual(revenue_type.amount, Decimal(100))
self.assertEqual(debit_revenue_type.amount, Decimal(0))
# Set a credit type on revenue
with Transaction().set_context(fiscalyear=fiscalyear.id):
credit_revenue_type, = Type.copy([revenue_type])
revenue.credit_type = credit_revenue_type
revenue.debit_type = None
revenue.save()
self.assertEqual(revenue_type.amount, Decimal(0))
self.assertEqual(credit_revenue_type.amount, Decimal(100))
# Set a credit type on receivable
with Transaction().set_context(fiscalyear=fiscalyear.id):
credit_receivable_type, = Type.copy([receivable_type])
receivable.credit_type = credit_receivable_type
receivable.debit_type = None
receivable.save()
self.assertEqual(receivable_type.amount, Decimal(100))
self.assertEqual(credit_receivable_type.amount, Decimal(0))
@with_transaction()
def test_move_post(self):
"Test posting move"
+9 -5
View File
@@ -21,15 +21,19 @@ this repository contains the full copyright notices and license terms. -->
<newline/>
<label name="type"/>
<group id="types" col="-1">
<field name="type"/>
<label name="debit_type"/>
<field name="debit_type"/>
</group>
<field name="type" colspan="5"/>
<label name="debit_type"/>
<field name="debit_type" colspan="5"/>
<label name="credit_type"/>
<field name="credit_type" colspan="5"/>
<label name="closed"/>
<field name="closed"/>
<label name="general_ledger_balance"/>
<field name="general_ledger_balance"/>
<newline/>
<label name="start_date"/>
<field name="start_date"/>
+1
View File
@@ -6,4 +6,5 @@ this repository contains the full copyright notices and license terms. -->
<field name="company" expand="1"/>
<field name="type" expand="1"/>
<field name="debit_type" expand="1"/>
<field name="credit_type" expand="1"/>
</tree>
+9 -5
View File
@@ -10,15 +10,19 @@ this repository contains the full copyright notices and license terms. -->
<field name="parent"/>
<label name="type"/>
<group id="types" col="-1">
<field name="type"/>
<label name="debit_type"/>
<field name="debit_type"/>
</group>
<field name="type" colspan="5"/>
<label name="debit_type"/>
<field name="debit_type" colspan="5"/>
<label name="credit_type"/>
<field name="credit_type" colspan="5"/>
<label name="closed"/>
<field name="closed"/>
<label name="general_ledger_balance"/>
<field name="general_ledger_balance"/>
<newline/>
<label name="start_date"/>
<field name="start_date"/>
+1
View File
@@ -5,4 +5,5 @@ this repository contains the full copyright notices and license terms. -->
<field name="rec_name" expand="2"/>
<field name="type" expand="1"/>
<field name="debit_type" expand="1"/>
<field name="credit_type" expand="1"/>
</tree>
+1
View File
@@ -5,4 +5,5 @@ this repository contains the full copyright notices and license terms. -->
<field name="rec_name" expand="2"/>
<field name="type" expand="1"/>
<field name="debit_type" expand="1"/>
<field name="credit_type" expand="1"/>
</tree>
+1
View File
@@ -6,4 +6,5 @@ this repository contains the full copyright notices and license terms. -->
<field name="company" expand="1"/>
<field name="type" expand="1"/>
<field name="debit_type" expand="1"/>
<field name="credit_type" expand="1"/>
</tree>