automatically apply formulas on click

This commit is contained in:
imperosol
2025-11-26 15:53:16 +01:00
parent df8b23a4a1
commit a354f33ed9
5 changed files with 72 additions and 27 deletions

View File

@@ -1,6 +1,10 @@
import { AlertMessage } from "#core:utils/alert-message";
import { BasketItem } from "#counter:counter/basket";
import type { CounterConfig, ErrorMessage } from "#counter:counter/types";
import type {
CounterConfig,
ErrorMessage,
ProductFormula,
} from "#counter:counter/types";
import type { CounterProductSelect } from "./components/counter-product-select-index.ts";
document.addEventListener("alpine:init", () => {
@@ -47,15 +51,43 @@ document.addEventListener("alpine:init", () => {
this.basket[id] = item;
this.checkFormulas();
if (this.sumBasket() > this.customerBalance) {
item.quantity = oldQty;
if (item.quantity === 0) {
delete this.basket[id];
}
return gettext("Not enough money");
this.alertMessage.display(gettext("Not enough money"), { success: false });
}
},
return "";
checkFormulas() {
const products = new Set(
Object.keys(this.basket).map((i: string) => Number.parseInt(i)),
);
const formula: ProductFormula = config.formulas.find((f: ProductFormula) => {
return f.products.every((p: number) => products.has(p));
});
if (formula === undefined) {
return;
}
for (const product of formula.products) {
const key = product.toString();
this.basket[key].quantity -= 1;
if (this.basket[key].quantity <= 0) {
this.removeFromBasket(key);
}
}
this.alertMessage.display(
interpolate(
gettext("Formula %(formula)s applied"),
{ formula: config.products[formula.result.toString()].name },
true,
),
{ success: true },
);
this.addToBasket(formula.result.toString(), 1);
},
getBasketSize() {
@@ -70,14 +102,7 @@ document.addEventListener("alpine:init", () => {
(acc: number, cur: BasketItem) => acc + cur.sum(),
0,
) as number;
return total;
},
addToBasketWithMessage(id: string, quantity: number) {
const message = this.addToBasket(id, quantity);
if (message.length > 0) {
this.alertMessage.display(message, { success: false });
}
return Math.round(total * 100) / 100;
},
onRefillingSuccess(event: CustomEvent) {
@@ -116,7 +141,7 @@ document.addEventListener("alpine:init", () => {
this.finish();
}
} else {
this.addToBasketWithMessage(code, quantity);
this.addToBasket(code, quantity);
}
this.codeField.widget.clear();
this.codeField.widget.focus();

View File

@@ -7,10 +7,16 @@ export interface InitialFormData {
errors?: string[];
}
export interface ProductFormula {
result: number;
products: number[];
}
export interface CounterConfig {
customerBalance: number;
customerId: number;
products: Record<string, Product>;
formulas: ProductFormula[];
formInitial: InitialFormData[];
cancelUrl: string;
}

View File

@@ -10,12 +10,12 @@
float: right;
}
.basket-error-container {
.basket-message-container {
position: relative;
display: block
}
.basket-error {
.basket-message {
z-index: 10; // to get on top of tomselect
text-align: center;
position: absolute;