chore: import enterprise addons 19.0 bulk snapshot

This commit is contained in:
1b-agent committed 2026-09-16 10:13:08 +00:00
commit ca4af030d3
39951 files changed
+15570005

No files matched your search

@@ -0,0 +1,17 @@
import { registry } from "@web/core/registry";
import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
import { _t } from "@web/core/l10n/translation";
export class SwedenBlackboxError extends Error {}
function swedenBlackboxErrorHandler(env, error, originalError) {
if (originalError instanceof SwedenBlackboxError) {
env.services.dialog.add(AlertDialog, {
title: _t("Blackbox Error"),
body: originalError.message,
});
return true;
}
return false;
}
registry.category("error_handlers").add("swedenBlackboxErrorHandler", swedenBlackboxErrorHandler);
@@ -0,0 +1,101 @@
import { PosStore } from "@point_of_sale/app/services/pos_store";
import { _t } from "@web/core/l10n/translation";
import { patch } from "@web/core/utils/patch";
import { SwedenBlackboxError } from "@l10n_se_pos/app/errors/error_handlers";
const { DateTime } = luxon;
patch(PosStore.prototype, {
useBlackBoxSweden() {
return !!this.config.iface_sweden_fiscal_data_module;
},
disallowLineQuantityChange() {
const result = super.disallowLineQuantityChange(...arguments);
return this.useBlackBoxSweden() || result;
},
async preSyncAllOrders(orders) {
if (this.useBlackBoxSweden() && orders.length > 0) {
for (const order of orders) {
await this.pushSingleOrder(order);
}
}
return super.preSyncAllOrders(orders);
},
async pushSingleOrder(order) {
if (this.useBlackBoxSweden() && order) {
if (!order.receipt_type) {
order.receipt_type = "normal";
order.sequence_number = await this.getOrderSequenceNumber();
}
try {
order.sweden_blackbox_tax_category_a = order.getSpecificTax("A");
order.sweden_blackbox_tax_category_b = order.getSpecificTax("B");
order.sweden_blackbox_tax_category_c = order.getSpecificTax("C");
order.sweden_blackbox_tax_category_d = order.getSpecificTax("D");
const data = await this.pushOrderToSwedenBlackbox(order);
const result = data.result ?? data;
if (result.error && result.error.errorCode != "000000") {
throw result.error;
}
this.setDataForPushOrderFromSwedenBlackBox(order, result);
} catch (err) {
order.state = "draft";
throw new SwedenBlackboxError(err?.status?.message_title ?? err?.status ?? err);
}
}
},
async pushOrderToSwedenBlackbox(order) {
const fdm = this.hardwareProxy.deviceControllers.fiscal_data_module;
const data = {
date: new DateTime(order.date_order).toFormat("yyyyMMddHHmm"),
receipt_id: order.sequence_number.toString(),
pos_id: this.config.id.toString(),
organisation_number: this.company.company_registry.replace(/\D/g, ""),
receipt_total: order.displayPrice.toFixed(2).toString().replace(".", ","),
negative_total:
order.totalDue < 0
? Math.abs(order.totalDue).toFixed(2).toString().replace(".", ",")
: "0,00",
receipt_type: order.receipt_type,
vat1: order.sweden_blackbox_tax_category_a
? "25,00;" + order.sweden_blackbox_tax_category_a.toFixed(2).replace(".", ",")
: " ",
vat2: order.sweden_blackbox_tax_category_b
? "12,00;" + order.sweden_blackbox_tax_category_b.toFixed(2).replace(".", ",")
: " ",
vat3: order.sweden_blackbox_tax_category_c
? "6,00;" + order.sweden_blackbox_tax_category_c.toFixed(2).replace(".", ",")
: " ",
vat4: order.sweden_blackbox_tax_category_d
? "0,00;" + order.sweden_blackbox_tax_category_d.toFixed(2).replace(".", ",")
: " ",
};
return new Promise((resolve, reject) => {
fdm.addListener((data) =>
data.status === "ok" || data.status === "success" ? resolve(data) : reject(data)
);
fdm.action({
action: "registerReceipt",
high_level_message: data,
})
.then((response) => {
if (!response.result) {
reject(_t("Blackbox is disconnected"));
}
})
.catch(reject);
});
},
setDataForPushOrderFromSwedenBlackBox(order, data) {
order.sweden_blackbox_signature = data.signature_control;
order.sweden_blackbox_unit_id = data.unit_id;
},
async getOrderSequenceNumber() {
return await this.data.call("pos.config", "get_order_sequence_number", [this.config.id]);
},
async getProfoOrderSequenceNumber() {
return await this.data.call("pos.config", "get_profo_order_sequence_number", [
this.config.id,
]);
},
});
@@ -0,0 +1,85 @@
import { patch } from "@web/core/utils/patch";
import { PosStore } from "@point_of_sale/app/services/pos_store";
import { _t } from "@web/core/l10n/translation";
import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
patch(PosStore.prototype, {
useBlackBoxSweden() {
return !!this.config.iface_sweden_fiscal_data_module;
},
hasNegativeAndPositiveProducts(product) {
const isPositive = product.list_price >= 0;
const order = this.getOrder();
for (const id in order.getOrderlines()) {
const line = order.getOrderlines()[id];
if (
(line.product_id.list_price >= 0 && !isPositive) ||
(line.product_id.list_price < 0 && isPositive)
) {
return true;
}
}
return false;
},
async addLineToCurrentOrder(vals, opt = {}, configure = true) {
const product = vals.product_tmpl_id;
const productTaxesIds = product.taxes_id.map((tax) => tax.id);
if (this.useBlackBoxSweden() && product.taxes_id.length === 0) {
this.dialog.add(AlertDialog, {
title: _t("POS error"),
body: _t("Product has no tax associated with it."),
});
return;
} else if (
this.useBlackBoxSweden() &&
!this.models["account.tax"]
.filter((tax) => productTaxesIds.includes(tax.id))
?.every((tax) => tax.tax_group_id.pos_receipt_label)
) {
this.dialog.add(AlertDialog, {
title: _t("POS error"),
body: _t(
"Product has an invalid tax amount. Only 25%, 12%, 6% and 0% are allowed."
),
});
return;
} else if (this.useBlackBoxSweden() && this.getOrder().lines.find((l) => l.is_return)) {
this.dialog.add(AlertDialog, {
title: _t("POS error"),
body: _t("Cannot modify a refund order."),
});
return;
} else if (this.useBlackBoxSweden() && this.hasNegativeAndPositiveProducts(product)) {
this.dialog.add(AlertDialog, {
title: _t("POS error"),
body: _t("You can only make positive or negative order. You cannot mix both."),
});
return;
} else {
return await super.addLineToCurrentOrder(vals, opt, configure);
}
},
async printReceipt({ order = this.getOrder() } = {}) {
if (this.useBlackBoxSweden()) {
if (order) {
if (order.nb_print > 1) {
this.dialog.add(AlertDialog, {
title: _t("POS error"),
body: _t("A duplicate has already been printed once."),
});
return;
}
if (order.nb_print === 1) {
order.receipt_type = "kopia";
await this.pushSingleOrder(order);
order.receipt_type = false;
order.isReprint = true;
}
return super.printReceipt(...arguments);
}
} else {
return super.printReceipt(...arguments);
}
},
});
@@ -0,0 +1,19 @@
import { ControlButtons } from "@point_of_sale/app/screens/product_screen/control_buttons/control_buttons";
import { patch } from "@web/core/utils/patch";
patch(ControlButtons.prototype, {
async clickPrintBill() {
const order = this.pos.getOrder();
if (this.pos.useBlackBoxSweden()) {
order.isProfo = true;
order.receipt_type = "profo";
const sequence = await this.pos.getProfoOrderSequenceNumber();
order.sequence_number = sequence;
await this.pos.pushSingleOrder(order);
order.receipt_type = false;
}
await super.clickPrintBill(...arguments);
order.isProfo = false;
},
});
@@ -0,0 +1,18 @@
import { OrderReceipt } from "@point_of_sale/app/screens/receipt_screen/receipt/order_receipt";
import { deserializeDateTime } from "@web/core/l10n/dates";
import { patch } from "@web/core/utils/patch";
patch(OrderReceipt.prototype, {
get seType() {
if (this.order.isReprint) {
return "COPY";
} else if (this.order.isProfo) {
return "PRO FORMA";
} else {
return (this.order.amount_total < 0 ? "return" : "") + "receipt";
}
},
get originalDate() {
return deserializeDateTime(this.order.creation_date).toFormat("HH:mm dd/MM/yyyy");
},
});
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-inherit="point_of_sale.OrderReceipt" t-inherit-mode="extension">
<xpath expr="//div[hasclass('after-footer')]" position="after">
<t t-if="order.config.iface_sweden_fiscal_data_module">
<div style="font-size: 75%;">
<br/>
<div>
<span>POS ID: </span>
<t t-esc="order.config.name"/>
</div>
<div>
<span>Blackbox Unit ID: </span>
<t t-esc="order.sweden_blackbox_unit_id"/>
</div>
<div style="word-break: break-all;">
<span>Blackbox Signature: </span>
<t t-esc="order.sweden_blackbox_signature"/>
</div>
</div>
</t>
</xpath>
</t>
</templates>
@@ -0,0 +1,24 @@
import { PosOrder } from "@point_of_sale/app/models/pos_order";
import { patch } from "@web/core/utils/patch";
patch(PosOrder.prototype, {
useBlackBoxSweden() {
return !!this.config.iface_sweden_fiscal_data_module;
},
getSpecificTax(category) {
const tax = this.prices.taxDetails.subtotals[0].tax_groups.find(
(tax) => tax.group_label === category
);
if (tax) {
return tax.tax_amount;
}
return false;
},
waitForPushOrder() {
var result = super.waitForPushOrder(...arguments);
result = Boolean(this.useBlackBoxSweden() || result);
return result;
},
});
@@ -0,0 +1,45 @@
/* global posmodel */
import * as Chrome from "@point_of_sale/../tests/pos/tours/utils/chrome_util";
import * as ProductScreen from "@point_of_sale/../tests/pos/tours/utils/product_screen_util";
import * as PaymentScreen from "@point_of_sale/../tests/pos/tours/utils/payment_screen_util";
import * as ReceiptScreen from "@point_of_sale/../tests/pos/tours/utils/receipt_screen_util";
import * as Dialog from "@point_of_sale/../tests/generic_helpers/dialog_util";
import { registry } from "@web/core/registry";
class FiscalDataModuleDummy {
async action() {
return { result: true };
}
addListener(callback) {
callback({
status: "ok",
value: { error: null },
signature_controle: "abc",
unit_id: "123",
});
}
}
registry.category("web_tour.tours").add("test_l10n_se_pos_01", {
steps: () =>
[
Chrome.startPoS(),
Dialog.confirm("Open Register"),
{
content: "mock the connected fiscal data moudle",
trigger: ".pos .pos-content",
run: function () {
posmodel.hardwareProxy.deviceControllers.fiscal_data_module =
new FiscalDataModuleDummy();
},
},
ProductScreen.clickDisplayedProduct("Magnetic Board"),
ProductScreen.clickPayButton(),
PaymentScreen.clickPaymentMethod("Cash"),
PaymentScreen.clickValidate(),
ReceiptScreen.isShown(),
ReceiptScreen.receiptIsThere(),
].flat(),
});