diff --git a/backend/src/utils/functions.ts b/backend/src/utils/functions.ts index 3fa2e59..764fa48 100644 --- a/backend/src/utils/functions.ts +++ b/backend/src/utils/functions.ts @@ -5,7 +5,7 @@ import bwipjs from "bwip-js" import Sharp from "sharp" import { tenants } from "../../db/schema" -import { eq } from "drizzle-orm" +import { eq, sql } from "drizzle-orm" export const useNextNumberRangeNumber = async ( server: FastifyInstance, @@ -19,47 +19,53 @@ export const useNextNumberRangeNumber = async ( cancellationInvoices: "invoices", } - const [tenant] = await server.db - .select() - .from(tenants) - .where(eq(tenants.id, tenantId)) + return server.db.transaction(async (tx) => { + // Serialisiert Nummernvergaben dieses Mandanten auch ueber mehrere + // Backend-Prozesse hinweg, bis die Transaktion abgeschlossen ist. + await tx.execute(sql`select pg_advisory_xact_lock(${tenantId})`) - if (!tenant) { - throw new Error(`Tenant ${tenantId} not found`) - } + const [tenant] = await tx + .select() + .from(tenants) + .where(eq(tenants.id, tenantId)) - const numberRanges = tenant.numberRanges || {} + if (!tenant) { + throw new Error(`Tenant ${tenantId} not found`) + } - const resolvedNumberRange = numberRanges[numberRange] - ? numberRange - : numberRangeFallbacks[numberRange] + const numberRanges = tenant.numberRanges || {} - if (!resolvedNumberRange || !numberRanges[resolvedNumberRange]) { - throw new Error(`Number range '${numberRange}' not found`) - } + const resolvedNumberRange = numberRanges[numberRange] + ? numberRange + : numberRangeFallbacks[numberRange] - const current = numberRanges[resolvedNumberRange] + if (!resolvedNumberRange || !numberRanges[resolvedNumberRange]) { + throw new Error(`Number range '${numberRange}' not found`) + } - const usedNumber = - (current.prefix || "") + - current.nextNumber + - (current.suffix || "") + const current = numberRanges[resolvedNumberRange] - const updatedRanges = { - // @ts-ignore - ...numberRanges, - [resolvedNumberRange]: { - ...current, - nextNumber: current.nextNumber + 1, - }, - } + const usedNumber = + (current.prefix || "") + + current.nextNumber + + (current.suffix || "") - await server.db - .update(tenants) - .set({ numberRanges: updatedRanges }) - .where(eq(tenants.id, tenantId)) + const updatedRanges = { + // @ts-ignore + ...numberRanges, + [resolvedNumberRange]: { + ...current, + nextNumber: current.nextNumber + 1, + }, + } - return { usedNumber } + await tx + .update(tenants) + .set({ numberRanges: updatedRanges }) + .where(eq(tenants.id, tenantId)) + + return { usedNumber } + }) } export async function encodeBase64ToNiimbot(base64Png: string, printDirection: "top" | "left" = "top") { diff --git a/frontend/pages/createDocument/edit/[[id]].vue b/frontend/pages/createDocument/edit/[[id]].vue index bec580e..282d77c 100644 --- a/frontend/pages/createDocument/edit/[[id]].vue +++ b/frontend/pages/createDocument/edit/[[id]].vue @@ -1761,7 +1761,7 @@ const saveDocument = async (state, resetup = false) => { itemInfo.value.state = state normalizeCustomSurchargePercentage() - if (state !== "Entwurf") { + if (state !== "Entwurf" && !itemInfo.value.documentNumber) { console.log("???") const type = itemInfo.value.type