diff --git a/.gitignore b/.gitignore index 7db909f..ef4d893 100644 --- a/.gitignore +++ b/.gitignore @@ -132,7 +132,4 @@ dmypy.json .pyre/ tmp/ -.claude/ -.vscode/ -.github -CLAUDE.md +.claude/settings.json diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b49667d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,91 @@ +# Kidekoop — Odoo 18.0 Custom Addons + +Odoo 18.0 (OCB community) addons repo. Code in **English**. + +## ⚠️ Critical rules (non-negotiable) + +- **DO NOT modify** the OCB core (`ocb/`) nor these original OCA addons (reference/inheritance only): + `product_main_seller`, `account_invoice_triple_discount`, `product_get_price_helper`, + `product_price_category`, `purchase_triple_discount`, `base_bank_from_iban`, `l10n_es_partner`. + All changes go in our own custom addons. +- **Do NOT use `_()` in field definitions** (triggers import-time warnings). Only in methods/executable code. +- **Business logic ALWAYS on `product.product`** (variants), never on `product.template` (use `related` there). + Avoids issues with pricelists and reports that operate at the variant level. +- **No logic in QWeb**: prepare all data in the Python controller; templates only do simple attribute access. +- **No business logic in JavaScript**: UI/events only. +- Translations: edit `.po` files with `polib` (append). **`msgmerge` corrupts the files** — do not use it. + +## Stack + +Odoo 18.0 · Python 3.10+ · PostgreSQL · Docker Compose · XML/QWeb/JS. +Formatting: `black` (line 88) + `isort` (black profile) + `flake8` + `pylint-odoo`. Pre-commit active. + +## Commands + +```bash +docker-compose up -d # env (8070=web, 8073=longpolling) +docker-compose run odoo odoo -d odoo --test-enable --stop-after-init -u # tests (run, NOT exec: avoids cache) +docker-compose exec odoo odoo -d odoo -u --stop-after-init # update addon +docker-compose logs -f odoo # logs +docker-compose exec db psql -U odoo -d odoo # postgres +make lint | make format | make check-format | make flake8 | make pylint-required +pre-commit run --all-files +``` + +## Odoo conventions + +- Models `snake.case` · classes `PascalCase` · files `snake_case.py` · XML IDs `module.name`. +- Manifest always `__manifest__.py`, version `18.0.X.Y.Z`, `depends` alphabetically ordered. +- Views: 4 spaces, explicit `position` in XPath, groups via `module.xml_id`, `sequence` for ordering. +- Bulk: prefer `search().write()` over loops; `create([vals, ...])` for bulk create. +- Notifications: `ir.actions.client` + `display_notification`. +- Detailed logging in price/discount computations: `_logger.info("[PRICE] ...", ...)`. + +## Custom addons + +Pricing & products: + +- `product_sale_price_from_pricelist` — auto-computes sale price from last purchase price + pricelist. + Requires taxes on the product and `last_purchase_price_compute_type != "manual_update"`. + Also applies supplier discounts from `supplierinfo`. +- `product_pricelist_total_margin` — total margin computed additively (Markup or Commercial Margin), with global limits. +- `product_price_category_supplier` — price categories per supplier. +- `product_origin_char` — free-text origin field per product (template-based). +- `account_invoice_triple_discount_readonly` — fix for triple-discount accumulation bug (always use it). + +Sales & website: + +- `website_sale_aplicoop` — Eskaera: collaborative purchasing for consumer co-ops (group orders, + per-member carts, cutoff/pickup dates, lazy loading, multi-language). +- `website_sale_disable_cart` — turns `/shop` into a read-only catalog: hides the cart UI and + redirects the standard `/shop/cart*` routes to a configurable URL (default `/shop`). +- `portal_event_registration` — portal users view their event registrations + upload attachments to chatter. + +Membership: + +- `membership_monthly_invoicing` — auto-creates a monthly membership invoice per active member (cron-driven). +- `membership_expiry_reminder` — automated renewal-reminder emails near expiry, with online renew link. + +Logistics & accounting: + +- `stock_picking_batch_custom` — batch picking extras: extra detailed-op columns, ordering by + category/product/partner, and a full-screen operator (Basket Assembly) view. +- `account_banking_mandate_batch` — contextual action to bulk-create/validate SEPA mandates for selected partners. +- `l10n_es_edi_tbai_reagyp_recibidas` — TicketBAI fix: REAGYP vendor-bill regime key 19 → 02. + +## Documentation + +- Per-addon details: its `README.rst` (OCA) or `README_DEV.md` (technical). +- Global patterns: `.github/copilot-instructions.md` (extended version of this file). +- Guides: `docs/QWEB_BEST_PRACTICES.md`, `docs/OCA_DOCUMENTATION.md`, `docs/LAZY_LOADING.md`. +- OCA `readme/` structure (DESCRIPTION, INSTALL, CONFIGURE, USAGE, CONTRIBUTORS, CREDITS). + Credits: Criptomart (author). + +## Commits + +`[TAG] module: description` — tags: `[ADD] [FIX] [IMP] [REF] [REM] [I18N] [DOC]`. + +## Available skills + +Per-language skills (`odoo-python`, `odoo-xml-views`, `odoo-qweb-html`, `odoo-javascript`) and the +OpenSpec workflow (`openspec-explore/propose/apply-change/archive-change`, `/opsx:*` commands) live in `.claude/`. diff --git a/pos_payment_method_cashdro_fix/README.rst b/pos_payment_method_cashdro_fix/README.rst deleted file mode 100644 index 9854e0a..0000000 --- a/pos_payment_method_cashdro_fix/README.rst +++ /dev/null @@ -1,86 +0,0 @@ -====================== -POS CashDro 18.0 Fixes -====================== - -.. |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 - -|badge1| |badge2| - -The 18.0 migration of ``pos_payment_method_cashdro`` -(`OCA/pos@6a4c251d `_) left three -uses of the 17.0 API that stop the CashDro integration from working. The module -has no tests nor tours and needs a physical drawer to be exercised, so nothing -in the OCA CI catches them. - -This module patches the three of them from the outside, without touching the -OCA sources: - -#. ``_cashdro_url()`` reads ``order.selected_paymentline``, replaced in 18.0 by - ``order.get_selected_paymentline()``. Reading ``.payment_method`` on the - resulting ``undefined`` raises a ``TypeError`` on every payment, which the - caller swallows into a generic *"An error occurred while connecting to the - cashdro"* message. -#. The ``add_paymentline`` patch checks ``line.payment_method``, renamed to - ``line.payment_method_id`` in 18.0. The condition is never true, so the - payment line keeps the default due amount instead of waiting for the amount - the customer inserts in the drawer. -#. ``pos.session._loader_params_pos_payment_method`` is the 17.0 loading API, - replaced in 18.0 by ``_load_pos_data_fields`` on each model. The override is - dead code, so ``cashdro_host``, ``cashdro_user`` and ``cashdro_password`` - never reach the front end. - -**Table of contents** - -.. contents:: - :local: - -Usage -===== - -There is nothing to configure: installing the module is enough. - -To check the three fixes on a PoS with a CashDro terminal: - -#. Open a PoS session, add a product and go to the payment screen. -#. Select the CashDro payment method. The payment line must show **0**, not the - due amount (fix 2). -#. The drawer must start the operation and ask for the amount, instead of the - *"An error occurred while connecting to the cashdro"* dialog (fixes 1 and 3). -#. With no CashDro at hand, the browser console tells fix 1 from fix 3 apart: - without this module the failure is a ``TypeError: Cannot read properties of - undefined (reading 'payment_method')``; with it, a network error against the - configured host. - -The Python side is covered by the tests. The base module lives outside this -repo, so the OCA sources have to be on the addons path (see -``docker-compose.override.yml``, which is local and untracked):: - - docker-compose run --rm odoo odoo -c /etc/odoo/odoo.conf \ - --addons-path=/mnt/extra-addons,/mnt/oca/pos,/usr/lib/python3/dist-packages/odoo/addons \ - -d odoo -u pos_payment_method_cashdro_fix --test-enable --stop-after-init - -Known issues / Roadmap -====================== - -This module is meant to be temporary. The fixes are proposed upstream in -``upstream/pos_payment_method_cashdro-18.0-fixes.patch``; once they are merged -in ``OCA/pos`` this module can be uninstalled and removed. - -It is written to stay harmless in the meantime: the Python override only adds -the credential fields that are missing from the loader, and the JavaScript -patches are idempotent with respect to the fixed upstream code. - -The JavaScript side can't be covered by automated tests, as it needs a CashDro -terminal answering on the network. - -Contributors -============ - -* `Criptomart `_: - - * Criptomart diff --git a/pos_payment_method_cashdro_fix/__init__.py b/pos_payment_method_cashdro_fix/__init__.py deleted file mode 100644 index 8f9e965..0000000 --- a/pos_payment_method_cashdro_fix/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright 2026 - Today Criptomart -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from . import models diff --git a/pos_payment_method_cashdro_fix/__manifest__.py b/pos_payment_method_cashdro_fix/__manifest__.py deleted file mode 100644 index bbe4598..0000000 --- a/pos_payment_method_cashdro_fix/__manifest__.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2026 - Today Criptomart -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -{ - "name": "POS CashDro 18.0 Fixes", - "version": "18.0.1.0.0", - "summary": "Fix the 17.0 API leftovers that break pos_payment_method_cashdro on 18.0", - "category": "Point of Sale", - "license": "AGPL-3", - "author": "Criptomart", - "maintainers": ["Criptomart"], - "website": "https://git.criptomart.net/criptomart/addons-cm", - "depends": [ - "point_of_sale", - "pos_payment_method_cashdro", - ], - "assets": { - "point_of_sale._assets_pos": [ - "pos_payment_method_cashdro_fix/static/src/js/payment_cashdro_fix.esm.js", - "pos_payment_method_cashdro_fix/static/src/js/models_fix.esm.js", - ], - }, - "installable": True, -} diff --git a/pos_payment_method_cashdro_fix/models/__init__.py b/pos_payment_method_cashdro_fix/models/__init__.py deleted file mode 100644 index 58690ef..0000000 --- a/pos_payment_method_cashdro_fix/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import pos_payment_method diff --git a/pos_payment_method_cashdro_fix/models/pos_payment_method.py b/pos_payment_method_cashdro_fix/models/pos_payment_method.py deleted file mode 100644 index 8ec6d8d..0000000 --- a/pos_payment_method_cashdro_fix/models/pos_payment_method.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2026 - Today Criptomart -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api -from odoo import models - -CASHDRO_FIELDS = ["cashdro_host", "cashdro_user", "cashdro_password"] - - -class PosPaymentMethod(models.Model): - _inherit = "pos.payment.method" - - @api.model - def _load_pos_data_fields(self, config_id): - """Send the CashDro credentials to the PoS front end. - - `pos_payment_method_cashdro` still declares them through - `_loader_params_pos_payment_method`, the 17.0 loading API, which 18.0 - replaced by this method. That override is dead code, so the front end - never receives the host and can't build the CashDro url. - - Only the missing fields are added, so this module stays harmless once - the base one is fixed upstream. - """ - fields = super()._load_pos_data_fields(config_id) - fields.extend(field for field in CASHDRO_FIELDS if field not in fields) - return fields diff --git a/pos_payment_method_cashdro_fix/readme/CONTRIBUTORS.rst b/pos_payment_method_cashdro_fix/readme/CONTRIBUTORS.rst deleted file mode 100644 index 16df929..0000000 --- a/pos_payment_method_cashdro_fix/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,3 +0,0 @@ -* `Criptomart `_: - - * Criptomart diff --git a/pos_payment_method_cashdro_fix/readme/DESCRIPTION.rst b/pos_payment_method_cashdro_fix/readme/DESCRIPTION.rst deleted file mode 100644 index c5f2de1..0000000 --- a/pos_payment_method_cashdro_fix/readme/DESCRIPTION.rst +++ /dev/null @@ -1,22 +0,0 @@ -The 18.0 migration of ``pos_payment_method_cashdro`` -(`OCA/pos@6a4c251d `_) left three -uses of the 17.0 API that stop the CashDro integration from working. The module -has no tests nor tours and needs a physical drawer to be exercised, so nothing -in the OCA CI catches them. - -This module patches the three of them from the outside, without touching the -OCA sources: - -#. ``_cashdro_url()`` reads ``order.selected_paymentline``, replaced in 18.0 by - ``order.get_selected_paymentline()``. Reading ``.payment_method`` on the - resulting ``undefined`` raises a ``TypeError`` on every payment, which the - caller swallows into a generic *"An error occurred while connecting to the - cashdro"* message. -#. The ``add_paymentline`` patch checks ``line.payment_method``, renamed to - ``line.payment_method_id`` in 18.0. The condition is never true, so the - payment line keeps the default due amount instead of waiting for the amount - the customer inserts in the drawer. -#. ``pos.session._loader_params_pos_payment_method`` is the 17.0 loading API, - replaced in 18.0 by ``_load_pos_data_fields`` on each model. The override is - dead code, so ``cashdro_host``, ``cashdro_user`` and ``cashdro_password`` - never reach the front end. diff --git a/pos_payment_method_cashdro_fix/readme/ROADMAP.rst b/pos_payment_method_cashdro_fix/readme/ROADMAP.rst deleted file mode 100644 index bab1608..0000000 --- a/pos_payment_method_cashdro_fix/readme/ROADMAP.rst +++ /dev/null @@ -1,10 +0,0 @@ -This module is meant to be temporary. The fixes are proposed upstream in -``upstream/pos_payment_method_cashdro-18.0-fixes.patch``; once they are merged -in ``OCA/pos`` this module can be uninstalled and removed. - -It is written to stay harmless in the meantime: the Python override only adds -the credential fields that are missing from the loader, and the JavaScript -patches are idempotent with respect to the fixed upstream code. - -The JavaScript side can't be covered by automated tests, as it needs a CashDro -terminal answering on the network. See ``USAGE`` for the manual check. diff --git a/pos_payment_method_cashdro_fix/readme/USAGE.rst b/pos_payment_method_cashdro_fix/readme/USAGE.rst deleted file mode 100644 index 6499224..0000000 --- a/pos_payment_method_cashdro_fix/readme/USAGE.rst +++ /dev/null @@ -1,21 +0,0 @@ -There is nothing to configure: installing the module is enough. - -To check the three fixes on a PoS with a CashDro terminal: - -#. Open a PoS session, add a product and go to the payment screen. -#. Select the CashDro payment method. The payment line must show **0**, not the - due amount (fix 2). -#. The drawer must start the operation and ask for the amount, instead of the - *"An error occurred while connecting to the cashdro"* dialog (fixes 1 and 3). -#. With no CashDro at hand, the browser console tells fix 1 from fix 3 apart: - without this module the failure is a ``TypeError: Cannot read properties of - undefined (reading 'payment_method')``; with it, a network error against the - configured host. - -The Python side is covered by the tests. The base module lives outside this -repo, so the OCA sources have to be on the addons path (see -``docker-compose.override.yml``, which is local and untracked):: - - docker-compose run --rm odoo odoo -c /etc/odoo/odoo.conf \ - --addons-path=/mnt/extra-addons,/mnt/oca/pos,/usr/lib/python3/dist-packages/odoo/addons \ - -d odoo -u pos_payment_method_cashdro_fix --test-enable --stop-after-init diff --git a/pos_payment_method_cashdro_fix/static/src/js/models_fix.esm.js b/pos_payment_method_cashdro_fix/static/src/js/models_fix.esm.js deleted file mode 100644 index 51598ff..0000000 --- a/pos_payment_method_cashdro_fix/static/src/js/models_fix.esm.js +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright 2026 - Today Criptomart - License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - - The `add_paymentline` patch of `pos_payment_method_cashdro` checks - `line.payment_method`, renamed to `payment_method_id` in 18.0, so the - condition is never met and the line keeps the default due amount instead of - waiting for the amount the customer actually inserts in the drawer. -*/ - -import { PosOrder } from "@point_of_sale/app/models/pos_order"; -import { patch } from "@web/core/utils/patch"; - -patch(PosOrder.prototype, { - /** - * @override - * Set the amount to 0 as it's going to be filled by the Cashdro response. - */ - add_paymentline() { - const line = super.add_paymentline(...arguments); - if (!line) { - return line; - } - if ( - line.payment_method_id?.use_payment_terminal === "cashdro" && - line.amount > 0 // For refund transactions we need to keep the amount - ) { - line.set_amount(0); - } - return line; - }, -}); diff --git a/pos_payment_method_cashdro_fix/static/src/js/payment_cashdro_fix.esm.js b/pos_payment_method_cashdro_fix/static/src/js/payment_cashdro_fix.esm.js deleted file mode 100644 index 3410747..0000000 --- a/pos_payment_method_cashdro_fix/static/src/js/payment_cashdro_fix.esm.js +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2026 - Today Criptomart - License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - - `_cashdro_url` was left with the 17.0 API in the 18.0 migration of - `pos_payment_method_cashdro`: `order.selected_paymentline` no longer exists, - so reading `.payment_method` on it throws a TypeError that the caller - swallows as a generic connection error. Rewritten with the 18.0 accessors. -*/ - -import { PaymentCashdro } from "@pos_payment_method_cashdro/js/payment_cashdro.esm"; -import { patch } from "@web/core/utils/patch"; - -patch(PaymentCashdro.prototype, { - /** - * @override - * The whole body has to be replaced: the very first statement is the one - * that breaks, so there is nothing left to delegate to `super`. - */ - _cashdro_url() { - // Cashdro machines don't support safe POST calls, so we're sending - // all the data quite unsafely constantly... - const order = this.pos.get_order(); - const method = order.get_selected_paymentline()?.payment_method_id; - const host = method && method.cashdro_host; - if (!host) { - return false; - } - let url = `${host}/Cashdro3WS/index.php`; - url += `?name=${method.cashdro_user}`; - url += `&password=${method.cashdro_password}`; - return url; - }, -}); diff --git a/pos_payment_method_cashdro_fix/tests/__init__.py b/pos_payment_method_cashdro_fix/tests/__init__.py deleted file mode 100644 index 02c4d2e..0000000 --- a/pos_payment_method_cashdro_fix/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import test_load_pos_data_fields diff --git a/pos_payment_method_cashdro_fix/tests/test_load_pos_data_fields.py b/pos_payment_method_cashdro_fix/tests/test_load_pos_data_fields.py deleted file mode 100644 index ebee5e4..0000000 --- a/pos_payment_method_cashdro_fix/tests/test_load_pos_data_fields.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2026 - Today Criptomart -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo.tests import tagged -from odoo.tests.common import TransactionCase - -from ..models.pos_payment_method import CASHDRO_FIELDS - - -@tagged("post_install", "-at_install") -class TestLoadPosDataFields(TransactionCase): - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.payment_method = cls.env["pos.payment.method"] - # Nothing dereferences it, but we pass a real config when there's one - cls.config_id = cls.env["pos.config"].search([], limit=1).id - - def test_cashdro_credentials_are_loaded(self): - """The front end can't build the CashDro url without them.""" - fields = self.payment_method._load_pos_data_fields(self.config_id) - for field in CASHDRO_FIELDS: - self.assertIn(field, fields) - - def test_no_duplicated_fields(self): - """Once the base module is fixed upstream we must not add them twice.""" - fields = self.payment_method._load_pos_data_fields(self.config_id) - self.assertEqual(sorted(fields), sorted(set(fields))) - - def test_fields_exist_on_the_model(self): - """Guard against a rename of the credentials in the base module.""" - for field in CASHDRO_FIELDS: - self.assertIn(field, self.payment_method._fields) diff --git a/pos_payment_method_cashdro_fix/upstream/pos_payment_method_cashdro-18.0-fixes.patch b/pos_payment_method_cashdro_fix/upstream/pos_payment_method_cashdro-18.0-fixes.patch deleted file mode 100644 index 84ca58f..0000000 --- a/pos_payment_method_cashdro_fix/upstream/pos_payment_method_cashdro-18.0-fixes.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 11c65e8000282b9a761346f1fbff16e09581fc17 Mon Sep 17 00:00:00 2001 -From: Criptomart -Date: Tue, 11 Aug 2026 13:21:28 +0200 -Subject: [PATCH] [FIX] pos_payment_method_cashdro: leftovers of the 17.0 API - -The 18.0 migration kept three uses of APIs that no longer exist, and the -module has neither tests nor tours (it needs a physical drawer), so the CI -can't catch them. - -* `_cashdro_url()` reads `order.selected_paymentline`, replaced by - `order.get_selected_paymentline()` in 18.0. Reading `.payment_method` on - the resulting `undefined` throws a TypeError on every payment, which - `cashdro_send_payment_request()` swallows into a generic "An error occurred - while connecting to the cashdro" dialog. - -* The `add_paymentline()` patch checks `line.payment_method`, renamed to - `line.payment_method_id` in 18.0, so the payment line is never zeroed and - keeps the default due amount instead of the amount the customer inserts. - -* `_loader_params_pos_payment_method()` is the 17.0 loading API, replaced in - 18.0 by `_load_pos_data_fields()` on each model. The override is dead code - and the CashDro credentials never reach the front end, so `_cashdro_url()` - has no host to build the url with. ---- - pos_payment_method_cashdro/__manifest__.py | 2 +- - pos_payment_method_cashdro/models/__init__.py | 1 - - .../models/pos_payment_method.py | 11 ++++++++++- - pos_payment_method_cashdro/models/pos_session.py | 14 -------------- - .../static/src/js/models.esm.js | 4 ++-- - .../static/src/js/payment_cashdro.esm.js | 3 ++- - 6 files changed, 15 insertions(+), 20 deletions(-) - delete mode 100644 pos_payment_method_cashdro/models/pos_session.py - -diff --git a/pos_payment_method_cashdro/__manifest__.py b/pos_payment_method_cashdro/__manifest__.py -index 708aac5..c19a642 100644 ---- a/pos_payment_method_cashdro/__manifest__.py -+++ b/pos_payment_method_cashdro/__manifest__.py -@@ -3,7 +3,7 @@ - { - "name": "PoS Payment Method CashDro", - "summary": "Allows to pay with CashDro Terminals on the Point of Sale", -- "version": "18.0.1.0.2", -+ "version": "18.0.1.0.3", - "category": "Point Of Sale", - "website": "https://github.com/OCA/pos", - "author": "Tecnativa, Odoo Community Association (OCA)", -diff --git a/pos_payment_method_cashdro/models/__init__.py b/pos_payment_method_cashdro/models/__init__.py -index 604d90c..58690ef 100644 ---- a/pos_payment_method_cashdro/models/__init__.py -+++ b/pos_payment_method_cashdro/models/__init__.py -@@ -1,2 +1 @@ - from . import pos_payment_method --from . import pos_session -diff --git a/pos_payment_method_cashdro/models/pos_payment_method.py b/pos_payment_method_cashdro/models/pos_payment_method.py -index 285984a..08a64a1 100644 ---- a/pos_payment_method_cashdro/models/pos_payment_method.py -+++ b/pos_payment_method_cashdro/models/pos_payment_method.py -@@ -1,6 +1,6 @@ - # Copyright 2021 Tecnativa - David Vidal - # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --from odoo import fields, models -+from odoo import api, fields, models - - - class PosPaymentMethod(models.Model): -@@ -16,6 +16,15 @@ class PosPaymentMethod(models.Model): - cashdro_user = fields.Char() - cashdro_password = fields.Char() - -+ @api.model -+ def _load_pos_data_fields(self, config_id): -+ """The front end needs the credentials to build the CashDro url""" -+ return super()._load_pos_data_fields(config_id) + [ -+ "cashdro_host", -+ "cashdro_user", -+ "cashdro_password", -+ ] -+ - def _onchange_journal_id(self): - """Cash payment method force the `use_payment_terminal` to `False` as - it's assumed that a cash journal can't have a payment terminal. Let's keep -diff --git a/pos_payment_method_cashdro/models/pos_session.py b/pos_payment_method_cashdro/models/pos_session.py -deleted file mode 100644 -index 6123090..0000000 ---- a/pos_payment_method_cashdro/models/pos_session.py -+++ /dev/null -@@ -1,14 +0,0 @@ --# Copyright 2024 Tecnativa - David Vidal --# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --from odoo import models -- -- --class PosSession(models.Model): -- _inherit = "pos.session" -- -- def _loader_params_pos_payment_method(self): -- result = super()._loader_params_pos_payment_method() -- result["search_params"]["fields"].extend( -- ["cashdro_host", "cashdro_user", "cashdro_password"] -- ) -- return result -diff --git a/pos_payment_method_cashdro/static/src/js/models.esm.js b/pos_payment_method_cashdro/static/src/js/models.esm.js -index d228f08..d1ee2f7 100644 ---- a/pos_payment_method_cashdro/static/src/js/models.esm.js -+++ b/pos_payment_method_cashdro/static/src/js/models.esm.js -@@ -22,8 +22,8 @@ patch(PosOrder.prototype, { - return line; - } - if ( -- line.payment_method && -- line.payment_method.use_payment_terminal === "cashdro" && -+ line.payment_method_id && -+ line.payment_method_id.use_payment_terminal === "cashdro" && - line.amount > 0 // For refund transactions we need to keep the amount - ) { - line.set_amount(0); -diff --git a/pos_payment_method_cashdro/static/src/js/payment_cashdro.esm.js b/pos_payment_method_cashdro/static/src/js/payment_cashdro.esm.js -index 0c0bdf2..2c618bf 100644 ---- a/pos_payment_method_cashdro/static/src/js/payment_cashdro.esm.js -+++ b/pos_payment_method_cashdro/static/src/js/payment_cashdro.esm.js -@@ -107,7 +107,8 @@ export class PaymentCashdro extends PaymentInterface { - _cashdro_url() { - // Cashdro machines don't support safe POST calls, so we're sending - // all the data quite unsafely constantly... -- const method = this.pos.get_order().selected_paymentline.payment_method; -+ const order = this.pos.get_order(); -+ const method = order.get_selected_paymentline()?.payment_method_id; - const host = method && method.cashdro_host; - if (!host) { - return false; --- -2.43.0 - diff --git a/pos_payment_method_cashdro_rounding/__init__.py b/pos_payment_method_cashdro_rounding/__init__.py deleted file mode 100644 index 9f3f569..0000000 --- a/pos_payment_method_cashdro_rounding/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright Criptomart -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). diff --git a/pos_payment_method_cashdro_rounding/__manifest__.py b/pos_payment_method_cashdro_rounding/__manifest__.py deleted file mode 100644 index a16b1e3..0000000 --- a/pos_payment_method_cashdro_rounding/__manifest__.py +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "POS CashDro Rounding", - "version": "18.0.1.0.0", - "summary": "Apply cash/currency rounding to CashDro payment request amount.", - "category": "Point of Sale", - "license": "AGPL-3", - "author": "Criptomart", - "depends": [ - "point_of_sale", - "pos_payment_method_cashdro", - ], - "assets": { - "point_of_sale._assets_pos": [ - "pos_payment_method_cashdro_rounding/static/src/js/cashdro_rounding.esm.js", - ], - }, - "installable": True, -} diff --git a/pos_payment_method_cashdro_rounding/static/src/js/cashdro_rounding.esm.js b/pos_payment_method_cashdro_rounding/static/src/js/cashdro_rounding.esm.js deleted file mode 100644 index eb01842..0000000 --- a/pos_payment_method_cashdro_rounding/static/src/js/cashdro_rounding.esm.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright Criptomart - License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - - Apply the PoS cash rounding to the amount requested to the CashDro, keeping - the OCA integration flow untouched. -*/ - -import { PaymentCashdro } from "@pos_payment_method_cashdro/js/payment_cashdro.esm"; -import { patch } from "@web/core/utils/patch"; - -patch(PaymentCashdro.prototype, { - /** - * @override - * The base module asks the CashDro for the plain due amount, which ignores - * the cash rounding configured in the PoS. As the drawer can only give back - * change with the coins it holds, we request the amount the customer is - * really expected to pay: the due amount with the cash rounding applied, - * which is the very same amount core defaults a payment line to. - * - * Only the url builder is patched so the rest of the payment flow of the - * base module (request, acknowledge, polling and error handling) is kept. - */ - _cashdro_payment_url(parameters) { - const order = this.pos.get_order(); - const line = order.get_selected_paymentline(); - if (!line || !order.shouldRound(line.payment_method_id)) { - return super._cashdro_payment_url(...arguments); - } - // CashDro treats decimals as positions in an integer, so we round the - // product to avoid the trailing decimals of the floating point - // computation or the drawer would reject our request. - const amount = Math.round( - order.getDefaultAmountDueToPayIn(line.payment_method_id) * 100 - ); - return super._cashdro_payment_url({ ...parameters, amount }); - }, -});