add pos_cashdro_refund,pos_cashdro_allow_manual

This commit is contained in:
Luis 2026-04-24 13:34:06 +02:00
parent 9b25650118
commit b7e8f8967c
14 changed files with 409 additions and 0 deletions

View file

@ -0,0 +1,45 @@
/** @odoo-module **/
// Copyright 2026 Criptomart
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import {Component} from "point_of_sale.Registries";
import PaymentScreen from "point_of_sale.PaymentScreen";
import {useListener} from "@web/core/utils/hooks";
const CashdroAllowManualPaymentScreen = (OriginalPaymentScreen) =>
class extends OriginalPaymentScreen {
setup() {
super.setup();
useListener("cashdro-send-manual", this._cashdroSendManual);
}
/**
* Mark the Cashdro payment line as done using the amount that is already
* set on the line (entered manually via the numpad), without contacting
* the CashDro machine.
*
* Sets `cashdro_manual_done = true` on the line so the delete button
* remains visible even in `done` state, letting the cashier undo the
* operation in case of a mistake.
*
* Refuses to proceed when the amount is 0 to avoid locking the POS with
* an undeletable zero-amount payment line.
*/
async _cashdroSendManual({detail: line}) {
if (!line.get_amount()) {
this.showPopup("ErrorPopup", {
title: this.env._t("Importe no válido"),
body: this.env._t(
"Introduzca el importe en el teclado numérico antes de confirmar manualmente el pago."
),
});
return;
}
// Flag this line as manually confirmed so the template keeps
// showing its delete button even after the status is 'done'.
line.cashdro_manual_done = true;
line.set_payment_status("done");
}
};
Component.extend(PaymentScreen, CashdroAllowManualPaymentScreen);

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Copyright 2026 Criptomart
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
Extends the PaymentScreenPaymentLines template to add a "Manual" button
next to the Send/Retry action buttons on Cashdro payment lines.
The button is shown when:
- the payment method is of type "cashdro"
- cashdro_allow_manual_amount is True on that payment method
- the line is in "pending" or "retry" state (the two states where
the numpad is already active and the cashier can edit the amount)
Clicking it triggers the "cashdro-send-manual" event which is handled
by CashdroAllowManualPaymentScreen in PaymentScreen.esm.js.
-->
<templates id="template" xml:space="preserve">
<t
t-name="pos_cashdro_allow_manual.PaymentScreenPaymentLines"
t-inherit="point_of_sale.PaymentScreenPaymentLines"
t-inherit-mode="extension"
owl="1"
>
<!--
//div[hasclass('send_payment_request')] matches two nodes:
1. the "Send" button shown in the "pending" state
2. the "Retry" button shown in the "retry" state
position="after" inserts our node after each match,
so the Manual button appears in both states.
-->
<xpath expr="//div[hasclass('send_payment_request')]" position="before">
<t
t-if="line.payment_method.use_payment_terminal === 'cashdro'
and line.payment_method.cashdro_allow_manual_amount"
>
<div
class="button cashdro-manual-button"
style="flex: 0 0 auto; padding: 0 12px; font-size: 0.8em; opacity: 0.75;"
title="Confirmar importe manualmente sin usar la máquina CashDro"
t-on-click="() => this.trigger('cashdro-send-manual', line)"
>
Manual
</div>
</t>
</xpath>
<!--
Extend the t-if on the wrapper <t> that controls the delete button
visibility so that manually-confirmed Cashdro lines keep showing the
delete button even in 'done' state. This lets the cashier undo
an accidental Manual press without blocking the POS session.
The targeted element is the <t t-if="..."> that wraps the
delete-button <div> inside the selected payment line block.
-->
<xpath
expr="//t[@t-if='line.selected']/div/t[div[hasclass('delete-button')]]"
position="attributes"
>
<attribute name="t-if">!line.payment_status or !['done', 'reversed', 'waitingCard', 'waitingCapture'].includes(line.payment_status) or line.cashdro_manual_done</attribute>
</xpath>
</t>
</templates>