add pos_cashdro_refund,pos_cashdro_allow_manual
This commit is contained in:
parent
9b25650118
commit
b7e8f8967c
14 changed files with 409 additions and 0 deletions
3
pos_cashdro_allow_manual/__init__.py
Normal file
3
pos_cashdro_allow_manual/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Copyright 2026 Criptomart
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||||
|
from . import models
|
||||||
23
pos_cashdro_allow_manual/__manifest__.py
Normal file
23
pos_cashdro_allow_manual/__manifest__.py
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2026 Criptomart
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||||
|
{
|
||||||
|
"name": "POS CashDro Allow Manual Amount",
|
||||||
|
"summary": "Permite introducir manualmente el importe en pagos CashDro",
|
||||||
|
"version": "16.0.1.0.0",
|
||||||
|
"category": "Point of Sale",
|
||||||
|
"license": "AGPL-3",
|
||||||
|
"author": "Criptomart",
|
||||||
|
"depends": [
|
||||||
|
"pos_payment_method_cashdro",
|
||||||
|
],
|
||||||
|
"data": [
|
||||||
|
"views/pos_payment_method_views.xml",
|
||||||
|
],
|
||||||
|
"assets": {
|
||||||
|
"point_of_sale.assets": [
|
||||||
|
"pos_cashdro_allow_manual/static/src/js/PaymentScreen.esm.js",
|
||||||
|
"pos_cashdro_allow_manual/static/src/xml/PaymentScreenPaymentLines.xml",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"installable": True,
|
||||||
|
}
|
||||||
4
pos_cashdro_allow_manual/models/__init__.py
Normal file
4
pos_cashdro_allow_manual/models/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Copyright 2026 Criptomart
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||||
|
from . import pos_payment_method
|
||||||
|
from . import pos_session
|
||||||
18
pos_cashdro_allow_manual/models/pos_payment_method.py
Normal file
18
pos_cashdro_allow_manual/models/pos_payment_method.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Copyright 2026 Criptomart
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class PosPaymentMethod(models.Model):
|
||||||
|
_inherit = "pos.payment.method"
|
||||||
|
|
||||||
|
cashdro_allow_manual_amount = fields.Boolean(
|
||||||
|
string="Permitir importe manual",
|
||||||
|
help=(
|
||||||
|
"Cuando está activado, aparece un botón 'Manual' en la pantalla de "
|
||||||
|
"pago del TPV que permite confirmar el importe de la línea sin pasar "
|
||||||
|
"por la máquina CashDro. Útil ante fallos de comunicación, "
|
||||||
|
"devoluciones u otras situaciones de emergencia."
|
||||||
|
),
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
12
pos_cashdro_allow_manual/models/pos_session.py
Normal file
12
pos_cashdro_allow_manual/models/pos_session.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright 2026 Criptomart
|
||||||
|
# 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"].append("cashdro_allow_manual_amount")
|
||||||
|
return result
|
||||||
45
pos_cashdro_allow_manual/static/src/js/PaymentScreen.esm.js
Normal file
45
pos_cashdro_allow_manual/static/src/js/PaymentScreen.esm.js
Normal 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);
|
||||||
|
|
@ -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>
|
||||||
18
pos_cashdro_allow_manual/views/pos_payment_method_views.xml
Normal file
18
pos_cashdro_allow_manual/views/pos_payment_method_views.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!-- Copyright 2026 Criptomart
|
||||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
||||||
|
<odoo>
|
||||||
|
<record id="pos_payment_method_cashdro_allow_manual_form" model="ir.ui.view">
|
||||||
|
<field name="name">pos.payment.method.cashdro.allow.manual.form</field>
|
||||||
|
<field name="model">pos.payment.method</field>
|
||||||
|
<field name="inherit_id" ref="pos_payment_method_cashdro.pos_payment_method_view_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="cashdro_password" position="after">
|
||||||
|
<field
|
||||||
|
name="cashdro_allow_manual_amount"
|
||||||
|
attrs="{'invisible': [('use_payment_terminal', '!=', 'cashdro')]}"
|
||||||
|
/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
2
pos_cashdro_refund/__init__.py
Normal file
2
pos_cashdro_refund/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Copyright 2026 Criptomart
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||||
21
pos_cashdro_refund/__manifest__.py
Normal file
21
pos_cashdro_refund/__manifest__.py
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright 2026 Criptomart
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||||
|
{
|
||||||
|
"name": "POS CashDro Refund",
|
||||||
|
"summary": "Permite devoluciones (payouts) a través de la máquina CashDro desde el TPV",
|
||||||
|
"version": "16.0.1.0.0",
|
||||||
|
"category": "Point of Sale",
|
||||||
|
"license": "AGPL-3",
|
||||||
|
"author": "Criptomart",
|
||||||
|
"depends": [
|
||||||
|
"pos_payment_method_cashdro",
|
||||||
|
],
|
||||||
|
"assets": {
|
||||||
|
"point_of_sale.assets": [
|
||||||
|
"pos_cashdro_refund/static/src/js/PasswordInputPopup.js",
|
||||||
|
"pos_cashdro_refund/static/src/js/payment_cashdro_refund.esm.js",
|
||||||
|
"pos_cashdro_refund/static/src/xml/PasswordInputPopup.xml",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"installable": True,
|
||||||
|
}
|
||||||
38
pos_cashdro_refund/static/src/js/PasswordInputPopup.js
Normal file
38
pos_cashdro_refund/static/src/js/PasswordInputPopup.js
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
odoo.define("pos_cashdro_refund.PasswordInputPopup", function (require) {
|
||||||
|
"use strict";
|
||||||
|
/* Copyright 2026 Criptomart - extracted from pos_payment_method_cashdro
|
||||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
|
||||||
|
|
||||||
|
const AbstractAwaitablePopup = require("point_of_sale.AbstractAwaitablePopup");
|
||||||
|
const Registries = require("point_of_sale.Registries");
|
||||||
|
const {_lt} = require("@web/core/l10n/translation");
|
||||||
|
const {onMounted, useRef, useState} = owl;
|
||||||
|
|
||||||
|
class PasswordInputPopup extends AbstractAwaitablePopup {
|
||||||
|
setup() {
|
||||||
|
super.setup();
|
||||||
|
this.state = useState({inputValue: this.props.startingValue});
|
||||||
|
this.inputRef = useRef("input");
|
||||||
|
onMounted(this.onMounted);
|
||||||
|
}
|
||||||
|
onMounted() {
|
||||||
|
this.inputRef.el.focus();
|
||||||
|
}
|
||||||
|
getPayload() {
|
||||||
|
return this.state.inputValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PasswordInputPopup.template = "PasswordInputPopup";
|
||||||
|
PasswordInputPopup.defaultProps = {
|
||||||
|
confirmText: _lt("Ok"),
|
||||||
|
cancelText: _lt("Cancel"),
|
||||||
|
title: "",
|
||||||
|
body: "",
|
||||||
|
startingValue: "",
|
||||||
|
placeholder: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
Registries.Component.add(PasswordInputPopup);
|
||||||
|
|
||||||
|
return PasswordInputPopup;
|
||||||
|
});
|
||||||
117
pos_cashdro_refund/static/src/js/payment_cashdro_refund.esm.js
Normal file
117
pos_cashdro_refund/static/src/js/payment_cashdro_refund.esm.js
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
/** @odoo-module */
|
||||||
|
/* Copyright 2026 Criptomart - extracted from pos_payment_method_cashdro
|
||||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
Adds refund (payout) support to the CashDro payment terminal integration.
|
||||||
|
When the order due amount is negative (i.e. a return/refund), this module:
|
||||||
|
1. Asks the cashier for the CashDro password to authorise the payout.
|
||||||
|
2. Sends a type=3 (payout) request to the CashDro instead of the normal
|
||||||
|
type=4 (collection) request.
|
||||||
|
3. Sets the payment line amount to the negative amount dispensed by the
|
||||||
|
machine (totalout).
|
||||||
|
Normal (positive) payments are delegated unchanged to the original
|
||||||
|
cashdro_send_payment_request method.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {PaymentCashdro} from "@pos_payment_method_cashdro/js/payment_cashdro.esm";
|
||||||
|
import {Gui} from "point_of_sale.Gui";
|
||||||
|
import {_t} from "web.core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dedicated refund (payout) handler added to the CashDro prototype.
|
||||||
|
*
|
||||||
|
* Keeping this as a SEPARATE named method (rather than inlining it inside an
|
||||||
|
* override of cashdro_send_payment_request) means that pos_cashdro_rounding
|
||||||
|
* can always delegate refunds here regardless of which module loaded last.
|
||||||
|
* Both modules patch cashdro_send_payment_request directly on the prototype,
|
||||||
|
* so the last writer wins for that method; but _cashdro_send_refund_request is
|
||||||
|
* only ever written by this module and is never overwritten.
|
||||||
|
*/
|
||||||
|
PaymentCashdro.prototype._cashdro_send_refund_request = async function (order) {
|
||||||
|
const payment_line = order.selected_paymentline;
|
||||||
|
const due = order.get_due(payment_line);
|
||||||
|
// Include cash rounding if applied (same logic as pos_cashdro_rounding for
|
||||||
|
// normal payments). get_rounding_applied() returns 0 when no rounding is
|
||||||
|
// configured, so this is safe without pos_cashdro_rounding installed.
|
||||||
|
const rounding = order.get_rounding_applied ? order.get_rounding_applied() : 0;
|
||||||
|
const amount = Math.round(Math.abs(due + rounding) * 100);
|
||||||
|
|
||||||
|
// Require password authorisation before opening the drawer for a payout.
|
||||||
|
const {confirmed, payload: password} = await Gui.showPopup(
|
||||||
|
"PasswordInputPopup",
|
||||||
|
{
|
||||||
|
title: _t("CashDro Refund Authorization"),
|
||||||
|
body: _t("Enter the CashDro password to authorize this refund"),
|
||||||
|
placeholder: _t("Password"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!confirmed) {
|
||||||
|
payment_line.set_payment_status("retry");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const method = payment_line.payment_method;
|
||||||
|
if (password !== method.cashdro_password) {
|
||||||
|
await Gui.showPopup("ErrorPopup", {
|
||||||
|
title: _t("Authentication Failed"),
|
||||||
|
body: _t("The CashDro password is incorrect."),
|
||||||
|
});
|
||||||
|
payment_line.set_payment_status("retry");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const start_url = this._cashdro_payout_url({amount: amount});
|
||||||
|
console.log(start_url);
|
||||||
|
const res = await this._cashdro_request(start_url);
|
||||||
|
console.log(res);
|
||||||
|
const operation_id = res.data || "";
|
||||||
|
this.pos.get_order().cashdro_operation = operation_id;
|
||||||
|
|
||||||
|
const ack_url = this._cashdro_ack_url(operation_id);
|
||||||
|
const res_ack = await this._cashdro_request(ack_url);
|
||||||
|
console.log(res_ack);
|
||||||
|
|
||||||
|
const ask_url = this._cashdro_ask_url(operation_id);
|
||||||
|
const operation_data = await this._cashdro_request_payment(ask_url);
|
||||||
|
console.log(operation_data);
|
||||||
|
|
||||||
|
const data = JSON.parse(operation_data.data);
|
||||||
|
payment_line.cashdro_operation_data = data;
|
||||||
|
// CashDro reports the dispensed amount in totalout for payouts.
|
||||||
|
const dispensed = data.operation.totalout / 100;
|
||||||
|
payment_line.set_amount(-dispensed);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the URL for a type=3 (payout/refund) operation on the CashDro.
|
||||||
|
*/
|
||||||
|
PaymentCashdro.prototype._cashdro_payout_url = function (parameters) {
|
||||||
|
const user = this.pos.get_cashier().id || this.pos.user.id;
|
||||||
|
let url = `${this._cashdro_url()}&operation=startOperation&type=3`;
|
||||||
|
url += `&posid=pos-${this.pos.pos_session.name}`;
|
||||||
|
url += `&posuser=${user}`;
|
||||||
|
url += `¶meters=${encodeURIComponent(JSON.stringify(parameters))}`;
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override cashdro_send_payment_request to route refunds to
|
||||||
|
* _cashdro_send_refund_request.
|
||||||
|
*
|
||||||
|
* NOTE: if pos_cashdro_rounding is also installed it will overwrite this
|
||||||
|
* override (because "rounding" > "refund" alphabetically), but that is fine
|
||||||
|
* because pos_cashdro_rounding also delegates negative amounts to
|
||||||
|
* _cashdro_send_refund_request. This override only matters when the rounding
|
||||||
|
* module is NOT installed.
|
||||||
|
*/
|
||||||
|
const _originalSendPaymentRequest =
|
||||||
|
PaymentCashdro.prototype.cashdro_send_payment_request;
|
||||||
|
|
||||||
|
PaymentCashdro.prototype.cashdro_send_payment_request = async function (order) {
|
||||||
|
const payment_line = order.selected_paymentline;
|
||||||
|
const due = order.get_due(payment_line);
|
||||||
|
if (due < 0) {
|
||||||
|
return this._cashdro_send_refund_request(order);
|
||||||
|
}
|
||||||
|
return _originalSendPaymentRequest.call(this, order);
|
||||||
|
};
|
||||||
33
pos_cashdro_refund/static/src/xml/PasswordInputPopup.xml
Normal file
33
pos_cashdro_refund/static/src/xml/PasswordInputPopup.xml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Copyright 2026 Criptomart - extracted from pos_payment_method_cashdro
|
||||||
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
||||||
|
<templates id="template" xml:space="preserve">
|
||||||
|
|
||||||
|
<t t-name="PasswordInputPopup" owl="1">
|
||||||
|
<div class="popup popup-textinput">
|
||||||
|
<header class="title">
|
||||||
|
<t t-esc="props.title" />
|
||||||
|
</header>
|
||||||
|
<div class="body">
|
||||||
|
<p>
|
||||||
|
<t t-esc="props.body" />
|
||||||
|
</p>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
t-model="state.inputValue"
|
||||||
|
t-ref="input"
|
||||||
|
t-att-placeholder="props.placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="button confirm highlight" t-on-click="confirm">
|
||||||
|
<t t-esc="props.confirmText" />
|
||||||
|
</div>
|
||||||
|
<div class="button cancel" t-on-click="cancel">
|
||||||
|
<t t-esc="props.cancelText" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
</templates>
|
||||||
|
|
@ -11,6 +11,17 @@ import { PaymentCashdro } from "@pos_payment_method_cashdro/js/payment_cashdro.e
|
||||||
PaymentCashdro.prototype.cashdro_send_payment_request = async function (order) {
|
PaymentCashdro.prototype.cashdro_send_payment_request = async function (order) {
|
||||||
const payment_line = order.selected_paymentline;
|
const payment_line = order.selected_paymentline;
|
||||||
try {
|
try {
|
||||||
|
// If pos_cashdro_refund is installed this method handles payouts.
|
||||||
|
// Rounding is not applicable to refunds so we delegate and return.
|
||||||
|
const due = order.get_due(payment_line);
|
||||||
|
if (due < 0) {
|
||||||
|
if (this._cashdro_send_refund_request) {
|
||||||
|
return this._cashdro_send_refund_request(order);
|
||||||
|
}
|
||||||
|
// Refund module not installed – nothing we can do.
|
||||||
|
payment_line.set_payment_status("retry");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Cashdro treats decimals as positions in an integer we also have
|
// Cashdro treats decimals as positions in an integer we also have
|
||||||
// to deal with floating point computing to avoid decimals at the
|
// to deal with floating point computing to avoid decimals at the
|
||||||
// end or the drawer will reject our request.
|
// end or the drawer will reject our request.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue