From 1ad6c65ec1873ee4886bc0ecd48548afb661e9f8 Mon Sep 17 00:00:00 2001 From: bobrador Date: Mon, 14 Oct 2024 16:25:16 +0200 Subject: [PATCH] [ADD] account_analytic_distribution_manual_date: New module account_analytic_distribution_manual_date --- .../README.rst | 113 +++++ .../__init__.py | 3 + .../__manifest__.py | 21 + .../i18n/ca_ES.po | 46 ++ .../i18n/es .po | 46 ++ .../models/__init__.py | 2 + .../account_analytic_distribution_manual.py | 10 + .../models/account_move.py | 71 +++ .../pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 2 + .../readme/DESCRIPTION.md | 3 + .../readme/USAGE.md | 18 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 462 ++++++++++++++++++ .../analytic_distribution.esm.js | 51 ++ .../tests/__init__.py | 1 + .../tests/test_manual_distribution_date.py | 156 ++++++ ...unt_analytic_distribution_manual_views.xml | 62 +++ 18 files changed, 1070 insertions(+) create mode 100644 account_analytic_distribution_manual_date/README.rst create mode 100644 account_analytic_distribution_manual_date/__init__.py create mode 100644 account_analytic_distribution_manual_date/__manifest__.py create mode 100644 account_analytic_distribution_manual_date/i18n/ca_ES.po create mode 100644 account_analytic_distribution_manual_date/i18n/es .po create mode 100644 account_analytic_distribution_manual_date/models/__init__.py create mode 100644 account_analytic_distribution_manual_date/models/account_analytic_distribution_manual.py create mode 100644 account_analytic_distribution_manual_date/models/account_move.py create mode 100644 account_analytic_distribution_manual_date/pyproject.toml create mode 100644 account_analytic_distribution_manual_date/readme/CONTRIBUTORS.md create mode 100644 account_analytic_distribution_manual_date/readme/DESCRIPTION.md create mode 100644 account_analytic_distribution_manual_date/readme/USAGE.md create mode 100644 account_analytic_distribution_manual_date/static/description/icon.png create mode 100644 account_analytic_distribution_manual_date/static/description/index.html create mode 100644 account_analytic_distribution_manual_date/static/src/components/analytic_distribution/analytic_distribution.esm.js create mode 100644 account_analytic_distribution_manual_date/tests/__init__.py create mode 100644 account_analytic_distribution_manual_date/tests/test_manual_distribution_date.py create mode 100644 account_analytic_distribution_manual_date/views/account_analytic_distribution_manual_views.xml diff --git a/account_analytic_distribution_manual_date/README.rst b/account_analytic_distribution_manual_date/README.rst new file mode 100644 index 0000000000..af497fd598 --- /dev/null +++ b/account_analytic_distribution_manual_date/README.rst @@ -0,0 +1,113 @@ +========================================= +Account analytic distribution manual date +========================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:87883cfe72166f656358d438fe09302ad6946598cf4bd9fde07fe7540827c940 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |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-OCA%2Faccount--analytic-lightgray.png?logo=github + :target: https://github.com/OCA/account-analytic/tree/17.0/account_analytic_distribution_manual_date + :alt: OCA/account-analytic +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-analytic-17-0/account-analytic-17-0-account_analytic_distribution_manual_date + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-analytic&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module introduces **Start Date** and **End Date** fields for manual +distribution. + +This functionality enforces stricter management of distributions by +ensuring only relevant distributions within the specified time periods +are shown, based on the invoice date, the Journal Entry date or the +today's date + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To utilize this module, follow these steps: + +1. **Navigate to Manual Analytic Distributions**: + + - Go to **Invoicing** → **Configuration** → **Manual Analytic + Distributions**. + +2. **Create or Edit a Distribution**: + + - Create a new distribution or edit an existing one. + - Set the **Start Date** and **End Date** for the distribution. + +3. **Create an Invoice or Vendor Bill**: + + - Proceed to create a new **Invoice** or **Vendor Bill**. + +4. **Add a Line to the Invoice**: + + - Create a line item on the invoice. + - Select a manual distribution using the distribution widget. + +5. **Filtered Manual Distributions**: + + - Now, the available Manual Distributions will be filtered based on + the **Invoice Date** or **Today's Date**. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* (Nagarro - APSL) Bernat Obrador + +Contributors +------------ + +- APSL - Nagarro + + - Bernat Obrador + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/account-analytic `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_analytic_distribution_manual_date/__init__.py b/account_analytic_distribution_manual_date/__init__.py new file mode 100644 index 0000000000..79301c6b51 --- /dev/null +++ b/account_analytic_distribution_manual_date/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2024 (APSL - Nagarro) Bernat Obrador +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import models diff --git a/account_analytic_distribution_manual_date/__manifest__.py b/account_analytic_distribution_manual_date/__manifest__.py new file mode 100644 index 0000000000..d6ef505439 --- /dev/null +++ b/account_analytic_distribution_manual_date/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright 2024 (APSL - Nagarro) Bernat Obrador +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Account analytic distribution manual date", + "summary": "Account analytic distribution manual date", + "version": "17.0.1.0.0", + "license": "AGPL-3", + "website": "https://github.com/OCA/account-analytic", + "author": "(Nagarro - APSL) Bernat Obrador, Odoo Community Association (OCA)", + "depends": ["account_analytic_distribution_manual"], + "data": [ + "views/account_analytic_distribution_manual_views.xml", + ], + "assets": { + "web.assets_backend": [ + "account_analytic_distribution_manual_date/static/src/components/**/*", + ], + }, + "installable": True, +} diff --git a/account_analytic_distribution_manual_date/i18n/ca_ES.po b/account_analytic_distribution_manual_date/i18n/ca_ES.po new file mode 100644 index 0000000000..017bdea7bd --- /dev/null +++ b/account_analytic_distribution_manual_date/i18n/ca_ES.po @@ -0,0 +1,46 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_analytic_distribution_manual_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-10-14 13:14+0000\n" +"PO-Revision-Date: 2024-10-14 13:14+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_analytic_distribution_manual_date +#: model:ir.model,name:account_analytic_distribution_manual_date.model_account_analytic_distribution_manual +msgid "Account analytic distribution manual" +msgstr "Distribució Analítica Manual" + +#. module: account_analytic_distribution_manual_date +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual_date.view_account_analytic_distribution_manual_form_inherit +msgid "Distribution Dates" +msgstr "Dates de Distribució" + +#. module: account_analytic_distribution_manual_date +#: model:ir.model.fields,field_description:account_analytic_distribution_manual_date.field_account_analytic_distribution_manual__end_date +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual_date.view_account_analytic_distribution_manual_form_inherit +msgid "End Date" +msgstr "Data de Fi" + +#. module: account_analytic_distribution_manual_date +#: model:ir.model.fields,field_description:account_analytic_distribution_manual_date.field_account_analytic_distribution_manual__start_date +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual_date.view_account_analytic_distribution_manual_form_inherit +msgid "Start Date" +msgstr "Data d'Inici" + +#. module: account_analytic_distribution_manual_date +#. odoo-python +#: code:addons/account_analytic_distribution_manual_date/models/account_move.py:0 +#: code:addons/account_analytic_distribution_manual_date/models/account_move.py:0 +#, python-format +msgid "The invoice date %s is outside the manual distribution period %s - %s." +msgstr "La data de la factura %s està fora del període de la distribució manual %s - %s." diff --git a/account_analytic_distribution_manual_date/i18n/es .po b/account_analytic_distribution_manual_date/i18n/es .po new file mode 100644 index 0000000000..9d13746424 --- /dev/null +++ b/account_analytic_distribution_manual_date/i18n/es .po @@ -0,0 +1,46 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_analytic_distribution_manual_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-10-14 13:14+0000\n" +"PO-Revision-Date: 2024-10-14 13:14+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_analytic_distribution_manual_date +#: model:ir.model,name:account_analytic_distribution_manual_date.model_account_analytic_distribution_manual +msgid "Account analytic distribution manual" +msgstr "Distribución Analítica Manual" + +#. module: account_analytic_distribution_manual_date +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual_date.view_account_analytic_distribution_manual_form_inherit +msgid "Distribution Dates" +msgstr "Fechas de Distribución" + +#. module: account_analytic_distribution_manual_date +#: model:ir.model.fields,field_description:account_analytic_distribution_manual_date.field_account_analytic_distribution_manual__end_date +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual_date.view_account_analytic_distribution_manual_form_inherit +msgid "End Date" +msgstr "Fecha de Fin" + +#. module: account_analytic_distribution_manual_date +#: model:ir.model.fields,field_description:account_analytic_distribution_manual_date.field_account_analytic_distribution_manual__start_date +#: model_terms:ir.ui.view,arch_db:account_analytic_distribution_manual_date.view_account_analytic_distribution_manual_form_inherit +msgid "Start Date" +msgstr "Fecha de Inicio" + +#. module: account_analytic_distribution_manual_date +#. odoo-python +#: code:addons/account_analytic_distribution_manual_date/models/account_move.py:0 +#: code:addons/account_analytic_distribution_manual_date/models/account_move.py:0 +#, python-format +msgid "The invoice date %s is outside the manual distribution period %s - %s." +msgstr "La fecha de la factura %s está fuera del período de la distribución manual %s - %s." diff --git a/account_analytic_distribution_manual_date/models/__init__.py b/account_analytic_distribution_manual_date/models/__init__.py new file mode 100644 index 0000000000..43f7d8bfbf --- /dev/null +++ b/account_analytic_distribution_manual_date/models/__init__.py @@ -0,0 +1,2 @@ +from . import account_analytic_distribution_manual +from . import account_move diff --git a/account_analytic_distribution_manual_date/models/account_analytic_distribution_manual.py b/account_analytic_distribution_manual_date/models/account_analytic_distribution_manual.py new file mode 100644 index 0000000000..47aaa6be0d --- /dev/null +++ b/account_analytic_distribution_manual_date/models/account_analytic_distribution_manual.py @@ -0,0 +1,10 @@ +# Copyright 2024 (APSL - Nagarro) Bernat Obrador +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class AccountAnalyticDistributionManual(models.Model): + _inherit = "account.analytic.distribution.manual" + + start_date = fields.Date() + end_date = fields.Date() diff --git a/account_analytic_distribution_manual_date/models/account_move.py b/account_analytic_distribution_manual_date/models/account_move.py new file mode 100644 index 0000000000..0869936170 --- /dev/null +++ b/account_analytic_distribution_manual_date/models/account_move.py @@ -0,0 +1,71 @@ +# Copyright 2024 (APSL - Nagarro) Bernat Obrador +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import _, fields, models +from odoo.exceptions import UserError + + +class AccountMove(models.Model): + _inherit = "account.move" + + def write(self, vals): + date_string = ( + vals.get("invoice_date") + or self.invoice_date + or vals.get("date") + or self.date + ) + date = ( + fields.Date.from_string(date_string) + if date_string + else fields.Date.context_today(self) + ) + + invoice_line_ids = vals.get("invoice_line_ids", []) + + if invoice_line_ids: + for line in invoice_line_ids: + if len(line) > 2 and "manual_distribution_id" in line[2]: + manual_distribution = self.env[ + "account.analytic.distribution.manual" + ].browse(line[2]["manual_distribution_id"]) + if manual_distribution and not ( + manual_distribution.start_date + <= date + <= manual_distribution.end_date + ): + raise UserError( + _( + "The invoice date %(invoice_date)s is outside the " + "manual distribution period %(start_date)s - " + "%(end_date)s." + ) + % { + "invoice_date": date, + "start_date": manual_distribution.start_date, + "end_date": manual_distribution.end_date, + } + ) + # If invoice date has changed but no lines has changed + elif "needed_terms_dirty" not in vals: + for line in self.invoice_line_ids: + manual_distribution = line.manual_distribution_id + if manual_distribution: + if not ( + manual_distribution.start_date + <= date + <= manual_distribution.end_date + ): + raise UserError( + _( + "The invoice date %(invoice_date)s is outside the " + "manual distribution period %(start_date)s - " + "%(end_date)s." + ) + % { + "invoice_date": date, + "start_date": manual_distribution.start_date, + "end_date": manual_distribution.end_date, + } + ) + + return super().write(vals) diff --git a/account_analytic_distribution_manual_date/pyproject.toml b/account_analytic_distribution_manual_date/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/account_analytic_distribution_manual_date/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/account_analytic_distribution_manual_date/readme/CONTRIBUTORS.md b/account_analytic_distribution_manual_date/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..8bb25787ab --- /dev/null +++ b/account_analytic_distribution_manual_date/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- APSL - Nagarro \<\> + - Bernat Obrador \ No newline at end of file diff --git a/account_analytic_distribution_manual_date/readme/DESCRIPTION.md b/account_analytic_distribution_manual_date/readme/DESCRIPTION.md new file mode 100644 index 0000000000..9b6764a688 --- /dev/null +++ b/account_analytic_distribution_manual_date/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module introduces **Start Date** and **End Date** fields for manual distribution. + +This functionality enforces stricter management of distributions by ensuring only relevant distributions within the specified time periods are shown, based on the invoice date, the Journal Entry date or the today's date \ No newline at end of file diff --git a/account_analytic_distribution_manual_date/readme/USAGE.md b/account_analytic_distribution_manual_date/readme/USAGE.md new file mode 100644 index 0000000000..4590d3e4d8 --- /dev/null +++ b/account_analytic_distribution_manual_date/readme/USAGE.md @@ -0,0 +1,18 @@ +To utilize this module, follow these steps: + +1. **Navigate to Manual Analytic Distributions**: + - Go to **Invoicing** → **Configuration** → **Manual Analytic Distributions**. + +2. **Create or Edit a Distribution**: + - Create a new distribution or edit an existing one. + - Set the **Start Date** and **End Date** for the distribution. + +3. **Create an Invoice or Vendor Bill**: + - Proceed to create a new **Invoice** or **Vendor Bill**. + +4. **Add a Line to the Invoice**: + - Create a line item on the invoice. + - Select a manual distribution using the distribution widget. + +5. **Filtered Manual Distributions**: + - Now, the available Manual Distributions will be filtered based on the **Invoice Date** or **Today's Date**. diff --git a/account_analytic_distribution_manual_date/static/description/icon.png b/account_analytic_distribution_manual_date/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/account_analytic_distribution_manual_date/static/description/index.html b/account_analytic_distribution_manual_date/static/description/index.html new file mode 100644 index 0000000000..b12a37a525 --- /dev/null +++ b/account_analytic_distribution_manual_date/static/description/index.html @@ -0,0 +1,462 @@ + + + + + +Account analytic distribution manual date + + + +
+

Account analytic distribution manual date

+ + +

Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

+

This module introduces Start Date and End Date fields for manual +distribution.

+

This functionality enforces stricter management of distributions by +ensuring only relevant distributions within the specified time periods +are shown, based on the invoice date, the Journal Entry date or the +today’s date

+

Table of contents

+ +
+

Usage

+

To utilize this module, follow these steps:

+
    +
  1. Navigate to Manual Analytic Distributions:
      +
    • Go to InvoicingConfigurationManual Analytic +Distributions.
    • +
    +
  2. +
  3. Create or Edit a Distribution:
      +
    • Create a new distribution or edit an existing one.
    • +
    • Set the Start Date and End Date for the distribution.
    • +
    +
  4. +
  5. Create an Invoice or Vendor Bill:
      +
    • Proceed to create a new Invoice or Vendor Bill.
    • +
    +
  6. +
  7. Add a Line to the Invoice:
      +
    • Create a line item on the invoice.
    • +
    • Select a manual distribution using the distribution widget.
    • +
    +
  8. +
  9. Filtered Manual Distributions:
      +
    • Now, the available Manual Distributions will be filtered based on +the Invoice Date or Today’s Date.
    • +
    +
  10. +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • (Nagarro - APSL) Bernat Obrador
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/account-analytic project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/account_analytic_distribution_manual_date/static/src/components/analytic_distribution/analytic_distribution.esm.js b/account_analytic_distribution_manual_date/static/src/components/analytic_distribution/analytic_distribution.esm.js new file mode 100644 index 0000000000..b056fa4aa1 --- /dev/null +++ b/account_analytic_distribution_manual_date/static/src/components/analytic_distribution/analytic_distribution.esm.js @@ -0,0 +1,51 @@ +/** @odoo-module **/ +// Copyright 2024 (APSL - Nagarro) Bernat Obrador +// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import {AnalyticDistribution} from "@analytic/components/analytic_distribution/analytic_distribution"; +import {patch} from "@web/core/utils/patch"; +const {useState} = owl; + +patch(AnalyticDistribution.prototype, { + setup() { + super.setup(...arguments); + + this.state_invoice_date = useState({ + date: this.getDate(), + }); + }, + + async fetchAnalyticDistributionManual(domain, limit = null) { + await this.refreshInvoiceDate(); + + domain.push( + ["start_date", "<=", this.state_invoice_date.date], + ["end_date", ">=", this.state_invoice_date.date] + ); + + return super.fetchAnalyticDistributionManual(domain, limit); + }, + async refreshInvoiceDate() { + if (this.state_invoice_date.date !== this.getDate()) { + this.state_invoice_date.date = this.getDate(); + } + }, + async processSelectedOption(selected_option) { + await super.processSelectedOption(selected_option); + // This solves a bug if saiving the record with the widget open + super.save(); + }, + getDate() { + try { + const parentRecordData = this.props.record._parentRecord.data || {}; + + if (this.props.record.model.config.resModel === "account.move") { + return ( + parentRecordData.invoice_date || parentRecordData.date || new Date() + ); + } + return new Date(); + } catch (error) { + return new Date(); + } + }, +}); diff --git a/account_analytic_distribution_manual_date/tests/__init__.py b/account_analytic_distribution_manual_date/tests/__init__.py new file mode 100644 index 0000000000..cf378adc0f --- /dev/null +++ b/account_analytic_distribution_manual_date/tests/__init__.py @@ -0,0 +1 @@ +from . import test_manual_distribution_date diff --git a/account_analytic_distribution_manual_date/tests/test_manual_distribution_date.py b/account_analytic_distribution_manual_date/tests/test_manual_distribution_date.py new file mode 100644 index 0000000000..9b62a1862d --- /dev/null +++ b/account_analytic_distribution_manual_date/tests/test_manual_distribution_date.py @@ -0,0 +1,156 @@ +# Copyright 2024 (APSL - Nagarro) Bernat Obrador +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from datetime import date, datetime + +from freezegun import freeze_time + +from odoo.exceptions import UserError +from odoo.tests import TransactionCase + + +class TestAccountMove(TransactionCase): + @classmethod + @freeze_time("2024-01-01") + def setUpClass(cls): + super().setUpClass() + + cls.manual_distribution = cls.env[ + "account.analytic.distribution.manual" + ].create( + { + "name": "Test", + "start_date": "2024-01-01", + "end_date": "2024-12-31", + } + ) + + cls.invoice = cls.env["account.move"].create( + { + "move_type": "out_invoice", + "invoice_line_ids": [ + ( + 0, + 0, + { + "name": "Product A", + "quantity": 1, + "price_unit": 100.0, + "manual_distribution_id": cls.manual_distribution.id, + }, + ) + ], + } + ) + + @freeze_time("2024-01-01") + def test_assert_date_time(self): + """Check that date is 2024-01-01""" + assert datetime.now() == datetime(2024, 1, 1) + + @freeze_time("2024-01-01") + def test_write_without_invoice_date(self): + """Test valid date within manual distribution range.""" + self.invoice.write( + { + "invoice_line_ids": [ + ( + 1, + self.invoice.invoice_line_ids[0].id, + { + "manual_distribution_id": self.manual_distribution.id, + }, + ) + ] + } + ) + + updated_distribution_id = self.invoice.invoice_line_ids[ + 0 + ].manual_distribution_id.id + self.assertEqual(self.manual_distribution.id, updated_distribution_id) + + @freeze_time("2024-01-01") + def test_write_with_valid_date(self): + """Test valid date within manual distribution range.""" + new_date = "2024-07-01" + self.invoice.write({"invoice_date": new_date}) + self.assertEqual(self.invoice.invoice_date, date.fromisoformat(new_date)) + + @freeze_time("2024-01-01") + def test_write_with_date_outside_distribution_range(self): + """Test write raises UserError when date is outside the distribution range.""" + with self.assertRaises(UserError): + self.invoice.write( + { + "invoice_line_ids": [ + ( + 1, + self.invoice.invoice_line_ids[0].id, + { + "manual_distribution_id": self.manual_distribution.id, + }, + ) + ], + "invoice_date": "2025-01-01", + } + ) + + @freeze_time("2024-01-01") + def test_write_without_date_outside_distribution_range(self): + """ + Test write raises UserError when invoice date is not changed + and it's outside distribution range. + """ + self.manual_distribution.write( + {"start_date": "2024-08-01", "end_date": "2024-08-31"} + ) + + with self.assertRaises(UserError): + self.invoice.write( + { + "invoice_line_ids": [ + ( + 1, + self.invoice.invoice_line_ids[0].id, + { + "manual_distribution_id": self.manual_distribution.id, + }, + ) + ] + } + ) + + def test_write_without_invoice_date_with_new_distribution(self): + """ + Test write without changing invoice_date when it's + still valid within the distribution range. + """ + + new_distribution = self.env["account.analytic.distribution.manual"].create( + { + "name": "New Test Distribution", + "start_date": "2024-01-10", + "end_date": "2024-12-31", + } + ) + + self.invoice.invoice_line_ids[0].manual_distribution_id = new_distribution + + self.invoice.write( + { + "invoice_line_ids": [ + ( + 1, + self.invoice.invoice_line_ids[0].id, + { + "manual_distribution_id": new_distribution.id, + }, + ) + ] + } + ) + + updated_distribution_id = self.invoice.invoice_line_ids[ + 0 + ].manual_distribution_id.id + self.assertNotEqual(self.manual_distribution.id, updated_distribution_id) diff --git a/account_analytic_distribution_manual_date/views/account_analytic_distribution_manual_views.xml b/account_analytic_distribution_manual_date/views/account_analytic_distribution_manual_views.xml new file mode 100644 index 0000000000..b0c7928810 --- /dev/null +++ b/account_analytic_distribution_manual_date/views/account_analytic_distribution_manual_views.xml @@ -0,0 +1,62 @@ + + + + + view.account.analytic.distribution.manual.tree.inherit + account.analytic.distribution.manual + + + + + + + + + + + view.account.analytic.distribution.manual.form.inherit + account.analytic.distribution.manual + + + + + + + + + + + + + + + account.move.form.inherit + account.move + + + + onInvoiceDateChange() + + + + +