@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.
@@ -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": "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",
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": "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",
6
6
  "names": []
7
7
  }
@@ -131,10 +131,8 @@ function SalesDocumentPaymentsSection({
131
131
  [currencyCode]
132
132
  );
133
133
  const handlePaymentSaved = React.useCallback(
134
- async (totals) => {
135
- if (totals && onTotalsChange) {
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
- const totals = result.result?.orderTotals ?? null;
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": "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",
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-7c7b3f9d84",
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-7c7b3f9d84"
220
+ "@open-mercato/shared": "0.4.7-develop-d6331ed114"
221
221
  },
222
222
  "devDependencies": {
223
- "@open-mercato/shared": "0.4.7-develop-7c7b3f9d84",
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: any) => {
86
- const filters: Record<string, any> = {}
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
- ensurePaymentMethodOption(record?.paymentMethodId ?? null, record?.paymentMethodSnapshot ?? null)
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={(totals) =>
4204
- setRecord((prev) =>
4205
- prev
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
  }