From 79d28d85bfe3debfe333f4b8d9be8578016df9eb Mon Sep 17 00:00:00 2001 From: Flectra Community Bot Date: Sun, 14 Nov 2021 03:10:44 +0000 Subject: [PATCH] Automatic Update form OCA2FC Migrator --- .gitlab-ci.yml | 68 +- README.md | 1 + account_tax_balance/i18n/es_AR.po | 22 +- partner_statement/COPYRIGHT | 18 + partner_statement/LICENSE | 663 ++++++++++++++++++ partner_statement/README.rst | 133 ++++ partner_statement/__init__.py | 4 + partner_statement/__manifest__.py | 26 + partner_statement/i18n/ca.po | 494 +++++++++++++ partner_statement/i18n/de.po | 549 +++++++++++++++ partner_statement/i18n/es.po | 532 ++++++++++++++ partner_statement/i18n/es_AR.po | 512 ++++++++++++++ partner_statement/i18n/fr.po | 528 ++++++++++++++ partner_statement/i18n/hr_HR.po | 498 +++++++++++++ partner_statement/i18n/it.po | 507 ++++++++++++++ partner_statement/i18n/nl.po | 495 +++++++++++++ partner_statement/i18n/nl_NL.po | 497 +++++++++++++ partner_statement/i18n/partner_statement.pot | 498 +++++++++++++ partner_statement/i18n/pt.po | 497 +++++++++++++ partner_statement/i18n/pt_BR.po | 516 ++++++++++++++ partner_statement/i18n/ro.po | 515 ++++++++++++++ partner_statement/report/__init__.py | 3 + .../report/activity_statement.py | 193 +++++ .../report/outstanding_statement.py | 152 ++++ .../report/report_statement_common.py | 439 ++++++++++++ .../security/ir.model.access.csv | 3 + .../security/statement_security.xml | 11 + partner_statement/static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 484 +++++++++++++ .../static/src/scss/layout_statement.scss | 22 + partner_statement/tests/__init__.py | 3 + .../tests/test_activity_statement.py | 114 +++ .../tests/test_outstanding_statement.py | 82 +++ .../tests/test_res_config_settings.py | 35 + .../views/activity_statement.xml | 171 +++++ partner_statement/views/aging_buckets.xml | 70 ++ partner_statement/views/assets.xml | 18 + .../views/outstanding_statement.xml | 167 +++++ .../views/res_config_settings.xml | 86 +++ partner_statement/wizard/__init__.py | 4 + .../wizard/activity_statement_wizard.py | 42 ++ .../wizard/outstanding_statement_wizard.py | 19 + .../wizard/res_config_settings.py | 58 ++ partner_statement/wizard/statement_common.py | 71 ++ partner_statement/wizard/statement_wizard.xml | 129 ++++ requirements.txt | 2 + 46 files changed, 9939 insertions(+), 12 deletions(-) create mode 100644 partner_statement/COPYRIGHT create mode 100644 partner_statement/LICENSE create mode 100644 partner_statement/README.rst create mode 100644 partner_statement/__init__.py create mode 100644 partner_statement/__manifest__.py create mode 100644 partner_statement/i18n/ca.po create mode 100644 partner_statement/i18n/de.po create mode 100644 partner_statement/i18n/es.po create mode 100644 partner_statement/i18n/es_AR.po create mode 100644 partner_statement/i18n/fr.po create mode 100644 partner_statement/i18n/hr_HR.po create mode 100644 partner_statement/i18n/it.po create mode 100644 partner_statement/i18n/nl.po create mode 100644 partner_statement/i18n/nl_NL.po create mode 100644 partner_statement/i18n/partner_statement.pot create mode 100644 partner_statement/i18n/pt.po create mode 100644 partner_statement/i18n/pt_BR.po create mode 100644 partner_statement/i18n/ro.po create mode 100644 partner_statement/report/__init__.py create mode 100644 partner_statement/report/activity_statement.py create mode 100644 partner_statement/report/outstanding_statement.py create mode 100644 partner_statement/report/report_statement_common.py create mode 100644 partner_statement/security/ir.model.access.csv create mode 100644 partner_statement/security/statement_security.xml create mode 100644 partner_statement/static/description/icon.png create mode 100644 partner_statement/static/description/index.html create mode 100644 partner_statement/static/src/scss/layout_statement.scss create mode 100644 partner_statement/tests/__init__.py create mode 100644 partner_statement/tests/test_activity_statement.py create mode 100644 partner_statement/tests/test_outstanding_statement.py create mode 100644 partner_statement/tests/test_res_config_settings.py create mode 100644 partner_statement/views/activity_statement.xml create mode 100644 partner_statement/views/aging_buckets.xml create mode 100644 partner_statement/views/assets.xml create mode 100644 partner_statement/views/outstanding_statement.xml create mode 100644 partner_statement/views/res_config_settings.xml create mode 100644 partner_statement/wizard/__init__.py create mode 100644 partner_statement/wizard/activity_statement_wizard.py create mode 100644 partner_statement/wizard/outstanding_statement_wizard.py create mode 100644 partner_statement/wizard/res_config_settings.py create mode 100644 partner_statement/wizard/statement_common.py create mode 100644 partner_statement/wizard/statement_wizard.xml create mode 100644 requirements.txt diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5a8a9e9..e1a6929 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ test_all_modules: script: - apt-get install -y p7zip-full - apt-get install -y expect-dev + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - su - flectra -c "mkdir ~/others" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-closing.git ~/others/account-closing" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-invoicing.git ~/others/account-invoicing" @@ -70,13 +71,14 @@ test_all_modules: --db_password flectra --database test_all --test-enable - --init account_move_line_report_xls,account_tax_balance,account_financial_report,mis_builder_cash_flow + --init account_move_line_report_xls,account_tax_balance,account_financial_report,mis_builder_cash_flow,partner_statement --stop-after-init --log-level error --log-handler flectra.addons.account_move_line_report_xls:TEST --log-handler flectra.addons.account_tax_balance:TEST --log-handler flectra.addons.account_financial_report:TEST --log-handler flectra.addons.mis_builder_cash_flow:TEST + --log-handler flectra.addons.partner_statement:TEST " @@ -89,6 +91,7 @@ test_module_account_move_line_report_xls: script: - apt-get install -y p7zip-full - apt install -y expect-dev + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - su - flectra -c "mkdir ~/others" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-closing.git ~/others/account-closing" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-invoicing.git ~/others/account-invoicing" @@ -148,6 +151,7 @@ test_module_account_tax_balance: script: - apt-get install -y p7zip-full - apt install -y expect-dev + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - su - flectra -c "mkdir ~/others" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-closing.git ~/others/account-closing" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-invoicing.git ~/others/account-invoicing" @@ -207,6 +211,7 @@ test_module_account_financial_report: script: - apt-get install -y p7zip-full - apt install -y expect-dev + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - su - flectra -c "mkdir ~/others" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-closing.git ~/others/account-closing" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-invoicing.git ~/others/account-invoicing" @@ -266,6 +271,7 @@ test_module_mis_builder_cash_flow: script: - apt-get install -y p7zip-full - apt install -y expect-dev + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - su - flectra -c "mkdir ~/others" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-closing.git ~/others/account-closing" - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-invoicing.git ~/others/account-invoicing" @@ -316,3 +322,63 @@ test_module_mis_builder_cash_flow: --log-level error --log-handler flectra.addons.mis_builder_cash_flow:TEST" +test_module_partner_statement: + stage: testsingle + when: on_failure + image: + name: registry.gitlab.com/jamotion/flectra/ubuntudev:2-latest + entrypoint: ["/bin/sh", "-c"] + script: + - apt-get install -y p7zip-full + - apt install -y expect-dev + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-closing.git ~/others/account-closing" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-invoicing.git ~/others/account-invoicing" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-payment.git ~/others/account-payment" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/bank-payment.git ~/others/bank-payment" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/brand.git ~/others/brand" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/community-data-files.git ~/others/community-data-files" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/connector.git ~/others/connector" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/edi.git ~/others/edi" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/mis-builder.git ~/others/mis-builder" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/partner-contact.git ~/others/partner-contact" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/product-attribute.git ~/others/product-attribute" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/queue.git ~/others/queue" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/report-print-send.git ~/others/report-print-send" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/reporting-engine.git ~/others/reporting-engine" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/rest-framework.git ~/others/rest-framework" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/sale-workflow.git ~/others/sale-workflow" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/server-auth.git ~/others/server-auth" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/server-env.git ~/others/server-env" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/server-tools.git ~/others/server-tools" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/server-ux.git ~/others/server-ux" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/social.git ~/others/social" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/stock-logistics-transport.git ~/others/stock-logistics-transport" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/stock-logistics-warehouse.git ~/others/stock-logistics-warehouse" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/stock-logistics-workflow.git ~/others/stock-logistics-workflow" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/storage.git ~/others/storage" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/web.git ~/others/web" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/wms.git ~/others/wms" + - sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && dpkg-reconfigure --frontend=noninteractive locales && update-locale LANG=en_US.UTF-8 + - mkdir ${CI_PROJECT_DIR}/ci_data + - wget -O ${CI_PROJECT_DIR}/ci_data/test_base.zip https://gitlab.com/flectra-community/devops/oca2fc/raw/master/ci_data/test_base.zip + - 7z x -o ${CI_PROJECT_DIR}/ci_data/ ${CI_PROJECT_DIR}/ci_data/test_base.zip + - export PGPASSWORD="flectra" + - createdb -h psql -U flectra -O flectra -T template1 test_partner_statement + - psql -h psql -U flectra -d test_partner_statement -f ${CI_PROJECT_DIR}/ci_data/dump.sql + - su - flectra -c "mkdir -p ~/.local/share/filestore" + - mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_partner_statement + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_partner_statement + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR},~/others/account-closing,~/others/account-invoicing,~/others/account-payment,~/others/bank-payment,~/others/brand,~/others/community-data-files,~/others/connector,~/others/edi,~/others/mis-builder,~/others/partner-contact,~/others/product-attribute,~/others/queue,~/others/report-print-send,~/others/reporting-engine,~/others/rest-framework,~/others/sale-workflow,~/others/server-auth,~/others/server-env,~/others/server-tools,~/others/server-ux,~/others/social,~/others/stock-logistics-transport,~/others/stock-logistics-warehouse,~/others/stock-logistics-workflow,~/others/storage,~/others/web,~/others/wms + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_partner_statement + --test-enable -i partner_statement + --stop-after-init + --log-level error + --log-handler flectra.addons.partner_statement:TEST" + diff --git a/README.md b/README.md index 6554dbc..c837a2e 100644 --- a/README.md +++ b/README.md @@ -13,5 +13,6 @@ addon | version | summary [account_tax_balance](account_tax_balance/) | 2.0.1.2.0| Compute tax balances based on date range [account_financial_report](account_financial_report/) | 2.0.1.5.1| OCA Financial Reports [mis_builder_cash_flow](mis_builder_cash_flow/) | 2.0.1.0.0| MIS Builder Cash Flow +[partner_statement](partner_statement/) | 2.0.1.0.0| OCA Financial Reports diff --git a/account_tax_balance/i18n/es_AR.po b/account_tax_balance/i18n/es_AR.po index c1cdd66..d483306 100644 --- a/account_tax_balance/i18n/es_AR.po +++ b/account_tax_balance/i18n/es_AR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 13.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2020-08-12 00:59+0000\n" +"PO-Revision-Date: 2021-11-08 06:35+0000\n" "Last-Translator: Ignacio Buioli \n" "Language-Team: none\n" "Language: es_AR\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.10\n" +"X-Generator: Weblate 4.3.2\n" #. module: account_tax_balance #: code:addons/account_tax_balance/wizard/open_tax_balances.py:0 @@ -101,7 +101,7 @@ msgstr "Mostrar Nombre" #: model:ir.model.fields,field_description:account_tax_balance.field_account_move__financial_type #: model:ir.model.fields,field_description:account_tax_balance.field_account_payment__financial_type msgid "Financial Type" -msgstr "" +msgstr "Tipo Financiero" #. module: account_tax_balance #: model:ir.model.fields,field_description:account_tax_balance.field_wizard_open_tax_balances__from_date @@ -129,12 +129,12 @@ msgstr "ID" #. module: account_tax_balance #: model:ir.model,name:account_tax_balance.model_account_move msgid "Journal Entry" -msgstr "" +msgstr "Apunte Contable" #. module: account_tax_balance #: model:ir.model,name:account_tax_balance.model_account_move_line msgid "Journal Item" -msgstr "Elemento del Diario" +msgstr "Asiento Contable" #. module: account_tax_balance #: model:ir.model.fields,field_description:account_tax_balance.field_account_move____last_update @@ -158,7 +158,7 @@ msgstr "Última actualización en" #: code:addons/account_tax_balance/models/account_move.py:0 #, python-format msgid "Liquidity" -msgstr "" +msgstr "Liquidez" #. module: account_tax_balance #: model_terms:ir.ui.view,arch_db:account_tax_balance.view_account_move_filter @@ -174,31 +174,31 @@ msgstr "Ver Impuestos" #: code:addons/account_tax_balance/models/account_move.py:0 #, python-format msgid "Other" -msgstr "" +msgstr "Otro" #. module: account_tax_balance #: code:addons/account_tax_balance/models/account_move.py:0 #, python-format msgid "Payable" -msgstr "" +msgstr "Pagadero" #. module: account_tax_balance #: code:addons/account_tax_balance/models/account_move.py:0 #, python-format msgid "Payable refund" -msgstr "" +msgstr "Reembolso a Pagar" #. module: account_tax_balance #: code:addons/account_tax_balance/models/account_move.py:0 #, python-format msgid "Receivable" -msgstr "" +msgstr "A Cobrar" #. module: account_tax_balance #: code:addons/account_tax_balance/models/account_move.py:0 #, python-format msgid "Receivable refund" -msgstr "" +msgstr "Reembolso a Cobrar" #. module: account_tax_balance #: model_terms:ir.ui.view,arch_db:account_tax_balance.view_tax_search_balance diff --git a/partner_statement/COPYRIGHT b/partner_statement/COPYRIGHT new file mode 100644 index 0000000..ec08969 --- /dev/null +++ b/partner_statement/COPYRIGHT @@ -0,0 +1,18 @@ +Most of the files are + + :Copyright: This stylesheet has been placed in the public domain. + +

Beta License: AGPL-3 OCA/account-financial-reporting Translate me on Weblate Try me on Runbot

+

This module extends the functionality of Invoicing to support the printing of customer and vendor statements. +There are two types of statements, Activity and Outstanding. Aging details can be shown in the reports, expressed in aging buckets, +so the customer or vendor can review how much is open, due or overdue.

+

The activity statement provides details of all activity on the partner receivables or payables +between two selected dates. This includes all invoices, refunds and payments. +Any outstanding balance dated prior to the chosen statement period will appear +as a forward balance at the top of the statement. The list is displayed in chronological +order and is split by currencies.

+

The outstanding statement provides details of all outstanding partner receivables or payables +up to a particular date. This includes all unpaid invoices, unclaimed refunds and +outstanding payments. The list is displayed in chronological order and is split by currencies.

+

Table of contents

+ +
+

Configuration

+

Users willing to access to this report should have proper Accounting & Finance rights:

+
    +
  1. Go to Settings / Users and edit your user to add the corresponding access rights as follows.
  2. +
  3. In Application / Accounting & Finance, select Billing or Billing Manager
  4. +
+

To configure this module, you need to:

+
    +
  1. Go to Configuration / Settings
  2. +
  3. Under the Followup Section of Accounting option select either or both of OCA Activity or Outstanding Statement
  4. +
  5. Once selected, you may set default options for the reports.
  6. +
  7. Click Save
  8. +
+

Removing the wizard from menus follows the same process.

+
+
+

Usage

+

To use this module, you need to:

+
    +
  1. Go to a list of Partners, Contacts, Customer or Vendors and select one or more.
  2. +
  3. Press ‘Action > Partner Activity Statement’ or ‘Action > Partner Outstanding Statement’ respectively.
  4. +
  5. Indicate if you want to display receivables or payables, and if you want to display aging buckets and the aging type.
  6. +
  7. Optionally complete advanced options such as filtering non due or negative balance partners.
  8. +
+
+
+

Known issues / Roadmap

+
    +
  • Email template.
  • +
  • Expose reports (using defaults) to billing users while restricting the wizard to managers option.
  • +
  • Concept of statement run - to start an async job to send out all statements.
  • +
+
+
+

Changelog

+
+

12.0.1.0.0 (2018-11-08)

+
    +
  • [BREAKING] Modules customer_activity_statement and customer_outstanding_statement merged to create partner_statement.
  • +
  • [ADD] New features. +* Age by months or days +* Filter negative balances
  • +
+
+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • ForgeFlow
  • +
+
+
+

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-financial-reporting project on GitHub.

+

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

+
+
+ + + diff --git a/partner_statement/static/src/scss/layout_statement.scss b/partner_statement/static/src/scss/layout_statement.scss new file mode 100644 index 0000000..b585182 --- /dev/null +++ b/partner_statement/static/src/scss/layout_statement.scss @@ -0,0 +1,22 @@ +.table-statement { + .amount { + text-align: right !important; + width: 14%; //spread 7 columns evenly + } + thead { + border-bottom: solid; // required for clean layout + tr th:first-child { + width: auto !important; // required for clean layout + } + tr th:last-child { + width: 16% !important; // required for boxed layout + } + } +} + +.statement-blocked { + background-color: $gray-500 !important; + td:last-child { + background-color: $gray-500 !important; + } +} diff --git a/partner_statement/tests/__init__.py b/partner_statement/tests/__init__.py new file mode 100644 index 0000000..6395f9e --- /dev/null +++ b/partner_statement/tests/__init__.py @@ -0,0 +1,3 @@ +from . import test_activity_statement +from . import test_outstanding_statement +from . import test_res_config_settings diff --git a/partner_statement/tests/test_activity_statement.py b/partner_statement/tests/test_activity_statement.py new file mode 100644 index 0000000..a51616c --- /dev/null +++ b/partner_statement/tests/test_activity_statement.py @@ -0,0 +1,114 @@ +# Copyright 2018 ForgeFlow, S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from datetime import date + +from flectra import fields +from flectra.tests.common import TransactionCase + + +class TestActivityStatement(TransactionCase): + """ Tests for Activity Statement.""" + + def setUp(self): + super().setUp() + + self.res_users_model = self.env["res.users"] + self.company = self.env.ref("base.main_company") + self.company.external_report_layout_id = self.env.ref( + "web.external_layout_standard" + ) + self.partner1 = self.env.ref("base.res_partner_1") + self.partner2 = self.env.ref("base.res_partner_2") + self.g_account_user = self.env.ref("account.group_account_user") + + self.user = self._create_user("user_1", [self.g_account_user], self.company).id + + self.statement_model = self.env["report.partner_statement.activity_statement"] + self.wiz = self.env["activity.statement.wizard"] + self.report_name = "partner_statement.activity_statement" + self.report_title = "Activity Statement" + self.today = fields.Date.context_today(self.wiz) + + def _create_user(self, login, groups, company): + group_ids = [group.id for group in groups] + user = self.res_users_model.create( + { + "name": login, + "login": login, + "email": "example@yourcompany.com", + "company_id": company.id, + "company_ids": [(4, company.id)], + "groups_id": [(6, 0, group_ids)], + } + ) + return user + + def test_customer_activity_statement(self): + + wiz_id = self.wiz.with_context( + active_ids=[self.partner1.id, self.partner2.id] + ).create({}) + + wiz_id.aging_type = "months" + wiz_id.show_aging_buckets = False + + statement = wiz_id.button_export_pdf() + + self.assertDictContainsSubset( + { + "type": "ir.actions.report", + "report_name": self.report_name, + "report_type": "qweb-pdf", + }, + statement, + "There was an error and the PDF report was not generated.", + ) + + data = wiz_id._prepare_statement() + docids = data["partner_ids"] + report = self.statement_model._get_report_values(docids, data) + self.assertIsInstance( + report, dict, "There was an error while compiling the report." + ) + self.assertIn( + "bucket_labels", report, "There was an error while compiling the report." + ) + + def test_customer_activity_report_no_wizard(self): + docids = [self.partner1.id, self.partner2.id] + report = self.statement_model._get_report_values(docids, False) + self.assertIsInstance( + report, dict, "There was an error while compiling the report." + ) + self.assertIn( + "bucket_labels", report, "There was an error while compiling the report." + ) + + def test_date_formatting(self): + date_fmt = "%d/%m/%Y" + test_date = date(2018, 9, 30) + res = self.statement_model._format_date_to_partner_lang(test_date, date_fmt) + self.assertEqual(res, "30/09/2018") + + test_date_string = "2018-09-30" + res = self.statement_model._format_date_to_partner_lang( + test_date_string, date_fmt + ) + self.assertEqual(res, "30/09/2018") + + def test_onchange_aging_type(self): + """Test that partner data is filled accordingly""" + wiz_id = self.wiz.with_context( + active_ids=[self.partner1.id, self.partner2.id] + ).new() + wiz_id.aging_type = "months" + wiz_id.onchange_aging_type() + self.assertEqual(wiz_id.date_end.month, wiz_id.date_start.month) + self.assertTrue(wiz_id.date_end.day > wiz_id.date_start.day) + self.assertTrue(wiz_id.date_end < self.today) + + wiz_id.aging_type = "days" + wiz_id.onchange_aging_type() + self.assertEqual((wiz_id.date_end - wiz_id.date_start).days, 30) + self.assertTrue(wiz_id.date_end == self.today) diff --git a/partner_statement/tests/test_outstanding_statement.py b/partner_statement/tests/test_outstanding_statement.py new file mode 100644 index 0000000..11c6cc1 --- /dev/null +++ b/partner_statement/tests/test_outstanding_statement.py @@ -0,0 +1,82 @@ +# Copyright 2018 ForgeFlow, S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from flectra.tests.common import TransactionCase + + +class TestOutstandingStatement(TransactionCase): + """ Tests for Outstanding Statement.""" + + def setUp(self): + super().setUp() + + self.res_users_model = self.env["res.users"] + self.company = self.env.ref("base.main_company") + self.company.external_report_layout_id = self.env.ref( + "web.external_layout_standard" + ) + self.partner1 = self.env.ref("base.res_partner_2") + self.partner2 = self.env.ref("base.res_partner_3") + self.g_account_user = self.env.ref("account.group_account_user") + + self.user = self._create_user("user_1", [self.g_account_user], self.company).id + + self.statement_model = self.env[ + "report.partner_statement.outstanding_statement" + ] + self.wiz = self.env["outstanding.statement.wizard"] + self.report_name = "partner_statement.outstanding_statement" + self.report_title = "Outstanding Statement" + + def _create_user(self, login, groups, company): + group_ids = [group.id for group in groups] + user = self.res_users_model.create( + { + "name": login, + "login": login, + "email": "example@yourcompany.com", + "company_id": company.id, + "company_ids": [(4, company.id)], + "groups_id": [(6, 0, group_ids)], + } + ) + return user + + def test_customer_outstanding_statement(self): + + wiz_id = self.wiz.with_context( + active_ids=[self.partner1.id, self.partner2.id] + ).create({}) + wiz_id.aging_type = "months" + + statement = wiz_id.button_export_pdf() + + self.assertDictContainsSubset( + { + "type": "ir.actions.report", + "report_name": self.report_name, + "report_type": "qweb-pdf", + }, + statement, + "There was an error and the PDF report was not generated.", + ) + + data = wiz_id._prepare_statement() + docids = data["partner_ids"] + report = self.statement_model._get_report_values(docids, data) + self.assertIsInstance( + report, dict, "There was an error while compiling the report." + ) + self.assertIn( + "bucket_labels", report, "There was an error while compiling the report." + ) + + def test_customer_outstanding_report_no_wizard(self): + docids = [self.partner1.id] + report = self.statement_model._get_report_values(docids, False) + self.assertIsInstance( + report, dict, "There was an error while compiling the report." + ) + self.assertIn( + "bucket_labels", report, "There was an error while compiling the report." + ) diff --git a/partner_statement/tests/test_res_config_settings.py b/partner_statement/tests/test_res_config_settings.py new file mode 100644 index 0000000..e5169f9 --- /dev/null +++ b/partner_statement/tests/test_res_config_settings.py @@ -0,0 +1,35 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from flectra.tests.common import TransactionCase + + +class TestResConfigSettings(TransactionCase): + def setUp(self): + super().setUp() + self.config = self.env["res.config.settings"] + self.cr.execute( + "SELECT uid FROM res_groups_users_rel " + "WHERE gid IN (SELECT res_id FROM ir_model_data " + " WHERE module='account' AND name='group_account_invoice') " + "ORDER BY uid DESC LIMIT 1" + ) + self.account_user = self.cr.fetchone()[0] + self.user_obj = self.env["res.users"].with_user(self.account_user) + + def test_groups(self): + conf = self.config.create( + { + "default_aging_type": "months", + "group_activity_statement": True, + "group_outstanding_statement": False, + } + ) + conf.set_values() + self.assertFalse( + self.user_obj._has_group("partner_statement.group_outstanding_statement") + ) + self.assertTrue( + self.user_obj._has_group("partner_statement.group_activity_statement") + ) + res = self.env["ir.default"].get("activity.statement.wizard", "aging_type") + self.assertEqual(res, "months") diff --git a/partner_statement/views/activity_statement.xml b/partner_statement/views/activity_statement.xml new file mode 100644 index 0000000..a4974e9 --- /dev/null +++ b/partner_statement/views/activity_statement.xml @@ -0,0 +1,171 @@ + + + + + + + Activity Statement + res.partner + partner_statement.activity_statement + qweb-pdf + partner_statement.activity_statement + + diff --git a/partner_statement/views/aging_buckets.xml b/partner_statement/views/aging_buckets.xml new file mode 100644 index 0000000..b7e47c7 --- /dev/null +++ b/partner_statement/views/aging_buckets.xml @@ -0,0 +1,70 @@ + + + + + diff --git a/partner_statement/views/assets.xml b/partner_statement/views/assets.xml new file mode 100644 index 0000000..963c09e --- /dev/null +++ b/partner_statement/views/assets.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/partner_statement/views/outstanding_statement.xml b/partner_statement/views/outstanding_statement.xml new file mode 100644 index 0000000..a3e63bd --- /dev/null +++ b/partner_statement/views/outstanding_statement.xml @@ -0,0 +1,167 @@ + + + + + + + Outstanding Statement + res.partner + partner_statement.outstanding_statement + qweb-pdf + partner_statement.outstanding_statement + + diff --git a/partner_statement/views/res_config_settings.xml b/partner_statement/views/res_config_settings.xml new file mode 100644 index 0000000..c3913ea --- /dev/null +++ b/partner_statement/views/res_config_settings.xml @@ -0,0 +1,86 @@ + + + + res.config.settings.view.form (in partner_statement) + res.config.settings + + + + +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
diff --git a/partner_statement/wizard/__init__.py b/partner_statement/wizard/__init__.py new file mode 100644 index 0000000..984e2b5 --- /dev/null +++ b/partner_statement/wizard/__init__.py @@ -0,0 +1,4 @@ +from . import statement_common +from . import activity_statement_wizard +from . import outstanding_statement_wizard +from . import res_config_settings diff --git a/partner_statement/wizard/activity_statement_wizard.py b/partner_statement/wizard/activity_statement_wizard.py new file mode 100644 index 0000000..99e7648 --- /dev/null +++ b/partner_statement/wizard/activity_statement_wizard.py @@ -0,0 +1,42 @@ +# Copyright 2018 ForgeFlow, S.L. (http://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from dateutil.relativedelta import relativedelta + +from flectra import api, fields, models + + +class ActivityStatementWizard(models.TransientModel): + """Activity Statement wizard.""" + + _inherit = "statement.common.wizard" + _name = "activity.statement.wizard" + _description = "Activity Statement Wizard" + + @api.model + def _get_date_start(self): + return ( + fields.Date.context_today(self).replace(day=1) - relativedelta(days=1) + ).replace(day=1) + + date_start = fields.Date(required=True, default=_get_date_start) + + @api.onchange("aging_type") + def onchange_aging_type(self): + super().onchange_aging_type() + if self.aging_type == "months": + self.date_start = self.date_end.replace(day=1) + else: + self.date_start = self.date_end - relativedelta(days=30) + + def _export(self): + """Export to PDF.""" + data = self._prepare_statement() + return self.env.ref( + "partner_statement.action_print_activity_statement" + ).report_action(self.ids, data=data) + + def _prepare_statement(self): + res = super()._prepare_statement() + res.update({"date_start": self.date_start}) + return res diff --git a/partner_statement/wizard/outstanding_statement_wizard.py b/partner_statement/wizard/outstanding_statement_wizard.py new file mode 100644 index 0000000..b5ad8bd --- /dev/null +++ b/partner_statement/wizard/outstanding_statement_wizard.py @@ -0,0 +1,19 @@ +# Copyright 2018 ForgeFlow, S.L. (http://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from flectra import models + + +class OutstandingStatementWizard(models.TransientModel): + """Outstanding Statement wizard.""" + + _name = "outstanding.statement.wizard" + _inherit = "statement.common.wizard" + _description = "Outstanding Statement Wizard" + + def _export(self): + """Export to PDF.""" + data = self._prepare_statement() + return self.env.ref( + "partner_statement.action_print_outstanding_statement" + ).report_action(self.ids, data=data) diff --git a/partner_statement/wizard/res_config_settings.py b/partner_statement/wizard/res_config_settings.py new file mode 100644 index 0000000..aea4f6a --- /dev/null +++ b/partner_statement/wizard/res_config_settings.py @@ -0,0 +1,58 @@ +from flectra import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + group_activity_statement = fields.Boolean( + "Enable OCA Activity Statements", + group="account.group_account_invoice", + implied_group="partner_statement.group_activity_statement", + ) + + default_aging_type = fields.Selection( + [("days", "Age by Days"), ("months", "Age by Months")], + string="Aging Method", + required=True, + default="days", + default_model="statement.common.wizard", + ) + + default_show_aging_buckets = fields.Boolean( + string="Show Aging Buckets", default_model="statement.common.wizard" + ) + + default_filter_partners_non_due = fields.Boolean( + string="Exclude partners with no due entries", + default_model="statement.common.wizard", + ) + + default_filter_negative_balances = fields.Boolean( + "Exclude Negative Balances", default_model="statement.common.wizard" + ) + + group_outstanding_statement = fields.Boolean( + "Enable OCA Outstanding Statements", + group="account.group_account_invoice", + implied_group="partner_statement.group_outstanding_statement", + ) + + def set_values(self): + self = self.with_context(active_test=False) + # default values fields + IrDefault = self.env["ir.default"].sudo() + for name, field in self._fields.items(): + if ( + name.startswith("default_") + and field.default_model == "statement.common.wizard" + ): + if isinstance(self[name], models.BaseModel): + if self._fields[name].type == "many2one": + value = self[name].id + else: + value = self[name].ids + else: + value = self[name] + IrDefault.set("activity.statement.wizard", name[8:], value) + IrDefault.set("outstanding.statement.wizard", name[8:], value) + return super().set_values() diff --git a/partner_statement/wizard/statement_common.py b/partner_statement/wizard/statement_common.py new file mode 100644 index 0000000..4cb60a6 --- /dev/null +++ b/partner_statement/wizard/statement_common.py @@ -0,0 +1,71 @@ +# Copyright 2018 Graeme Gellatly +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from dateutil.relativedelta import relativedelta + +from flectra import api, fields, models + + +class StatementCommon(models.AbstractModel): + + _name = "statement.common.wizard" + _description = "Statement Reports Common Wizard" + + name = fields.Char() + company_id = fields.Many2one( + comodel_name="res.company", + default=lambda self: self.env.company, + string="Company", + required=True, + ) + date_end = fields.Date(required=True, default=fields.Date.context_today) + show_aging_buckets = fields.Boolean(default=True) + number_partner_ids = fields.Integer( + default=lambda self: len(self._context["active_ids"]) + ) + filter_partners_non_due = fields.Boolean( + string="Don't show partners with no due entries", default=True + ) + filter_negative_balances = fields.Boolean("Exclude Negative Balances", default=True) + + aging_type = fields.Selection( + [("days", "Age by Days"), ("months", "Age by Months")], + string="Aging Method", + default="days", + required=True, + ) + + account_type = fields.Selection( + [("receivable", "Receivable"), ("payable", "Payable")], + string="Account type", + default="receivable", + ) + + @api.onchange("aging_type") + def onchange_aging_type(self): + if self.aging_type == "months": + self.date_end = fields.Date.context_today(self).replace( + day=1 + ) - relativedelta(days=1) + else: + self.date_end = fields.Date.context_today(self) + + def button_export_pdf(self): + self.ensure_one() + return self._export() + + def _prepare_statement(self): + self.ensure_one() + return { + "date_end": self.date_end, + "company_id": self.company_id.id, + "partner_ids": self._context["active_ids"], + "show_aging_buckets": self.show_aging_buckets, + "filter_non_due_partners": self.filter_partners_non_due, + "account_type": self.account_type, + "aging_type": self.aging_type, + "filter_negative_balances": self.filter_negative_balances, + } + + def _export(self): + raise NotImplementedError diff --git a/partner_statement/wizard/statement_wizard.xml b/partner_statement/wizard/statement_wizard.xml new file mode 100644 index 0000000..5e57e0b --- /dev/null +++ b/partner_statement/wizard/statement_wizard.xml @@ -0,0 +1,129 @@ + + + + + + Partner Activity Statement + + activity.statement.wizard + form + + new + + + Partner Outstanding Statement + + outstanding.statement.wizard + form + + new + + + + Statement Common Wizard View + statement.common.wizard + +
+
+ Aging details can be shown in the report, expressed in aging + buckets, so the partner can review how much is open, due or overdue. + +
+
+ + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + Outstanding Statement Wizard + outstanding.statement.wizard + + primary + + + The outstanding statement provides details of all partner's outstanding + receivables and payables up to a particular date. This includes all unpaid invoices, unclaimed + refunds and outstanding payments. The list is displayed in chronological order and is + split by currencies. + +
+
+
+
+
+ + Activity Statement Wizard + activity.statement.wizard + + primary + + + The activity statement provides details of all activity on + a partner's receivables and payables between two selected dates. This includes all invoices, + refunds and payments. Any outstanding balance dated prior to the chosen statement + period will appear as a forward balance at the top of the statement. The list is + displayed in chronological order and is split by currencies. + +
+
+
+ + + +
+
+
diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7d41f1b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +# generated from manifests external_dependencies +python-dateutil