Erweitere VoTiAn NG um Auftrags-, Stamm- und Verwaltungsfunktionen
Ergänzt Auftragserfassung und -bearbeitung, Unternehmerbelege, Stornos, Lagerkorrekturen, Stammdaten, Abrechnung, CRM, Formulare, Berichte und Preisverwaltung auf Basis der aktuellen PHP-Anwendung. Enthält Integrations- und Oberflächentests sowie dokumentierte Abgleiche und Prüfstände.
This commit is contained in:
1 parent
42c87282ee
commit
363bc27c26
190 files changed
+14815
-1857
No files matched your search
+27
-18
@@ -4,6 +4,7 @@ import { test, expect, type Page } from "@playwright/test";
|
||||
// into an application database, filesystem store, or production response.
|
||||
const capabilities = {
|
||||
readOrders: true,
|
||||
readStatistics: true,
|
||||
readCustomers: true,
|
||||
readCouriers: true,
|
||||
readInvoices: false,
|
||||
@@ -178,11 +179,21 @@ async function mockApi(
|
||||
csrfVersion += 1;
|
||||
return route.fulfill({ status: 204 });
|
||||
}
|
||||
if (path === "/statistics/query" && request.method() === "POST") {
|
||||
if (!authenticated) return respond(401, { message: "Anmeldung erforderlich." });
|
||||
const query = request.postDataJSON();
|
||||
const totals = { orders: 1234, revenue: 68000, courierRevenue: 47000, missingCourierValues: 0, serviceRevenue: 1500, fuelMarkup: 2300, courierService: 500, kilometers: 26000, co2eKg: 3300, kilometersOrders: 1200, co2eKgOrders: 1100 };
|
||||
return respond(200, overrides[path] ?? {
|
||||
periods: [query.interval, ...query.comparisons].map((interval: {from:string;to:string}) => ({interval,totals,rows:[{...totals,period:interval.from.slice(0,7),...Object.fromEntries(query.splits.map((_:string,i:number)=>[`split${i}`,"Testauswertung"]))}]})),
|
||||
splits: query.splits, dateBasis: query.dateBasis, period: query.period, completePeriod: true,
|
||||
});
|
||||
}
|
||||
throw new Error(`Unexpected mutation: ${request.method()} ${path}`);
|
||||
}
|
||||
if (!authenticated && path !== "/system")
|
||||
return respond(401, { message: "Anmeldung erforderlich." });
|
||||
let body: unknown = {
|
||||
"/statistics/options": {headquarters:[{id:1,label:"Test-Niederlassung"}],currentHeadquarters:1,groups:[],excludeFreeCancellations:false,relatedCustomer:false},
|
||||
"/me": currentUser,
|
||||
"/system": system,
|
||||
"/customers": customers,
|
||||
@@ -486,7 +497,7 @@ for (const customerAccess of ["empty", "denied", "loaded"] as const) {
|
||||
await expect(dialog.getByText("KUNDE / ZAHLER", { exact: true })).toBeVisible();
|
||||
await expect(dialog.getByRole("heading", { name: "Testzahler Westwind", exact: true })).toBeVisible();
|
||||
await page.getByRole("button", { name: "Details schließen", exact: true }).click();
|
||||
for (const module of ["Disposition", "Touren", "Auswertung"]) {
|
||||
for (const module of ["Disposition", "Touren"]) {
|
||||
await page.getByRole("button", { name: module, exact: true }).click();
|
||||
await expect(page.locator("main").getByText("Testzahler Westwind", { exact: true })).toBeVisible();
|
||||
await expect(page.locator("main").getByText("Testkunde Nordlicht", { exact: true })).toHaveCount(0);
|
||||
@@ -496,7 +507,7 @@ for (const customerAccess of ["empty", "denied", "loaded"] as const) {
|
||||
});
|
||||
}
|
||||
|
||||
test("orders and reports show safe customer fallbacks for missing identities and names", async ({ page }) => {
|
||||
test("orders show safe customer fallbacks for missing identities and names", async ({ page }) => {
|
||||
const variants = [
|
||||
{ customerId: null, customerName: null, label: "Kunde nicht zugeordnet" },
|
||||
{ customerId: 0, customerName: "", label: "Kunde nicht zugeordnet" },
|
||||
@@ -517,27 +528,25 @@ test("orders and reports show safe customer fallbacks for missing identities and
|
||||
await expect(page.getByRole("dialog").getByRole("heading", { name: label, exact: true })).toBeVisible();
|
||||
await page.getByRole("button", { name: "Details schließen", exact: true }).click();
|
||||
}
|
||||
await page.getByRole("button", { name: "Auswertung", exact: true }).click();
|
||||
await expect(page.locator("main").getByText("Kunde nicht zugeordnet", { exact: true })).toHaveCount(3);
|
||||
await expect(page.locator("main").getByText("Kunde #44", { exact: true })).toBeVisible();
|
||||
await expect(page.locator("main").getByText("Testkunde Nordlicht", { exact: true })).toBeVisible();
|
||||
await expect(page.locator("main")).not.toContainText(/Kunde #(null|undefined|0)/);
|
||||
});
|
||||
|
||||
test("customer reports aggregate by customer ID and use a name from any matching order", async ({ page }) => {
|
||||
await mockApi(page, {
|
||||
"/customers": [],
|
||||
"/orders": [
|
||||
{ ...orders[0], customerName: null },
|
||||
{ ...orders[0], id: 880002, number: "880002", customerName: "Testzahler Westwind" },
|
||||
],
|
||||
});
|
||||
test("statistics use server totals beyond the order list and submit comparison filters", async ({ page }) => {
|
||||
await mockApi(page, { "/orders": [orders[0]] });
|
||||
await page.goto("/");
|
||||
await page.getByRole("button", { name: "Auswertung", exact: true }).click();
|
||||
const row = page.getByRole("row").filter({ hasText: "Testzahler Westwind" });
|
||||
await expect(row).toHaveCount(1);
|
||||
await expect(row.getByRole("cell").nth(1)).toHaveText("2");
|
||||
await expect(row.getByRole("cell").nth(2)).toHaveText("85,00 €");
|
||||
await expect(page.getByText("Geladener Ausschnitt:")).toHaveCount(0);
|
||||
await page.getByRole("button", { name: "Vergleichszeitraum", exact: true }).click();
|
||||
await page.getByLabel("Kunde", {exact:true}).check();
|
||||
const pending=page.waitForRequest("**/api/statistics/query");
|
||||
await page.getByRole("button", { name: "Statistik berechnen", exact: true }).click();
|
||||
const query=(await pending).postDataJSON();
|
||||
expect(query.comparisons).toHaveLength(1);
|
||||
expect(query.splits).toEqual(["HEADQUARTERS","CUSTOMER"]);
|
||||
expect(query.headquarters).toEqual([1]);
|
||||
const comparison=page.getByRole("heading",{name:"Zeiträume im Vergleich"}).locator("..");
|
||||
await expect(comparison.getByRole("cell",{name:"1234",exact:true})).toHaveCount(2);
|
||||
await expect(page.getByRole("button",{name:"Statistik als CSV"})).toBeVisible();
|
||||
});
|
||||
|
||||
test("order history loads on demand and shows newest events with safe multiline details", async ({
|
||||
|
||||
Reference in new issue
Block a user