Skip to content

Commit 85b42af

Browse files
coreichampPHATTARAPON.K
andauthored
[16.0][IMP] budget: optional commitment, required analytics (#582)
Co-authored-by: PHATTARAPON.K <phattarapon.k@aginix.tech>
1 parent 94f8889 commit 85b42af

5 files changed

Lines changed: 58 additions & 21 deletions

File tree

account_move_kmitl/views/account_move_views.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
<field name="analytic_distribution" invisible="1"/>
3535
</group>
3636
<group name="analytic_dimensions">
37-
<field name="activity_analytic_id" domain="[('plan_id.code', '=', 'activities')]" options="{'no_create': True}" attrs="{'readonly': [('state', '=', 'posted')]}"/>
38-
<field name="department_analytic_id" domain="[('plan_id.code', '=', 'departments')]" options="{'no_create': True}" attrs="{'readonly': [('state', '=', 'posted')]}"/>
39-
<field name="fund_analytic_id" domain="[('plan_id.code', '=', 'funds')]" options="{'no_create': True}" attrs="{'readonly': [('state', '=', 'posted')]}"/>
40-
<field name="source_analytic_id" domain="[('plan_id.code', '=', 'sources')]" options="{'no_create': True}" attrs="{'readonly': [('state', '=', 'posted')]}"/>
41-
<field name="budget_account_id" options="{'no_create': True}" attrs="{'readonly': [('state', '=', 'posted')]}"/>
37+
<field name="activity_analytic_id" domain="[('plan_id.code', '=', 'activities')]" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '=', 'posted')]}"/>
38+
<field name="department_analytic_id" domain="[('plan_id.code', '=', 'departments')]" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '=', 'posted')]}"/>
39+
<field name="fund_analytic_id" domain="[('plan_id.code', '=', 'funds')]" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '=', 'posted')]}"/>
40+
<field name="source_analytic_id" domain="[('plan_id.code', '=', 'sources')]" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '=', 'posted')]}"/>
41+
<field name="budget_account_id" options="{'no_create': True}" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '=', 'posted')]}"/>
4242
</group>
4343
</group>
4444
<div class="oe_button_box" name="button_box_budget">

account_payment_budget/models/account_payment.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,25 @@ def _onchange_budget_commitment_id(self):
5858
if analytic_accounts:
5959
self.analytic_distribution = analytic_accounts
6060

61+
def _check_analytic_distribution_complete(self):
62+
required_plan_codes = {"activities", "departments", "funds", "sources"}
63+
if not self.analytic_distribution:
64+
raise ValidationError(_("Analytic distribution is required."))
65+
account_ids = [int(k) for k in self.analytic_distribution.keys()]
66+
accounts = self.env["account.analytic.account"].browse(account_ids)
67+
present_codes = set(accounts.mapped("root_plan_id.code"))
68+
missing = required_plan_codes - present_codes
69+
if missing:
70+
raise ValidationError(
71+
_("Missing required analytic dimensions: %s")
72+
% ", ".join(missing)
73+
)
74+
6175
def action_post(self):
62-
if self.budget_commitment_id and self.payment_type == 'outbound':
63-
self._consume_commitment(amount=self.amount)
76+
for payment in self:
77+
if payment.payment_type == "outbound":
78+
payment._check_analytic_distribution_complete()
79+
if payment.budget_commitment_id and payment.payment_type == "outbound":
80+
payment._consume_commitment(amount=payment.amount)
6481

6582
return super().action_post()

account_payment_budget/views/account_payment_views.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
<field name="analytic_distribution" widget="analytic_distribution" readonly="1"/>
1919
</group>
2020
<group name="analytic_dimensions">
21-
<field name="activity_analytic_id" domain="[('plan_id.code', '=', 'activities')]" options="{'no_create': True}" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
22-
<field name="department_analytic_id" domain="[('plan_id.code', '=', 'departments')]" options="{'no_create': True}" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
23-
<field name="fund_analytic_id" domain="[('plan_id.code', '=', 'funds')]" options="{'no_create': True}" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
24-
<field name="source_analytic_id" domain="[('plan_id.code', '=', 'sources')]" options="{'no_create': True}" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
25-
<field name="budget_account_id" options="{'no_create': True}" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
21+
<field name="activity_analytic_id" domain="[('plan_id.code', '=', 'activities')]" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '!=', 'draft')]}"/>
22+
<field name="department_analytic_id" domain="[('plan_id.code', '=', 'departments')]" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '!=', 'draft')]}"/>
23+
<field name="fund_analytic_id" domain="[('plan_id.code', '=', 'funds')]" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '!=', 'draft')]}"/>
24+
<field name="source_analytic_id" domain="[('plan_id.code', '=', 'sources')]" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '!=', 'draft')]}"/>
25+
<field name="budget_account_id" options="{'no_create': True}" required="1" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', '!=', 'draft')]}"/>
2626
</group>
2727
</group>
2828
</page>

disbursement/models/disbursement_request.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44

55
from odoo import Command, _, api, fields, models
6-
from odoo.exceptions import UserError
6+
from odoo.exceptions import UserError, ValidationError
77
from odoo.osv import expression
88

99
_logger = logging.getLogger(__name__)
@@ -279,6 +279,24 @@ def _onchange_budget_commitment_id(self):
279279
rec.budget_account_id = budget.account_id
280280
rec.analytic_distribution = budget.analytic_distribution
281281

282+
@api.constrains("analytic_distribution")
283+
def _check_analytic_distribution_complete(self):
284+
required_plan_codes = {"activities", "departments", "funds", "sources"}
285+
for rec in self:
286+
if rec.state == "cancel":
287+
continue
288+
if not rec.analytic_distribution:
289+
raise ValidationError(_("Analytic distribution is required."))
290+
account_ids = [int(k) for k in rec.analytic_distribution.keys()]
291+
accounts = self.env["account.analytic.account"].browse(account_ids)
292+
present_codes = set(accounts.mapped("root_plan_id.code"))
293+
missing = required_plan_codes - present_codes
294+
if missing:
295+
raise ValidationError(
296+
_("Missing required analytic dimensions: %s")
297+
% ", ".join(missing)
298+
)
299+
282300
@api.model
283301
def _search_source_analytic_id(self, operator, value):
284302
account_ids = []
@@ -567,6 +585,9 @@ def _create_bill(self):
567585
"currency_id": self.currency_id.id,
568586
"company_id": self.company_id.id,
569587
"invoice_line_ids": invoice_lines,
588+
"budget_commitment_id": self.budget_commitment_id.id,
589+
"budget_account_id": self.budget_account_id.id,
590+
"analytic_distribution": self.analytic_distribution,
570591
}
571592
)
572593

disbursement/views/disbursement_request_views.xml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,12 @@
7777
</group>
7878
<group>
7979
<field name="company_id" groups="base.group_multi_company" />
80-
<field name="budget_commitment_id" required="1" />
81-
<field name="source_analytic_id" readonly="1" options="{'no_create': True, 'no_open': True}" />
82-
<field name="department_analytic_id" readonly="1" options="{'no_create': True, 'no_open': True}" />
83-
<field name="fund_analytic_id" readonly="1" options="{'no_create': True, 'no_open': True}" />
84-
<field name="activity_analytic_id" readonly="1" options="{'no_create': True, 'no_open': True}" />
85-
<field name="budget_account_id" readonly="1" required="1" options="{'no_create': True, 'no_open': True}" />
86-
<field name="budget_account_id" readonly="0" invisible="1"/>
80+
<field name="budget_commitment_id" />
81+
<field name="source_analytic_id" required="1" options="{'no_create': True, 'no_open': True}" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', 'in', ['submitted', 'validated', 'cancel'])]}" />
82+
<field name="department_analytic_id" required="1" options="{'no_create': True, 'no_open': True}" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', 'in', ['submitted', 'validated', 'cancel'])]}" />
83+
<field name="fund_analytic_id" required="1" options="{'no_create': True, 'no_open': True}" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', 'in', ['submitted', 'validated', 'cancel'])]}" />
84+
<field name="activity_analytic_id" required="1" options="{'no_create': True, 'no_open': True}" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', 'in', ['submitted', 'validated', 'cancel'])]}" />
85+
<field name="budget_account_id" required="1" options="{'no_create': True, 'no_open': True}" attrs="{'readonly': ['|', ('budget_commitment_id', '!=', False), ('state', 'in', ['submitted', 'validated', 'cancel'])]}" />
8786
<field name="analytic_distribution" invisible="1"/>
8887
</group>
8988
</group>
@@ -99,7 +98,7 @@
9998
<field name="tax_ids" widget="many2many_tags" />
10099
<field name="wht_tax_id" optional="show"/>
101100
<field name="account_id" />
102-
<field name="analytic_distribution" widget="analytic_distribution" groups="analytic.group_analytic_accounting" />
101+
<field name="analytic_distribution" widget="analytic_distribution" groups="analytic.group_analytic_accounting" readonly="1" />
103102
<field name="price_subtotal" />
104103
<field name="price_tax" optional="hide" />
105104
<field name="price_total" />

0 commit comments

Comments
 (0)