Skip to content

Commit

Permalink
Merge pull request #448 from ecosoft-odoo/16.0-mig-budget_activity
Browse files Browse the repository at this point in the history
[16.0][MIG] budget_activity
  • Loading branch information
Saran440 authored Sep 24, 2024
2 parents 4323cce + 4220111 commit e4813d5
Show file tree
Hide file tree
Showing 35 changed files with 1,633 additions and 0 deletions.
97 changes: 97 additions & 0 deletions budget_activity/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
===============
Budget Activity
===============

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:a5a8909d4b508145ac8b4f7811bc684d06e2e7e126e227c8e349ee255d4c9c7b
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-ecosoft--odoo%2Fbudgeting-lightgray.png?logo=github
:target: https://github.com/ecosoft-odoo/budgeting/tree/16.0/budget_activity
:alt: ecosoft-odoo/budgeting

|badge1| |badge2| |badge3|

This module helps the system accurately record the account code for budget recording.
It includes an "Activity" linking the two, where the activity serves as a match between what the user understands and the account code.
The user can select from a list of activity that have been created in the system,
and the system will then match the selected activity to the corresponding account,
so the user does not need to understand the account themselves.

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

Usage
=====

To used this module you have to configued Budget Activity first.

#. Go to Budgeting > Activity > Budget Activity
#. Create new activity, select a KPI (if you want to group it) and match the activity to an account.
#. Add a `Keyword` if you need to search for other words to show this activity. For example, the activity name is `Activity1` and the keywords are `Ticket` and `Transportation`. In the Activity field, the user can search for the name `Ticket` to see the activity `Activity1`.
#. Go to Budgeting > Configurations > Budget Template
#. Create new template or use old template (if you have).
#. When you select a KPI, it will automatically select the corresponding activity and account. If you haven't set up an activity in the KPI, you can select the activity and it will automatically select the corresponding account.


In the usage window, you will see a new field called "Activity" where the user can select from a list of options.
The system will then match the selected activity to the corresponding account that has been set up.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/ecosoft-odoo/budgeting/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/ecosoft-odoo/budgeting/issues/new?body=module:%20budget_activity%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Ecosoft

Contributors
~~~~~~~~~~~~

* `Ecosoft <http://ecosoft.co.th>`__:

* Kitti Upariphutthiphong <kittiu@ecosoft.co.th>
* Saran Lim. <saranl@ecosoft.co.th>
* Pimolnat Suntian <pimolnats@ecosoft.co.th>

Maintainers
~~~~~~~~~~~

.. |maintainer-kittiu| image:: https://github.com/kittiu.png?size=40px
:target: https://github.com/kittiu
:alt: kittiu

Current maintainer:

|maintainer-kittiu|

This module is part of the `ecosoft-odoo/budgeting <https://github.com/ecosoft-odoo/budgeting/tree/16.0/budget_activity>`_ project on GitHub.

You are welcome to contribute.
4 changes: 4 additions & 0 deletions budget_activity/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models
from . import report
28 changes: 28 additions & 0 deletions budget_activity/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Budget Activity",
"version": "16.0.1.0.0",
"category": "Accounting",
"license": "AGPL-3",
"author": "Ecosoft, Odoo Community Association (OCA)",
"website": "https://github.com/ecosoft-odoo/budgeting",
"depends": ["budget_control"],
"data": [
"security/budget_activity_security.xml",
"security/ir.model.access.csv",
"report/budget_monitor_report_view.xml",
"views/account_move_views.xml",
"views/analytic_line_views.xml",
"views/budget_activity_view.xml",
"views/budget_kpi_view.xml",
"views/budget_template_view.xml",
"views/budget_menuitem.xml",
"views/budget_move_adjustment_view.xml",
],
"demo": ["demo/budget_activity_demo.xml"],
"installable": True,
"maintainers": ["kittiu"],
"development_status": "Alpha",
}
48 changes: 48 additions & 0 deletions budget_activity/demo/budget_activity_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo noupdate="1">
<!-- Add Activity Demo -->
<record id="budget_activity_expense_demo" model="budget.activity">
<field name="name">Expense</field>
<field name="kpi_id" ref="budget_control.budget_kpi1_demo" />
<field name="account_id" eval="ref('l10n_generic_coa.expense')" />
</record>
<record id="budget_activity_purchase_equipment_demo" model="budget.activity">
<field name="name">Purchase of Equipments</field>
<field name="kpi_id" ref="budget_control.budget_kpi2_demo" />
<field name="account_id" eval="ref('l10n_generic_coa.expense_invest')" />
</record>
<record id="budget_activity_rent_demo" model="budget.activity">
<field name="name">Rent</field>
<field name="kpi_id" ref="budget_control.budget_kpi3_demo" />
<field name="account_id" eval="ref('l10n_generic_coa.expense_rent')" />
</record>

<!-- Template Demo -->
<record
id="budget_control.budget_template_line_demo_kpi_600000"
model="budget.template.line"
>
<field
name="activity_ids"
eval="[(4, ref('budget_activity.budget_activity_expense_demo'))]"
/>
</record>
<record
id="budget_control.budget_template_line_demo_kpi_611000"
model="budget.template.line"
>
<field
name="activity_ids"
eval="[(4, ref('budget_activity.budget_activity_purchase_equipment_demo'))]"
/>
</record>
<record
id="budget_control.budget_template_line_demo_kpi_612000"
model="budget.template.line"
>
<field
name="activity_ids"
eval="[(4, ref('budget_activity.budget_activity_rent_demo'))]"
/>
</record>
</odoo>
11 changes: 11 additions & 0 deletions budget_activity/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import res_company
from . import account_move
from . import budget_activity
from . import account_analytic_line
from . import base_budget_move
from . import budget_subkpi
from . import budget_kpi_template
from . import budget_period
from . import budget_move_adjustment
14 changes: 14 additions & 0 deletions budget_activity/models/account_analytic_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models


class AccountAnalyticLine(models.Model):
_inherit = "account.analytic.line"

activity_id = fields.Many2one(
comodel_name="budget.activity",
string="Activity",
index=True,
)
54 changes: 54 additions & 0 deletions budget_activity/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, fields, models


class AccountMoveLine(models.Model):
_inherit = "account.move.line"

activity_id = fields.Many2one(
comodel_name="budget.activity",
string="Activity",
index=True,
)

def _is_realtime_inventory_product(self):
# Case non-realtime inventory product
# activity's account takes priority over product's account
if self.product_id.type != "product":
return False
if not hasattr(self.product_id.categ_id, "property_valuation"):
return False
return self.product_id.categ_id.property_valuation == "real_time"

def _compute_account_id(self):
"""In case of Realtime Inventory Product,
activity's account takes priority"""
input_lines = self.filtered(
lambda line: (
line._is_realtime_inventory_product()
and line.move_id.company_id.anglo_saxon_accounting
)
).with_prefetch(
["move_id", "move_id.company_id", "move_id.journal_id.company_id"]
)
for line in input_lines:
line = line.with_company(line.move_id.journal_id.company_id)
if line.activity_id:
line.account_id = line.activity_id.account_id
return super(AccountMoveLine, self - input_lines)._compute_account_id()

def _prepare_analytic_lines(self):
"""Add activity_id to analytic line"""
analytic_line_vals = super()._prepare_analytic_lines()
self.ensure_one()
if self.activity_id: # Check if activity_id is set
for analytic_line in analytic_line_vals:
analytic_line["activity_id"] = self.activity_id.id
return analytic_line_vals

@api.onchange("activity_id")
def _onchange_activity_id(self):
if self.activity_id:
self.account_id = self.activity_id.account_id
74 changes: 74 additions & 0 deletions budget_activity/models/base_budget_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import _, api, fields, models
from odoo.exceptions import UserError


class BaseBudgetMove(models.AbstractModel):
_inherit = "base.budget.move"

activity_id = fields.Many2one(
comodel_name="budget.activity",
string="Activity",
index=True,
)
account_id = fields.Many2one(
compute="_compute_activity_account",
store=True,
help="When activity is selected, always use activity's account to "
"enusre that the KPI budgeting which rely on account is valid. "
"Because in some case, i.e., perpetual inventory, "
"account in account.move.line can be different with "
"account in account.budget.move.",
)

@api.depends("activity_id")
def _compute_activity_account(self):
budget_control_key = self.env.company.budget_control_key
if budget_control_key == "activity_id":
for rec in self:
rec.account_id = (
rec.activity_id.account_id if rec.activity_id else rec.account_id
)

@api.constrains("activity_id", "account_id")
def _check_activity_account(self):
budget_control_key = self.env.company.budget_control_key
if budget_control_key == "activity_id":
for rec in self.filtered("activity_id"):
if rec.account_id != rec.activity_id.account_id:
raise UserError(
_("Account not equal to Activity's Account: %s")
% rec.activity_id.account_id.display_name
)


class BudgetDoclineMixinBase(models.AbstractModel):
_inherit = "budget.docline.mixin.base"

activity_id = fields.Many2one(
comodel_name="budget.activity",
string="Activity",
domain=lambda self: self._domain_activity(),
index=True,
)

def _domain_activity(self):
return []


class BudgetDoclineMixin(models.AbstractModel):
_inherit = "budget.docline.mixin"

def _update_budget_commitment(self, budget_vals, analytic, reverse=False):
budget_vals = super()._update_budget_commitment(
budget_vals, analytic, reverse=reverse
)
budget_vals["activity_id"] = self.activity_id.id
# For case object without account_id (PR/PO), normally account is from
# product, it should now changed to follow activity.
# But if account_id is part of object (INV), use whatever is passed-in.
if "account_id" not in self:
budget_vals["account_id"] = self["activity_id"].account_id.id
return budget_vals
Loading

0 comments on commit e4813d5

Please sign in to comment.