[IMP] pos_sale: Possibility to apply fixed amount on downpayment

Until now, it was not possible to apply fixed amount on downpayment.
Users were forced to compute the percentage to apply on a
downpayment on the side when the wanted to apply a fixed downpayment.
This is no more the case.

This commit also changes a bit the NumberPopup in the PoS.
The NumberPopup can now have a subtitle, a suffix to its input (usefull
for symbols like currency or percentage) and in the case of a percentage,
can have an indication under the confirm button about how much the
percentage means in other unit (like a percentage of a price).

The commit also removes the previous downpayment lines on the new
order line in the ProductScreen as they were not showing
useful information.

closes odoo/odoo#118594

Task-id: 2836904
Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
This commit is contained in:
Adrien Guilliams (adgu)
2023-05-10 15:19:37 +02:00
parent 1eb2e7c814
commit a253eb65fb
5 changed files with 118 additions and 20 deletions
@@ -11,10 +11,13 @@ export class NumberPopup extends AbstractAwaitablePopup {
confirmText: _t("Confirm"),
cancelText: _t("Discard"),
title: _t("Confirm?"),
subtitle: "",
body: "",
cheap: false,
startingValue: null,
isPassword: false,
inputSuffix: "",
getInputBufferReminder: () => false,
};
/**
@@ -147,6 +147,7 @@ export class PaymentScreen extends Component {
title: tip ? this.env._t("Change Tip") : this.env._t("Add Tip"),
startingValue: value,
isInputSelected: true,
inputSuffix: this.env.pos.currency.symbol,
});
if (confirmed) {
+46 -8
View File
@@ -2551,6 +2551,13 @@ td {
padding: 20px;
border-radius: 3px 3px 0px 0px;
border-bottom: solid 1px rgba(60,60,60,0.1);
display: flex;
flex-direction: column;
}
.pos .popup .subtitle {
padding: 5px;
font-size: 14px;
font-weight: normal;
}
.pos .popup .body {
font-weight: normal;
@@ -2597,6 +2604,22 @@ td {
color: $primary;
}
.pos .button .flex-column {
display: flex;
justify-content: center;
height: 40px;
gap: 2px;
flex-direction: column;
}
.pos .button .flex-column span {
line-height: normal;
}
.pos .button .flex-column .input-buffer-reminder {
font-weight: normal;
}
.pos .popup .button.dont-show-again {
width: 130px;
}
@@ -2633,6 +2656,23 @@ td {
height: 180px;
line-height:180px;
}
.pos .input-symbol {
display: flex;
align-items: center;
gap: 14px;
justify-content: center;
}
.pos .input-symbol .popup-input {
display: flex;
gap: 4px;
}
.pos .input-symbol .popup-input .input-value {
flex-grow: 1;
}
.pos .popup input,
.pos .popup-input {
text-align: left;
@@ -2682,7 +2722,7 @@ td {
}
.pos .popup-number .popup-input {
text-align: center;
text-align: right;
}
.pos .popup input:focus,
.pos .popup-input.active {
@@ -2730,11 +2770,14 @@ td {
background: $primary;
}
.pos .popup.popup-number {
width: 300px;
height: 450px;
max-width: none;
width: auto;
padding: 0 10px;
}
.pos .footer.centered {
text-align: center;
display: flex;
justify-content: center;
}
.pos .footer.centered .button {
float: none;
@@ -2773,11 +2816,6 @@ td {
color: white;
border-color: #444;
}
.pos .popup.popup-password {
width: 254px;
height: 510px;
}
.pos .popup-password .mode-button.add,
.pos .popup-password .input-button.dot {
display: none;
@@ -4,10 +4,14 @@
<t t-name="NumberPopup" owl="1">
<div class="popup popup-number" t-att-class="{ 'popup-password': props.isPassword }">
<header class="title drag-handle">
<t t-esc="props.title" />
<span><t t-esc="props.title"/></span>
<span t-if="props.subtitle" class="subtitle"><t t-esc="props.subtitle"/></span>
</header>
<div class="popup-input value active">
<span t-att-class="{ 'highlight': state.toStartOver }"><t t-esc="inputBuffer"/></span>
<div class="input-symbol">
<div class="popup-input value active">
<span class="input-value" t-att-class="{ 'highlight': state.toStartOver }"><t t-esc="inputBuffer"/></span>
<span t-if="props.inputSuffix"><t t-esc="props.inputSuffix" /></span>
</div>
</div>
<div class="popup-numpad">
<!-- FIXME POSREF do we really need to hardcode all of these? -->
@@ -49,7 +53,12 @@
</div>
<footer class="footer centered">
<div class="button confirm highlight" t-on-mousedown.prevent="confirm">
<t t-esc="props.confirmText" />
<div class="flex-column">
<span><t t-esc="props.confirmText" /></span>
<span t-if="props.getInputBufferReminder(state.buffer)" class="input-buffer-reminder">
(<t t-esc="props.getInputBufferReminder(state.buffer)" />)
</span>
</div>
</div>
<div class="button cancel" t-on-mousedown.prevent="cancel">
<t t-esc="props.cancelText" />
@@ -94,8 +94,17 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo
const { confirmed, payload: selectedOption } = await this.popup.add(SelectionPopup, {
title: this.env._t("What do you want to do?"),
list: [
{ id: "0", label: this.env._t("Apply a down payment"), item: false },
{ id: "1", label: this.env._t("Settle the order"), item: true },
{ id: "0", label: this.env._t("Settle the order"), item: "settle" },
{
id: "1",
label: this.env._t("Apply a down payment (percentage)"),
item: "dpPercentage",
},
{
id: "2",
label: this.env._t("Apply a down payment (fixed amount)"),
item: "dpAmount",
},
],
});
@@ -159,7 +168,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo
currentPOSOrder.set_pricelist(orderPricelist);
}
if (selectedOption) {
if (selectedOption == "settle") {
// settle the order
const lines = sale_order.order_line;
const product_to_add_in_pos = lines
@@ -249,9 +258,13 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo
} else {
// apply a downpayment
if (this.env.pos.config.down_payment_product_id) {
const lines = sale_order.order_line;
let lines = sale_order.order_line;
const tab = [];
lines = lines.filter((line) => {
return (
line.product_id[0] !== this.env.pos.config.down_payment_product_id[0]
);
});
for (let i = 0; i < lines.length; i++) {
tab[i] = {
product_name: lines[i].product_id[1],
@@ -282,14 +295,48 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo
down_payment = sale_order.amount_total;
}
let popupTitle = "";
let popupInputSuffix = "";
const popupTotalDue = sale_order.amount_total;
let getInputBufferReminder = () => false;
const popupSubtitle = this.env._t("Due balance: %s");
if (selectedOption == "dpAmount") {
popupTitle = this.env._t("Down Payment");
popupInputSuffix = this.env.pos.currency.symbol;
} else {
popupTitle = this.env._t("Down Payment");
popupInputSuffix = "%";
getInputBufferReminder = (buffer) => {
if (buffer && buffer.length > 0) {
const percentage = parseFloat(buffer);
if (isNaN(percentage)) {
return false;
}
return this.env.utils.formatCurrency(
(popupTotalDue * percentage) / 100
);
} else {
return false;
}
};
}
const { confirmed, payload } = await this.popup.add(NumberPopup, {
title: sprintf(
this.env._t("Percentage of %s"),
title: popupTitle,
subtitle: sprintf(
popupSubtitle,
this.env.utils.formatCurrency(sale_order.amount_total)
),
inputSuffix: popupInputSuffix,
startingValue: 0,
getInputBufferReminder,
});
if (confirmed) {
if (!confirmed) {
return;
}
if (selectedOption == "dpAmount") {
down_payment = parseFloat(payload);
} else {
down_payment = (down_payment * parseFloat(payload)) / 100;
}