286 lines
8.1 KiB
TypeScript
286 lines
8.1 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { mockApi, seedAuthenticatedState } from "./support/network.js";
|
|
import { isDesktopProject } from "./support/projects";
|
|
|
|
const json = (body: unknown, status = 200) => ({
|
|
status,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(body),
|
|
});
|
|
|
|
test.describe("Admin POS drafts", () => {
|
|
test("assigns a draft order to a customer, invoice collection, and recalculated pricing", async ({
|
|
page,
|
|
}, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
await seedAuthenticatedState(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: [
|
|
"admin",
|
|
"department_access_1",
|
|
"add_order",
|
|
"edit_order",
|
|
"list_orders",
|
|
"list_order_items",
|
|
"edit_order_items",
|
|
"list_products",
|
|
],
|
|
sessionData: {
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: 6001,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const currentOrder = {
|
|
id: 56625,
|
|
customer_id: 6001,
|
|
customer_name: "Uspecificeret kunde",
|
|
user_id: 77,
|
|
cashier_id: 5,
|
|
cashier_name: "Jeppe",
|
|
department_id: 1,
|
|
reg_1: "EC21233",
|
|
reg_2: null,
|
|
reg_3: null,
|
|
reference: "reff",
|
|
notes: "",
|
|
po: "po00",
|
|
total_net_amount: 111700,
|
|
created_at: "2026-04-20 13:20:57",
|
|
invoice_collection_id: 7001,
|
|
invoice_collection: {
|
|
id: 7001,
|
|
customer_number: 6001,
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
},
|
|
economic_invoice_module: null,
|
|
stripe_invoice_module: null,
|
|
error_message: null,
|
|
pending_handheld: false,
|
|
completed_at: null,
|
|
booking_id: null,
|
|
wash_id: null,
|
|
lane: null,
|
|
safety_seal: null,
|
|
};
|
|
|
|
const orderPutPayloads: Array<Record<string, unknown>> = [];
|
|
const orderItemsPutPayloads: Array<Record<string, unknown>> = [];
|
|
const productPriceRequests: Array<Record<string, string>> = [];
|
|
|
|
await page.route("https://api.truckwash.io:4433/departments**", async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [{ id: 1, name: "Demo", visible: true }],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route("https://api.truckwash.io:4433/orders**", async (route) => {
|
|
const request = route.request();
|
|
|
|
if (request.method() === "PUT") {
|
|
const payload = request.postDataJSON();
|
|
orderPutPayloads.push(payload);
|
|
|
|
if (payload.customer_id) {
|
|
currentOrder.customer_id = Number(payload.customer_id);
|
|
currentOrder.customer_name = "Acme Logistics";
|
|
}
|
|
|
|
if (payload.invoice_collection_id) {
|
|
currentOrder.invoice_collection_id = Number(payload.invoice_collection_id);
|
|
currentOrder.invoice_collection = {
|
|
id: Number(payload.invoice_collection_id),
|
|
customer_number: currentOrder.customer_id,
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
};
|
|
}
|
|
|
|
await route.fulfill(json({ success: true, data: { message: "Order updated successfully" } }));
|
|
return;
|
|
}
|
|
|
|
const includesDraftOrder = currentOrder.customer_id === 6001;
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: includesDraftOrder ? [currentOrder] : [],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: 100,
|
|
total: includesDraftOrder ? 1 : 0,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route("https://api.truckwash.io:4433/customers?search=**", async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{
|
|
customerNumber: 424242,
|
|
name: "Acme Logistics",
|
|
city: "Roskilde",
|
|
},
|
|
],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: 100,
|
|
total: 1,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route("https://api.truckwash.io:4433/collected-invoices**", async (route) => {
|
|
const request = route.request();
|
|
if (request.method() !== "GET") {
|
|
await route.fallback();
|
|
return;
|
|
}
|
|
|
|
const url = new URL(request.url());
|
|
const filters = url.searchParams.get("filters") || "";
|
|
if (!filters.includes("customer_number:424242")) {
|
|
await route.fulfill(json({ data: [], meta: { pagination: { page: 1, per_page: 100, total: 0 } } }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{
|
|
id: 9001,
|
|
customer_number: 424242,
|
|
customer_name: "Acme Logistics",
|
|
created_at: "2026-04-18 09:00:00",
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
total_net_amount: 100000,
|
|
},
|
|
{
|
|
id: 9002,
|
|
customer_number: 424242,
|
|
customer_name: "Acme Logistics",
|
|
created_at: "2026-04-16 09:00:00",
|
|
closed_at: "2026-04-17 00:00:00",
|
|
booked_invoice_id: null,
|
|
total_net_amount: 250000,
|
|
},
|
|
],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: 100,
|
|
total: 2,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route("https://api.truckwash.io:4433/order/items**", async (route) => {
|
|
const request = route.request();
|
|
|
|
if (request.method() === "PUT") {
|
|
orderItemsPutPayloads.push(request.postDataJSON());
|
|
await route.fulfill(json({ success: true, data: { message: "Order item updated" } }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{
|
|
id: 8001,
|
|
order_id: currentOrder.id,
|
|
product_id: 101,
|
|
reference: "",
|
|
notes: "",
|
|
cashier_id: currentOrder.cashier_id,
|
|
price: 111700,
|
|
quantity: 1,
|
|
related_item_id: 0,
|
|
include_in_invoice: true,
|
|
product: {
|
|
id: 101,
|
|
name: "Truck wash",
|
|
price: 111700,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route("https://api.truckwash.io:4433/products**", async (route) => {
|
|
const url = new URL(route.request().url());
|
|
productPriceRequests.push(Object.fromEntries(url.searchParams.entries()));
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
id: 101,
|
|
name: "Truck wash",
|
|
price: 99900,
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.goto("/admin/1/modules/pos/drafts");
|
|
await expect(page).toHaveURL(/\/admin\/1\/modules\/pos\/drafts$/);
|
|
|
|
await expect(page.getByTestId("draft-order-assign-customer-button-56625")).toBeVisible();
|
|
|
|
await page.getByTestId("draft-order-assign-customer-button-56625").click();
|
|
|
|
const modal = page.getByTestId("draft-order-assign-customer-modal");
|
|
await expect(modal).toBeVisible();
|
|
await expect(page.getByTestId("draft-order-recalculate-prices")).toBeChecked();
|
|
|
|
await page.getByTestId("draft-order-assign-customer-search").fill("Acme");
|
|
await page.getByTestId("draft-order-customer-option-424242").click();
|
|
await expect(page.getByTestId("draft-order-invoice-collection-option-9001")).toBeVisible();
|
|
await page.getByTestId("draft-order-invoice-collection-option-9002").click();
|
|
|
|
await page.getByTestId("draft-order-assign-submit").click();
|
|
|
|
await expect(modal).toHaveCount(0);
|
|
await expect(page.getByTestId("draft-order-assign-customer-button-56625")).toHaveCount(0);
|
|
|
|
expect(orderPutPayloads).toEqual([
|
|
{ id: 56625, customer_id: 424242 },
|
|
{ id: 56625, invoice_collection_id: 9002 },
|
|
]);
|
|
|
|
expect(orderItemsPutPayloads).toHaveLength(1);
|
|
expect(orderItemsPutPayloads[0]).toMatchObject({
|
|
id: 8001,
|
|
price: 99900,
|
|
quantity: 1,
|
|
});
|
|
|
|
expect(productPriceRequests).toHaveLength(1);
|
|
expect(productPriceRequests[0]).toMatchObject({
|
|
id: "101",
|
|
customer_id: "424242",
|
|
department_id: "1",
|
|
final_price: "true",
|
|
});
|
|
});
|
|
});
|