@open-mercato/core 0.4.7-develop-7c7b3f9d84 → 0.4.7-develop-d6331ed114
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/sales/api/payments/route.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +6 -9
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +16 -2
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +3 -8
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/package.json +3 -3
- package/src/modules/sales/api/payments/route.ts +2 -2
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +8 -16
- package/src/modules/sales/commands/payments.ts +19 -3
- package/src/modules/sales/components/documents/PaymentsSection.tsx +4 -9
|
@@ -238,6 +238,14 @@ const createPaymentCommand = {
|
|
|
238
238
|
ensureSameScope(method, input.organizationId, input.tenantId);
|
|
239
239
|
paymentMethod = method;
|
|
240
240
|
}
|
|
241
|
+
const orderPaymentMethodIdBefore = order.paymentMethodId ?? null;
|
|
242
|
+
const orderPaymentMethodCodeBefore = order.paymentMethodCode ?? null;
|
|
243
|
+
if (paymentMethod && !order.paymentMethodId) {
|
|
244
|
+
order.paymentMethodId = paymentMethod.id;
|
|
245
|
+
order.paymentMethodCode = paymentMethod.code ?? null;
|
|
246
|
+
order.updatedAt = /* @__PURE__ */ new Date();
|
|
247
|
+
em.persist(order);
|
|
248
|
+
}
|
|
241
249
|
if (input.documentStatusEntryId !== void 0) {
|
|
242
250
|
const orderStatus = await resolveDictionaryEntryValue(em, input.documentStatusEntryId ?? null);
|
|
243
251
|
if (input.documentStatusEntryId && !orderStatus) {
|
|
@@ -361,7 +369,7 @@ const createPaymentCommand = {
|
|
|
361
369
|
} catch (err) {
|
|
362
370
|
console.error("[sales.payments.create] Failed to create notification:", err);
|
|
363
371
|
}
|
|
364
|
-
return { paymentId: payment.id, orderTotals: totals };
|
|
372
|
+
return { paymentId: payment.id, orderTotals: totals, orderPaymentMethodIdBefore, orderPaymentMethodCodeBefore };
|
|
365
373
|
},
|
|
366
374
|
captureAfter: async (_input, result, ctx) => {
|
|
367
375
|
const em = ctx.container.resolve("em").fork();
|
|
@@ -380,7 +388,7 @@ const createPaymentCommand = {
|
|
|
380
388
|
tenantId: after.tenantId,
|
|
381
389
|
organizationId: after.organizationId,
|
|
382
390
|
snapshotAfter: after,
|
|
383
|
-
payload: { undo: { after } }
|
|
391
|
+
payload: { undo: { after, orderPaymentMethodIdBefore: result.orderPaymentMethodIdBefore ?? null, orderPaymentMethodCodeBefore: result.orderPaymentMethodCodeBefore ?? null } }
|
|
384
392
|
};
|
|
385
393
|
},
|
|
386
394
|
undo: async ({ logEntry, ctx }) => {
|
|
@@ -410,6 +418,12 @@ const createPaymentCommand = {
|
|
|
410
418
|
for (const id of orderIds) {
|
|
411
419
|
const order = await em.findOne(SalesOrder, { id });
|
|
412
420
|
if (!order) continue;
|
|
421
|
+
if (id === after.orderId && "orderPaymentMethodIdBefore" in (payload ?? {})) {
|
|
422
|
+
order.paymentMethodId = payload.orderPaymentMethodIdBefore ?? null;
|
|
423
|
+
order.paymentMethodCode = payload.orderPaymentMethodCodeBefore ?? null;
|
|
424
|
+
order.updatedAt = /* @__PURE__ */ new Date();
|
|
425
|
+
await em.flush();
|
|
426
|
+
}
|
|
413
427
|
await recomputeOrderPaymentTotals(em, order);
|
|
414
428
|
await em.flush();
|
|
415
429
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/sales/commands/payments.ts"],
|
|
4
|
-
"sourcesContent": ["// @ts-nocheck\n\nimport { registerCommand, type CommandHandler } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { loadCustomFieldValues } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { setRecordCustomFields } from '@open-mercato/core/modules/entities/lib/helpers'\nimport { E } from '#generated/entities.ids.generated'\nimport {\n SalesInvoice,\n SalesOrder,\n SalesOrderLine,\n SalesPayment,\n SalesPaymentAllocation,\n SalesPaymentMethod,\n} from '../data/entities'\nimport {\n paymentCreateSchema,\n paymentUpdateSchema,\n type PaymentCreateInput,\n type PaymentUpdateInput,\n} from '../data/validators'\nimport {\n assertFound,\n cloneJson,\n ensureOrganizationScope,\n ensureSameScope,\n ensureTenantScope,\n extractUndoPayload,\n toNumericString,\n} from './shared'\nimport { resolveDictionaryEntryValue } from '../lib/dictionaries'\nimport { invalidateCrudCache } from '@open-mercato/shared/lib/crud/cache'\nimport { emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveNotificationService } from '../../notifications/lib/notificationService'\nimport { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'\nimport { notificationTypes } from '../notifications'\n\nexport type PaymentAllocationSnapshot = {\n id: string\n orderId: string | null\n invoiceId: string | null\n amount: number\n currencyCode: string\n metadata: Record<string, unknown> | null\n}\n\nexport type PaymentSnapshot = {\n id: string\n orderId: string | null\n organizationId: string\n tenantId: string\n paymentMethodId: string | null\n paymentReference: string | null\n statusEntryId: string | null\n status: string | null\n amount: number\n currencyCode: string\n capturedAmount: number\n refundedAmount: number\n receivedAt: string | null\n capturedAt: string | null\n metadata: Record<string, unknown> | null\n customFields?: Record<string, unknown> | null\n customFieldSetId?: string | null\n allocations: PaymentAllocationSnapshot[]\n}\n\ntype PaymentUndoPayload = {\n before?: PaymentSnapshot | null\n after?: PaymentSnapshot | null\n}\n\nconst toNumber = (value: unknown): number => {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nconst normalizeCustomFieldsInput = (input: unknown): Record<string, unknown> =>\n input && typeof input === 'object' && !Array.isArray(input) ? (input as Record<string, unknown>) : {}\n\nconst paymentCrudEvents: CrudEventsConfig = {\n module: 'sales',\n entity: 'payment',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nconst ORDER_RESOURCE = 'sales.order'\n\nasync function invalidateOrderCache(container: any, order: SalesOrder | null | undefined, tenantId: string | null) {\n if (!order) return\n await invalidateCrudCache(\n container,\n ORDER_RESOURCE,\n { id: order.id, organizationId: order.organizationId, tenantId: order.tenantId },\n tenantId,\n 'updated'\n )\n}\n\nexport async function loadPaymentSnapshot(em: EntityManager, id: string): Promise<PaymentSnapshot | null> {\n const payment = await findOneWithDecryption(\n em,\n SalesPayment,\n { id },\n { populate: ['order', 'allocations', 'allocations.order', 'allocations.invoice'] },\n )\n if (!payment) return null\n const allocations: PaymentAllocationSnapshot[] = Array.from(payment.allocations ?? []).map((allocation) => ({\n id: allocation.id,\n orderId:\n typeof allocation.order === 'string'\n ? allocation.order\n : allocation.order?.id ?? (allocation as any).order_id ?? null,\n invoiceId:\n typeof allocation.invoice === 'string'\n ? allocation.invoice\n : allocation.invoice?.id ?? (allocation as any).invoice_id ?? null,\n amount: toNumber(allocation.amount),\n currencyCode: allocation.currencyCode,\n metadata: allocation.metadata ? cloneJson(allocation.metadata) : null,\n }))\n const customFieldValues = await loadCustomFieldValues({\n em,\n entityId: E.sales.sales_payment,\n recordIds: [payment.id],\n tenantIdByRecord: { [payment.id]: payment.tenantId ?? null },\n organizationIdByRecord: { [payment.id]: payment.organizationId ?? null },\n })\n const customFields = customFieldValues[payment.id]\n const normalizedCustomFields =\n customFields && Object.keys(customFields).length ? customFields : null\n return {\n id: payment.id,\n orderId: typeof payment.order === 'string' ? payment.order : payment.order?.id ?? null,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n paymentMethodId:\n typeof payment.paymentMethod === 'string'\n ? payment.paymentMethod\n : payment.paymentMethod?.id ?? null,\n paymentReference: payment.paymentReference ?? null,\n statusEntryId: payment.statusEntryId ?? null,\n status: payment.status ?? null,\n amount: toNumber(payment.amount),\n currencyCode: payment.currencyCode,\n capturedAmount: toNumber(payment.capturedAmount),\n refundedAmount: toNumber(payment.refundedAmount),\n receivedAt: payment.receivedAt ? payment.receivedAt.toISOString() : null,\n capturedAt: payment.capturedAt ? payment.capturedAt.toISOString() : null,\n metadata: payment.metadata ? cloneJson(payment.metadata) : null,\n customFields: normalizedCustomFields,\n customFieldSetId: (payment as any).customFieldSetId ?? (payment as any).custom_field_set_id ?? null,\n allocations,\n }\n}\n\nexport async function restorePaymentSnapshot(em: EntityManager, snapshot: PaymentSnapshot): Promise<void> {\n const orderRef = snapshot.orderId ? em.getReference(SalesOrder, snapshot.orderId) : null\n const methodRef = snapshot.paymentMethodId\n ? em.getReference(SalesPaymentMethod, snapshot.paymentMethodId)\n : null\n const entity =\n (await em.findOne(SalesPayment, { id: snapshot.id })) ??\n em.create(SalesPayment, {\n id: snapshot.id,\n createdAt: new Date(),\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n })\n entity.order = orderRef\n entity.paymentMethod = methodRef\n entity.organizationId = snapshot.organizationId\n entity.tenantId = snapshot.tenantId\n entity.paymentReference = snapshot.paymentReference\n entity.statusEntryId = snapshot.statusEntryId\n entity.status = snapshot.status\n entity.amount = toNumericString(snapshot.amount) ?? '0'\n entity.currencyCode = snapshot.currencyCode\n entity.capturedAmount = toNumericString(snapshot.capturedAmount) ?? '0'\n entity.refundedAmount = toNumericString(snapshot.refundedAmount) ?? '0'\n entity.receivedAt = snapshot.receivedAt ? new Date(snapshot.receivedAt) : null\n entity.capturedAt = snapshot.capturedAt ? new Date(snapshot.capturedAt) : null\n entity.metadata = snapshot.metadata ? cloneJson(snapshot.metadata) : null\n entity.customFieldSetId =\n (snapshot as any).customFieldSetId ?? (snapshot as any).custom_field_set_id ?? null\n entity.updatedAt = new Date()\n await em.flush()\n\n if ((snapshot as any).customFields !== undefined) {\n await setRecordCustomFields(em, {\n entityId: E.sales.sales_payment,\n recordId: entity.id,\n organizationId: entity.organizationId,\n tenantId: entity.tenantId,\n values:\n snapshot.customFields && typeof snapshot.customFields === 'object'\n ? (snapshot.customFields as Record<string, unknown>)\n : {},\n })\n }\n\n const existingAllocations = await em.find(SalesPaymentAllocation, { payment: entity })\n existingAllocations.forEach((allocation) => em.remove(allocation))\n snapshot.allocations.forEach((allocation) => {\n const order =\n allocation.orderId && typeof allocation.orderId === 'string'\n ? em.getReference(SalesOrder, allocation.orderId)\n : null\n const invoice =\n allocation.invoiceId && typeof allocation.invoiceId === 'string'\n ? em.getReference(SalesInvoice, allocation.invoiceId)\n : null\n const newAllocation = em.create(SalesPaymentAllocation, {\n payment: entity,\n order,\n invoice,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n amount: toNumericString(allocation.amount) ?? '0',\n currencyCode: allocation.currencyCode,\n metadata: allocation.metadata ? cloneJson(allocation.metadata) : null,\n })\n em.persist(newAllocation)\n })\n em.persist(entity)\n}\n\nasync function recomputeOrderPaymentTotals(\n em: EntityManager,\n order: SalesOrder\n): Promise<{ paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number }> {\n const orderId = order.id\n const scope = { organizationId: order.organizationId, tenantId: order.tenantId }\n\n const allocations = await findWithDecryption(\n em,\n SalesPaymentAllocation,\n { ...scope, order: orderId },\n { populate: ['payment'] },\n scope,\n )\n\n const paymentIds = new Set<string>()\n allocations.forEach((allocation) => {\n const paymentRef = allocation.payment\n const paymentId =\n typeof paymentRef === 'object' && paymentRef !== null\n ? paymentRef.id\n : typeof paymentRef === 'string'\n ? paymentRef\n : null\n if (paymentId) paymentIds.add(paymentId)\n })\n\n const payments =\n paymentIds.size > 0\n ? await em.find(SalesPayment, { id: { $in: Array.from(paymentIds) }, deletedAt: null, ...scope })\n : await em.find(SalesPayment, { order: orderId, deletedAt: null, ...scope })\n\n const resolvePaidAmount = (payment: SalesPayment) => {\n const captured = toNumber(payment.capturedAmount)\n return captured > 0 ? captured : toNumber(payment.amount)\n }\n\n const activePaymentIds = new Set(payments.map((payment) => payment.id))\n const paidTotal =\n allocations.length > 0\n ? allocations.reduce((sum, allocation) => {\n const paymentRef = allocation.payment\n const paymentId =\n typeof paymentRef === 'object' && paymentRef !== null\n ? paymentRef.id\n : typeof paymentRef === 'string'\n ? paymentRef\n : null\n if (paymentId && !activePaymentIds.has(paymentId)) return sum\n return sum + toNumber(allocation.amount)\n }, 0)\n : payments.reduce((sum, payment) => sum + resolvePaidAmount(payment), 0)\n\n const refundedTotal = payments.reduce(\n (sum, payment) => sum + toNumber(payment.refundedAmount),\n 0\n )\n\n const grandTotal = toNumber(order.grandTotalGrossAmount)\n const outstanding = Math.max(grandTotal - paidTotal + refundedTotal, 0)\n order.paidTotalAmount = toNumericString(paidTotal) ?? '0'\n order.refundedTotalAmount = toNumericString(refundedTotal) ?? '0'\n order.outstandingAmount = toNumericString(outstanding) ?? '0'\n return {\n paidTotalAmount: paidTotal,\n refundedTotalAmount: refundedTotal,\n outstandingAmount: outstanding,\n }\n}\n\nconst createPaymentCommand: CommandHandler<\n PaymentCreateInput,\n { paymentId: string; orderTotals?: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } }\n> = {\n id: 'sales.payments.create',\n async execute(rawInput, ctx) {\n const input = paymentCreateSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { translate } = await resolveTranslations()\n if (!input.orderId) {\n throw new CrudHttpError(400, { error: translate('sales.payments.order_required', 'Order is required for payments.') })\n }\n const order = assertFound(\n await em.findOne(SalesOrder, { id: input.orderId }),\n 'sales.payments.order_not_found'\n )\n ensureSameScope(order, input.organizationId, input.tenantId)\n if (order.deletedAt) {\n throw new CrudHttpError(404, { error: 'sales.payments.order_not_found' })\n }\n if (\n order.currencyCode &&\n input.currencyCode &&\n order.currencyCode.toUpperCase() !== input.currencyCode.toUpperCase()\n ) {\n throw new CrudHttpError(400, {\n error: translate('sales.payments.currency_mismatch', 'Payment currency must match the order currency.'),\n })\n }\n let paymentMethod = null\n if (input.paymentMethodId) {\n const method = assertFound(\n await em.findOne(SalesPaymentMethod, { id: input.paymentMethodId }),\n 'sales.payments.method_not_found'\n )\n ensureSameScope(method, input.organizationId, input.tenantId)\n paymentMethod = method\n }\n if (input.documentStatusEntryId !== undefined) {\n const orderStatus = await resolveDictionaryEntryValue(em, input.documentStatusEntryId ?? null)\n if (input.documentStatusEntryId && !orderStatus) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.'),\n })\n }\n order.statusEntryId = input.documentStatusEntryId ?? null\n order.status = orderStatus\n order.updatedAt = new Date()\n em.persist(order)\n }\n if (input.lineStatusEntryId !== undefined) {\n const lineStatus = await resolveDictionaryEntryValue(em, input.lineStatusEntryId ?? null)\n if (input.lineStatusEntryId && !lineStatus) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.'),\n })\n }\n const orderLines = await em.find(SalesOrderLine, { order })\n orderLines.forEach((line) => {\n line.statusEntryId = input.lineStatusEntryId ?? null\n line.status = lineStatus\n line.updatedAt = new Date()\n })\n orderLines.forEach((line) => em.persist(line))\n }\n const status = await resolveDictionaryEntryValue(em, input.statusEntryId ?? null)\n const payment = em.create(SalesPayment, {\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n order,\n paymentMethod,\n paymentReference: input.paymentReference ?? null,\n statusEntryId: input.statusEntryId ?? null,\n status,\n amount: toNumericString(input.amount) ?? '0',\n currencyCode: input.currencyCode,\n capturedAmount: toNumericString(input.capturedAmount) ?? '0',\n refundedAmount: toNumericString(input.refundedAmount) ?? '0',\n receivedAt: input.receivedAt ?? null,\n capturedAt: input.capturedAt ?? null,\n metadata: input.metadata ? cloneJson(input.metadata) : null,\n customFieldSetId: input.customFieldSetId ?? null,\n })\n const allocationInputs = Array.isArray(input.allocations) ? input.allocations : []\n const allocations = allocationInputs.length\n ? allocationInputs\n : [\n {\n orderId: input.orderId,\n invoiceId: null,\n amount: input.amount,\n currencyCode: input.currencyCode,\n metadata: null,\n },\n ]\n allocations.forEach((allocation) => {\n const orderRef = allocation.orderId ? em.getReference(SalesOrder, allocation.orderId) : order\n const invoiceRef = allocation.invoiceId ? em.getReference(SalesInvoice, allocation.invoiceId) : null\n const entity = em.create(SalesPaymentAllocation, {\n payment,\n order: orderRef,\n invoice: invoiceRef,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n amount: toNumericString(allocation.amount) ?? '0',\n currencyCode: allocation.currencyCode,\n metadata: allocation.metadata ? cloneJson(allocation.metadata) : null,\n })\n em.persist(entity)\n })\n em.persist(payment)\n if (input.customFields !== undefined) {\n if (!payment.id) {\n await em.flush()\n }\n await setRecordCustomFields(em, {\n entityId: E.sales.sales_payment,\n recordId: payment.id,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n values: normalizeCustomFieldsInput(input.customFields),\n })\n }\n await em.flush()\n const totals = await recomputeOrderPaymentTotals(em, order)\n await em.flush()\n await invalidateOrderCache(ctx.container, order, ctx.auth?.tenantId ?? null)\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'created',\n entity: payment,\n identifiers: {\n id: payment.id,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n },\n indexer: { entityType: E.sales.sales_payment },\n events: paymentCrudEvents,\n })\n\n // Create notification for payment received\n try {\n const notificationService = resolveNotificationService(ctx.container)\n const typeDef = notificationTypes.find((type) => type.type === 'sales.payment.received')\n if (typeDef) {\n const amountDisplay = payment.amount && payment.currencyCode\n ? `${payment.currencyCode} ${payment.amount}`\n : ''\n const notificationInput = buildFeatureNotificationFromType(typeDef, {\n requiredFeature: 'sales.orders.manage',\n bodyVariables: {\n orderNumber: order.orderNumber ?? '',\n amount: amountDisplay,\n },\n sourceEntityType: 'sales:order',\n sourceEntityId: order.id,\n linkHref: `/backend/sales/orders/${order.id}`,\n })\n\n await notificationService.createForFeature(notificationInput, {\n tenantId: payment.tenantId,\n organizationId: payment.organizationId ?? null,\n })\n }\n } catch (err) {\n // Notification creation is non-critical, don't fail the command\n console.error('[sales.payments.create] Failed to create notification:', err)\n }\n\n return { paymentId: payment.id, orderTotals: totals }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return result?.paymentId ? loadPaymentSnapshot(em, result.paymentId) : null\n },\n buildLog: async ({ result, snapshots }) => {\n const after = snapshots.after as PaymentSnapshot | undefined\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('sales.audit.payments.create', 'Create payment'),\n resourceKind: 'sales.payment',\n resourceId: result.paymentId,\n parentResourceKind: 'sales.order',\n parentResourceId: after.orderId ?? null,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n snapshotAfter: after,\n payload: { undo: { after } satisfies PaymentUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PaymentUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const existing = await em.findOne(SalesPayment, { id: after.id })\n if (existing) {\n const orderRef =\n typeof existing.order === 'string' ? existing.order : existing.order?.id ?? null\n const allocations = await em.find(SalesPaymentAllocation, { payment: existing })\n const allocationOrders = allocations\n .map((allocation) =>\n typeof allocation.order === 'string'\n ? allocation.order\n : allocation.order?.id ?? null\n )\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n\n allocations.forEach((allocation) => em.remove(allocation))\n await em.flush()\n\n em.remove(existing)\n await em.flush()\n\n const orderIds = Array.from(\n new Set(\n [\n orderRef,\n ...allocationOrders,\n ].filter((value): value is string => typeof value === 'string' && value.length > 0)\n )\n )\n for (const id of orderIds) {\n const order = await em.findOne(SalesOrder, { id })\n if (!order) continue\n await recomputeOrderPaymentTotals(em, order)\n await em.flush()\n }\n }\n },\n}\n\nconst updatePaymentCommand: CommandHandler<\n PaymentUpdateInput,\n { paymentId: string; orderTotals?: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } }\n> = {\n id: 'sales.payments.update',\n async prepare(rawInput, ctx) {\n const parsed = paymentUpdateSchema.parse(rawInput ?? {})\n if (!parsed.id) return {}\n const em = ctx.container.resolve('em') as EntityManager\n const snapshot = await loadPaymentSnapshot(em, parsed.id)\n if (snapshot) {\n ensureTenantScope(ctx, snapshot.tenantId)\n ensureOrganizationScope(ctx, snapshot.organizationId)\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const input = paymentUpdateSchema.parse(rawInput ?? {})\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { translate } = await resolveTranslations()\n const scopeSeed = assertFound(\n await em.findOne(SalesPayment, { id: input.id }),\n 'sales.payments.not_found'\n )\n const resolvedTenantId = input.tenantId ?? scopeSeed.tenantId\n const resolvedOrganizationId = input.organizationId ?? scopeSeed.organizationId\n ensureTenantScope(ctx, resolvedTenantId)\n ensureOrganizationScope(ctx, resolvedOrganizationId)\n const payment = assertFound(\n await findOneWithDecryption(\n em,\n SalesPayment,\n { id: input.id },\n { populate: ['order'] },\n { tenantId: resolvedTenantId, organizationId: resolvedOrganizationId },\n ),\n 'sales.payments.not_found'\n )\n ensureSameScope(payment, resolvedOrganizationId, resolvedTenantId)\n const previousOrder = payment.order as SalesOrder | null\n if (input.orderId !== undefined) {\n if (!input.orderId) {\n payment.order = null\n } else {\n const order = assertFound(\n await em.findOne(SalesOrder, { id: input.orderId }),\n 'sales.payments.order_not_found'\n )\n ensureSameScope(order, resolvedOrganizationId, resolvedTenantId)\n if (\n order.currencyCode &&\n input.currencyCode &&\n order.currencyCode.toUpperCase() !== input.currencyCode.toUpperCase()\n ) {\n throw new CrudHttpError(400, {\n error: translate('sales.payments.currency_mismatch', 'Payment currency must match the order currency.'),\n })\n }\n payment.order = order\n }\n }\n if (input.paymentMethodId !== undefined) {\n if (!input.paymentMethodId) {\n payment.paymentMethod = null\n } else {\n const method = assertFound(\n await em.findOne(SalesPaymentMethod, { id: input.paymentMethodId }),\n 'sales.payments.method_not_found'\n )\n ensureSameScope(method, resolvedOrganizationId, resolvedTenantId)\n payment.paymentMethod = method\n }\n }\n const currentOrder = payment.order as SalesOrder | null\n if ((input.documentStatusEntryId !== undefined || input.lineStatusEntryId !== undefined) && !currentOrder) {\n throw new CrudHttpError(400, { error: translate('sales.payments.order_required', 'Order is required for payments.') })\n }\n if (currentOrder && input.documentStatusEntryId !== undefined) {\n const orderStatus = await resolveDictionaryEntryValue(em, input.documentStatusEntryId ?? null)\n if (input.documentStatusEntryId && !orderStatus) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.'),\n })\n }\n currentOrder.statusEntryId = input.documentStatusEntryId ?? null\n currentOrder.status = orderStatus\n currentOrder.updatedAt = new Date()\n em.persist(currentOrder)\n }\n if (currentOrder && input.lineStatusEntryId !== undefined) {\n const lineStatus = await resolveDictionaryEntryValue(em, input.lineStatusEntryId ?? null)\n if (input.lineStatusEntryId && !lineStatus) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.'),\n })\n }\n const orderLines = await em.find(SalesOrderLine, { order: currentOrder })\n orderLines.forEach((line) => {\n line.statusEntryId = input.lineStatusEntryId ?? null\n line.status = lineStatus\n line.updatedAt = new Date()\n })\n orderLines.forEach((line) => em.persist(line))\n }\n if (input.paymentReference !== undefined) payment.paymentReference = input.paymentReference ?? null\n if (input.statusEntryId !== undefined) {\n payment.statusEntryId = input.statusEntryId ?? null\n payment.status = await resolveDictionaryEntryValue(em, input.statusEntryId ?? null)\n }\n if (input.amount !== undefined) payment.amount = toNumericString(input.amount) ?? '0'\n if (input.currencyCode !== undefined) payment.currencyCode = input.currencyCode\n if (input.capturedAmount !== undefined) {\n payment.capturedAmount = toNumericString(input.capturedAmount) ?? '0'\n }\n if (input.refundedAmount !== undefined) {\n payment.refundedAmount = toNumericString(input.refundedAmount) ?? '0'\n }\n if (input.receivedAt !== undefined) payment.receivedAt = input.receivedAt ?? null\n if (input.capturedAt !== undefined) payment.capturedAt = input.capturedAt ?? null\n if (input.metadata !== undefined) {\n payment.metadata = input.metadata ? cloneJson(input.metadata) : null\n }\n if (input.customFieldSetId !== undefined) {\n payment.customFieldSetId = input.customFieldSetId ?? null\n }\n if (input.customFields !== undefined) {\n if (!payment.id) {\n await em.flush()\n }\n await setRecordCustomFields(em, {\n entityId: E.sales.sales_payment,\n recordId: payment.id,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n values: normalizeCustomFieldsInput(input.customFields),\n })\n }\n if (input.allocations !== undefined) {\n const existingAllocations = await em.find(SalesPaymentAllocation, { payment })\n existingAllocations.forEach((allocation) => em.remove(allocation))\n const allocationInputs = Array.isArray(input.allocations) ? input.allocations : []\n allocationInputs.forEach((allocation) => {\n const orderRef =\n allocation.orderId ??\n (typeof payment.order === 'string' ? payment.order : payment.order?.id) ??\n null\n const order =\n orderRef && typeof orderRef === 'string' ? em.getReference(SalesOrder, orderRef) : null\n const invoice = allocation.invoiceId\n ? em.getReference(SalesInvoice, allocation.invoiceId)\n : null\n const entity = em.create(SalesPaymentAllocation, {\n payment,\n order,\n invoice,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n amount: toNumericString(allocation.amount) ?? '0',\n currencyCode: allocation.currencyCode,\n metadata: allocation.metadata ? cloneJson(allocation.metadata) : null,\n })\n em.persist(entity)\n })\n }\n payment.updatedAt = new Date()\n await em.flush()\n\n const nextOrder =\n (payment.order as SalesOrder | null) ??\n (typeof payment.order === 'string'\n ? await em.findOne(SalesOrder, { id: payment.order })\n : null)\n let totals: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } | undefined\n if (nextOrder) {\n totals = await recomputeOrderPaymentTotals(em, nextOrder)\n await em.flush()\n await invalidateOrderCache(ctx.container, nextOrder, ctx.auth?.tenantId ?? null)\n }\n if (previousOrder && (!nextOrder || previousOrder.id !== nextOrder.id)) {\n await recomputeOrderPaymentTotals(em, previousOrder)\n await em.flush()\n await invalidateOrderCache(ctx.container, previousOrder, ctx.auth?.tenantId ?? null)\n }\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'updated',\n entity: payment,\n identifiers: {\n id: payment.id,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n },\n indexer: { entityType: E.sales.sales_payment },\n events: paymentCrudEvents,\n })\n\n return { paymentId: payment.id, orderTotals: totals }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return result?.paymentId ? loadPaymentSnapshot(em, result.paymentId) : null\n },\n buildLog: async ({ snapshots, result }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as PaymentSnapshot | undefined\n const after = snapshots.after as PaymentSnapshot | undefined\n return {\n actionLabel: translate('sales.audit.payments.update', 'Update payment'),\n resourceKind: 'sales.payment',\n resourceId: result.paymentId,\n parentResourceKind: 'sales.order',\n parentResourceId: after?.orderId ?? before?.orderId ?? null,\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n snapshotAfter: after ?? null,\n payload: { undo: { before, after } satisfies PaymentUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PaymentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await restorePaymentSnapshot(em, before)\n await em.flush()\n if (before.orderId) {\n const order = await em.findOne(SalesOrder, { id: before.orderId })\n if (order) {\n await recomputeOrderPaymentTotals(em, order)\n await em.flush()\n }\n }\n },\n}\n\nconst deletePaymentCommand: CommandHandler<\n { id: string; orderId?: string | null; organizationId: string; tenantId: string },\n { paymentId: string; orderTotals?: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } }\n> = {\n id: 'sales.payments.delete',\n async prepare(rawInput, ctx) {\n const parsed = paymentUpdateSchema.parse(rawInput ?? {})\n if (!parsed.id) return {}\n const em = ctx.container.resolve('em') as EntityManager\n const snapshot = await loadPaymentSnapshot(em, parsed.id)\n if (snapshot) {\n ensureTenantScope(ctx, snapshot.tenantId)\n ensureOrganizationScope(ctx, snapshot.organizationId)\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const input = paymentUpdateSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const payment = assertFound(\n await findOneWithDecryption(\n em,\n SalesPayment,\n { id: input.id },\n { populate: ['order'] },\n { tenantId: input.tenantId, organizationId: input.organizationId },\n ),\n 'sales.payments.not_found'\n )\n ensureSameScope(payment, input.organizationId, input.tenantId)\n const order = payment.order as SalesOrder | null\n const allocations = await em.find(SalesPaymentAllocation, { payment })\n const allocationOrders = allocations\n .map((allocation) =>\n typeof allocation.order === 'string'\n ? allocation.order\n : allocation.order?.id ?? null\n )\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n allocations.forEach((allocation) => em.remove(allocation))\n await em.flush()\n em.remove(payment)\n await em.flush()\n let totals: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } | undefined\n const orderIds = Array.from(\n new Set(\n [\n order && typeof order === 'object' ? order.id : null,\n ...allocationOrders,\n ].filter((value): value is string => typeof value === 'string' && value.length > 0)\n )\n )\n const primaryOrderId = order && typeof order === 'object' ? order.id : null\n for (const orderId of orderIds) {\n const target = typeof order === 'object' && order.id === orderId ? order : await em.findOne(SalesOrder, { id: orderId })\n if (!target) continue\n const recomputed = await recomputeOrderPaymentTotals(em, target)\n if (!totals || (primaryOrderId && orderId === primaryOrderId)) {\n totals = recomputed\n }\n await em.flush()\n await invalidateOrderCache(ctx.container, target, ctx.auth?.tenantId ?? null)\n }\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: payment,\n identifiers: {\n id: payment.id,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n },\n indexer: { entityType: E.sales.sales_payment },\n events: paymentCrudEvents,\n })\n if (allocations.length) {\n await Promise.all(\n allocations.map((allocation) =>\n emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: allocation,\n identifiers: {\n id: allocation.id,\n organizationId: allocation.organizationId ?? null,\n tenantId: allocation.tenantId ?? null,\n },\n indexer: { entityType: E.sales.sales_payment_allocation },\n })\n )\n )\n }\n return { paymentId: payment.id, orderTotals: totals }\n },\n buildLog: async ({ snapshots, result }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as PaymentSnapshot | undefined\n return {\n actionLabel: translate('sales.audit.payments.delete', 'Delete payment'),\n resourceKind: 'sales.payment',\n resourceId: result.paymentId,\n parentResourceKind: 'sales.order',\n parentResourceId: before?.orderId ?? null,\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n payload: { undo: { before } satisfies PaymentUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PaymentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await restorePaymentSnapshot(em, before)\n await em.flush()\n if (before.orderId) {\n const order = await em.findOne(SalesOrder, { id: before.orderId })\n if (order) {\n await recomputeOrderPaymentTotals(em, order)\n await em.flush()\n }\n }\n },\n}\n\nexport const paymentCommands = [createPaymentCommand, updatePaymentCommand, deletePaymentCommand]\n\nregisterCommand(createPaymentCommand)\nregisterCommand(updatePaymentCommand)\nregisterCommand(deletePaymentCommand)\n"],
|
|
5
|
-
"mappings": "AAEA,SAAS,uBAA4C;AAErD,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AACtC,SAAS,6BAA6B;AACtC,SAAS,SAAS;AAClB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mCAAmC;AAC5C,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,uBAAuB,0BAA0B;AAC1D,SAAS,kCAAkC;AAC3C,SAAS,wCAAwC;AACjD,SAAS,yBAAyB;AAqClC,MAAM,WAAW,CAAC,UAA2B;AAC3C,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,QAAQ;AACpD,UAAM,SAAS,OAAO,KAAK;AAC3B,QAAI,CAAC,OAAO,MAAM,MAAM,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,MAAM,6BAA6B,CAAC,UAClC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAK,QAAoC,CAAC;AAEtG,MAAM,oBAAsC;AAAA,EAC1C,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,EAC5B;AACF;AAEA,MAAM,iBAAiB;AAEvB,eAAe,qBAAqB,WAAgB,OAAsC,UAAyB;AACjH,MAAI,CAAC,MAAO;AACZ,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,EAAE,IAAI,MAAM,IAAI,gBAAgB,MAAM,gBAAgB,UAAU,MAAM,SAAS;AAAA,IAC/E;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,oBAAoB,IAAmB,IAA6C;AACxG,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,EAAE,GAAG;AAAA,IACL,EAAE,UAAU,CAAC,SAAS,eAAe,qBAAqB,qBAAqB,EAAE;AAAA,EACnF;AACA,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,cAA2C,MAAM,KAAK,QAAQ,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB;AAAA,IAC1G,IAAI,WAAW;AAAA,IACf,SACE,OAAO,WAAW,UAAU,WACxB,WAAW,QACX,WAAW,OAAO,MAAO,WAAmB,YAAY;AAAA,IAC9D,WACE,OAAO,WAAW,YAAY,WAC1B,WAAW,UACX,WAAW,SAAS,MAAO,WAAmB,cAAc;AAAA,IAClE,QAAQ,SAAS,WAAW,MAAM;AAAA,IAClC,cAAc,WAAW;AAAA,IACzB,UAAU,WAAW,WAAW,UAAU,WAAW,QAAQ,IAAI;AAAA,EACnE,EAAE;AACF,QAAM,oBAAoB,MAAM,sBAAsB;AAAA,IACpD;AAAA,IACA,UAAU,EAAE,MAAM;AAAA,IAClB,WAAW,CAAC,QAAQ,EAAE;AAAA,IACtB,kBAAkB,EAAE,CAAC,QAAQ,EAAE,GAAG,QAAQ,YAAY,KAAK;AAAA,IAC3D,wBAAwB,EAAE,CAAC,QAAQ,EAAE,GAAG,QAAQ,kBAAkB,KAAK;AAAA,EACzE,CAAC;AACD,QAAM,eAAe,kBAAkB,QAAQ,EAAE;AACjD,QAAM,yBACJ,gBAAgB,OAAO,KAAK,YAAY,EAAE,SAAS,eAAe;AACpE,SAAO;AAAA,IACL,IAAI,QAAQ;AAAA,IACZ,SAAS,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,QAAQ,OAAO,MAAM;AAAA,IAClF,gBAAgB,QAAQ;AAAA,IACxB,UAAU,QAAQ;AAAA,IAClB,iBACE,OAAO,QAAQ,kBAAkB,WAC7B,QAAQ,gBACR,QAAQ,eAAe,MAAM;AAAA,IACnC,kBAAkB,QAAQ,oBAAoB;AAAA,IAC9C,eAAe,QAAQ,iBAAiB;AAAA,IACxC,QAAQ,QAAQ,UAAU;AAAA,IAC1B,QAAQ,SAAS,QAAQ,MAAM;AAAA,IAC/B,cAAc,QAAQ;AAAA,IACtB,gBAAgB,SAAS,QAAQ,cAAc;AAAA,IAC/C,gBAAgB,SAAS,QAAQ,cAAc;AAAA,IAC/C,YAAY,QAAQ,aAAa,QAAQ,WAAW,YAAY,IAAI;AAAA,IACpE,YAAY,QAAQ,aAAa,QAAQ,WAAW,YAAY,IAAI;AAAA,IACpE,UAAU,QAAQ,WAAW,UAAU,QAAQ,QAAQ,IAAI;AAAA,IAC3D,cAAc;AAAA,IACd,kBAAmB,QAAgB,oBAAqB,QAAgB,uBAAuB;AAAA,IAC/F;AAAA,EACF;AACF;AAEA,eAAsB,uBAAuB,IAAmB,UAA0C;AACxG,QAAM,WAAW,SAAS,UAAU,GAAG,aAAa,YAAY,SAAS,OAAO,IAAI;AACpF,QAAM,YAAY,SAAS,kBACvB,GAAG,aAAa,oBAAoB,SAAS,eAAe,IAC5D;AACJ,QAAM,SACH,MAAM,GAAG,QAAQ,cAAc,EAAE,IAAI,SAAS,GAAG,CAAC,KACnD,GAAG,OAAO,cAAc;AAAA,IACtB,IAAI,SAAS;AAAA,IACb,WAAW,oBAAI,KAAK;AAAA,IACpB,gBAAgB,SAAS;AAAA,IACzB,UAAU,SAAS;AAAA,EACrB,CAAC;AACH,SAAO,QAAQ;AACf,SAAO,gBAAgB;AACvB,SAAO,iBAAiB,SAAS;AACjC,SAAO,WAAW,SAAS;AAC3B,SAAO,mBAAmB,SAAS;AACnC,SAAO,gBAAgB,SAAS;AAChC,SAAO,SAAS,SAAS;AACzB,SAAO,SAAS,gBAAgB,SAAS,MAAM,KAAK;AACpD,SAAO,eAAe,SAAS;AAC/B,SAAO,iBAAiB,gBAAgB,SAAS,cAAc,KAAK;AACpE,SAAO,iBAAiB,gBAAgB,SAAS,cAAc,KAAK;AACpE,SAAO,aAAa,SAAS,aAAa,IAAI,KAAK,SAAS,UAAU,IAAI;AAC1E,SAAO,aAAa,SAAS,aAAa,IAAI,KAAK,SAAS,UAAU,IAAI;AAC1E,SAAO,WAAW,SAAS,WAAW,UAAU,SAAS,QAAQ,IAAI;AACrE,SAAO,mBACJ,SAAiB,oBAAqB,SAAiB,uBAAuB;AACjF,SAAO,YAAY,oBAAI,KAAK;AAC5B,QAAM,GAAG,MAAM;AAEf,MAAK,SAAiB,iBAAiB,QAAW;AAChD,UAAM,sBAAsB,IAAI;AAAA,MAC9B,UAAU,EAAE,MAAM;AAAA,MAClB,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,UAAU,OAAO;AAAA,MACjB,QACE,SAAS,gBAAgB,OAAO,SAAS,iBAAiB,WACrD,SAAS,eACV,CAAC;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,sBAAsB,MAAM,GAAG,KAAK,wBAAwB,EAAE,SAAS,OAAO,CAAC;AACrF,sBAAoB,QAAQ,CAAC,eAAe,GAAG,OAAO,UAAU,CAAC;AACjE,WAAS,YAAY,QAAQ,CAAC,eAAe;AAC3C,UAAM,QACJ,WAAW,WAAW,OAAO,WAAW,YAAY,WAChD,GAAG,aAAa,YAAY,WAAW,OAAO,IAC9C;AACN,UAAM,UACJ,WAAW,aAAa,OAAO,WAAW,cAAc,WACpD,GAAG,aAAa,cAAc,WAAW,SAAS,IAClD;AACN,UAAM,gBAAgB,GAAG,OAAO,wBAAwB;AAAA,MACtD,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,gBAAgB,SAAS;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,QAAQ,gBAAgB,WAAW,MAAM,KAAK;AAAA,MAC9C,cAAc,WAAW;AAAA,MACzB,UAAU,WAAW,WAAW,UAAU,WAAW,QAAQ,IAAI;AAAA,IACnE,CAAC;AACD,OAAG,QAAQ,aAAa;AAAA,EAC1B,CAAC;AACD,KAAG,QAAQ,MAAM;AACnB;AAEA,eAAe,4BACb,IACA,OAC8F;AAC9F,QAAM,UAAU,MAAM;AACtB,QAAM,QAAQ,EAAE,gBAAgB,MAAM,gBAAgB,UAAU,MAAM,SAAS;AAE/E,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,IACA,EAAE,GAAG,OAAO,OAAO,QAAQ;AAAA,IAC3B,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,aAAa,oBAAI,IAAY;AACnC,cAAY,QAAQ,CAAC,eAAe;AAClC,UAAM,aAAa,WAAW;AAC9B,UAAM,YACJ,OAAO,eAAe,YAAY,eAAe,OAC7C,WAAW,KACX,OAAO,eAAe,WACpB,aACA;AACR,QAAI,UAAW,YAAW,IAAI,SAAS;AAAA,EACzC,CAAC;AAED,QAAM,WACJ,WAAW,OAAO,IACd,MAAM,GAAG,KAAK,cAAc,EAAE,IAAI,EAAE,KAAK,MAAM,KAAK,UAAU,EAAE,GAAG,WAAW,MAAM,GAAG,MAAM,CAAC,IAC9F,MAAM,GAAG,KAAK,cAAc,EAAE,OAAO,SAAS,WAAW,MAAM,GAAG,MAAM,CAAC;AAE/E,QAAM,oBAAoB,CAAC,YAA0B;AACnD,UAAM,WAAW,SAAS,QAAQ,cAAc;AAChD,WAAO,WAAW,IAAI,WAAW,SAAS,QAAQ,MAAM;AAAA,EAC1D;AAEA,QAAM,mBAAmB,IAAI,IAAI,SAAS,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC;AACtE,QAAM,YACJ,YAAY,SAAS,IACjB,YAAY,OAAO,CAAC,KAAK,eAAe;AACtC,UAAM,aAAa,WAAW;AAC9B,UAAM,YACJ,OAAO,eAAe,YAAY,eAAe,OAC7C,WAAW,KACX,OAAO,eAAe,WACpB,aACA;AACR,QAAI,aAAa,CAAC,iBAAiB,IAAI,SAAS,EAAG,QAAO;AAC1D,WAAO,MAAM,SAAS,WAAW,MAAM;AAAA,EACzC,GAAG,CAAC,IACJ,SAAS,OAAO,CAAC,KAAK,YAAY,MAAM,kBAAkB,OAAO,GAAG,CAAC;AAE3E,QAAM,gBAAgB,SAAS;AAAA,IAC7B,CAAC,KAAK,YAAY,MAAM,SAAS,QAAQ,cAAc;AAAA,IACvD;AAAA,EACF;AAEA,QAAM,aAAa,SAAS,MAAM,qBAAqB;AACvD,QAAM,cAAc,KAAK,IAAI,aAAa,YAAY,eAAe,CAAC;AACtE,QAAM,kBAAkB,gBAAgB,SAAS,KAAK;AACtD,QAAM,sBAAsB,gBAAgB,aAAa,KAAK;AAC9D,QAAM,oBAAoB,gBAAgB,WAAW,KAAK;AAC1D,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,EACrB;AACF;AAEA,MAAM,uBAGF;AAAA,EACF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACtD,sBAAkB,KAAK,MAAM,QAAQ;AACrC,4BAAwB,KAAK,MAAM,cAAc;AACjD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,QAAI,CAAC,MAAM,SAAS;AAClB,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,iCAAiC,iCAAiC,EAAE,CAAC;AAAA,IACvH;AACA,UAAM,QAAQ;AAAA,MACZ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,MAClD;AAAA,IACF;AACA,oBAAgB,OAAO,MAAM,gBAAgB,MAAM,QAAQ;AAC3D,QAAI,MAAM,WAAW;AACnB,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,iCAAiC,CAAC;AAAA,IAC1E;AACA,QACE,MAAM,gBACN,MAAM,gBACN,MAAM,aAAa,YAAY,MAAM,MAAM,aAAa,YAAY,GACpE;AACA,YAAM,IAAI,cAAc,KAAK;AAAA,QAC3B,OAAO,UAAU,oCAAoC,iDAAiD;AAAA,MACxG,CAAC;AAAA,IACH;AACA,QAAI,gBAAgB;AACpB,QAAI,MAAM,iBAAiB;AACzB,YAAM,SAAS;AAAA,QACb,MAAM,GAAG,QAAQ,oBAAoB,EAAE,IAAI,MAAM,gBAAgB,CAAC;AAAA,QAClE;AAAA,MACF;AACA,sBAAgB,QAAQ,MAAM,gBAAgB,MAAM,QAAQ;AAC5D,sBAAgB;AAAA,IAClB;AACA,QAAI,MAAM,0BAA0B,QAAW;AAC7C,YAAM,cAAc,MAAM,4BAA4B,IAAI,MAAM,yBAAyB,IAAI;AAC7F,UAAI,MAAM,yBAAyB,CAAC,aAAa;AAC/C,cAAM,IAAI,cAAc,KAAK;AAAA,UAC3B,OAAO,UAAU,wCAAwC,qCAAqC;AAAA,QAChG,CAAC;AAAA,MACH;AACA,YAAM,gBAAgB,MAAM,yBAAyB;AACrD,YAAM,SAAS;AACf,YAAM,YAAY,oBAAI,KAAK;AAC3B,SAAG,QAAQ,KAAK;AAAA,IAClB;AACA,QAAI,MAAM,sBAAsB,QAAW;AACzC,YAAM,aAAa,MAAM,4BAA4B,IAAI,MAAM,qBAAqB,IAAI;AACxF,UAAI,MAAM,qBAAqB,CAAC,YAAY;AAC1C,cAAM,IAAI,cAAc,KAAK;AAAA,UAC3B,OAAO,UAAU,wCAAwC,qCAAqC;AAAA,QAChG,CAAC;AAAA,MACH;AACA,YAAM,aAAa,MAAM,GAAG,KAAK,gBAAgB,EAAE,MAAM,CAAC;AAC1D,iBAAW,QAAQ,CAAC,SAAS;AAC3B,aAAK,gBAAgB,MAAM,qBAAqB;AAChD,aAAK,SAAS;AACd,aAAK,YAAY,oBAAI,KAAK;AAAA,MAC5B,CAAC;AACD,iBAAW,QAAQ,CAAC,SAAS,GAAG,QAAQ,IAAI,CAAC;AAAA,IAC/C;AACA,UAAM,SAAS,MAAM,4BAA4B,IAAI,MAAM,iBAAiB,IAAI;AAChF,UAAM,UAAU,GAAG,OAAO,cAAc;AAAA,MACtC,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,MACA,kBAAkB,MAAM,oBAAoB;AAAA,MAC5C,eAAe,MAAM,iBAAiB;AAAA,MACtC;AAAA,MACA,QAAQ,gBAAgB,MAAM,MAAM,KAAK;AAAA,MACzC,cAAc,MAAM;AAAA,MACpB,gBAAgB,gBAAgB,MAAM,cAAc,KAAK;AAAA,MACzD,gBAAgB,gBAAgB,MAAM,cAAc,KAAK;AAAA,MACzD,YAAY,MAAM,cAAc;AAAA,MAChC,YAAY,MAAM,cAAc;AAAA,MAChC,UAAU,MAAM,WAAW,UAAU,MAAM,QAAQ,IAAI;AAAA,MACvD,kBAAkB,MAAM,oBAAoB;AAAA,IAC9C,CAAC;AACD,UAAM,mBAAmB,MAAM,QAAQ,MAAM,WAAW,IAAI,MAAM,cAAc,CAAC;AACjF,UAAM,cAAc,iBAAiB,SACjC,mBACA;AAAA,MACE;AAAA,QACE,SAAS,MAAM;AAAA,QACf,WAAW;AAAA,QACX,QAAQ,MAAM;AAAA,QACd,cAAc,MAAM;AAAA,QACpB,UAAU;AAAA,MACZ;AAAA,IACF;AACJ,gBAAY,QAAQ,CAAC,eAAe;AAClC,YAAM,WAAW,WAAW,UAAU,GAAG,aAAa,YAAY,WAAW,OAAO,IAAI;AACxF,YAAM,aAAa,WAAW,YAAY,GAAG,aAAa,cAAc,WAAW,SAAS,IAAI;AAChG,YAAM,SAAS,GAAG,OAAO,wBAAwB;AAAA,QAC/C;AAAA,QACA,OAAO;AAAA,QACP,SAAS;AAAA,QACT,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB,QAAQ,gBAAgB,WAAW,MAAM,KAAK;AAAA,QAC9C,cAAc,WAAW;AAAA,QACzB,UAAU,WAAW,WAAW,UAAU,WAAW,QAAQ,IAAI;AAAA,MACnE,CAAC;AACD,SAAG,QAAQ,MAAM;AAAA,IACnB,CAAC;AACD,OAAG,QAAQ,OAAO;AAClB,QAAI,MAAM,iBAAiB,QAAW;AACpC,UAAI,CAAC,QAAQ,IAAI;AACf,cAAM,GAAG,MAAM;AAAA,MACjB;AACA,YAAM,sBAAsB,IAAI;AAAA,QAC9B,UAAU,EAAE,MAAM;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB,QAAQ,2BAA2B,MAAM,YAAY;AAAA,MACvD,CAAC;AAAA,IACH;AACA,UAAM,GAAG,MAAM;AACf,UAAM,SAAS,MAAM,4BAA4B,IAAI,KAAK;AAC1D,UAAM,GAAG,MAAM;AACf,UAAM,qBAAqB,IAAI,WAAW,OAAO,IAAI,MAAM,YAAY,IAAI;AAE3E,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,QAAQ;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,UAAU,QAAQ;AAAA,MACpB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc;AAAA,MAC7C,QAAQ;AAAA,IACV,CAAC;AAGD,QAAI;AACF,YAAM,sBAAsB,2BAA2B,IAAI,SAAS;AACpE,YAAM,UAAU,kBAAkB,KAAK,CAAC,SAAS,KAAK,SAAS,wBAAwB;AACvF,UAAI,SAAS;AACX,cAAM,gBAAgB,QAAQ,UAAU,QAAQ,eAC5C,GAAG,QAAQ,YAAY,IAAI,QAAQ,MAAM,KACzC;AACJ,cAAM,oBAAoB,iCAAiC,SAAS;AAAA,UAClE,iBAAiB;AAAA,UACjB,eAAe;AAAA,YACb,aAAa,MAAM,eAAe;AAAA,YAClC,QAAQ;AAAA,UACV;AAAA,UACA,kBAAkB;AAAA,UAClB,gBAAgB,MAAM;AAAA,UACtB,UAAU,yBAAyB,MAAM,EAAE;AAAA,QAC7C,CAAC;AAED,cAAM,oBAAoB,iBAAiB,mBAAmB;AAAA,UAC5D,UAAU,QAAQ;AAAA,UAClB,gBAAgB,QAAQ,kBAAkB;AAAA,QAC5C,CAAC;AAAA,MACH;AAAA,IACF,SAAS,KAAK;AAEZ,cAAQ,MAAM,0DAA0D,GAAG;AAAA,IAC7E;AAEA,WAAO,EAAE,WAAW,QAAQ,IAAI,aAAa,OAAO;AAAA,EACtD;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,QAAQ,YAAY,oBAAoB,IAAI,OAAO,SAAS,IAAI;AAAA,EACzE;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,QAAQ,UAAU;AACxB,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,WAAO;AAAA,MACL,aAAa,UAAU,+BAA+B,gBAAgB;AAAA,MACtE,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,MAAM,WAAW;AAAA,MACnC,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,eAAe;AAAA,MACf,SAAS,EAAE,MAAM,EAAE,MAAM,EAA+B;AAAA,IAC1D;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,MAAO;AACZ,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,MAAM,GAAG,QAAQ,cAAc,EAAE,IAAI,MAAM,GAAG,CAAC;AAChE,QAAI,UAAU;AACZ,YAAM,WACJ,OAAO,SAAS,UAAU,WAAW,SAAS,QAAQ,SAAS,OAAO,MAAM;AAC9E,YAAM,cAAc,MAAM,GAAG,KAAK,wBAAwB,EAAE,SAAS,SAAS,CAAC;AAC/E,YAAM,mBAAmB,YACtB;AAAA,QAAI,CAAC,eACJ,OAAO,WAAW,UAAU,WACxB,WAAW,QACX,WAAW,OAAO,MAAM;AAAA,MAC9B,EACC,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAEnF,kBAAY,QAAQ,CAAC,eAAe,GAAG,OAAO,UAAU,CAAC;AACzD,YAAM,GAAG,MAAM;AAEf,SAAG,OAAO,QAAQ;AAClB,YAAM,GAAG,MAAM;AAEf,YAAM,WAAW,MAAM;AAAA,QACrB,IAAI;AAAA,UACF;AAAA,YACE;AAAA,YACA,GAAG;AAAA,UACL,EAAE,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAAA,QACpF;AAAA,MACF;AACA,iBAAW,MAAM,UAAU;AACzB,cAAM,QAAQ,MAAM,GAAG,QAAQ,YAAY,EAAE,GAAG,CAAC;AACjD,YAAI,CAAC,MAAO;AACZ,cAAM,4BAA4B,IAAI,KAAK;AAC3C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,uBAGF;AAAA,EACF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACvD,QAAI,CAAC,OAAO,GAAI,QAAO,CAAC;AACxB,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,UAAM,WAAW,MAAM,oBAAoB,IAAI,OAAO,EAAE;AACxD,QAAI,UAAU;AACZ,wBAAkB,KAAK,SAAS,QAAQ;AACxC,8BAAwB,KAAK,SAAS,cAAc;AAAA,IACtD;AACA,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACtD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,YAAY;AAAA,MAChB,MAAM,GAAG,QAAQ,cAAc,EAAE,IAAI,MAAM,GAAG,CAAC;AAAA,MAC/C;AAAA,IACF;AACA,UAAM,mBAAmB,MAAM,YAAY,UAAU;AACrD,UAAM,yBAAyB,MAAM,kBAAkB,UAAU;AACjE,sBAAkB,KAAK,gBAAgB;AACvC,4BAAwB,KAAK,sBAAsB;AACnD,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,EAAE,IAAI,MAAM,GAAG;AAAA,QACf,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,QACtB,EAAE,UAAU,kBAAkB,gBAAgB,uBAAuB;AAAA,MACvE;AAAA,MACA;AAAA,IACF;AACA,oBAAgB,SAAS,wBAAwB,gBAAgB;AACjE,UAAM,gBAAgB,QAAQ;AAC9B,QAAI,MAAM,YAAY,QAAW;AAC/B,UAAI,CAAC,MAAM,SAAS;AAClB,gBAAQ,QAAQ;AAAA,MAClB,OAAO;AACL,cAAM,QAAQ;AAAA,UACZ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,UAClD;AAAA,QACF;AACA,wBAAgB,OAAO,wBAAwB,gBAAgB;AAC/D,YACE,MAAM,gBACN,MAAM,gBACN,MAAM,aAAa,YAAY,MAAM,MAAM,aAAa,YAAY,GACpE;AACA,gBAAM,IAAI,cAAc,KAAK;AAAA,YAC3B,OAAO,UAAU,oCAAoC,iDAAiD;AAAA,UACxG,CAAC;AAAA,QACH;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AACA,QAAI,MAAM,oBAAoB,QAAW;AACvC,UAAI,CAAC,MAAM,iBAAiB;AAC1B,gBAAQ,gBAAgB;AAAA,MAC1B,OAAO;AACL,cAAM,SAAS;AAAA,UACb,MAAM,GAAG,QAAQ,oBAAoB,EAAE,IAAI,MAAM,gBAAgB,CAAC;AAAA,UAClE;AAAA,QACF;AACA,wBAAgB,QAAQ,wBAAwB,gBAAgB;AAChE,gBAAQ,gBAAgB;AAAA,MAC1B;AAAA,IACF;AACA,UAAM,eAAe,QAAQ;AAC7B,SAAK,MAAM,0BAA0B,UAAa,MAAM,sBAAsB,WAAc,CAAC,cAAc;AACzG,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,iCAAiC,iCAAiC,EAAE,CAAC;AAAA,IACvH;AACA,QAAI,gBAAgB,MAAM,0BAA0B,QAAW;AAC7D,YAAM,cAAc,MAAM,4BAA4B,IAAI,MAAM,yBAAyB,IAAI;AAC7F,UAAI,MAAM,yBAAyB,CAAC,aAAa;AAC/C,cAAM,IAAI,cAAc,KAAK;AAAA,UAC3B,OAAO,UAAU,wCAAwC,qCAAqC;AAAA,QAChG,CAAC;AAAA,MACH;AACA,mBAAa,gBAAgB,MAAM,yBAAyB;AAC5D,mBAAa,SAAS;AACtB,mBAAa,YAAY,oBAAI,KAAK;AAClC,SAAG,QAAQ,YAAY;AAAA,IACzB;AACA,QAAI,gBAAgB,MAAM,sBAAsB,QAAW;AACzD,YAAM,aAAa,MAAM,4BAA4B,IAAI,MAAM,qBAAqB,IAAI;AACxF,UAAI,MAAM,qBAAqB,CAAC,YAAY;AAC1C,cAAM,IAAI,cAAc,KAAK;AAAA,UAC3B,OAAO,UAAU,wCAAwC,qCAAqC;AAAA,QAChG,CAAC;AAAA,MACH;AACA,YAAM,aAAa,MAAM,GAAG,KAAK,gBAAgB,EAAE,OAAO,aAAa,CAAC;AACxE,iBAAW,QAAQ,CAAC,SAAS;AAC3B,aAAK,gBAAgB,MAAM,qBAAqB;AAChD,aAAK,SAAS;AACd,aAAK,YAAY,oBAAI,KAAK;AAAA,MAC5B,CAAC;AACD,iBAAW,QAAQ,CAAC,SAAS,GAAG,QAAQ,IAAI,CAAC;AAAA,IAC/C;AACA,QAAI,MAAM,qBAAqB,OAAW,SAAQ,mBAAmB,MAAM,oBAAoB;AAC/F,QAAI,MAAM,kBAAkB,QAAW;AACrC,cAAQ,gBAAgB,MAAM,iBAAiB;AAC/C,cAAQ,SAAS,MAAM,4BAA4B,IAAI,MAAM,iBAAiB,IAAI;AAAA,IACpF;AACA,QAAI,MAAM,WAAW,OAAW,SAAQ,SAAS,gBAAgB,MAAM,MAAM,KAAK;AAClF,QAAI,MAAM,iBAAiB,OAAW,SAAQ,eAAe,MAAM;AACnE,QAAI,MAAM,mBAAmB,QAAW;AACtC,cAAQ,iBAAiB,gBAAgB,MAAM,cAAc,KAAK;AAAA,IACpE;AACA,QAAI,MAAM,mBAAmB,QAAW;AACtC,cAAQ,iBAAiB,gBAAgB,MAAM,cAAc,KAAK;AAAA,IACpE;AACA,QAAI,MAAM,eAAe,OAAW,SAAQ,aAAa,MAAM,cAAc;AAC7E,QAAI,MAAM,eAAe,OAAW,SAAQ,aAAa,MAAM,cAAc;AAC7E,QAAI,MAAM,aAAa,QAAW;AAChC,cAAQ,WAAW,MAAM,WAAW,UAAU,MAAM,QAAQ,IAAI;AAAA,IAClE;AACA,QAAI,MAAM,qBAAqB,QAAW;AACxC,cAAQ,mBAAmB,MAAM,oBAAoB;AAAA,IACvD;AACA,QAAI,MAAM,iBAAiB,QAAW;AACpC,UAAI,CAAC,QAAQ,IAAI;AACf,cAAM,GAAG,MAAM;AAAA,MACjB;AACA,YAAM,sBAAsB,IAAI;AAAA,QAC9B,UAAU,EAAE,MAAM;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,gBAAgB,QAAQ;AAAA,QACxB,UAAU,QAAQ;AAAA,QAClB,QAAQ,2BAA2B,MAAM,YAAY;AAAA,MACvD,CAAC;AAAA,IACH;AACA,QAAI,MAAM,gBAAgB,QAAW;AACnC,YAAM,sBAAsB,MAAM,GAAG,KAAK,wBAAwB,EAAE,QAAQ,CAAC;AAC7E,0BAAoB,QAAQ,CAAC,eAAe,GAAG,OAAO,UAAU,CAAC;AACjE,YAAM,mBAAmB,MAAM,QAAQ,MAAM,WAAW,IAAI,MAAM,cAAc,CAAC;AACjF,uBAAiB,QAAQ,CAAC,eAAe;AACvC,cAAM,WACJ,WAAW,YACV,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,QAAQ,OAAO,OACpE;AACF,cAAM,QACJ,YAAY,OAAO,aAAa,WAAW,GAAG,aAAa,YAAY,QAAQ,IAAI;AACrF,cAAM,UAAU,WAAW,YACvB,GAAG,aAAa,cAAc,WAAW,SAAS,IAClD;AACJ,cAAM,SAAS,GAAG,OAAO,wBAAwB;AAAA,UAC/C;AAAA,UACA;AAAA,UACA;AAAA,UACA,gBAAgB,QAAQ;AAAA,UACxB,UAAU,QAAQ;AAAA,UAClB,QAAQ,gBAAgB,WAAW,MAAM,KAAK;AAAA,UAC9C,cAAc,WAAW;AAAA,UACzB,UAAU,WAAW,WAAW,UAAU,WAAW,QAAQ,IAAI;AAAA,QACnE,CAAC;AACD,WAAG,QAAQ,MAAM;AAAA,MACnB,CAAC;AAAA,IACH;AACA,YAAQ,YAAY,oBAAI,KAAK;AAC7B,UAAM,GAAG,MAAM;AAEf,UAAM,YACH,QAAQ,UACR,OAAO,QAAQ,UAAU,WACtB,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,QAAQ,MAAM,CAAC,IAClD;AACN,QAAI;AACJ,QAAI,WAAW;AACb,eAAS,MAAM,4BAA4B,IAAI,SAAS;AACxD,YAAM,GAAG,MAAM;AACf,YAAM,qBAAqB,IAAI,WAAW,WAAW,IAAI,MAAM,YAAY,IAAI;AAAA,IACjF;AACA,QAAI,kBAAkB,CAAC,aAAa,cAAc,OAAO,UAAU,KAAK;AACtE,YAAM,4BAA4B,IAAI,aAAa;AACnD,YAAM,GAAG,MAAM;AACf,YAAM,qBAAqB,IAAI,WAAW,eAAe,IAAI,MAAM,YAAY,IAAI;AAAA,IACrF;AAEA,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,QAAQ;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,UAAU,QAAQ;AAAA,MACpB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc;AAAA,MAC7C,QAAQ;AAAA,IACV,CAAC;AAED,WAAO,EAAE,WAAW,QAAQ,IAAI,aAAa,OAAO;AAAA,EACtD;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,QAAQ,YAAY,oBAAoB,IAAI,OAAO,SAAS,IAAI;AAAA,EACzE;AAAA,EACA,UAAU,OAAO,EAAE,WAAW,OAAO,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,UAAM,QAAQ,UAAU;AACxB,WAAO;AAAA,MACL,aAAa,UAAU,+BAA+B,gBAAgB;AAAA,MACtE,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,WAAW,QAAQ,WAAW;AAAA,MACvD,UAAU,OAAO,YAAY,QAAQ,YAAY;AAAA,MACjD,gBAAgB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,MACnE,gBAAgB,UAAU;AAAA,MAC1B,eAAe,SAAS;AAAA,MACxB,SAAS,EAAE,MAAM,EAAE,QAAQ,MAAM,EAA+B;AAAA,IAClE;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,uBAAuB,IAAI,MAAM;AACvC,UAAM,GAAG,MAAM;AACf,QAAI,OAAO,SAAS;AAClB,YAAM,QAAQ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,OAAO,QAAQ,CAAC;AACjE,UAAI,OAAO;AACT,cAAM,4BAA4B,IAAI,KAAK;AAC3C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,uBAGF;AAAA,EACF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACvD,QAAI,CAAC,OAAO,GAAI,QAAO,CAAC;AACxB,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,UAAM,WAAW,MAAM,oBAAoB,IAAI,OAAO,EAAE;AACxD,QAAI,UAAU;AACZ,wBAAkB,KAAK,SAAS,QAAQ;AACxC,8BAAwB,KAAK,SAAS,cAAc;AAAA,IACtD;AACA,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACtD,sBAAkB,KAAK,MAAM,QAAQ;AACrC,4BAAwB,KAAK,MAAM,cAAc;AACjD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,EAAE,IAAI,MAAM,GAAG;AAAA,QACf,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,QACtB,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,MACnE;AAAA,MACA;AAAA,IACF;AACA,oBAAgB,SAAS,MAAM,gBAAgB,MAAM,QAAQ;AAC7D,UAAM,QAAQ,QAAQ;AACtB,UAAM,cAAc,MAAM,GAAG,KAAK,wBAAwB,EAAE,QAAQ,CAAC;AACrE,UAAM,mBAAmB,YACtB;AAAA,MAAI,CAAC,eACJ,OAAO,WAAW,UAAU,WACxB,WAAW,QACX,WAAW,OAAO,MAAM;AAAA,IAC9B,EACC,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AACnF,gBAAY,QAAQ,CAAC,eAAe,GAAG,OAAO,UAAU,CAAC;AACzD,UAAM,GAAG,MAAM;AACf,OAAG,OAAO,OAAO;AACjB,UAAM,GAAG,MAAM;AACf,QAAI;AACJ,UAAM,WAAW,MAAM;AAAA,MACrB,IAAI;AAAA,QACF;AAAA,UACE,SAAS,OAAO,UAAU,WAAW,MAAM,KAAK;AAAA,UAChD,GAAG;AAAA,QACL,EAAE,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAAA,MACpF;AAAA,IACF;AACA,UAAM,iBAAiB,SAAS,OAAO,UAAU,WAAW,MAAM,KAAK;AACvE,eAAW,WAAW,UAAU;AAC9B,YAAM,SAAS,OAAO,UAAU,YAAY,MAAM,OAAO,UAAU,QAAQ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,QAAQ,CAAC;AACvH,UAAI,CAAC,OAAQ;AACb,YAAM,aAAa,MAAM,4BAA4B,IAAI,MAAM;AAC/D,UAAI,CAAC,UAAW,kBAAkB,YAAY,gBAAiB;AAC7D,iBAAS;AAAA,MACX;AACA,YAAM,GAAG,MAAM;AACf,YAAM,qBAAqB,IAAI,WAAW,QAAQ,IAAI,MAAM,YAAY,IAAI;AAAA,IAC9E;AACA,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,QAAQ;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,UAAU,QAAQ;AAAA,MACpB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc;AAAA,MAC7C,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,YAAY,QAAQ;AACtB,YAAM,QAAQ;AAAA,QACZ,YAAY;AAAA,UAAI,CAAC,eACf,oBAAoB;AAAA,YAClB;AAAA,YACA,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,aAAa;AAAA,cACX,IAAI,WAAW;AAAA,cACf,gBAAgB,WAAW,kBAAkB;AAAA,cAC7C,UAAU,WAAW,YAAY;AAAA,YACnC;AAAA,YACA,SAAS,EAAE,YAAY,EAAE,MAAM,yBAAyB;AAAA,UAC1D,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,WAAW,QAAQ,IAAI,aAAa,OAAO;AAAA,EACtD;AAAA,EACA,UAAU,OAAO,EAAE,WAAW,OAAO,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,WAAO;AAAA,MACL,aAAa,UAAU,+BAA+B,gBAAgB;AAAA,MACtE,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,QAAQ,WAAW;AAAA,MACrC,UAAU,QAAQ,YAAY;AAAA,MAC9B,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,gBAAgB,UAAU;AAAA,MAC1B,SAAS,EAAE,MAAM,EAAE,OAAO,EAA+B;AAAA,IAC3D;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,uBAAuB,IAAI,MAAM;AACvC,UAAM,GAAG,MAAM;AACf,QAAI,OAAO,SAAS;AAClB,YAAM,QAAQ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,OAAO,QAAQ,CAAC;AACjE,UAAI,OAAO;AACT,cAAM,4BAA4B,IAAI,KAAK;AAC3C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,kBAAkB,CAAC,sBAAsB,sBAAsB,oBAAoB;AAEhG,gBAAgB,oBAAoB;AACpC,gBAAgB,oBAAoB;AACpC,gBAAgB,oBAAoB;",
|
|
4
|
+
"sourcesContent": ["// @ts-nocheck\n\nimport { registerCommand, type CommandHandler } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { loadCustomFieldValues } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { setRecordCustomFields } from '@open-mercato/core/modules/entities/lib/helpers'\nimport { E } from '#generated/entities.ids.generated'\nimport {\n SalesInvoice,\n SalesOrder,\n SalesOrderLine,\n SalesPayment,\n SalesPaymentAllocation,\n SalesPaymentMethod,\n} from '../data/entities'\nimport {\n paymentCreateSchema,\n paymentUpdateSchema,\n type PaymentCreateInput,\n type PaymentUpdateInput,\n} from '../data/validators'\nimport {\n assertFound,\n cloneJson,\n ensureOrganizationScope,\n ensureSameScope,\n ensureTenantScope,\n extractUndoPayload,\n toNumericString,\n} from './shared'\nimport { resolveDictionaryEntryValue } from '../lib/dictionaries'\nimport { invalidateCrudCache } from '@open-mercato/shared/lib/crud/cache'\nimport { emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveNotificationService } from '../../notifications/lib/notificationService'\nimport { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'\nimport { notificationTypes } from '../notifications'\n\nexport type PaymentAllocationSnapshot = {\n id: string\n orderId: string | null\n invoiceId: string | null\n amount: number\n currencyCode: string\n metadata: Record<string, unknown> | null\n}\n\nexport type PaymentSnapshot = {\n id: string\n orderId: string | null\n organizationId: string\n tenantId: string\n paymentMethodId: string | null\n paymentReference: string | null\n statusEntryId: string | null\n status: string | null\n amount: number\n currencyCode: string\n capturedAmount: number\n refundedAmount: number\n receivedAt: string | null\n capturedAt: string | null\n metadata: Record<string, unknown> | null\n customFields?: Record<string, unknown> | null\n customFieldSetId?: string | null\n allocations: PaymentAllocationSnapshot[]\n}\n\ntype PaymentUndoPayload = {\n before?: PaymentSnapshot | null\n after?: PaymentSnapshot | null\n orderPaymentMethodIdBefore?: string | null\n orderPaymentMethodCodeBefore?: string | null\n}\n\nconst toNumber = (value: unknown): number => {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nconst normalizeCustomFieldsInput = (input: unknown): Record<string, unknown> =>\n input && typeof input === 'object' && !Array.isArray(input) ? (input as Record<string, unknown>) : {}\n\nconst paymentCrudEvents: CrudEventsConfig = {\n module: 'sales',\n entity: 'payment',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nconst ORDER_RESOURCE = 'sales.order'\n\nasync function invalidateOrderCache(container: any, order: SalesOrder | null | undefined, tenantId: string | null) {\n if (!order) return\n await invalidateCrudCache(\n container,\n ORDER_RESOURCE,\n { id: order.id, organizationId: order.organizationId, tenantId: order.tenantId },\n tenantId,\n 'updated'\n )\n}\n\nexport async function loadPaymentSnapshot(em: EntityManager, id: string): Promise<PaymentSnapshot | null> {\n const payment = await findOneWithDecryption(\n em,\n SalesPayment,\n { id },\n { populate: ['order', 'allocations', 'allocations.order', 'allocations.invoice'] },\n )\n if (!payment) return null\n const allocations: PaymentAllocationSnapshot[] = Array.from(payment.allocations ?? []).map((allocation) => ({\n id: allocation.id,\n orderId:\n typeof allocation.order === 'string'\n ? allocation.order\n : allocation.order?.id ?? (allocation as any).order_id ?? null,\n invoiceId:\n typeof allocation.invoice === 'string'\n ? allocation.invoice\n : allocation.invoice?.id ?? (allocation as any).invoice_id ?? null,\n amount: toNumber(allocation.amount),\n currencyCode: allocation.currencyCode,\n metadata: allocation.metadata ? cloneJson(allocation.metadata) : null,\n }))\n const customFieldValues = await loadCustomFieldValues({\n em,\n entityId: E.sales.sales_payment,\n recordIds: [payment.id],\n tenantIdByRecord: { [payment.id]: payment.tenantId ?? null },\n organizationIdByRecord: { [payment.id]: payment.organizationId ?? null },\n })\n const customFields = customFieldValues[payment.id]\n const normalizedCustomFields =\n customFields && Object.keys(customFields).length ? customFields : null\n return {\n id: payment.id,\n orderId: typeof payment.order === 'string' ? payment.order : payment.order?.id ?? null,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n paymentMethodId:\n typeof payment.paymentMethod === 'string'\n ? payment.paymentMethod\n : payment.paymentMethod?.id ?? null,\n paymentReference: payment.paymentReference ?? null,\n statusEntryId: payment.statusEntryId ?? null,\n status: payment.status ?? null,\n amount: toNumber(payment.amount),\n currencyCode: payment.currencyCode,\n capturedAmount: toNumber(payment.capturedAmount),\n refundedAmount: toNumber(payment.refundedAmount),\n receivedAt: payment.receivedAt ? payment.receivedAt.toISOString() : null,\n capturedAt: payment.capturedAt ? payment.capturedAt.toISOString() : null,\n metadata: payment.metadata ? cloneJson(payment.metadata) : null,\n customFields: normalizedCustomFields,\n customFieldSetId: (payment as any).customFieldSetId ?? (payment as any).custom_field_set_id ?? null,\n allocations,\n }\n}\n\nexport async function restorePaymentSnapshot(em: EntityManager, snapshot: PaymentSnapshot): Promise<void> {\n const orderRef = snapshot.orderId ? em.getReference(SalesOrder, snapshot.orderId) : null\n const methodRef = snapshot.paymentMethodId\n ? em.getReference(SalesPaymentMethod, snapshot.paymentMethodId)\n : null\n const entity =\n (await em.findOne(SalesPayment, { id: snapshot.id })) ??\n em.create(SalesPayment, {\n id: snapshot.id,\n createdAt: new Date(),\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n })\n entity.order = orderRef\n entity.paymentMethod = methodRef\n entity.organizationId = snapshot.organizationId\n entity.tenantId = snapshot.tenantId\n entity.paymentReference = snapshot.paymentReference\n entity.statusEntryId = snapshot.statusEntryId\n entity.status = snapshot.status\n entity.amount = toNumericString(snapshot.amount) ?? '0'\n entity.currencyCode = snapshot.currencyCode\n entity.capturedAmount = toNumericString(snapshot.capturedAmount) ?? '0'\n entity.refundedAmount = toNumericString(snapshot.refundedAmount) ?? '0'\n entity.receivedAt = snapshot.receivedAt ? new Date(snapshot.receivedAt) : null\n entity.capturedAt = snapshot.capturedAt ? new Date(snapshot.capturedAt) : null\n entity.metadata = snapshot.metadata ? cloneJson(snapshot.metadata) : null\n entity.customFieldSetId =\n (snapshot as any).customFieldSetId ?? (snapshot as any).custom_field_set_id ?? null\n entity.updatedAt = new Date()\n await em.flush()\n\n if ((snapshot as any).customFields !== undefined) {\n await setRecordCustomFields(em, {\n entityId: E.sales.sales_payment,\n recordId: entity.id,\n organizationId: entity.organizationId,\n tenantId: entity.tenantId,\n values:\n snapshot.customFields && typeof snapshot.customFields === 'object'\n ? (snapshot.customFields as Record<string, unknown>)\n : {},\n })\n }\n\n const existingAllocations = await em.find(SalesPaymentAllocation, { payment: entity })\n existingAllocations.forEach((allocation) => em.remove(allocation))\n snapshot.allocations.forEach((allocation) => {\n const order =\n allocation.orderId && typeof allocation.orderId === 'string'\n ? em.getReference(SalesOrder, allocation.orderId)\n : null\n const invoice =\n allocation.invoiceId && typeof allocation.invoiceId === 'string'\n ? em.getReference(SalesInvoice, allocation.invoiceId)\n : null\n const newAllocation = em.create(SalesPaymentAllocation, {\n payment: entity,\n order,\n invoice,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n amount: toNumericString(allocation.amount) ?? '0',\n currencyCode: allocation.currencyCode,\n metadata: allocation.metadata ? cloneJson(allocation.metadata) : null,\n })\n em.persist(newAllocation)\n })\n em.persist(entity)\n}\n\nasync function recomputeOrderPaymentTotals(\n em: EntityManager,\n order: SalesOrder\n): Promise<{ paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number }> {\n const orderId = order.id\n const scope = { organizationId: order.organizationId, tenantId: order.tenantId }\n\n const allocations = await findWithDecryption(\n em,\n SalesPaymentAllocation,\n { ...scope, order: orderId },\n { populate: ['payment'] },\n scope,\n )\n\n const paymentIds = new Set<string>()\n allocations.forEach((allocation) => {\n const paymentRef = allocation.payment\n const paymentId =\n typeof paymentRef === 'object' && paymentRef !== null\n ? paymentRef.id\n : typeof paymentRef === 'string'\n ? paymentRef\n : null\n if (paymentId) paymentIds.add(paymentId)\n })\n\n const payments =\n paymentIds.size > 0\n ? await em.find(SalesPayment, { id: { $in: Array.from(paymentIds) }, deletedAt: null, ...scope })\n : await em.find(SalesPayment, { order: orderId, deletedAt: null, ...scope })\n\n const resolvePaidAmount = (payment: SalesPayment) => {\n const captured = toNumber(payment.capturedAmount)\n return captured > 0 ? captured : toNumber(payment.amount)\n }\n\n const activePaymentIds = new Set(payments.map((payment) => payment.id))\n const paidTotal =\n allocations.length > 0\n ? allocations.reduce((sum, allocation) => {\n const paymentRef = allocation.payment\n const paymentId =\n typeof paymentRef === 'object' && paymentRef !== null\n ? paymentRef.id\n : typeof paymentRef === 'string'\n ? paymentRef\n : null\n if (paymentId && !activePaymentIds.has(paymentId)) return sum\n return sum + toNumber(allocation.amount)\n }, 0)\n : payments.reduce((sum, payment) => sum + resolvePaidAmount(payment), 0)\n\n const refundedTotal = payments.reduce(\n (sum, payment) => sum + toNumber(payment.refundedAmount),\n 0\n )\n\n const grandTotal = toNumber(order.grandTotalGrossAmount)\n const outstanding = Math.max(grandTotal - paidTotal + refundedTotal, 0)\n order.paidTotalAmount = toNumericString(paidTotal) ?? '0'\n order.refundedTotalAmount = toNumericString(refundedTotal) ?? '0'\n order.outstandingAmount = toNumericString(outstanding) ?? '0'\n return {\n paidTotalAmount: paidTotal,\n refundedTotalAmount: refundedTotal,\n outstandingAmount: outstanding,\n }\n}\n\nconst createPaymentCommand: CommandHandler<\n PaymentCreateInput,\n { paymentId: string; orderTotals?: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number }; orderPaymentMethodIdBefore?: string | null; orderPaymentMethodCodeBefore?: string | null }\n> = {\n id: 'sales.payments.create',\n async execute(rawInput, ctx) {\n const input = paymentCreateSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { translate } = await resolveTranslations()\n if (!input.orderId) {\n throw new CrudHttpError(400, { error: translate('sales.payments.order_required', 'Order is required for payments.') })\n }\n const order = assertFound(\n await em.findOne(SalesOrder, { id: input.orderId }),\n 'sales.payments.order_not_found'\n )\n ensureSameScope(order, input.organizationId, input.tenantId)\n if (order.deletedAt) {\n throw new CrudHttpError(404, { error: 'sales.payments.order_not_found' })\n }\n if (\n order.currencyCode &&\n input.currencyCode &&\n order.currencyCode.toUpperCase() !== input.currencyCode.toUpperCase()\n ) {\n throw new CrudHttpError(400, {\n error: translate('sales.payments.currency_mismatch', 'Payment currency must match the order currency.'),\n })\n }\n let paymentMethod = null\n if (input.paymentMethodId) {\n const method = assertFound(\n await em.findOne(SalesPaymentMethod, { id: input.paymentMethodId }),\n 'sales.payments.method_not_found'\n )\n ensureSameScope(method, input.organizationId, input.tenantId)\n paymentMethod = method\n }\n const orderPaymentMethodIdBefore = order.paymentMethodId ?? null\n const orderPaymentMethodCodeBefore = order.paymentMethodCode ?? null\n if (paymentMethod && !order.paymentMethodId) {\n order.paymentMethodId = paymentMethod.id\n order.paymentMethodCode = paymentMethod.code ?? null\n order.updatedAt = new Date()\n em.persist(order)\n }\n if (input.documentStatusEntryId !== undefined) {\n const orderStatus = await resolveDictionaryEntryValue(em, input.documentStatusEntryId ?? null)\n if (input.documentStatusEntryId && !orderStatus) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.'),\n })\n }\n order.statusEntryId = input.documentStatusEntryId ?? null\n order.status = orderStatus\n order.updatedAt = new Date()\n em.persist(order)\n }\n if (input.lineStatusEntryId !== undefined) {\n const lineStatus = await resolveDictionaryEntryValue(em, input.lineStatusEntryId ?? null)\n if (input.lineStatusEntryId && !lineStatus) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.'),\n })\n }\n const orderLines = await em.find(SalesOrderLine, { order })\n orderLines.forEach((line) => {\n line.statusEntryId = input.lineStatusEntryId ?? null\n line.status = lineStatus\n line.updatedAt = new Date()\n })\n orderLines.forEach((line) => em.persist(line))\n }\n const status = await resolveDictionaryEntryValue(em, input.statusEntryId ?? null)\n const payment = em.create(SalesPayment, {\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n order,\n paymentMethod,\n paymentReference: input.paymentReference ?? null,\n statusEntryId: input.statusEntryId ?? null,\n status,\n amount: toNumericString(input.amount) ?? '0',\n currencyCode: input.currencyCode,\n capturedAmount: toNumericString(input.capturedAmount) ?? '0',\n refundedAmount: toNumericString(input.refundedAmount) ?? '0',\n receivedAt: input.receivedAt ?? null,\n capturedAt: input.capturedAt ?? null,\n metadata: input.metadata ? cloneJson(input.metadata) : null,\n customFieldSetId: input.customFieldSetId ?? null,\n })\n const allocationInputs = Array.isArray(input.allocations) ? input.allocations : []\n const allocations = allocationInputs.length\n ? allocationInputs\n : [\n {\n orderId: input.orderId,\n invoiceId: null,\n amount: input.amount,\n currencyCode: input.currencyCode,\n metadata: null,\n },\n ]\n allocations.forEach((allocation) => {\n const orderRef = allocation.orderId ? em.getReference(SalesOrder, allocation.orderId) : order\n const invoiceRef = allocation.invoiceId ? em.getReference(SalesInvoice, allocation.invoiceId) : null\n const entity = em.create(SalesPaymentAllocation, {\n payment,\n order: orderRef,\n invoice: invoiceRef,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n amount: toNumericString(allocation.amount) ?? '0',\n currencyCode: allocation.currencyCode,\n metadata: allocation.metadata ? cloneJson(allocation.metadata) : null,\n })\n em.persist(entity)\n })\n em.persist(payment)\n if (input.customFields !== undefined) {\n if (!payment.id) {\n await em.flush()\n }\n await setRecordCustomFields(em, {\n entityId: E.sales.sales_payment,\n recordId: payment.id,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n values: normalizeCustomFieldsInput(input.customFields),\n })\n }\n await em.flush()\n const totals = await recomputeOrderPaymentTotals(em, order)\n await em.flush()\n await invalidateOrderCache(ctx.container, order, ctx.auth?.tenantId ?? null)\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'created',\n entity: payment,\n identifiers: {\n id: payment.id,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n },\n indexer: { entityType: E.sales.sales_payment },\n events: paymentCrudEvents,\n })\n\n // Create notification for payment received\n try {\n const notificationService = resolveNotificationService(ctx.container)\n const typeDef = notificationTypes.find((type) => type.type === 'sales.payment.received')\n if (typeDef) {\n const amountDisplay = payment.amount && payment.currencyCode\n ? `${payment.currencyCode} ${payment.amount}`\n : ''\n const notificationInput = buildFeatureNotificationFromType(typeDef, {\n requiredFeature: 'sales.orders.manage',\n bodyVariables: {\n orderNumber: order.orderNumber ?? '',\n amount: amountDisplay,\n },\n sourceEntityType: 'sales:order',\n sourceEntityId: order.id,\n linkHref: `/backend/sales/orders/${order.id}`,\n })\n\n await notificationService.createForFeature(notificationInput, {\n tenantId: payment.tenantId,\n organizationId: payment.organizationId ?? null,\n })\n }\n } catch (err) {\n // Notification creation is non-critical, don't fail the command\n console.error('[sales.payments.create] Failed to create notification:', err)\n }\n\n return { paymentId: payment.id, orderTotals: totals, orderPaymentMethodIdBefore, orderPaymentMethodCodeBefore }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return result?.paymentId ? loadPaymentSnapshot(em, result.paymentId) : null\n },\n buildLog: async ({ result, snapshots }) => {\n const after = snapshots.after as PaymentSnapshot | undefined\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('sales.audit.payments.create', 'Create payment'),\n resourceKind: 'sales.payment',\n resourceId: result.paymentId,\n parentResourceKind: 'sales.order',\n parentResourceId: after.orderId ?? null,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n snapshotAfter: after,\n payload: { undo: { after, orderPaymentMethodIdBefore: result.orderPaymentMethodIdBefore ?? null, orderPaymentMethodCodeBefore: result.orderPaymentMethodCodeBefore ?? null } satisfies PaymentUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PaymentUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const existing = await em.findOne(SalesPayment, { id: after.id })\n if (existing) {\n const orderRef =\n typeof existing.order === 'string' ? existing.order : existing.order?.id ?? null\n const allocations = await em.find(SalesPaymentAllocation, { payment: existing })\n const allocationOrders = allocations\n .map((allocation) =>\n typeof allocation.order === 'string'\n ? allocation.order\n : allocation.order?.id ?? null\n )\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n\n allocations.forEach((allocation) => em.remove(allocation))\n await em.flush()\n\n em.remove(existing)\n await em.flush()\n\n const orderIds = Array.from(\n new Set(\n [\n orderRef,\n ...allocationOrders,\n ].filter((value): value is string => typeof value === 'string' && value.length > 0)\n )\n )\n for (const id of orderIds) {\n const order = await em.findOne(SalesOrder, { id })\n if (!order) continue\n if (id === after.orderId && 'orderPaymentMethodIdBefore' in (payload ?? {})) {\n order.paymentMethodId = payload.orderPaymentMethodIdBefore ?? null\n order.paymentMethodCode = payload.orderPaymentMethodCodeBefore ?? null\n order.updatedAt = new Date()\n await em.flush()\n }\n await recomputeOrderPaymentTotals(em, order)\n await em.flush()\n }\n }\n },\n}\n\nconst updatePaymentCommand: CommandHandler<\n PaymentUpdateInput,\n { paymentId: string; orderTotals?: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } }\n> = {\n id: 'sales.payments.update',\n async prepare(rawInput, ctx) {\n const parsed = paymentUpdateSchema.parse(rawInput ?? {})\n if (!parsed.id) return {}\n const em = ctx.container.resolve('em') as EntityManager\n const snapshot = await loadPaymentSnapshot(em, parsed.id)\n if (snapshot) {\n ensureTenantScope(ctx, snapshot.tenantId)\n ensureOrganizationScope(ctx, snapshot.organizationId)\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const input = paymentUpdateSchema.parse(rawInput ?? {})\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const { translate } = await resolveTranslations()\n const scopeSeed = assertFound(\n await em.findOne(SalesPayment, { id: input.id }),\n 'sales.payments.not_found'\n )\n const resolvedTenantId = input.tenantId ?? scopeSeed.tenantId\n const resolvedOrganizationId = input.organizationId ?? scopeSeed.organizationId\n ensureTenantScope(ctx, resolvedTenantId)\n ensureOrganizationScope(ctx, resolvedOrganizationId)\n const payment = assertFound(\n await findOneWithDecryption(\n em,\n SalesPayment,\n { id: input.id },\n { populate: ['order'] },\n { tenantId: resolvedTenantId, organizationId: resolvedOrganizationId },\n ),\n 'sales.payments.not_found'\n )\n ensureSameScope(payment, resolvedOrganizationId, resolvedTenantId)\n const previousOrder = payment.order as SalesOrder | null\n if (input.orderId !== undefined) {\n if (!input.orderId) {\n payment.order = null\n } else {\n const order = assertFound(\n await em.findOne(SalesOrder, { id: input.orderId }),\n 'sales.payments.order_not_found'\n )\n ensureSameScope(order, resolvedOrganizationId, resolvedTenantId)\n if (\n order.currencyCode &&\n input.currencyCode &&\n order.currencyCode.toUpperCase() !== input.currencyCode.toUpperCase()\n ) {\n throw new CrudHttpError(400, {\n error: translate('sales.payments.currency_mismatch', 'Payment currency must match the order currency.'),\n })\n }\n payment.order = order\n }\n }\n if (input.paymentMethodId !== undefined) {\n if (!input.paymentMethodId) {\n payment.paymentMethod = null\n } else {\n const method = assertFound(\n await em.findOne(SalesPaymentMethod, { id: input.paymentMethodId }),\n 'sales.payments.method_not_found'\n )\n ensureSameScope(method, resolvedOrganizationId, resolvedTenantId)\n payment.paymentMethod = method\n }\n }\n const currentOrder = payment.order as SalesOrder | null\n if ((input.documentStatusEntryId !== undefined || input.lineStatusEntryId !== undefined) && !currentOrder) {\n throw new CrudHttpError(400, { error: translate('sales.payments.order_required', 'Order is required for payments.') })\n }\n if (currentOrder && input.documentStatusEntryId !== undefined) {\n const orderStatus = await resolveDictionaryEntryValue(em, input.documentStatusEntryId ?? null)\n if (input.documentStatusEntryId && !orderStatus) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.'),\n })\n }\n currentOrder.statusEntryId = input.documentStatusEntryId ?? null\n currentOrder.status = orderStatus\n currentOrder.updatedAt = new Date()\n em.persist(currentOrder)\n }\n if (currentOrder && input.lineStatusEntryId !== undefined) {\n const lineStatus = await resolveDictionaryEntryValue(em, input.lineStatusEntryId ?? null)\n if (input.lineStatusEntryId && !lineStatus) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.'),\n })\n }\n const orderLines = await em.find(SalesOrderLine, { order: currentOrder })\n orderLines.forEach((line) => {\n line.statusEntryId = input.lineStatusEntryId ?? null\n line.status = lineStatus\n line.updatedAt = new Date()\n })\n orderLines.forEach((line) => em.persist(line))\n }\n if (input.paymentReference !== undefined) payment.paymentReference = input.paymentReference ?? null\n if (input.statusEntryId !== undefined) {\n payment.statusEntryId = input.statusEntryId ?? null\n payment.status = await resolveDictionaryEntryValue(em, input.statusEntryId ?? null)\n }\n if (input.amount !== undefined) payment.amount = toNumericString(input.amount) ?? '0'\n if (input.currencyCode !== undefined) payment.currencyCode = input.currencyCode\n if (input.capturedAmount !== undefined) {\n payment.capturedAmount = toNumericString(input.capturedAmount) ?? '0'\n }\n if (input.refundedAmount !== undefined) {\n payment.refundedAmount = toNumericString(input.refundedAmount) ?? '0'\n }\n if (input.receivedAt !== undefined) payment.receivedAt = input.receivedAt ?? null\n if (input.capturedAt !== undefined) payment.capturedAt = input.capturedAt ?? null\n if (input.metadata !== undefined) {\n payment.metadata = input.metadata ? cloneJson(input.metadata) : null\n }\n if (input.customFieldSetId !== undefined) {\n payment.customFieldSetId = input.customFieldSetId ?? null\n }\n if (input.customFields !== undefined) {\n if (!payment.id) {\n await em.flush()\n }\n await setRecordCustomFields(em, {\n entityId: E.sales.sales_payment,\n recordId: payment.id,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n values: normalizeCustomFieldsInput(input.customFields),\n })\n }\n if (input.allocations !== undefined) {\n const existingAllocations = await em.find(SalesPaymentAllocation, { payment })\n existingAllocations.forEach((allocation) => em.remove(allocation))\n const allocationInputs = Array.isArray(input.allocations) ? input.allocations : []\n allocationInputs.forEach((allocation) => {\n const orderRef =\n allocation.orderId ??\n (typeof payment.order === 'string' ? payment.order : payment.order?.id) ??\n null\n const order =\n orderRef && typeof orderRef === 'string' ? em.getReference(SalesOrder, orderRef) : null\n const invoice = allocation.invoiceId\n ? em.getReference(SalesInvoice, allocation.invoiceId)\n : null\n const entity = em.create(SalesPaymentAllocation, {\n payment,\n order,\n invoice,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n amount: toNumericString(allocation.amount) ?? '0',\n currencyCode: allocation.currencyCode,\n metadata: allocation.metadata ? cloneJson(allocation.metadata) : null,\n })\n em.persist(entity)\n })\n }\n payment.updatedAt = new Date()\n await em.flush()\n\n const nextOrder =\n (payment.order as SalesOrder | null) ??\n (typeof payment.order === 'string'\n ? await em.findOne(SalesOrder, { id: payment.order })\n : null)\n let totals: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } | undefined\n if (nextOrder) {\n totals = await recomputeOrderPaymentTotals(em, nextOrder)\n await em.flush()\n await invalidateOrderCache(ctx.container, nextOrder, ctx.auth?.tenantId ?? null)\n }\n if (previousOrder && (!nextOrder || previousOrder.id !== nextOrder.id)) {\n await recomputeOrderPaymentTotals(em, previousOrder)\n await em.flush()\n await invalidateOrderCache(ctx.container, previousOrder, ctx.auth?.tenantId ?? null)\n }\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'updated',\n entity: payment,\n identifiers: {\n id: payment.id,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n },\n indexer: { entityType: E.sales.sales_payment },\n events: paymentCrudEvents,\n })\n\n return { paymentId: payment.id, orderTotals: totals }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return result?.paymentId ? loadPaymentSnapshot(em, result.paymentId) : null\n },\n buildLog: async ({ snapshots, result }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as PaymentSnapshot | undefined\n const after = snapshots.after as PaymentSnapshot | undefined\n return {\n actionLabel: translate('sales.audit.payments.update', 'Update payment'),\n resourceKind: 'sales.payment',\n resourceId: result.paymentId,\n parentResourceKind: 'sales.order',\n parentResourceId: after?.orderId ?? before?.orderId ?? null,\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n snapshotAfter: after ?? null,\n payload: { undo: { before, after } satisfies PaymentUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PaymentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await restorePaymentSnapshot(em, before)\n await em.flush()\n if (before.orderId) {\n const order = await em.findOne(SalesOrder, { id: before.orderId })\n if (order) {\n await recomputeOrderPaymentTotals(em, order)\n await em.flush()\n }\n }\n },\n}\n\nconst deletePaymentCommand: CommandHandler<\n { id: string; orderId?: string | null; organizationId: string; tenantId: string },\n { paymentId: string; orderTotals?: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } }\n> = {\n id: 'sales.payments.delete',\n async prepare(rawInput, ctx) {\n const parsed = paymentUpdateSchema.parse(rawInput ?? {})\n if (!parsed.id) return {}\n const em = ctx.container.resolve('em') as EntityManager\n const snapshot = await loadPaymentSnapshot(em, parsed.id)\n if (snapshot) {\n ensureTenantScope(ctx, snapshot.tenantId)\n ensureOrganizationScope(ctx, snapshot.organizationId)\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const input = paymentUpdateSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const payment = assertFound(\n await findOneWithDecryption(\n em,\n SalesPayment,\n { id: input.id },\n { populate: ['order'] },\n { tenantId: input.tenantId, organizationId: input.organizationId },\n ),\n 'sales.payments.not_found'\n )\n ensureSameScope(payment, input.organizationId, input.tenantId)\n const order = payment.order as SalesOrder | null\n const allocations = await em.find(SalesPaymentAllocation, { payment })\n const allocationOrders = allocations\n .map((allocation) =>\n typeof allocation.order === 'string'\n ? allocation.order\n : allocation.order?.id ?? null\n )\n .filter((value): value is string => typeof value === 'string' && value.length > 0)\n allocations.forEach((allocation) => em.remove(allocation))\n await em.flush()\n em.remove(payment)\n await em.flush()\n let totals: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } | undefined\n const orderIds = Array.from(\n new Set(\n [\n order && typeof order === 'object' ? order.id : null,\n ...allocationOrders,\n ].filter((value): value is string => typeof value === 'string' && value.length > 0)\n )\n )\n const primaryOrderId = order && typeof order === 'object' ? order.id : null\n for (const orderId of orderIds) {\n const target = typeof order === 'object' && order.id === orderId ? order : await em.findOne(SalesOrder, { id: orderId })\n if (!target) continue\n const recomputed = await recomputeOrderPaymentTotals(em, target)\n if (!totals || (primaryOrderId && orderId === primaryOrderId)) {\n totals = recomputed\n }\n await em.flush()\n await invalidateOrderCache(ctx.container, target, ctx.auth?.tenantId ?? null)\n }\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: payment,\n identifiers: {\n id: payment.id,\n organizationId: payment.organizationId,\n tenantId: payment.tenantId,\n },\n indexer: { entityType: E.sales.sales_payment },\n events: paymentCrudEvents,\n })\n if (allocations.length) {\n await Promise.all(\n allocations.map((allocation) =>\n emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: allocation,\n identifiers: {\n id: allocation.id,\n organizationId: allocation.organizationId ?? null,\n tenantId: allocation.tenantId ?? null,\n },\n indexer: { entityType: E.sales.sales_payment_allocation },\n })\n )\n )\n }\n return { paymentId: payment.id, orderTotals: totals }\n },\n buildLog: async ({ snapshots, result }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as PaymentSnapshot | undefined\n return {\n actionLabel: translate('sales.audit.payments.delete', 'Delete payment'),\n resourceKind: 'sales.payment',\n resourceId: result.paymentId,\n parentResourceKind: 'sales.order',\n parentResourceId: before?.orderId ?? null,\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n payload: { undo: { before } satisfies PaymentUndoPayload },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PaymentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await restorePaymentSnapshot(em, before)\n await em.flush()\n if (before.orderId) {\n const order = await em.findOne(SalesOrder, { id: before.orderId })\n if (order) {\n await recomputeOrderPaymentTotals(em, order)\n await em.flush()\n }\n }\n },\n}\n\nexport const paymentCommands = [createPaymentCommand, updatePaymentCommand, deletePaymentCommand]\n\nregisterCommand(createPaymentCommand)\nregisterCommand(updatePaymentCommand)\nregisterCommand(deletePaymentCommand)\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,uBAA4C;AAErD,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AACtC,SAAS,6BAA6B;AACtC,SAAS,SAAS;AAClB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mCAAmC;AAC5C,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,uBAAuB,0BAA0B;AAC1D,SAAS,kCAAkC;AAC3C,SAAS,wCAAwC;AACjD,SAAS,yBAAyB;AAuClC,MAAM,WAAW,CAAC,UAA2B;AAC3C,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,QAAQ;AACpD,UAAM,SAAS,OAAO,KAAK;AAC3B,QAAI,CAAC,OAAO,MAAM,MAAM,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,MAAM,6BAA6B,CAAC,UAClC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAK,QAAoC,CAAC;AAEtG,MAAM,oBAAsC;AAAA,EAC1C,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,EAC5B;AACF;AAEA,MAAM,iBAAiB;AAEvB,eAAe,qBAAqB,WAAgB,OAAsC,UAAyB;AACjH,MAAI,CAAC,MAAO;AACZ,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,EAAE,IAAI,MAAM,IAAI,gBAAgB,MAAM,gBAAgB,UAAU,MAAM,SAAS;AAAA,IAC/E;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,oBAAoB,IAAmB,IAA6C;AACxG,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,EAAE,GAAG;AAAA,IACL,EAAE,UAAU,CAAC,SAAS,eAAe,qBAAqB,qBAAqB,EAAE;AAAA,EACnF;AACA,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,cAA2C,MAAM,KAAK,QAAQ,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB;AAAA,IAC1G,IAAI,WAAW;AAAA,IACf,SACE,OAAO,WAAW,UAAU,WACxB,WAAW,QACX,WAAW,OAAO,MAAO,WAAmB,YAAY;AAAA,IAC9D,WACE,OAAO,WAAW,YAAY,WAC1B,WAAW,UACX,WAAW,SAAS,MAAO,WAAmB,cAAc;AAAA,IAClE,QAAQ,SAAS,WAAW,MAAM;AAAA,IAClC,cAAc,WAAW;AAAA,IACzB,UAAU,WAAW,WAAW,UAAU,WAAW,QAAQ,IAAI;AAAA,EACnE,EAAE;AACF,QAAM,oBAAoB,MAAM,sBAAsB;AAAA,IACpD;AAAA,IACA,UAAU,EAAE,MAAM;AAAA,IAClB,WAAW,CAAC,QAAQ,EAAE;AAAA,IACtB,kBAAkB,EAAE,CAAC,QAAQ,EAAE,GAAG,QAAQ,YAAY,KAAK;AAAA,IAC3D,wBAAwB,EAAE,CAAC,QAAQ,EAAE,GAAG,QAAQ,kBAAkB,KAAK;AAAA,EACzE,CAAC;AACD,QAAM,eAAe,kBAAkB,QAAQ,EAAE;AACjD,QAAM,yBACJ,gBAAgB,OAAO,KAAK,YAAY,EAAE,SAAS,eAAe;AACpE,SAAO;AAAA,IACL,IAAI,QAAQ;AAAA,IACZ,SAAS,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,QAAQ,OAAO,MAAM;AAAA,IAClF,gBAAgB,QAAQ;AAAA,IACxB,UAAU,QAAQ;AAAA,IAClB,iBACE,OAAO,QAAQ,kBAAkB,WAC7B,QAAQ,gBACR,QAAQ,eAAe,MAAM;AAAA,IACnC,kBAAkB,QAAQ,oBAAoB;AAAA,IAC9C,eAAe,QAAQ,iBAAiB;AAAA,IACxC,QAAQ,QAAQ,UAAU;AAAA,IAC1B,QAAQ,SAAS,QAAQ,MAAM;AAAA,IAC/B,cAAc,QAAQ;AAAA,IACtB,gBAAgB,SAAS,QAAQ,cAAc;AAAA,IAC/C,gBAAgB,SAAS,QAAQ,cAAc;AAAA,IAC/C,YAAY,QAAQ,aAAa,QAAQ,WAAW,YAAY,IAAI;AAAA,IACpE,YAAY,QAAQ,aAAa,QAAQ,WAAW,YAAY,IAAI;AAAA,IACpE,UAAU,QAAQ,WAAW,UAAU,QAAQ,QAAQ,IAAI;AAAA,IAC3D,cAAc;AAAA,IACd,kBAAmB,QAAgB,oBAAqB,QAAgB,uBAAuB;AAAA,IAC/F;AAAA,EACF;AACF;AAEA,eAAsB,uBAAuB,IAAmB,UAA0C;AACxG,QAAM,WAAW,SAAS,UAAU,GAAG,aAAa,YAAY,SAAS,OAAO,IAAI;AACpF,QAAM,YAAY,SAAS,kBACvB,GAAG,aAAa,oBAAoB,SAAS,eAAe,IAC5D;AACJ,QAAM,SACH,MAAM,GAAG,QAAQ,cAAc,EAAE,IAAI,SAAS,GAAG,CAAC,KACnD,GAAG,OAAO,cAAc;AAAA,IACtB,IAAI,SAAS;AAAA,IACb,WAAW,oBAAI,KAAK;AAAA,IACpB,gBAAgB,SAAS;AAAA,IACzB,UAAU,SAAS;AAAA,EACrB,CAAC;AACH,SAAO,QAAQ;AACf,SAAO,gBAAgB;AACvB,SAAO,iBAAiB,SAAS;AACjC,SAAO,WAAW,SAAS;AAC3B,SAAO,mBAAmB,SAAS;AACnC,SAAO,gBAAgB,SAAS;AAChC,SAAO,SAAS,SAAS;AACzB,SAAO,SAAS,gBAAgB,SAAS,MAAM,KAAK;AACpD,SAAO,eAAe,SAAS;AAC/B,SAAO,iBAAiB,gBAAgB,SAAS,cAAc,KAAK;AACpE,SAAO,iBAAiB,gBAAgB,SAAS,cAAc,KAAK;AACpE,SAAO,aAAa,SAAS,aAAa,IAAI,KAAK,SAAS,UAAU,IAAI;AAC1E,SAAO,aAAa,SAAS,aAAa,IAAI,KAAK,SAAS,UAAU,IAAI;AAC1E,SAAO,WAAW,SAAS,WAAW,UAAU,SAAS,QAAQ,IAAI;AACrE,SAAO,mBACJ,SAAiB,oBAAqB,SAAiB,uBAAuB;AACjF,SAAO,YAAY,oBAAI,KAAK;AAC5B,QAAM,GAAG,MAAM;AAEf,MAAK,SAAiB,iBAAiB,QAAW;AAChD,UAAM,sBAAsB,IAAI;AAAA,MAC9B,UAAU,EAAE,MAAM;AAAA,MAClB,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,UAAU,OAAO;AAAA,MACjB,QACE,SAAS,gBAAgB,OAAO,SAAS,iBAAiB,WACrD,SAAS,eACV,CAAC;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,sBAAsB,MAAM,GAAG,KAAK,wBAAwB,EAAE,SAAS,OAAO,CAAC;AACrF,sBAAoB,QAAQ,CAAC,eAAe,GAAG,OAAO,UAAU,CAAC;AACjE,WAAS,YAAY,QAAQ,CAAC,eAAe;AAC3C,UAAM,QACJ,WAAW,WAAW,OAAO,WAAW,YAAY,WAChD,GAAG,aAAa,YAAY,WAAW,OAAO,IAC9C;AACN,UAAM,UACJ,WAAW,aAAa,OAAO,WAAW,cAAc,WACpD,GAAG,aAAa,cAAc,WAAW,SAAS,IAClD;AACN,UAAM,gBAAgB,GAAG,OAAO,wBAAwB;AAAA,MACtD,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,gBAAgB,SAAS;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,QAAQ,gBAAgB,WAAW,MAAM,KAAK;AAAA,MAC9C,cAAc,WAAW;AAAA,MACzB,UAAU,WAAW,WAAW,UAAU,WAAW,QAAQ,IAAI;AAAA,IACnE,CAAC;AACD,OAAG,QAAQ,aAAa;AAAA,EAC1B,CAAC;AACD,KAAG,QAAQ,MAAM;AACnB;AAEA,eAAe,4BACb,IACA,OAC8F;AAC9F,QAAM,UAAU,MAAM;AACtB,QAAM,QAAQ,EAAE,gBAAgB,MAAM,gBAAgB,UAAU,MAAM,SAAS;AAE/E,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,IACA,EAAE,GAAG,OAAO,OAAO,QAAQ;AAAA,IAC3B,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,aAAa,oBAAI,IAAY;AACnC,cAAY,QAAQ,CAAC,eAAe;AAClC,UAAM,aAAa,WAAW;AAC9B,UAAM,YACJ,OAAO,eAAe,YAAY,eAAe,OAC7C,WAAW,KACX,OAAO,eAAe,WACpB,aACA;AACR,QAAI,UAAW,YAAW,IAAI,SAAS;AAAA,EACzC,CAAC;AAED,QAAM,WACJ,WAAW,OAAO,IACd,MAAM,GAAG,KAAK,cAAc,EAAE,IAAI,EAAE,KAAK,MAAM,KAAK,UAAU,EAAE,GAAG,WAAW,MAAM,GAAG,MAAM,CAAC,IAC9F,MAAM,GAAG,KAAK,cAAc,EAAE,OAAO,SAAS,WAAW,MAAM,GAAG,MAAM,CAAC;AAE/E,QAAM,oBAAoB,CAAC,YAA0B;AACnD,UAAM,WAAW,SAAS,QAAQ,cAAc;AAChD,WAAO,WAAW,IAAI,WAAW,SAAS,QAAQ,MAAM;AAAA,EAC1D;AAEA,QAAM,mBAAmB,IAAI,IAAI,SAAS,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC;AACtE,QAAM,YACJ,YAAY,SAAS,IACjB,YAAY,OAAO,CAAC,KAAK,eAAe;AACtC,UAAM,aAAa,WAAW;AAC9B,UAAM,YACJ,OAAO,eAAe,YAAY,eAAe,OAC7C,WAAW,KACX,OAAO,eAAe,WACpB,aACA;AACR,QAAI,aAAa,CAAC,iBAAiB,IAAI,SAAS,EAAG,QAAO;AAC1D,WAAO,MAAM,SAAS,WAAW,MAAM;AAAA,EACzC,GAAG,CAAC,IACJ,SAAS,OAAO,CAAC,KAAK,YAAY,MAAM,kBAAkB,OAAO,GAAG,CAAC;AAE3E,QAAM,gBAAgB,SAAS;AAAA,IAC7B,CAAC,KAAK,YAAY,MAAM,SAAS,QAAQ,cAAc;AAAA,IACvD;AAAA,EACF;AAEA,QAAM,aAAa,SAAS,MAAM,qBAAqB;AACvD,QAAM,cAAc,KAAK,IAAI,aAAa,YAAY,eAAe,CAAC;AACtE,QAAM,kBAAkB,gBAAgB,SAAS,KAAK;AACtD,QAAM,sBAAsB,gBAAgB,aAAa,KAAK;AAC9D,QAAM,oBAAoB,gBAAgB,WAAW,KAAK;AAC1D,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,EACrB;AACF;AAEA,MAAM,uBAGF;AAAA,EACF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACtD,sBAAkB,KAAK,MAAM,QAAQ;AACrC,4BAAwB,KAAK,MAAM,cAAc;AACjD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,QAAI,CAAC,MAAM,SAAS;AAClB,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,iCAAiC,iCAAiC,EAAE,CAAC;AAAA,IACvH;AACA,UAAM,QAAQ;AAAA,MACZ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,MAClD;AAAA,IACF;AACA,oBAAgB,OAAO,MAAM,gBAAgB,MAAM,QAAQ;AAC3D,QAAI,MAAM,WAAW;AACnB,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,iCAAiC,CAAC;AAAA,IAC1E;AACA,QACE,MAAM,gBACN,MAAM,gBACN,MAAM,aAAa,YAAY,MAAM,MAAM,aAAa,YAAY,GACpE;AACA,YAAM,IAAI,cAAc,KAAK;AAAA,QAC3B,OAAO,UAAU,oCAAoC,iDAAiD;AAAA,MACxG,CAAC;AAAA,IACH;AACA,QAAI,gBAAgB;AACpB,QAAI,MAAM,iBAAiB;AACzB,YAAM,SAAS;AAAA,QACb,MAAM,GAAG,QAAQ,oBAAoB,EAAE,IAAI,MAAM,gBAAgB,CAAC;AAAA,QAClE;AAAA,MACF;AACA,sBAAgB,QAAQ,MAAM,gBAAgB,MAAM,QAAQ;AAC5D,sBAAgB;AAAA,IAClB;AACA,UAAM,6BAA6B,MAAM,mBAAmB;AAC5D,UAAM,+BAA+B,MAAM,qBAAqB;AAChE,QAAI,iBAAiB,CAAC,MAAM,iBAAiB;AAC3C,YAAM,kBAAkB,cAAc;AACtC,YAAM,oBAAoB,cAAc,QAAQ;AAChD,YAAM,YAAY,oBAAI,KAAK;AAC3B,SAAG,QAAQ,KAAK;AAAA,IAClB;AACA,QAAI,MAAM,0BAA0B,QAAW;AAC7C,YAAM,cAAc,MAAM,4BAA4B,IAAI,MAAM,yBAAyB,IAAI;AAC7F,UAAI,MAAM,yBAAyB,CAAC,aAAa;AAC/C,cAAM,IAAI,cAAc,KAAK;AAAA,UAC3B,OAAO,UAAU,wCAAwC,qCAAqC;AAAA,QAChG,CAAC;AAAA,MACH;AACA,YAAM,gBAAgB,MAAM,yBAAyB;AACrD,YAAM,SAAS;AACf,YAAM,YAAY,oBAAI,KAAK;AAC3B,SAAG,QAAQ,KAAK;AAAA,IAClB;AACA,QAAI,MAAM,sBAAsB,QAAW;AACzC,YAAM,aAAa,MAAM,4BAA4B,IAAI,MAAM,qBAAqB,IAAI;AACxF,UAAI,MAAM,qBAAqB,CAAC,YAAY;AAC1C,cAAM,IAAI,cAAc,KAAK;AAAA,UAC3B,OAAO,UAAU,wCAAwC,qCAAqC;AAAA,QAChG,CAAC;AAAA,MACH;AACA,YAAM,aAAa,MAAM,GAAG,KAAK,gBAAgB,EAAE,MAAM,CAAC;AAC1D,iBAAW,QAAQ,CAAC,SAAS;AAC3B,aAAK,gBAAgB,MAAM,qBAAqB;AAChD,aAAK,SAAS;AACd,aAAK,YAAY,oBAAI,KAAK;AAAA,MAC5B,CAAC;AACD,iBAAW,QAAQ,CAAC,SAAS,GAAG,QAAQ,IAAI,CAAC;AAAA,IAC/C;AACA,UAAM,SAAS,MAAM,4BAA4B,IAAI,MAAM,iBAAiB,IAAI;AAChF,UAAM,UAAU,GAAG,OAAO,cAAc;AAAA,MACtC,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,MACA,kBAAkB,MAAM,oBAAoB;AAAA,MAC5C,eAAe,MAAM,iBAAiB;AAAA,MACtC;AAAA,MACA,QAAQ,gBAAgB,MAAM,MAAM,KAAK;AAAA,MACzC,cAAc,MAAM;AAAA,MACpB,gBAAgB,gBAAgB,MAAM,cAAc,KAAK;AAAA,MACzD,gBAAgB,gBAAgB,MAAM,cAAc,KAAK;AAAA,MACzD,YAAY,MAAM,cAAc;AAAA,MAChC,YAAY,MAAM,cAAc;AAAA,MAChC,UAAU,MAAM,WAAW,UAAU,MAAM,QAAQ,IAAI;AAAA,MACvD,kBAAkB,MAAM,oBAAoB;AAAA,IAC9C,CAAC;AACD,UAAM,mBAAmB,MAAM,QAAQ,MAAM,WAAW,IAAI,MAAM,cAAc,CAAC;AACjF,UAAM,cAAc,iBAAiB,SACjC,mBACA;AAAA,MACE;AAAA,QACE,SAAS,MAAM;AAAA,QACf,WAAW;AAAA,QACX,QAAQ,MAAM;AAAA,QACd,cAAc,MAAM;AAAA,QACpB,UAAU;AAAA,MACZ;AAAA,IACF;AACJ,gBAAY,QAAQ,CAAC,eAAe;AAClC,YAAM,WAAW,WAAW,UAAU,GAAG,aAAa,YAAY,WAAW,OAAO,IAAI;AACxF,YAAM,aAAa,WAAW,YAAY,GAAG,aAAa,cAAc,WAAW,SAAS,IAAI;AAChG,YAAM,SAAS,GAAG,OAAO,wBAAwB;AAAA,QAC/C;AAAA,QACA,OAAO;AAAA,QACP,SAAS;AAAA,QACT,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB,QAAQ,gBAAgB,WAAW,MAAM,KAAK;AAAA,QAC9C,cAAc,WAAW;AAAA,QACzB,UAAU,WAAW,WAAW,UAAU,WAAW,QAAQ,IAAI;AAAA,MACnE,CAAC;AACD,SAAG,QAAQ,MAAM;AAAA,IACnB,CAAC;AACD,OAAG,QAAQ,OAAO;AAClB,QAAI,MAAM,iBAAiB,QAAW;AACpC,UAAI,CAAC,QAAQ,IAAI;AACf,cAAM,GAAG,MAAM;AAAA,MACjB;AACA,YAAM,sBAAsB,IAAI;AAAA,QAC9B,UAAU,EAAE,MAAM;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB,QAAQ,2BAA2B,MAAM,YAAY;AAAA,MACvD,CAAC;AAAA,IACH;AACA,UAAM,GAAG,MAAM;AACf,UAAM,SAAS,MAAM,4BAA4B,IAAI,KAAK;AAC1D,UAAM,GAAG,MAAM;AACf,UAAM,qBAAqB,IAAI,WAAW,OAAO,IAAI,MAAM,YAAY,IAAI;AAE3E,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,QAAQ;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,UAAU,QAAQ;AAAA,MACpB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc;AAAA,MAC7C,QAAQ;AAAA,IACV,CAAC;AAGD,QAAI;AACF,YAAM,sBAAsB,2BAA2B,IAAI,SAAS;AACpE,YAAM,UAAU,kBAAkB,KAAK,CAAC,SAAS,KAAK,SAAS,wBAAwB;AACvF,UAAI,SAAS;AACX,cAAM,gBAAgB,QAAQ,UAAU,QAAQ,eAC5C,GAAG,QAAQ,YAAY,IAAI,QAAQ,MAAM,KACzC;AACJ,cAAM,oBAAoB,iCAAiC,SAAS;AAAA,UAClE,iBAAiB;AAAA,UACjB,eAAe;AAAA,YACb,aAAa,MAAM,eAAe;AAAA,YAClC,QAAQ;AAAA,UACV;AAAA,UACA,kBAAkB;AAAA,UAClB,gBAAgB,MAAM;AAAA,UACtB,UAAU,yBAAyB,MAAM,EAAE;AAAA,QAC7C,CAAC;AAED,cAAM,oBAAoB,iBAAiB,mBAAmB;AAAA,UAC5D,UAAU,QAAQ;AAAA,UAClB,gBAAgB,QAAQ,kBAAkB;AAAA,QAC5C,CAAC;AAAA,MACH;AAAA,IACF,SAAS,KAAK;AAEZ,cAAQ,MAAM,0DAA0D,GAAG;AAAA,IAC7E;AAEA,WAAO,EAAE,WAAW,QAAQ,IAAI,aAAa,QAAQ,4BAA4B,6BAA6B;AAAA,EAChH;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,QAAQ,YAAY,oBAAoB,IAAI,OAAO,SAAS,IAAI;AAAA,EACzE;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,QAAQ,UAAU;AACxB,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,WAAO;AAAA,MACL,aAAa,UAAU,+BAA+B,gBAAgB;AAAA,MACtE,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,MAAM,WAAW;AAAA,MACnC,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,eAAe;AAAA,MACf,SAAS,EAAE,MAAM,EAAE,OAAO,4BAA4B,OAAO,8BAA8B,MAAM,8BAA8B,OAAO,gCAAgC,KAAK,EAA+B;AAAA,IAC5M;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,MAAO;AACZ,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,MAAM,GAAG,QAAQ,cAAc,EAAE,IAAI,MAAM,GAAG,CAAC;AAChE,QAAI,UAAU;AACZ,YAAM,WACJ,OAAO,SAAS,UAAU,WAAW,SAAS,QAAQ,SAAS,OAAO,MAAM;AAC9E,YAAM,cAAc,MAAM,GAAG,KAAK,wBAAwB,EAAE,SAAS,SAAS,CAAC;AAC/E,YAAM,mBAAmB,YACtB;AAAA,QAAI,CAAC,eACJ,OAAO,WAAW,UAAU,WACxB,WAAW,QACX,WAAW,OAAO,MAAM;AAAA,MAC9B,EACC,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAEnF,kBAAY,QAAQ,CAAC,eAAe,GAAG,OAAO,UAAU,CAAC;AACzD,YAAM,GAAG,MAAM;AAEf,SAAG,OAAO,QAAQ;AAClB,YAAM,GAAG,MAAM;AAEf,YAAM,WAAW,MAAM;AAAA,QACrB,IAAI;AAAA,UACF;AAAA,YACE;AAAA,YACA,GAAG;AAAA,UACL,EAAE,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAAA,QACpF;AAAA,MACF;AACA,iBAAW,MAAM,UAAU;AACzB,cAAM,QAAQ,MAAM,GAAG,QAAQ,YAAY,EAAE,GAAG,CAAC;AACjD,YAAI,CAAC,MAAO;AACZ,YAAI,OAAO,MAAM,WAAW,iCAAiC,WAAW,CAAC,IAAI;AAC3E,gBAAM,kBAAkB,QAAQ,8BAA8B;AAC9D,gBAAM,oBAAoB,QAAQ,gCAAgC;AAClE,gBAAM,YAAY,oBAAI,KAAK;AAC3B,gBAAM,GAAG,MAAM;AAAA,QACjB;AACA,cAAM,4BAA4B,IAAI,KAAK;AAC3C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,uBAGF;AAAA,EACF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACvD,QAAI,CAAC,OAAO,GAAI,QAAO,CAAC;AACxB,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,UAAM,WAAW,MAAM,oBAAoB,IAAI,OAAO,EAAE;AACxD,QAAI,UAAU;AACZ,wBAAkB,KAAK,SAAS,QAAQ;AACxC,8BAAwB,KAAK,SAAS,cAAc;AAAA,IACtD;AACA,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACtD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,YAAY;AAAA,MAChB,MAAM,GAAG,QAAQ,cAAc,EAAE,IAAI,MAAM,GAAG,CAAC;AAAA,MAC/C;AAAA,IACF;AACA,UAAM,mBAAmB,MAAM,YAAY,UAAU;AACrD,UAAM,yBAAyB,MAAM,kBAAkB,UAAU;AACjE,sBAAkB,KAAK,gBAAgB;AACvC,4BAAwB,KAAK,sBAAsB;AACnD,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,EAAE,IAAI,MAAM,GAAG;AAAA,QACf,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,QACtB,EAAE,UAAU,kBAAkB,gBAAgB,uBAAuB;AAAA,MACvE;AAAA,MACA;AAAA,IACF;AACA,oBAAgB,SAAS,wBAAwB,gBAAgB;AACjE,UAAM,gBAAgB,QAAQ;AAC9B,QAAI,MAAM,YAAY,QAAW;AAC/B,UAAI,CAAC,MAAM,SAAS;AAClB,gBAAQ,QAAQ;AAAA,MAClB,OAAO;AACL,cAAM,QAAQ;AAAA,UACZ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,UAClD;AAAA,QACF;AACA,wBAAgB,OAAO,wBAAwB,gBAAgB;AAC/D,YACE,MAAM,gBACN,MAAM,gBACN,MAAM,aAAa,YAAY,MAAM,MAAM,aAAa,YAAY,GACpE;AACA,gBAAM,IAAI,cAAc,KAAK;AAAA,YAC3B,OAAO,UAAU,oCAAoC,iDAAiD;AAAA,UACxG,CAAC;AAAA,QACH;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AACA,QAAI,MAAM,oBAAoB,QAAW;AACvC,UAAI,CAAC,MAAM,iBAAiB;AAC1B,gBAAQ,gBAAgB;AAAA,MAC1B,OAAO;AACL,cAAM,SAAS;AAAA,UACb,MAAM,GAAG,QAAQ,oBAAoB,EAAE,IAAI,MAAM,gBAAgB,CAAC;AAAA,UAClE;AAAA,QACF;AACA,wBAAgB,QAAQ,wBAAwB,gBAAgB;AAChE,gBAAQ,gBAAgB;AAAA,MAC1B;AAAA,IACF;AACA,UAAM,eAAe,QAAQ;AAC7B,SAAK,MAAM,0BAA0B,UAAa,MAAM,sBAAsB,WAAc,CAAC,cAAc;AACzG,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,iCAAiC,iCAAiC,EAAE,CAAC;AAAA,IACvH;AACA,QAAI,gBAAgB,MAAM,0BAA0B,QAAW;AAC7D,YAAM,cAAc,MAAM,4BAA4B,IAAI,MAAM,yBAAyB,IAAI;AAC7F,UAAI,MAAM,yBAAyB,CAAC,aAAa;AAC/C,cAAM,IAAI,cAAc,KAAK;AAAA,UAC3B,OAAO,UAAU,wCAAwC,qCAAqC;AAAA,QAChG,CAAC;AAAA,MACH;AACA,mBAAa,gBAAgB,MAAM,yBAAyB;AAC5D,mBAAa,SAAS;AACtB,mBAAa,YAAY,oBAAI,KAAK;AAClC,SAAG,QAAQ,YAAY;AAAA,IACzB;AACA,QAAI,gBAAgB,MAAM,sBAAsB,QAAW;AACzD,YAAM,aAAa,MAAM,4BAA4B,IAAI,MAAM,qBAAqB,IAAI;AACxF,UAAI,MAAM,qBAAqB,CAAC,YAAY;AAC1C,cAAM,IAAI,cAAc,KAAK;AAAA,UAC3B,OAAO,UAAU,wCAAwC,qCAAqC;AAAA,QAChG,CAAC;AAAA,MACH;AACA,YAAM,aAAa,MAAM,GAAG,KAAK,gBAAgB,EAAE,OAAO,aAAa,CAAC;AACxE,iBAAW,QAAQ,CAAC,SAAS;AAC3B,aAAK,gBAAgB,MAAM,qBAAqB;AAChD,aAAK,SAAS;AACd,aAAK,YAAY,oBAAI,KAAK;AAAA,MAC5B,CAAC;AACD,iBAAW,QAAQ,CAAC,SAAS,GAAG,QAAQ,IAAI,CAAC;AAAA,IAC/C;AACA,QAAI,MAAM,qBAAqB,OAAW,SAAQ,mBAAmB,MAAM,oBAAoB;AAC/F,QAAI,MAAM,kBAAkB,QAAW;AACrC,cAAQ,gBAAgB,MAAM,iBAAiB;AAC/C,cAAQ,SAAS,MAAM,4BAA4B,IAAI,MAAM,iBAAiB,IAAI;AAAA,IACpF;AACA,QAAI,MAAM,WAAW,OAAW,SAAQ,SAAS,gBAAgB,MAAM,MAAM,KAAK;AAClF,QAAI,MAAM,iBAAiB,OAAW,SAAQ,eAAe,MAAM;AACnE,QAAI,MAAM,mBAAmB,QAAW;AACtC,cAAQ,iBAAiB,gBAAgB,MAAM,cAAc,KAAK;AAAA,IACpE;AACA,QAAI,MAAM,mBAAmB,QAAW;AACtC,cAAQ,iBAAiB,gBAAgB,MAAM,cAAc,KAAK;AAAA,IACpE;AACA,QAAI,MAAM,eAAe,OAAW,SAAQ,aAAa,MAAM,cAAc;AAC7E,QAAI,MAAM,eAAe,OAAW,SAAQ,aAAa,MAAM,cAAc;AAC7E,QAAI,MAAM,aAAa,QAAW;AAChC,cAAQ,WAAW,MAAM,WAAW,UAAU,MAAM,QAAQ,IAAI;AAAA,IAClE;AACA,QAAI,MAAM,qBAAqB,QAAW;AACxC,cAAQ,mBAAmB,MAAM,oBAAoB;AAAA,IACvD;AACA,QAAI,MAAM,iBAAiB,QAAW;AACpC,UAAI,CAAC,QAAQ,IAAI;AACf,cAAM,GAAG,MAAM;AAAA,MACjB;AACA,YAAM,sBAAsB,IAAI;AAAA,QAC9B,UAAU,EAAE,MAAM;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,gBAAgB,QAAQ;AAAA,QACxB,UAAU,QAAQ;AAAA,QAClB,QAAQ,2BAA2B,MAAM,YAAY;AAAA,MACvD,CAAC;AAAA,IACH;AACA,QAAI,MAAM,gBAAgB,QAAW;AACnC,YAAM,sBAAsB,MAAM,GAAG,KAAK,wBAAwB,EAAE,QAAQ,CAAC;AAC7E,0BAAoB,QAAQ,CAAC,eAAe,GAAG,OAAO,UAAU,CAAC;AACjE,YAAM,mBAAmB,MAAM,QAAQ,MAAM,WAAW,IAAI,MAAM,cAAc,CAAC;AACjF,uBAAiB,QAAQ,CAAC,eAAe;AACvC,cAAM,WACJ,WAAW,YACV,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,QAAQ,OAAO,OACpE;AACF,cAAM,QACJ,YAAY,OAAO,aAAa,WAAW,GAAG,aAAa,YAAY,QAAQ,IAAI;AACrF,cAAM,UAAU,WAAW,YACvB,GAAG,aAAa,cAAc,WAAW,SAAS,IAClD;AACJ,cAAM,SAAS,GAAG,OAAO,wBAAwB;AAAA,UAC/C;AAAA,UACA;AAAA,UACA;AAAA,UACA,gBAAgB,QAAQ;AAAA,UACxB,UAAU,QAAQ;AAAA,UAClB,QAAQ,gBAAgB,WAAW,MAAM,KAAK;AAAA,UAC9C,cAAc,WAAW;AAAA,UACzB,UAAU,WAAW,WAAW,UAAU,WAAW,QAAQ,IAAI;AAAA,QACnE,CAAC;AACD,WAAG,QAAQ,MAAM;AAAA,MACnB,CAAC;AAAA,IACH;AACA,YAAQ,YAAY,oBAAI,KAAK;AAC7B,UAAM,GAAG,MAAM;AAEf,UAAM,YACH,QAAQ,UACR,OAAO,QAAQ,UAAU,WACtB,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,QAAQ,MAAM,CAAC,IAClD;AACN,QAAI;AACJ,QAAI,WAAW;AACb,eAAS,MAAM,4BAA4B,IAAI,SAAS;AACxD,YAAM,GAAG,MAAM;AACf,YAAM,qBAAqB,IAAI,WAAW,WAAW,IAAI,MAAM,YAAY,IAAI;AAAA,IACjF;AACA,QAAI,kBAAkB,CAAC,aAAa,cAAc,OAAO,UAAU,KAAK;AACtE,YAAM,4BAA4B,IAAI,aAAa;AACnD,YAAM,GAAG,MAAM;AACf,YAAM,qBAAqB,IAAI,WAAW,eAAe,IAAI,MAAM,YAAY,IAAI;AAAA,IACrF;AAEA,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,QAAQ;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,UAAU,QAAQ;AAAA,MACpB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc;AAAA,MAC7C,QAAQ;AAAA,IACV,CAAC;AAED,WAAO,EAAE,WAAW,QAAQ,IAAI,aAAa,OAAO;AAAA,EACtD;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,QAAQ,YAAY,oBAAoB,IAAI,OAAO,SAAS,IAAI;AAAA,EACzE;AAAA,EACA,UAAU,OAAO,EAAE,WAAW,OAAO,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,UAAM,QAAQ,UAAU;AACxB,WAAO;AAAA,MACL,aAAa,UAAU,+BAA+B,gBAAgB;AAAA,MACtE,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,WAAW,QAAQ,WAAW;AAAA,MACvD,UAAU,OAAO,YAAY,QAAQ,YAAY;AAAA,MACjD,gBAAgB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,MACnE,gBAAgB,UAAU;AAAA,MAC1B,eAAe,SAAS;AAAA,MACxB,SAAS,EAAE,MAAM,EAAE,QAAQ,MAAM,EAA+B;AAAA,IAClE;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,uBAAuB,IAAI,MAAM;AACvC,UAAM,GAAG,MAAM;AACf,QAAI,OAAO,SAAS;AAClB,YAAM,QAAQ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,OAAO,QAAQ,CAAC;AACjE,UAAI,OAAO;AACT,cAAM,4BAA4B,IAAI,KAAK;AAC3C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,uBAGF;AAAA,EACF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACvD,QAAI,CAAC,OAAO,GAAI,QAAO,CAAC;AACxB,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,UAAM,WAAW,MAAM,oBAAoB,IAAI,OAAO,EAAE;AACxD,QAAI,UAAU;AACZ,wBAAkB,KAAK,SAAS,QAAQ;AACxC,8BAAwB,KAAK,SAAS,cAAc;AAAA,IACtD;AACA,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,oBAAoB,MAAM,YAAY,CAAC,CAAC;AACtD,sBAAkB,KAAK,MAAM,QAAQ;AACrC,4BAAwB,KAAK,MAAM,cAAc;AACjD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,EAAE,IAAI,MAAM,GAAG;AAAA,QACf,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,QACtB,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,MACnE;AAAA,MACA;AAAA,IACF;AACA,oBAAgB,SAAS,MAAM,gBAAgB,MAAM,QAAQ;AAC7D,UAAM,QAAQ,QAAQ;AACtB,UAAM,cAAc,MAAM,GAAG,KAAK,wBAAwB,EAAE,QAAQ,CAAC;AACrE,UAAM,mBAAmB,YACtB;AAAA,MAAI,CAAC,eACJ,OAAO,WAAW,UAAU,WACxB,WAAW,QACX,WAAW,OAAO,MAAM;AAAA,IAC9B,EACC,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AACnF,gBAAY,QAAQ,CAAC,eAAe,GAAG,OAAO,UAAU,CAAC;AACzD,UAAM,GAAG,MAAM;AACf,OAAG,OAAO,OAAO;AACjB,UAAM,GAAG,MAAM;AACf,QAAI;AACJ,UAAM,WAAW,MAAM;AAAA,MACrB,IAAI;AAAA,QACF;AAAA,UACE,SAAS,OAAO,UAAU,WAAW,MAAM,KAAK;AAAA,UAChD,GAAG;AAAA,QACL,EAAE,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAAA,MACpF;AAAA,IACF;AACA,UAAM,iBAAiB,SAAS,OAAO,UAAU,WAAW,MAAM,KAAK;AACvE,eAAW,WAAW,UAAU;AAC9B,YAAM,SAAS,OAAO,UAAU,YAAY,MAAM,OAAO,UAAU,QAAQ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,QAAQ,CAAC;AACvH,UAAI,CAAC,OAAQ;AACb,YAAM,aAAa,MAAM,4BAA4B,IAAI,MAAM;AAC/D,UAAI,CAAC,UAAW,kBAAkB,YAAY,gBAAiB;AAC7D,iBAAS;AAAA,MACX;AACA,YAAM,GAAG,MAAM;AACf,YAAM,qBAAqB,IAAI,WAAW,QAAQ,IAAI,MAAM,YAAY,IAAI;AAAA,IAC9E;AACA,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,QAAQ;AAAA,QACZ,gBAAgB,QAAQ;AAAA,QACxB,UAAU,QAAQ;AAAA,MACpB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc;AAAA,MAC7C,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,YAAY,QAAQ;AACtB,YAAM,QAAQ;AAAA,QACZ,YAAY;AAAA,UAAI,CAAC,eACf,oBAAoB;AAAA,YAClB;AAAA,YACA,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,aAAa;AAAA,cACX,IAAI,WAAW;AAAA,cACf,gBAAgB,WAAW,kBAAkB;AAAA,cAC7C,UAAU,WAAW,YAAY;AAAA,YACnC;AAAA,YACA,SAAS,EAAE,YAAY,EAAE,MAAM,yBAAyB;AAAA,UAC1D,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,WAAW,QAAQ,IAAI,aAAa,OAAO;AAAA,EACtD;AAAA,EACA,UAAU,OAAO,EAAE,WAAW,OAAO,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,WAAO;AAAA,MACL,aAAa,UAAU,+BAA+B,gBAAgB;AAAA,MACtE,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,QAAQ,WAAW;AAAA,MACrC,UAAU,QAAQ,YAAY;AAAA,MAC9B,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,gBAAgB,UAAU;AAAA,MAC1B,SAAS,EAAE,MAAM,EAAE,OAAO,EAA+B;AAAA,IAC3D;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,uBAAuB,IAAI,MAAM;AACvC,UAAM,GAAG,MAAM;AACf,QAAI,OAAO,SAAS;AAClB,YAAM,QAAQ,MAAM,GAAG,QAAQ,YAAY,EAAE,IAAI,OAAO,QAAQ,CAAC;AACjE,UAAI,OAAO;AACT,cAAM,4BAA4B,IAAI,KAAK;AAC3C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,kBAAkB,CAAC,sBAAsB,sBAAsB,oBAAoB;AAEhG,gBAAgB,oBAAoB;AACpC,gBAAgB,oBAAoB;AACpC,gBAAgB,oBAAoB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -131,10 +131,8 @@ function SalesDocumentPaymentsSection({
|
|
|
131
131
|
[currencyCode]
|
|
132
132
|
);
|
|
133
133
|
const handlePaymentSaved = React.useCallback(
|
|
134
|
-
async (
|
|
135
|
-
|
|
136
|
-
onTotalsChange(totals);
|
|
137
|
-
}
|
|
134
|
+
async (_totals) => {
|
|
135
|
+
onTotalsChange?.();
|
|
138
136
|
await loadPayments();
|
|
139
137
|
emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: "order" });
|
|
140
138
|
handleDialogChange(false);
|
|
@@ -154,10 +152,7 @@ function SalesDocumentPaymentsSection({
|
|
|
154
152
|
errorMessage: t("sales.documents.payments.errorDelete", "Failed to delete payment.")
|
|
155
153
|
});
|
|
156
154
|
if (result.ok) {
|
|
157
|
-
|
|
158
|
-
if (totals && onTotalsChange) {
|
|
159
|
-
onTotalsChange(totals);
|
|
160
|
-
}
|
|
155
|
+
onTotalsChange?.();
|
|
161
156
|
flash(t("sales.documents.payments.deleted", "Payment deleted."), "success");
|
|
162
157
|
await loadPayments();
|
|
163
158
|
emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: "order" });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/sales/components/documents/PaymentsSection.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { LoadingMessage, ErrorMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport type { SectionAction } from '@open-mercato/ui/backend/detail'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { emitSalesDocumentTotalsRefresh } from '@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents'\nimport { PaymentDialog, type PaymentFormData, type PaymentTotals } from './PaymentDialog'\nimport { extractCustomFieldValues } from './customFieldHelpers'\nimport { Plus } from 'lucide-react'\n\ntype PaymentRow = {\n id: string\n paymentReference: string | null\n paymentMethodId: string | null\n paymentMethodName: string | null\n status: string | null\n statusEntryId: string | null\n statusLabel: string | null\n amount: number\n currencyCode: string | null\n receivedAt: string | null\n createdAt: string | null\n customValues?: Record<string, unknown> | null\n customFieldSetId?: string | null\n}\n\ntype SalesDocumentPaymentsSectionProps = {\n orderId: string\n currencyCode: string | null | undefined\n organizationId?: string | null\n tenantId?: string | null\n onActionChange?: (action: SectionAction | null) => void\n onTotalsChange?: (totals: PaymentTotals) => void\n onPaymentsChange?: (payments: PaymentRow[]) => void\n}\n\nfunction normalizeNumber(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nfunction formatMoney(value: number, currency: string | null | undefined): string {\n if (!currency || currency.trim().length !== 3) return value.toFixed(2)\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return `${currency.toUpperCase()} ${value.toFixed(2)}`\n }\n}\n\nexport function SalesDocumentPaymentsSection({\n orderId,\n currencyCode,\n organizationId: orgFromProps,\n tenantId: tenantFromProps,\n onActionChange,\n onTotalsChange,\n onPaymentsChange,\n}: SalesDocumentPaymentsSectionProps) {\n const t = useT()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const resolvedOrganizationId = orgFromProps ?? organizationId ?? null\n const resolvedTenantId = tenantFromProps ?? tenantId ?? null\n const [payments, setPayments] = React.useState<PaymentRow[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const [dialogOpen, setDialogOpen] = React.useState(false)\n const [editingPayment, setEditingPayment] = React.useState<PaymentFormData | null>(null)\n const onPaymentsChangeRef = React.useRef<typeof onPaymentsChange>(onPaymentsChange)\n\n React.useEffect(() => {\n onPaymentsChangeRef.current = onPaymentsChange\n }, [onPaymentsChange])\n\n const addActionLabel = t('sales.documents.payments.add', 'Add payment')\n const editActionLabel = t('sales.documents.payments.edit', 'Edit payment')\n const deleteActionLabel = t('sales.documents.payments.delete', 'Delete payment')\n\n const loadPayments = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/payments?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n if (response.ok && Array.isArray(response.result?.items)) {\n const mapped = response.result.items.flatMap<PaymentRow>((item) => {\n if (typeof item.id !== 'string') return []\n const customValues =\n item && typeof item === 'object'\n ? extractCustomFieldValues(item as Record<string, unknown>)\n : {}\n const record: PaymentRow = {\n id: item.id,\n paymentReference: typeof item.payment_reference === 'string' ? item.payment_reference : null,\n paymentMethodId: typeof item.payment_method_id === 'string' ? item.payment_method_id : null,\n paymentMethodName:\n typeof item.payment_method_name === 'string'\n ? item.payment_method_name\n : typeof item.payment_method_code === 'string'\n ? item.payment_method_code\n : null,\n status: typeof item.status === 'string' ? item.status : null,\n statusEntryId:\n typeof (item as any).status_entry_id === 'string'\n ? (item as any).status_entry_id\n : typeof (item as any).statusEntryId === 'string'\n ? (item as any).statusEntryId\n : null,\n statusLabel:\n typeof (item as any).status_label === 'string'\n ? (item as any).status_label\n : typeof (item as any).statusLabel === 'string'\n ? (item as any).statusLabel\n : null,\n amount: normalizeNumber(item.amount),\n currencyCode:\n typeof item.currency_code === 'string'\n ? item.currency_code\n : typeof currencyCode === 'string'\n ? currencyCode\n : null,\n receivedAt: typeof item.received_at === 'string' ? item.received_at : null,\n createdAt: typeof item.created_at === 'string' ? item.created_at : null,\n customValues: Object.keys(customValues).length ? customValues : null,\n customFieldSetId:\n typeof (item as any)?.custom_field_set_id === 'string'\n ? (item as any).custom_field_set_id\n : typeof (item as any)?.customFieldSetId === 'string'\n ? (item as any).customFieldSetId\n : null,\n }\n return [record]\n })\n setPayments(mapped)\n onPaymentsChangeRef.current?.(mapped)\n } else {\n setPayments([])\n onPaymentsChangeRef.current?.([])\n }\n } catch (err) {\n console.error('sales.payments.list', err)\n setError(t('sales.documents.payments.errorLoad', 'Failed to load payments.'))\n onPaymentsChangeRef.current?.([])\n } finally {\n setLoading(false)\n }\n }, [currencyCode, orderId, t])\n\n React.useEffect(() => {\n void loadPayments()\n }, [loadPayments])\n\n const openCreate = React.useCallback(() => {\n setEditingPayment(null)\n setDialogOpen(true)\n }, [])\n\n const handleDialogChange = React.useCallback((nextOpen: boolean) => {\n setDialogOpen(nextOpen)\n if (!nextOpen) {\n setEditingPayment(null)\n }\n }, [])\n\n const openEditPayment = React.useCallback(\n (record: PaymentRow) => {\n setEditingPayment({\n id: record.id,\n amount: record.amount ?? '',\n paymentMethodId: record.paymentMethodId ?? '',\n paymentReference: record.paymentReference ?? '',\n receivedAt: record.receivedAt ? record.receivedAt.slice(0, 10) : '',\n currencyCode: record.currencyCode ?? currencyCode ?? null,\n statusEntryId: record.statusEntryId ?? null,\n customValues: record.customValues ?? null,\n customFieldSetId: record.customFieldSetId ?? null,\n })\n setDialogOpen(true)\n },\n [currencyCode]\n )\n\n const handlePaymentSaved = React.useCallback(\n async (totals?: PaymentTotals | null) => {\n if (totals && onTotalsChange) {\n onTotalsChange(totals)\n }\n await loadPayments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n handleDialogChange(false)\n },\n [handleDialogChange, loadPayments, onTotalsChange, orderId]\n )\n\n const handleDelete = React.useCallback(\n async (row: PaymentRow) => {\n try {\n const result = await deleteCrud<{ orderTotals?: PaymentTotals | null }>('sales/payments', {\n body: {\n id: row.id,\n orderId,\n organizationId: resolvedOrganizationId ?? undefined,\n tenantId: resolvedTenantId ?? undefined,\n },\n errorMessage: t('sales.documents.payments.errorDelete', 'Failed to delete payment.'),\n })\n if (result.ok) {\n const totals = result.result?.orderTotals ?? null\n if (totals && onTotalsChange) {\n onTotalsChange(totals)\n }\n flash(t('sales.documents.payments.deleted', 'Payment deleted.'), 'success')\n await loadPayments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n }\n } catch (err) {\n console.error('sales.payments.delete', err)\n flash(t('sales.documents.payments.errorDelete', 'Failed to delete payment.'), 'error')\n }\n },\n [loadPayments, onTotalsChange, orderId, resolvedOrganizationId, resolvedTenantId, t]\n )\n\n React.useEffect(() => {\n if (!onActionChange) return\n if (payments.length === 0) {\n onActionChange(null)\n return\n }\n onActionChange({\n label: addActionLabel,\n onClick: openCreate,\n disabled: loading,\n })\n return () => onActionChange(null)\n }, [addActionLabel, loading, onActionChange, openCreate, payments.length])\n\n const columns = React.useMemo<ColumnDef<PaymentRow>[]>(\n () => [\n {\n accessorKey: 'paymentReference',\n header: t('sales.documents.payments.reference', 'Reference'),\n cell: ({ row }) => row.original.paymentReference || '\u2014',\n },\n {\n accessorKey: 'paymentMethodName',\n header: t('sales.documents.payments.method', 'Method'),\n cell: ({ row }) => row.original.paymentMethodName ?? '\u2014',\n },\n {\n accessorKey: 'status',\n header: t('sales.documents.payments.status', 'Status'),\n cell: ({ row }) => row.original.statusLabel ?? row.original.status ?? '\u2014',\n },\n {\n accessorKey: 'amount',\n header: t('sales.documents.payments.amount', 'Amount'),\n cell: ({ row }) => formatMoney(row.original.amount, row.original.currencyCode ?? currencyCode),\n },\n {\n accessorKey: 'receivedAt',\n header: t('sales.documents.payments.receivedAt', 'Received'),\n cell: ({ row }) =>\n row.original.receivedAt\n ? new Date(row.original.receivedAt).toLocaleDateString()\n : '\u2014',\n },\n {\n accessorKey: 'createdAt',\n header: t('sales.documents.payments.createdAt', 'Created'),\n cell: ({ row }) =>\n row.original.createdAt ? new Date(row.original.createdAt).toLocaleString() : '\u2014',\n meta: {\n tooltipContent: (row: PaymentRow) =>\n row.createdAt ? new Date(row.createdAt).toLocaleString() : undefined,\n },\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n return (\n <RowActions\n items={[\n { id: 'edit', label: editActionLabel, onSelect: () => openEditPayment(row.original) },\n {\n id: 'delete',\n label: deleteActionLabel,\n destructive: true,\n onSelect: () => void handleDelete(row.original),\n },\n ]}\n />\n )\n },\n },\n ],\n [currencyCode, deleteActionLabel, editActionLabel, handleDelete, openEditPayment, t]\n )\n\n if (loading) {\n return (\n <LoadingMessage\n label={t('sales.documents.payments.loading', 'Loading payments\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n )\n }\n\n if (error) {\n return (\n <ErrorMessage\n label={error}\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => void loadPayments()}>\n {t('sales.documents.payments.retry', 'Retry')}\n </Button>\n }\n />\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {payments.length ? (\n <DataTable<PaymentRow> columns={columns} data={payments} onRowClick={openEditPayment} />\n ) : (\n <TabEmptyState\n title={t('sales.documents.payments.emptyTitle', 'No payments yet.')}\n description={t(\n 'sales.documents.payments.emptyDescription',\n 'Track received payments to keep outstanding balances up to date.'\n )}\n action={{\n label: addActionLabel,\n onClick: openCreate,\n icon: <Plus className=\"h-4 w-4\" aria-hidden />,\n disabled: loading,\n }}\n />\n )}\n\n <PaymentDialog\n open={dialogOpen}\n onOpenChange={handleDialogChange}\n mode={editingPayment ? 'edit' : 'create'}\n payment={editingPayment}\n currencyCode={editingPayment?.currencyCode ?? currencyCode}\n orderId={orderId}\n organizationId={resolvedOrganizationId}\n tenantId={resolvedTenantId}\n onSaved={handlePaymentSaved}\n />\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { LoadingMessage, ErrorMessage, TabEmptyState } from '@open-mercato/ui/backend/detail'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport type { SectionAction } from '@open-mercato/ui/backend/detail'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { emitSalesDocumentTotalsRefresh } from '@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents'\nimport { PaymentDialog, type PaymentFormData, type PaymentTotals } from './PaymentDialog'\nimport { extractCustomFieldValues } from './customFieldHelpers'\nimport { Plus } from 'lucide-react'\n\ntype PaymentRow = {\n id: string\n paymentReference: string | null\n paymentMethodId: string | null\n paymentMethodName: string | null\n status: string | null\n statusEntryId: string | null\n statusLabel: string | null\n amount: number\n currencyCode: string | null\n receivedAt: string | null\n createdAt: string | null\n customValues?: Record<string, unknown> | null\n customFieldSetId?: string | null\n}\n\ntype SalesDocumentPaymentsSectionProps = {\n orderId: string\n currencyCode: string | null | undefined\n organizationId?: string | null\n tenantId?: string | null\n onActionChange?: (action: SectionAction | null) => void\n onTotalsChange?: () => void\n onPaymentsChange?: (payments: PaymentRow[]) => void\n}\n\nfunction normalizeNumber(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nfunction formatMoney(value: number, currency: string | null | undefined): string {\n if (!currency || currency.trim().length !== 3) return value.toFixed(2)\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(value)\n } catch {\n return `${currency.toUpperCase()} ${value.toFixed(2)}`\n }\n}\n\nexport function SalesDocumentPaymentsSection({\n orderId,\n currencyCode,\n organizationId: orgFromProps,\n tenantId: tenantFromProps,\n onActionChange,\n onTotalsChange,\n onPaymentsChange,\n}: SalesDocumentPaymentsSectionProps) {\n const t = useT()\n const { organizationId, tenantId } = useOrganizationScopeDetail()\n const resolvedOrganizationId = orgFromProps ?? organizationId ?? null\n const resolvedTenantId = tenantFromProps ?? tenantId ?? null\n const [payments, setPayments] = React.useState<PaymentRow[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const [dialogOpen, setDialogOpen] = React.useState(false)\n const [editingPayment, setEditingPayment] = React.useState<PaymentFormData | null>(null)\n const onPaymentsChangeRef = React.useRef<typeof onPaymentsChange>(onPaymentsChange)\n\n React.useEffect(() => {\n onPaymentsChangeRef.current = onPaymentsChange\n }, [onPaymentsChange])\n\n const addActionLabel = t('sales.documents.payments.add', 'Add payment')\n const editActionLabel = t('sales.documents.payments.edit', 'Edit payment')\n const deleteActionLabel = t('sales.documents.payments.delete', 'Delete payment')\n\n const loadPayments = React.useCallback(async () => {\n setLoading(true)\n setError(null)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/payments?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n if (response.ok && Array.isArray(response.result?.items)) {\n const mapped = response.result.items.flatMap<PaymentRow>((item) => {\n if (typeof item.id !== 'string') return []\n const customValues =\n item && typeof item === 'object'\n ? extractCustomFieldValues(item as Record<string, unknown>)\n : {}\n const record: PaymentRow = {\n id: item.id,\n paymentReference: typeof item.payment_reference === 'string' ? item.payment_reference : null,\n paymentMethodId: typeof item.payment_method_id === 'string' ? item.payment_method_id : null,\n paymentMethodName:\n typeof item.payment_method_name === 'string'\n ? item.payment_method_name\n : typeof item.payment_method_code === 'string'\n ? item.payment_method_code\n : null,\n status: typeof item.status === 'string' ? item.status : null,\n statusEntryId:\n typeof (item as any).status_entry_id === 'string'\n ? (item as any).status_entry_id\n : typeof (item as any).statusEntryId === 'string'\n ? (item as any).statusEntryId\n : null,\n statusLabel:\n typeof (item as any).status_label === 'string'\n ? (item as any).status_label\n : typeof (item as any).statusLabel === 'string'\n ? (item as any).statusLabel\n : null,\n amount: normalizeNumber(item.amount),\n currencyCode:\n typeof item.currency_code === 'string'\n ? item.currency_code\n : typeof currencyCode === 'string'\n ? currencyCode\n : null,\n receivedAt: typeof item.received_at === 'string' ? item.received_at : null,\n createdAt: typeof item.created_at === 'string' ? item.created_at : null,\n customValues: Object.keys(customValues).length ? customValues : null,\n customFieldSetId:\n typeof (item as any)?.custom_field_set_id === 'string'\n ? (item as any).custom_field_set_id\n : typeof (item as any)?.customFieldSetId === 'string'\n ? (item as any).customFieldSetId\n : null,\n }\n return [record]\n })\n setPayments(mapped)\n onPaymentsChangeRef.current?.(mapped)\n } else {\n setPayments([])\n onPaymentsChangeRef.current?.([])\n }\n } catch (err) {\n console.error('sales.payments.list', err)\n setError(t('sales.documents.payments.errorLoad', 'Failed to load payments.'))\n onPaymentsChangeRef.current?.([])\n } finally {\n setLoading(false)\n }\n }, [currencyCode, orderId, t])\n\n React.useEffect(() => {\n void loadPayments()\n }, [loadPayments])\n\n const openCreate = React.useCallback(() => {\n setEditingPayment(null)\n setDialogOpen(true)\n }, [])\n\n const handleDialogChange = React.useCallback((nextOpen: boolean) => {\n setDialogOpen(nextOpen)\n if (!nextOpen) {\n setEditingPayment(null)\n }\n }, [])\n\n const openEditPayment = React.useCallback(\n (record: PaymentRow) => {\n setEditingPayment({\n id: record.id,\n amount: record.amount ?? '',\n paymentMethodId: record.paymentMethodId ?? '',\n paymentReference: record.paymentReference ?? '',\n receivedAt: record.receivedAt ? record.receivedAt.slice(0, 10) : '',\n currencyCode: record.currencyCode ?? currencyCode ?? null,\n statusEntryId: record.statusEntryId ?? null,\n customValues: record.customValues ?? null,\n customFieldSetId: record.customFieldSetId ?? null,\n })\n setDialogOpen(true)\n },\n [currencyCode]\n )\n\n const handlePaymentSaved = React.useCallback(\n async (_totals?: PaymentTotals | null) => {\n onTotalsChange?.()\n await loadPayments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n handleDialogChange(false)\n },\n [handleDialogChange, loadPayments, onTotalsChange, orderId]\n )\n\n const handleDelete = React.useCallback(\n async (row: PaymentRow) => {\n try {\n const result = await deleteCrud<{ orderTotals?: PaymentTotals | null }>('sales/payments', {\n body: {\n id: row.id,\n orderId,\n organizationId: resolvedOrganizationId ?? undefined,\n tenantId: resolvedTenantId ?? undefined,\n },\n errorMessage: t('sales.documents.payments.errorDelete', 'Failed to delete payment.'),\n })\n if (result.ok) {\n onTotalsChange?.()\n flash(t('sales.documents.payments.deleted', 'Payment deleted.'), 'success')\n await loadPayments()\n emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: 'order' })\n }\n } catch (err) {\n console.error('sales.payments.delete', err)\n flash(t('sales.documents.payments.errorDelete', 'Failed to delete payment.'), 'error')\n }\n },\n [loadPayments, onTotalsChange, orderId, resolvedOrganizationId, resolvedTenantId, t]\n )\n\n React.useEffect(() => {\n if (!onActionChange) return\n if (payments.length === 0) {\n onActionChange(null)\n return\n }\n onActionChange({\n label: addActionLabel,\n onClick: openCreate,\n disabled: loading,\n })\n return () => onActionChange(null)\n }, [addActionLabel, loading, onActionChange, openCreate, payments.length])\n\n const columns = React.useMemo<ColumnDef<PaymentRow>[]>(\n () => [\n {\n accessorKey: 'paymentReference',\n header: t('sales.documents.payments.reference', 'Reference'),\n cell: ({ row }) => row.original.paymentReference || '\u2014',\n },\n {\n accessorKey: 'paymentMethodName',\n header: t('sales.documents.payments.method', 'Method'),\n cell: ({ row }) => row.original.paymentMethodName ?? '\u2014',\n },\n {\n accessorKey: 'status',\n header: t('sales.documents.payments.status', 'Status'),\n cell: ({ row }) => row.original.statusLabel ?? row.original.status ?? '\u2014',\n },\n {\n accessorKey: 'amount',\n header: t('sales.documents.payments.amount', 'Amount'),\n cell: ({ row }) => formatMoney(row.original.amount, row.original.currencyCode ?? currencyCode),\n },\n {\n accessorKey: 'receivedAt',\n header: t('sales.documents.payments.receivedAt', 'Received'),\n cell: ({ row }) =>\n row.original.receivedAt\n ? new Date(row.original.receivedAt).toLocaleDateString()\n : '\u2014',\n },\n {\n accessorKey: 'createdAt',\n header: t('sales.documents.payments.createdAt', 'Created'),\n cell: ({ row }) =>\n row.original.createdAt ? new Date(row.original.createdAt).toLocaleString() : '\u2014',\n meta: {\n tooltipContent: (row: PaymentRow) =>\n row.createdAt ? new Date(row.createdAt).toLocaleString() : undefined,\n },\n },\n {\n id: 'actions',\n header: '',\n cell: ({ row }) => {\n return (\n <RowActions\n items={[\n { id: 'edit', label: editActionLabel, onSelect: () => openEditPayment(row.original) },\n {\n id: 'delete',\n label: deleteActionLabel,\n destructive: true,\n onSelect: () => void handleDelete(row.original),\n },\n ]}\n />\n )\n },\n },\n ],\n [currencyCode, deleteActionLabel, editActionLabel, handleDelete, openEditPayment, t]\n )\n\n if (loading) {\n return (\n <LoadingMessage\n label={t('sales.documents.payments.loading', 'Loading payments\u2026')}\n className=\"border-0 bg-transparent p-0 py-8 justify-center\"\n />\n )\n }\n\n if (error) {\n return (\n <ErrorMessage\n label={error}\n action={\n <Button variant=\"outline\" size=\"sm\" onClick={() => void loadPayments()}>\n {t('sales.documents.payments.retry', 'Retry')}\n </Button>\n }\n />\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {payments.length ? (\n <DataTable<PaymentRow> columns={columns} data={payments} onRowClick={openEditPayment} />\n ) : (\n <TabEmptyState\n title={t('sales.documents.payments.emptyTitle', 'No payments yet.')}\n description={t(\n 'sales.documents.payments.emptyDescription',\n 'Track received payments to keep outstanding balances up to date.'\n )}\n action={{\n label: addActionLabel,\n onClick: openCreate,\n icon: <Plus className=\"h-4 w-4\" aria-hidden />,\n disabled: loading,\n }}\n />\n )}\n\n <PaymentDialog\n open={dialogOpen}\n onOpenChange={handleDialogChange}\n mode={editingPayment ? 'edit' : 'create'}\n payment={editingPayment}\n currencyCode={editingPayment?.currencyCode ?? currencyCode}\n orderId={orderId}\n organizationId={resolvedOrganizationId}\n tenantId={resolvedTenantId}\n onSaved={handlePaymentSaved}\n />\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.4.7-develop-
|
|
3
|
+
"version": "0.4.7-develop-d6331ed114",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -217,10 +217,10 @@
|
|
|
217
217
|
"semver": "^7.6.3"
|
|
218
218
|
},
|
|
219
219
|
"peerDependencies": {
|
|
220
|
-
"@open-mercato/shared": "0.4.7-develop-
|
|
220
|
+
"@open-mercato/shared": "0.4.7-develop-d6331ed114"
|
|
221
221
|
},
|
|
222
222
|
"devDependencies": {
|
|
223
|
-
"@open-mercato/shared": "0.4.7-develop-
|
|
223
|
+
"@open-mercato/shared": "0.4.7-develop-d6331ed114",
|
|
224
224
|
"@testing-library/dom": "^10.4.1",
|
|
225
225
|
"@testing-library/jest-dom": "^6.9.1",
|
|
226
226
|
"@testing-library/react": "^16.3.1",
|
|
@@ -82,8 +82,8 @@ const crud = makeCrudRoute({
|
|
|
82
82
|
receivedAt: F.received_at,
|
|
83
83
|
amount: F.amount,
|
|
84
84
|
},
|
|
85
|
-
buildFilters: async (query:
|
|
86
|
-
const filters: Record<string,
|
|
85
|
+
buildFilters: async (query: z.infer<typeof listSchema>) => {
|
|
86
|
+
const filters: Record<string, { $eq: string }> = {}
|
|
87
87
|
if (query.orderId) filters.order_id = { $eq: query.orderId }
|
|
88
88
|
if (query.paymentMethodId) filters.payment_method_id = { $eq: query.paymentMethodId }
|
|
89
89
|
return filters
|
|
@@ -2581,11 +2581,15 @@ export default function SalesDocumentDetailPage({
|
|
|
2581
2581
|
React.useEffect(() => {
|
|
2582
2582
|
if (kind !== 'order') return
|
|
2583
2583
|
ensureShippingMethodOption(record?.shippingMethodId ?? null, record?.shippingMethodSnapshot ?? null)
|
|
2584
|
-
|
|
2584
|
+
const paymentMethodSnapshotOrCode =
|
|
2585
|
+
record?.paymentMethodSnapshot ??
|
|
2586
|
+
(record?.paymentMethodCode ? { code: record.paymentMethodCode } : null)
|
|
2587
|
+
ensurePaymentMethodOption(record?.paymentMethodId ?? null, paymentMethodSnapshotOrCode)
|
|
2585
2588
|
}, [
|
|
2586
2589
|
ensurePaymentMethodOption,
|
|
2587
2590
|
ensureShippingMethodOption,
|
|
2588
2591
|
kind,
|
|
2592
|
+
record?.paymentMethodCode,
|
|
2589
2593
|
record?.paymentMethodId,
|
|
2590
2594
|
record?.paymentMethodSnapshot,
|
|
2591
2595
|
record?.shippingMethodId,
|
|
@@ -4200,21 +4204,9 @@ export default function SalesDocumentDetailPage({
|
|
|
4200
4204
|
tenantId={(record as any)?.tenantId ?? (record as any)?.tenant_id ?? null}
|
|
4201
4205
|
onActionChange={handleSectionActionChange}
|
|
4202
4206
|
onPaymentsChange={(payments) => setHasPayments(payments.length > 0)}
|
|
4203
|
-
onTotalsChange={(
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
? {
|
|
4207
|
-
...prev,
|
|
4208
|
-
paidTotalAmount:
|
|
4209
|
-
totals?.paidTotalAmount ?? prev.paidTotalAmount ?? null,
|
|
4210
|
-
refundedTotalAmount:
|
|
4211
|
-
totals?.refundedTotalAmount ?? prev.refundedTotalAmount ?? null,
|
|
4212
|
-
outstandingAmount:
|
|
4213
|
-
totals?.outstandingAmount ?? prev.outstandingAmount ?? null,
|
|
4214
|
-
}
|
|
4215
|
-
: prev
|
|
4216
|
-
)
|
|
4217
|
-
}
|
|
4207
|
+
onTotalsChange={() => {
|
|
4208
|
+
void refreshDocumentTotals()
|
|
4209
|
+
}}
|
|
4218
4210
|
/>
|
|
4219
4211
|
)
|
|
4220
4212
|
}
|
|
@@ -73,6 +73,8 @@ export type PaymentSnapshot = {
|
|
|
73
73
|
type PaymentUndoPayload = {
|
|
74
74
|
before?: PaymentSnapshot | null
|
|
75
75
|
after?: PaymentSnapshot | null
|
|
76
|
+
orderPaymentMethodIdBefore?: string | null
|
|
77
|
+
orderPaymentMethodCodeBefore?: string | null
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
const toNumber = (value: unknown): number => {
|
|
@@ -311,7 +313,7 @@ async function recomputeOrderPaymentTotals(
|
|
|
311
313
|
|
|
312
314
|
const createPaymentCommand: CommandHandler<
|
|
313
315
|
PaymentCreateInput,
|
|
314
|
-
{ paymentId: string; orderTotals?: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number } }
|
|
316
|
+
{ paymentId: string; orderTotals?: { paidTotalAmount: number; refundedTotalAmount: number; outstandingAmount: number }; orderPaymentMethodIdBefore?: string | null; orderPaymentMethodCodeBefore?: string | null }
|
|
315
317
|
> = {
|
|
316
318
|
id: 'sales.payments.create',
|
|
317
319
|
async execute(rawInput, ctx) {
|
|
@@ -349,6 +351,14 @@ const createPaymentCommand: CommandHandler<
|
|
|
349
351
|
ensureSameScope(method, input.organizationId, input.tenantId)
|
|
350
352
|
paymentMethod = method
|
|
351
353
|
}
|
|
354
|
+
const orderPaymentMethodIdBefore = order.paymentMethodId ?? null
|
|
355
|
+
const orderPaymentMethodCodeBefore = order.paymentMethodCode ?? null
|
|
356
|
+
if (paymentMethod && !order.paymentMethodId) {
|
|
357
|
+
order.paymentMethodId = paymentMethod.id
|
|
358
|
+
order.paymentMethodCode = paymentMethod.code ?? null
|
|
359
|
+
order.updatedAt = new Date()
|
|
360
|
+
em.persist(order)
|
|
361
|
+
}
|
|
352
362
|
if (input.documentStatusEntryId !== undefined) {
|
|
353
363
|
const orderStatus = await resolveDictionaryEntryValue(em, input.documentStatusEntryId ?? null)
|
|
354
364
|
if (input.documentStatusEntryId && !orderStatus) {
|
|
@@ -482,7 +492,7 @@ const createPaymentCommand: CommandHandler<
|
|
|
482
492
|
console.error('[sales.payments.create] Failed to create notification:', err)
|
|
483
493
|
}
|
|
484
494
|
|
|
485
|
-
return { paymentId: payment.id, orderTotals: totals }
|
|
495
|
+
return { paymentId: payment.id, orderTotals: totals, orderPaymentMethodIdBefore, orderPaymentMethodCodeBefore }
|
|
486
496
|
},
|
|
487
497
|
captureAfter: async (_input, result, ctx) => {
|
|
488
498
|
const em = (ctx.container.resolve('em') as EntityManager).fork()
|
|
@@ -501,7 +511,7 @@ const createPaymentCommand: CommandHandler<
|
|
|
501
511
|
tenantId: after.tenantId,
|
|
502
512
|
organizationId: after.organizationId,
|
|
503
513
|
snapshotAfter: after,
|
|
504
|
-
payload: { undo: { after } satisfies PaymentUndoPayload },
|
|
514
|
+
payload: { undo: { after, orderPaymentMethodIdBefore: result.orderPaymentMethodIdBefore ?? null, orderPaymentMethodCodeBefore: result.orderPaymentMethodCodeBefore ?? null } satisfies PaymentUndoPayload },
|
|
505
515
|
}
|
|
506
516
|
},
|
|
507
517
|
undo: async ({ logEntry, ctx }) => {
|
|
@@ -539,6 +549,12 @@ const createPaymentCommand: CommandHandler<
|
|
|
539
549
|
for (const id of orderIds) {
|
|
540
550
|
const order = await em.findOne(SalesOrder, { id })
|
|
541
551
|
if (!order) continue
|
|
552
|
+
if (id === after.orderId && 'orderPaymentMethodIdBefore' in (payload ?? {})) {
|
|
553
|
+
order.paymentMethodId = payload.orderPaymentMethodIdBefore ?? null
|
|
554
|
+
order.paymentMethodCode = payload.orderPaymentMethodCodeBefore ?? null
|
|
555
|
+
order.updatedAt = new Date()
|
|
556
|
+
await em.flush()
|
|
557
|
+
}
|
|
542
558
|
await recomputeOrderPaymentTotals(em, order)
|
|
543
559
|
await em.flush()
|
|
544
560
|
}
|