@open-mercato/core 0.6.6-develop.6330.1.a261878aa8 → 0.6.6-develop.6331.1.a33b8e99b7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +3 -0
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +2 -2
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +2 -2
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +12 -0
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +12 -0
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/data/entities.js +2 -2
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/business_rules/api/rules/route.js +3 -3
- package/dist/modules/business_rules/api/rules/route.js.map +2 -2
- package/dist/modules/business_rules/api/sets/route.js +3 -3
- package/dist/modules/business_rules/api/sets/route.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/[id]/page.js +12 -1
- package/dist/modules/business_rules/backend/rules/[id]/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/[id]/page.js +12 -1
- package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
- package/dist/modules/catalog/api/product-media/route.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +12 -0
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +15 -0
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +12 -1
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +13 -3
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/lib/bulkDelete.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/[id]/page.js +15 -3
- package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +2 -1
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +12 -1
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +3 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles/[id].js +3 -3
- package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users/[id].js +3 -3
- package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
- package/dist/modules/customers/api/addresses/route.js +4 -2
- package/dist/modules/customers/api/addresses/route.js.map +2 -2
- package/dist/modules/customers/api/tags/route.js +8 -3
- package/dist/modules/customers/api/tags/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +13 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +24 -9
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +53 -23
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js +13 -3
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +19 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +13 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +5 -5
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/pipeline-stages.js +24 -2
- package/dist/modules/customers/commands/pipeline-stages.js.map +2 -2
- package/dist/modules/customers/commands/pipelines.js +24 -2
- package/dist/modules/customers/commands/pipelines.js.map +2 -2
- package/dist/modules/customers/components/detail/AddressesSection.js +46 -29
- package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +5 -1
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/notesAdapter.js +25 -18
- package/dist/modules/customers/components/detail/notesAdapter.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/[id]/route.js +38 -19
- package/dist/modules/data_sync/api/schedules/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/route.js +1 -1
- package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +32 -15
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-schedule-service.js +19 -5
- package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +3 -3
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js +3 -3
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js +12 -1
- package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +12 -0
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +12 -0
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
- package/dist/modules/entities/api/entities.js +2 -2
- package/dist/modules/entities/api/entities.js.map +2 -2
- package/dist/modules/entities/api/records.js +7 -5
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/feature_toggles/api/overrides/route.js +2 -2
- package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
- package/dist/modules/feature_toggles/data/entities.js +1 -1
- package/dist/modules/feature_toggles/data/entities.js.map +2 -2
- package/dist/modules/feature_toggles/data/validators.js +2 -1
- package/dist/modules/feature_toggles/data/validators.js.map +2 -2
- package/dist/modules/feature_toggles/lib/queries.js +2 -1
- package/dist/modules/feature_toggles/lib/queries.js.map +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +12 -1
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +12 -1
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/resources/components/detail/notesAdapter.js +25 -18
- package/dist/modules/resources/components/detail/notesAdapter.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +14 -1
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +11 -10
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +6 -1
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/commands/returns.js +3 -3
- package/dist/modules/sales/commands/returns.js.map +2 -2
- package/dist/modules/sales/commands/shared.js +3 -3
- package/dist/modules/sales/commands/shared.js.map +2 -2
- package/dist/modules/sales/commands/shipments.js +6 -1
- package/dist/modules/sales/commands/shipments.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentDialog.js +6 -3
- package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +7 -3
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +6 -3
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +7 -3
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/di.js +39 -3
- package/dist/modules/sales/di.js.map +2 -2
- package/dist/modules/sales/setup.js +2 -0
- package/dist/modules/sales/setup.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +12 -1
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +12 -1
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +12 -1
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +12 -1
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/commands/job-histories.js +3 -3
- package/dist/modules/staff/commands/job-histories.js.map +2 -2
- package/dist/modules/staff/components/detail/addressesAdapter.js +33 -24
- package/dist/modules/staff/components/detail/addressesAdapter.js.map +2 -2
- package/dist/modules/staff/components/detail/notesAdapter.js +25 -18
- package/dist/modules/staff/components/detail/notesAdapter.js.map +2 -2
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js +37 -0
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +7 -1
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/route.js +3 -3
- package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js +12 -1
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +11 -1
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +3 -0
- package/src/modules/auth/api/roles/acl/route.ts +2 -2
- package/src/modules/auth/api/users/acl/route.ts +2 -2
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +17 -0
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +17 -0
- package/src/modules/auth/data/entities.ts +2 -2
- package/src/modules/business_rules/api/rules/route.ts +3 -3
- package/src/modules/business_rules/api/sets/route.ts +3 -3
- package/src/modules/business_rules/backend/rules/[id]/page.tsx +17 -1
- package/src/modules/business_rules/backend/sets/[id]/page.tsx +18 -1
- package/src/modules/catalog/api/product-media/route.ts +4 -0
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +17 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +21 -0
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +16 -1
- package/src/modules/catalog/components/PriceKindSettings.tsx +15 -7
- package/src/modules/catalog/lib/bulkDelete.ts +6 -0
- package/src/modules/currencies/backend/currencies/[id]/page.tsx +20 -3
- package/src/modules/currencies/backend/currencies/page.tsx +2 -1
- package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +17 -1
- package/src/modules/currencies/backend/exchange-rates/page.tsx +3 -2
- package/src/modules/customer_accounts/api/admin/roles/[id].ts +3 -3
- package/src/modules/customer_accounts/api/admin/users/[id].ts +3 -3
- package/src/modules/customers/api/addresses/route.ts +2 -0
- package/src/modules/customers/api/tags/route.ts +6 -1
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +19 -2
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +29 -8
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +47 -20
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.ts +13 -3
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +21 -1
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +18 -2
- package/src/modules/customers/commands/interactions.ts +5 -5
- package/src/modules/customers/commands/pipeline-stages.ts +26 -2
- package/src/modules/customers/commands/pipelines.ts +26 -2
- package/src/modules/customers/components/detail/AddressesSection.tsx +50 -28
- package/src/modules/customers/components/detail/DealForm.tsx +12 -0
- package/src/modules/customers/components/detail/notesAdapter.ts +29 -18
- package/src/modules/customers/i18n/de.json +2 -0
- package/src/modules/customers/i18n/en.json +2 -0
- package/src/modules/customers/i18n/es.json +2 -0
- package/src/modules/customers/i18n/pl.json +2 -0
- package/src/modules/data_sync/api/schedules/[id]/route.ts +38 -20
- package/src/modules/data_sync/api/schedules/route.ts +1 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +32 -15
- package/src/modules/data_sync/lib/sync-schedule-service.ts +30 -5
- package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +3 -3
- package/src/modules/dictionaries/api/[dictionaryId]/route.ts +3 -3
- package/src/modules/dictionaries/components/DictionariesManager.tsx +21 -1
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +2 -0
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +17 -0
- package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +17 -0
- package/src/modules/entities/api/entities.ts +2 -2
- package/src/modules/entities/api/records.ts +7 -5
- package/src/modules/feature_toggles/api/overrides/route.ts +2 -2
- package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +12 -0
- package/src/modules/feature_toggles/data/entities.ts +1 -1
- package/src/modules/feature_toggles/data/validators.ts +1 -0
- package/src/modules/feature_toggles/lib/queries.ts +1 -0
- package/src/modules/inbox_ops/api/settings/route.ts +2 -2
- package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +17 -1
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +17 -1
- package/src/modules/resources/components/detail/notesAdapter.ts +29 -18
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +17 -1
- package/src/modules/sales/commands/documents.ts +11 -10
- package/src/modules/sales/commands/payments.ts +11 -0
- package/src/modules/sales/commands/returns.ts +3 -3
- package/src/modules/sales/commands/shared.ts +10 -4
- package/src/modules/sales/commands/shipments.ts +14 -0
- package/src/modules/sales/components/documents/PaymentDialog.tsx +7 -3
- package/src/modules/sales/components/documents/PaymentsSection.tsx +8 -3
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +7 -3
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +8 -3
- package/src/modules/sales/di.ts +68 -9
- package/src/modules/sales/setup.ts +2 -0
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +17 -1
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +17 -1
- package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +17 -1
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +17 -1
- package/src/modules/staff/commands/job-histories.ts +3 -3
- package/src/modules/staff/components/detail/addressesAdapter.ts +40 -23
- package/src/modules/staff/components/detail/notesAdapter.ts +28 -18
- package/src/modules/translations/api/[entityType]/[entityId]/route.ts +74 -0
- package/src/modules/translations/components/TranslationManager.tsx +14 -1
- package/src/modules/workflows/api/definitions/[id]/route.ts +3 -3
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +18 -1
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +19 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/sales/commands/shipments.ts"],
|
|
4
|
-
"sourcesContent": ["// @ts-nocheck\n\nimport { randomUUID } from 'crypto'\nimport { registerCommand, type CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { LockMode } from '@mikro-orm/core'\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 { SalesOrder, SalesOrderLine, SalesShipment, SalesShipmentItem } from '../data/entities'\nimport {\n shipmentCreateSchema,\n shipmentUpdateSchema,\n type ShipmentCreateInput,\n type ShipmentUpdateInput,\n} from '../data/validators'\nimport {\n coerceShipmentQuantity as toNumber,\n readShipmentItemsSnapshot,\n refreshShipmentItemsSnapshot,\n type ShipmentItemSnapshot,\n buildShipmentItemSnapshots,\n} from '../lib/shipments/snapshots'\nimport {\n cloneJson,\n ensureOrganizationScope,\n ensureSameScope,\n ensureTenantScope,\n extractUndoPayload,\n} from './shared'\nimport { resolveDictionaryEntryValue } from '../lib/dictionaries'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst shipmentCrudEvents: CrudEventsConfig = {\n module: 'sales',\n entity: 'shipment',\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 ADDRESS_SNAPSHOT_KEY = 'shipmentAddressSnapshot'\n\nexport type ShipmentSnapshot = {\n id: string\n orderId: string\n organizationId: string\n tenantId: string\n shipmentNumber: string | null\n shippingMethodId: string | null\n statusEntryId: string | null\n status: string | null\n carrierName: string | null\n trackingNumbers: string[] | null\n shippedAt: string | null\n deliveredAt: string | null\n weightValue: number | null\n weightUnit: string | null\n declaredValueNet: number | null\n declaredValueGross: number | null\n currencyCode: string | null\n notesText: string | null\n metadata: Record<string, unknown> | null\n customFields?: Record<string, unknown> | null\n items: ShipmentItemSnapshot[]\n itemsSnapshot?: ShipmentItemSnapshot[] | null\n}\n\ntype ShipmentUndoPayload = {\n before?: ShipmentSnapshot | null\n after?: ShipmentSnapshot | null\n}\n\nconst buildShipmentCreateRedoInput = (snapshot: ShipmentSnapshot): ShipmentCreateInput => ({\n orderId: snapshot.orderId,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n shipmentNumber: snapshot.shipmentNumber ?? undefined,\n shippingMethodId: snapshot.shippingMethodId ?? undefined,\n statusEntryId: snapshot.statusEntryId ?? undefined,\n carrierName: snapshot.carrierName ?? undefined,\n trackingNumbers: snapshot.trackingNumbers ?? undefined,\n shippedAt: snapshot.shippedAt ? new Date(snapshot.shippedAt) : undefined,\n deliveredAt: snapshot.deliveredAt ? new Date(snapshot.deliveredAt) : undefined,\n weightValue: snapshot.weightValue ?? undefined,\n weightUnit: snapshot.weightUnit ?? undefined,\n declaredValueNet: snapshot.declaredValueNet ?? undefined,\n declaredValueGross: snapshot.declaredValueGross ?? undefined,\n currencyCode: snapshot.currencyCode ?? undefined,\n notes: snapshot.notesText ?? undefined,\n metadata: snapshot.metadata ? cloneJson(snapshot.metadata) : undefined,\n customFields: snapshot.customFields ? cloneJson(snapshot.customFields) : undefined,\n items: snapshot.items.map((item) => ({\n orderLineId: item.orderLineId,\n quantity: item.quantity,\n metadata: item.metadata ? cloneJson(item.metadata) : undefined,\n })),\n})\n\nconst parseTrackingNumbers = (input: unknown): string[] | null => {\n if (typeof input === 'string') {\n const entries = input\n .split(/[\\n,]/g)\n .map((value) => value.trim())\n .filter((value) => value.length > 0)\n return entries.length ? entries : null\n }\n if (Array.isArray(input)) {\n const entries = input\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value) => value.length > 0)\n return entries.length ? entries : null\n }\n return null\n}\n\nconst normalizeCustomFieldsInput = (input: unknown): Record<string, unknown> =>\n input && typeof input === 'object' && !Array.isArray(input) ? (input as Record<string, unknown>) : {}\n\nconst resolveLogger = (ctx: any): { warn?: (meta: any, message?: string) => void } | null => {\n const container = ctx?.container as any\n if (!container) return null\n const cradleLogger = container?.cradle?.logger ?? null\n if (cradleLogger?.warn) return cradleLogger\n const hasRegistration = typeof container.hasRegistration === 'function' ? container.hasRegistration.bind(container) : null\n if (hasRegistration?.('logger')) {\n const logger = container.resolve('logger')\n if (logger?.warn) return logger\n }\n if (hasRegistration?.('coreLogger')) {\n const logger = container.resolve('coreLogger')\n if (logger?.warn) return logger\n }\n return null\n}\n\nconst logShipmentDeleteScopeRejection = (\n ctx: any,\n reason: string,\n meta: Record<string, unknown>\n): void => {\n const logger = resolveLogger(ctx)\n const payload = { ...meta, command: 'sales.shipments.delete' }\n if (logger?.warn) {\n logger.warn(payload, reason)\n return\n }\n // eslint-disable-next-line no-console\n console.warn(`[sales.shipments.delete] ${reason}`, payload)\n}\n\nexport async function loadShipmentSnapshot(em: EntityManager, id: string): Promise<ShipmentSnapshot | null> {\n const shipment = await em.findOne(\n SalesShipment,\n { id },\n { populate: ['order', 'items', 'items.orderLine'] }\n )\n if (!shipment || !shipment.order) return null\n const storedSnapshot = readShipmentItemsSnapshot(\n (shipment as any).itemsSnapshot ?? (shipment as any).items_snapshot ?? null\n )\n const lineMap = new Map(\n Array.from(shipment.items ?? [])\n .map((item) => {\n const line = typeof item.orderLine === 'string' ? null : (item.orderLine as SalesOrderLine | null)\n return line ? [line.id, line] : null\n })\n .filter((entry): entry is [string, SalesOrderLine] => Boolean(entry))\n )\n const fallbackItems = buildShipmentItemSnapshots(Array.from(shipment.items ?? []), { lineMap })\n const itemsSnapshot = storedSnapshot.length ? storedSnapshot : fallbackItems\n const customFieldValues = await loadCustomFieldValues({\n em,\n entityId: E.sales.sales_shipment,\n recordIds: [shipment.id],\n tenantIdByRecord: { [shipment.id]: shipment.tenantId ?? null },\n organizationIdByRecord: { [shipment.id]: shipment.organizationId ?? null },\n })\n const customFields = customFieldValues[shipment.id]\n return {\n id: shipment.id,\n orderId: typeof shipment.order === 'string' ? shipment.order : shipment.order.id,\n organizationId: shipment.organizationId,\n tenantId: shipment.tenantId,\n shipmentNumber: shipment.shipmentNumber ?? null,\n shippingMethodId: shipment.shippingMethodId ?? null,\n statusEntryId: shipment.statusEntryId ?? null,\n status: shipment.status ?? null,\n carrierName: shipment.carrierName ?? null,\n trackingNumbers: shipment.trackingNumbers ? [...shipment.trackingNumbers] : null,\n shippedAt: shipment.shippedAt ? shipment.shippedAt.toISOString() : null,\n deliveredAt: shipment.deliveredAt ? shipment.deliveredAt.toISOString() : null,\n weightValue: shipment.weightValue !== undefined && shipment.weightValue !== null ? Number(shipment.weightValue) : null,\n weightUnit: shipment.weightUnit ?? null,\n declaredValueNet:\n shipment.declaredValueNet !== undefined && shipment.declaredValueNet !== null\n ? Number(shipment.declaredValueNet)\n : null,\n declaredValueGross:\n shipment.declaredValueGross !== undefined && shipment.declaredValueGross !== null\n ? Number(shipment.declaredValueGross)\n : null,\n currencyCode: shipment.currencyCode ?? null,\n notesText: shipment.notesText ?? null,\n metadata: shipment.metadata ? cloneJson(shipment.metadata) : null,\n customFields: customFields && Object.keys(customFields).length ? customFields : null,\n items: itemsSnapshot,\n itemsSnapshot,\n }\n}\n\nexport async function restoreShipmentSnapshot(em: EntityManager, snapshot: ShipmentSnapshot): Promise<void> {\n const order = await findOneWithDecryption(em, SalesOrder, { id: snapshot.orderId }, {}, { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId })\n if (!order) return\n const existing = await em.findOne(SalesShipment, { id: snapshot.id })\n const entity =\n existing ??\n em.create(SalesShipment, {\n id: snapshot.id,\n createdAt: new Date(),\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n })\n entity.order = order\n entity.organizationId = snapshot.organizationId\n entity.tenantId = snapshot.tenantId\n entity.shipmentNumber = snapshot.shipmentNumber ?? null\n entity.shippingMethodId = snapshot.shippingMethodId ?? null\n entity.statusEntryId = snapshot.statusEntryId ?? null\n entity.status = snapshot.status ?? null\n entity.carrierName = snapshot.carrierName ?? null\n entity.trackingNumbers = snapshot.trackingNumbers ? [...snapshot.trackingNumbers] : null\n entity.shippedAt = snapshot.shippedAt ? new Date(snapshot.shippedAt) : null\n entity.deliveredAt = snapshot.deliveredAt ? new Date(snapshot.deliveredAt) : null\n entity.weightValue = snapshot.weightValue !== null ? snapshot.weightValue.toString() : null\n entity.weightUnit = snapshot.weightUnit ?? null\n entity.declaredValueNet = snapshot.declaredValueNet !== null ? snapshot.declaredValueNet.toString() : null\n entity.declaredValueGross = snapshot.declaredValueGross !== null ? snapshot.declaredValueGross.toString() : null\n entity.currencyCode = snapshot.currencyCode ?? null\n entity.notesText = snapshot.notesText ?? null\n entity.metadata = snapshot.metadata ? cloneJson(snapshot.metadata) : null\n entity.updatedAt = new Date()\n em.persist(entity)\n await em.flush()\n\n const existingItems = await em.find(SalesShipmentItem, { shipment: entity })\n existingItems.forEach((item) => em.remove(item))\n const items = Array.isArray(snapshot.items) ? snapshot.items : []\n const lineIds = items\n .map((item) => item.orderLineId)\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n const lines = lineIds.length\n ? await em.find(SalesOrderLine, { id: { $in: lineIds }, order: order.id })\n : []\n const lineMap = new Map(lines.map((line) => [line.id, line]))\n const restoredItems: ShipmentItemSnapshot[] = []\n items.forEach((item) => {\n const line = lineMap.get(item.orderLineId)\n if (!line) return\n restoredItems.push(item)\n const lineRef = em.getReference(SalesOrderLine, line.id)\n const shipmentItem = em.create(SalesShipmentItem, {\n id: item.id ?? randomUUID(),\n shipment: entity,\n orderLine: lineRef,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n quantity: item.quantity.toString(),\n metadata: item.metadata ? cloneJson(item.metadata) : null,\n })\n em.persist(shipmentItem)\n })\n const snapshotItems = (snapshot.itemsSnapshot ?? restoredItems).filter((entry) =>\n entry?.orderLineId ? lineMap.has(entry.orderLineId) : false\n )\n entity.itemsSnapshot = snapshotItems && snapshotItems.length ? cloneJson(snapshotItems) : null\n if (!entity.itemsSnapshot) {\n await refreshShipmentItemsSnapshot(em, entity)\n }\n if ((snapshot as any).customFields !== undefined) {\n await setRecordCustomFields(em, {\n entityId: E.sales.sales_shipment,\n recordId: entity.id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n values: normalizeCustomFieldsInput((snapshot as any).customFields),\n })\n }\n em.persist(entity)\n}\n\nasync function deleteShipmentWithItems(em: EntityManager, shipment: SalesShipment): Promise<void> {\n const scope = { tenantId: shipment.tenantId, organizationId: shipment.organizationId }\n const items = await findWithDecryption(em, SalesShipmentItem, { shipment }, {}, scope)\n items.forEach((item) => em.remove(item))\n em.remove(shipment)\n await em.flush()\n}\n\nasync function recomputeFulfilledQuantities(em: EntityManager, order: SalesOrder): Promise<void> {\n const scope = { tenantId: order.tenantId, organizationId: order.organizationId }\n const shipments = await findWithDecryption(em, SalesShipment, { order, deletedAt: null }, {}, scope)\n const shipmentIds = shipments.map((entry) => entry.id)\n const shipmentItems = shipmentIds.length\n ? await findWithDecryption(em, SalesShipmentItem, { shipment: { $in: shipmentIds } }, {}, scope)\n : []\n const totals = shipmentItems.reduce<Map<string, number>>((acc, item) => {\n const lineId =\n typeof item.orderLine === 'string'\n ? item.orderLine\n : item.orderLine?.id ?? (item as any).orderLineId ?? null\n if (!lineId) return acc\n const next = (acc.get(lineId) ?? 0) + toNumber(item.quantity)\n acc.set(lineId, next)\n return acc\n }, new Map())\n const lines = await findWithDecryption(em, SalesOrderLine, { order }, { lockMode: LockMode.PESSIMISTIC_WRITE }, scope)\n lines.forEach((line) => {\n const shipped = totals.get(line.id) ?? 0\n line.fulfilledQuantity = shipped.toString()\n })\n}\n\nasync function loadOrder(\n em: EntityManager,\n id: string,\n scope?: { tenantId: string; organizationId: string }\n): Promise<SalesOrder> {\n const order = await findOneWithDecryption(em, SalesOrder, { id, deletedAt: null }, {}, scope)\n if (!order) throw new CrudHttpError(404, { error: 'sales.shipments.not_found' })\n return order\n}\n\nasync function loadShippedTotals(\n em: EntityManager,\n order: SalesOrder,\n excludeShipmentId?: string | null\n): Promise<Map<string, number>> {\n const scope = { tenantId: order.tenantId, organizationId: order.organizationId }\n const shipments = await findWithDecryption(em, SalesShipment, { order, deletedAt: null }, {}, scope)\n const shipmentIds = shipments\n .map((entry) => entry.id)\n .filter((id) => !excludeShipmentId || id !== excludeShipmentId)\n if (!shipmentIds.length) return new Map()\n const items = await findWithDecryption(em, SalesShipmentItem, { shipment: { $in: shipmentIds } }, {}, scope)\n return items.reduce<Map<string, number>>((acc, item) => {\n const lineId =\n typeof item.orderLine === 'string'\n ? item.orderLine\n : item.orderLine?.id ?? (item as any).orderLineId ?? null\n if (!lineId) return acc\n const next = (acc.get(lineId) ?? 0) + toNumber(item.quantity)\n acc.set(lineId, next)\n return acc\n }, new Map())\n}\n\nasync function validateShipmentItems(params: {\n em: EntityManager\n order: SalesOrder\n items?: ShipmentCreateInput['items']\n excludeShipmentId?: string | null\n lockOrderLines?: boolean\n}): Promise<{\n items: Array<{ orderLineId: string; quantity: number; metadata: Record<string, unknown> | null }>\n lineMap: Map<string, SalesOrderLine>\n}> {\n const { em, order, items, excludeShipmentId, lockOrderLines } = params\n const { translate } = await resolveTranslations()\n if (!items || !items.length) {\n throw new CrudHttpError(400, { error: translate('sales.shipments.items_required', 'Add at least one line to ship.') })\n }\n const scope = { tenantId: order.tenantId, organizationId: order.organizationId }\n const orderLines = await findWithDecryption(\n em,\n SalesOrderLine,\n { order },\n lockOrderLines ? { lockMode: LockMode.PESSIMISTIC_WRITE } : undefined,\n scope,\n )\n const lineMap = new Map(orderLines.map((line) => [line.id, line]))\n const shippedTotals = await loadShippedTotals(em, order, excludeShipmentId)\n const requestedTotals = new Map<string, number>()\n\n for (const item of items) {\n const lineId = item.orderLineId\n const quantity = toNumber(item.quantity)\n if (!lineId || quantity <= 0) {\n throw new CrudHttpError(400, { error: translate('sales.shipments.items_required', 'Add at least one line to ship.') })\n }\n const line = lineMap.get(lineId)\n if (!line) {\n throw new CrudHttpError(404, { error: translate('sales.shipments.line_missing', 'Order line not found.') })\n }\n const lineTotal = toNumber(line.quantity)\n const alreadyShipped = shippedTotals.get(lineId) ?? 0\n const nextTotal = (requestedTotals.get(lineId) ?? 0) + quantity\n if (nextTotal + alreadyShipped - 1e-6 > lineTotal) {\n throw new CrudHttpError(400, { error: translate('sales.shipments.quantity_exceeded', 'Cannot ship more than the remaining quantity.') })\n }\n requestedTotals.set(lineId, nextTotal)\n }\n\n return {\n items: items.map((item) => ({\n orderLineId: item.orderLineId,\n quantity: toNumber(item.quantity),\n metadata: item.metadata ? cloneJson(item.metadata) : null,\n })),\n lineMap,\n }\n}\n\nfunction mergeAddressSnapshot(\n baseMetadata: Record<string, unknown> | null | undefined,\n snapshot: Record<string, unknown> | null | undefined\n): Record<string, unknown> | null {\n const metadata = baseMetadata ? { ...baseMetadata } : {}\n if (snapshot && typeof snapshot === 'object') {\n metadata[ADDRESS_SNAPSHOT_KEY] = cloneJson(snapshot)\n }\n return Object.keys(metadata).length ? metadata : null\n}\n\nconst createShipmentCommand: CommandHandler<ShipmentCreateInput, { shipmentId: string }> = {\n id: 'sales.shipments.create',\n async execute(rawInput, ctx) {\n const input = shipmentCreateSchema.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 const shipment = await em.transactional(async (tx) => {\n const order = await loadOrder(tx, input.orderId, { tenantId: input.tenantId, organizationId: input.organizationId })\n ensureSameScope(order, input.organizationId, input.tenantId)\n const { items: normalizedItems, lineMap } = await validateShipmentItems({\n em: tx,\n order,\n items: input.items,\n lockOrderLines: true,\n })\n const statusValue = await resolveDictionaryEntryValue(tx, input.statusEntryId ?? null, { tenantId: input.tenantId })\n const trackingNumbers = parseTrackingNumbers(input.trackingNumbers) ?? null\n const metadata =\n mergeAddressSnapshot(\n input.metadata ? cloneJson(input.metadata) : null,\n input.shipmentAddressSnapshot ?? order.shippingAddressSnapshot ?? null\n ) ?? null\n\n const shipmentId = randomUUID()\n const entity = tx.create(SalesShipment, {\n id: shipmentId,\n order,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n shipmentNumber: input.shipmentNumber ?? null,\n shippingMethodId: input.shippingMethodId ?? null,\n statusEntryId: input.statusEntryId ?? null,\n status: statusValue,\n carrierName: input.carrierName ?? null,\n trackingNumbers,\n shippedAt: input.shippedAt ?? null,\n deliveredAt: input.deliveredAt ?? null,\n weightValue: input.weightValue !== undefined ? input.weightValue.toString() : null,\n weightUnit: input.weightUnit ?? null,\n declaredValueNet: input.declaredValueNet !== undefined ? input.declaredValueNet.toString() : null,\n declaredValueGross: input.declaredValueGross !== undefined ? input.declaredValueGross.toString() : null,\n currencyCode: input.currencyCode ?? order.currencyCode ?? null,\n notesText: input.notes ?? null,\n metadata,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n const createdItems: SalesShipmentItem[] = []\n normalizedItems.forEach((item) => {\n const lineRef = tx.getReference(SalesOrderLine, item.orderLineId)\n const shipmentItem = tx.create(SalesShipmentItem, {\n id: randomUUID(),\n shipment: entity,\n orderLine: lineRef,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n quantity: item.quantity.toString(),\n metadata: item.metadata ? cloneJson(item.metadata) : null,\n })\n createdItems.push(shipmentItem)\n tx.persist(shipmentItem)\n })\n tx.persist(entity)\n if (input.customFields !== undefined) {\n await setRecordCustomFields(tx, {\n entityId: E.sales.sales_shipment,\n recordId: entity.id,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n values: normalizeCustomFieldsInput(input.customFields),\n })\n }\n if (input.documentStatusEntryId !== undefined) {\n const orderStatus = await resolveDictionaryEntryValue(tx, input.documentStatusEntryId ?? null, { tenantId: input.tenantId })\n if (input.documentStatusEntryId && !orderStatus) {\n throw new CrudHttpError(400, { error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.') })\n }\n order.statusEntryId = input.documentStatusEntryId ?? null\n order.status = orderStatus\n order.updatedAt = new Date()\n }\n if (input.lineStatusEntryId !== undefined) {\n const lineStatus = await resolveDictionaryEntryValue(tx, input.lineStatusEntryId ?? null, { tenantId: input.tenantId })\n if (input.lineStatusEntryId && !lineStatus) {\n throw new CrudHttpError(400, { error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.') })\n }\n const uniqueLineIds = Array.from(new Set(normalizedItems.map((item) => item.orderLineId)))\n uniqueLineIds.forEach((lineId) => {\n const line = lineMap.get(lineId)\n if (!line) return\n line.statusEntryId = input.lineStatusEntryId ?? null\n line.status = lineStatus\n line.updatedAt = new Date()\n })\n }\n await refreshShipmentItemsSnapshot(tx, entity, { items: createdItems, lineMap })\n await tx.flush()\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n return entity\n })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'created',\n entity: shipment,\n identifiers: {\n id: shipment.id,\n organizationId: shipment.organizationId,\n tenantId: shipment.tenantId,\n },\n indexer: { entityType: E.sales.sales_shipment },\n events: shipmentCrudEvents,\n })\n\n return { shipmentId: shipment.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadShipmentSnapshot(em, result.shipmentId)\n },\n buildLog: async ({ result, snapshots }) => {\n const after = snapshots.after as ShipmentSnapshot | undefined\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('sales.audit.shipments.create', 'Create shipment'),\n resourceKind: 'sales.shipment',\n resourceId: result.shipmentId,\n parentResourceKind: 'sales.order',\n parentResourceId: after.orderId ?? null,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n snapshotAfter: after,\n payload: {\n undo: { after } satisfies ShipmentUndoPayload,\n __redoInput: buildShipmentCreateRedoInput(after),\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ShipmentUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await em.transactional(async (tx) => {\n const existing = await findOneWithDecryption(\n tx,\n SalesShipment,\n { id: after.id },\n { populate: ['order'] },\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n if (!existing) return\n const order = existing.order as SalesOrder | null\n await deleteShipmentWithItems(tx, existing)\n if (order) {\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n }\n })\n },\n redo: async ({ ctx, logEntry }) => {\n const after = resolveRedoSnapshot<ShipmentSnapshot>(logEntry)\n const shipmentId = after?.id ?? logEntry.resourceId ?? null\n if (!after || !shipmentId) {\n throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for sales.shipments.create' })\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await em.transactional(async (tx) => {\n await restoreShipmentSnapshot(tx, after)\n const order = await findOneWithDecryption(tx, SalesOrder, { id: after.orderId }, {}, { tenantId: after.tenantId, organizationId: after.organizationId })\n await tx.flush()\n if (order) {\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n }\n })\n\n const shipment = await findOneWithDecryption(\n em,\n SalesShipment,\n { id: after.id },\n {},\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'created',\n entity: shipment,\n identifiers: {\n id: after.id,\n organizationId: after.organizationId,\n tenantId: after.tenantId,\n },\n indexer: { entityType: E.sales.sales_shipment },\n events: shipmentCrudEvents,\n })\n\n return { shipmentId: after.id }\n },\n}\n\nconst updateShipmentCommand: CommandHandler<ShipmentUpdateInput, { shipmentId: string }> = {\n id: 'sales.shipments.update',\n async prepare(rawInput, ctx) {\n const parsed = shipmentUpdateSchema.parse(rawInput ?? {})\n if (!parsed.id) return {}\n const em = ctx.container.resolve('em') as EntityManager\n const snapshot = await loadShipmentSnapshot(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 = shipmentUpdateSchema.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\n const shipment = await em.transactional(async (tx) => {\n const shipmentEntity = await findOneWithDecryption(\n tx,\n SalesShipment,\n { id: input.id },\n { populate: ['order'] },\n { tenantId: input.tenantId, organizationId: input.organizationId },\n )\n if (!shipmentEntity || !shipmentEntity.order) {\n throw new CrudHttpError(404, { error: 'sales.shipments.not_found' })\n }\n ensureSameScope(shipmentEntity, input.organizationId, input.tenantId)\n const order = shipmentEntity.order as SalesOrder\n if (input.orderId && input.orderId !== order.id) {\n throw new CrudHttpError(400, { error: 'sales.shipments.invalid_order' })\n }\n\n // Check if order is financially closed - prevent modifications to shipments\n const paidAmount = parseFloat(order.paidTotalAmount || '0')\n const refundedAmount = parseFloat(order.refundedTotalAmount || '0')\n const grandTotal = parseFloat(order.grandTotalGrossAmount || '0')\n const tolerance = 1e-4 // Tolerance for floating-point comparisons\n\n // Check for full refund first (higher priority than payment)\n const isFullyRefunded = refundedAmount >= grandTotal - tolerance\n if (isFullyRefunded) {\n throw new CrudHttpError(422, { error: translate('sales.shipments.fully_returned', 'Cannot modify shipment: order is fully returned') })\n }\n\n // Check for completed payment\n const isFullyPaid = paidAmount >= grandTotal - tolerance\n if (isFullyPaid) {\n throw new CrudHttpError(422, { error: translate('sales.shipments.payment_completed', 'Cannot modify shipment: order payment is completed') })\n }\n const validatedItems = input.items\n ? await validateShipmentItems({\n em: tx,\n order,\n items: input.items,\n excludeShipmentId: shipmentEntity.id,\n })\n : null\n const normalizedItems = validatedItems?.items ?? null\n const lineMap = validatedItems?.lineMap ?? new Map<string, SalesOrderLine>()\n // Resolve the status label BEFORE mutating shipment scalars so this\n // dictionary read does not interleave with (and drop) the pending\n // shipment changeset under MikroORM v7 (SPEC-018 / #2453 class).\n const resolvedShipmentStatus = input.statusEntryId !== undefined\n ? await resolveDictionaryEntryValue(tx, input.statusEntryId ?? null, { tenantId: shipmentEntity.tenantId })\n : undefined\n if (input.shipmentNumber !== undefined) shipmentEntity.shipmentNumber = input.shipmentNumber ?? null\n if (input.shippingMethodId !== undefined) shipmentEntity.shippingMethodId = input.shippingMethodId ?? null\n if (input.statusEntryId !== undefined) {\n shipmentEntity.statusEntryId = input.statusEntryId ?? null\n shipmentEntity.status = resolvedShipmentStatus ?? null\n }\n if (input.carrierName !== undefined) shipmentEntity.carrierName = input.carrierName ?? null\n if (input.trackingNumbers !== undefined) shipmentEntity.trackingNumbers = parseTrackingNumbers(input.trackingNumbers)\n if (input.shippedAt !== undefined) shipmentEntity.shippedAt = input.shippedAt ?? null\n if (input.deliveredAt !== undefined) shipmentEntity.deliveredAt = input.deliveredAt ?? null\n if (input.weightValue !== undefined) shipmentEntity.weightValue = input.weightValue !== null ? input.weightValue.toString() : null\n if (input.weightUnit !== undefined) shipmentEntity.weightUnit = input.weightUnit ?? null\n if (input.declaredValueNet !== undefined) {\n shipmentEntity.declaredValueNet = input.declaredValueNet !== null ? input.declaredValueNet.toString() : null\n }\n if (input.declaredValueGross !== undefined) {\n shipmentEntity.declaredValueGross = input.declaredValueGross !== null ? input.declaredValueGross.toString() : null\n }\n if (input.currencyCode !== undefined) shipmentEntity.currencyCode = input.currencyCode ?? null\n if (input.notes !== undefined) shipmentEntity.notesText = input.notes ?? null\n if (input.metadata !== undefined || input.shipmentAddressSnapshot !== undefined) {\n shipmentEntity.metadata = mergeAddressSnapshot(\n input.metadata ? cloneJson(input.metadata) : shipmentEntity.metadata ?? null,\n input.shipmentAddressSnapshot\n )\n }\n shipmentEntity.updatedAt = new Date()\n\n // Persist the shipment scalar mutations before the item reads below run on\n // the same EntityManager. Under MikroORM v7 an interleaved query (the\n // findWithDecryption on SalesShipmentItem here and in the snapshot step)\n // resets the identity-map changeset, so shippingMethodId/status/carrier/etc.\n // would silently not persist even though the write returns 200 (#2453).\n await tx.flush()\n\n const shouldLoadItems = Boolean(normalizedItems || input.lineStatusEntryId !== undefined)\n const existingItems = shouldLoadItems ? await findWithDecryption(tx, SalesShipmentItem, { shipment: shipmentEntity }, {}, { tenantId: shipmentEntity.tenantId, organizationId: shipmentEntity.organizationId }) : []\n const newItems: SalesShipmentItem[] = []\n if (normalizedItems) {\n existingItems.forEach((item) => tx.remove(item))\n normalizedItems.forEach((item) => {\n const lineRef = tx.getReference(SalesOrderLine, item.orderLineId)\n const shipmentItem = tx.create(SalesShipmentItem, {\n id: randomUUID(),\n shipment: shipmentEntity,\n orderLine: lineRef,\n organizationId: shipmentEntity.organizationId,\n tenantId: shipmentEntity.tenantId,\n quantity: item.quantity.toString(),\n metadata: item.metadata ? cloneJson(item.metadata) : null,\n })\n newItems.push(shipmentItem)\n tx.persist(shipmentItem)\n })\n }\n\n if (input.customFields !== undefined) {\n await setRecordCustomFields(tx, {\n entityId: E.sales.sales_shipment,\n recordId: shipmentEntity.id,\n organizationId: shipmentEntity.organizationId,\n tenantId: shipmentEntity.tenantId,\n values: normalizeCustomFieldsInput(input.customFields),\n })\n }\n if (input.documentStatusEntryId !== undefined) {\n const orderStatus = await resolveDictionaryEntryValue(tx, input.documentStatusEntryId ?? null, { tenantId: shipmentEntity.tenantId })\n if (input.documentStatusEntryId && !orderStatus) {\n throw new CrudHttpError(400, { error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.') })\n }\n order.statusEntryId = input.documentStatusEntryId ?? null\n order.status = orderStatus\n order.updatedAt = new Date()\n }\n if (input.lineStatusEntryId !== undefined) {\n const lineStatus = await resolveDictionaryEntryValue(tx, input.lineStatusEntryId ?? null, { tenantId: shipmentEntity.tenantId })\n if (input.lineStatusEntryId && !lineStatus) {\n throw new CrudHttpError(400, { error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.') })\n }\n const targetLineIds = normalizedItems\n ? Array.from(new Set(normalizedItems.map((item) => item.orderLineId)))\n : Array.from(\n new Set(\n existingItems\n .map((item) =>\n typeof item.orderLine === 'string'\n ? item.orderLine\n : (item.orderLine as SalesOrderLine | null)?.id ?? null\n )\n .filter((id): id is string => Boolean(id))\n )\n )\n if (targetLineIds.length) {\n const missing = targetLineIds.filter((id) => !lineMap.has(id))\n if (missing.length) {\n const fetched = await tx.find(SalesOrderLine, { id: { $in: missing } })\n fetched.forEach((line) => lineMap.set(line.id, line))\n }\n targetLineIds.forEach((lineId) => {\n const line = lineMap.get(lineId)\n if (!line) return\n line.statusEntryId = input.lineStatusEntryId ?? null\n line.status = lineStatus\n line.updatedAt = new Date()\n })\n }\n }\n\n // Flush any order/line status mutations applied above before the snapshot\n // read below queries the same EntityManager (same interleaved-read hazard).\n await tx.flush()\n const itemsForSnapshot =\n normalizedItems || shouldLoadItems\n ? (normalizedItems ? newItems : existingItems)\n : await findWithDecryption(tx, SalesShipmentItem, { shipment: shipmentEntity }, {}, { tenantId: shipmentEntity.tenantId, organizationId: shipmentEntity.organizationId })\n await refreshShipmentItemsSnapshot(tx, shipmentEntity, { items: itemsForSnapshot, lineMap })\n await tx.flush()\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n return shipmentEntity\n })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'updated',\n entity: shipment,\n identifiers: {\n id: shipment.id,\n organizationId: shipment.organizationId,\n tenantId: shipment.tenantId,\n },\n indexer: { entityType: E.sales.sales_shipment },\n events: shipmentCrudEvents,\n })\n\n return { shipmentId: shipment.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadShipmentSnapshot(em, result.shipmentId)\n },\n buildLog: async ({ snapshots, result }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as ShipmentSnapshot | undefined\n const after = snapshots.after as ShipmentSnapshot | undefined\n return {\n actionLabel: translate('sales.audit.shipments.update', 'Update shipment'),\n resourceKind: 'sales.shipment',\n resourceId: result.shipmentId,\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: {\n undo: { before, after } satisfies ShipmentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ShipmentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await em.transactional(async (tx) => {\n await restoreShipmentSnapshot(tx, before)\n const order = await findOneWithDecryption(tx, SalesOrder, { id: before.orderId }, {}, { tenantId: before.tenantId, organizationId: before.organizationId })\n await tx.flush()\n if (order) {\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n }\n })\n },\n}\n\nconst deleteShipmentCommand: CommandHandler<\n { id: string; orderId: string; organizationId: string; tenantId: string },\n { shipmentId: string }\n> = {\n id: 'sales.shipments.delete',\n async prepare(rawInput, ctx) {\n const parsed = shipmentUpdateSchema.parse(rawInput ?? {})\n if (!parsed.id) return {}\n const em = ctx.container.resolve('em') as EntityManager\n const snapshot = await loadShipmentSnapshot(em, parsed.id)\n if (snapshot) {\n try {\n ensureTenantScope(ctx, snapshot.tenantId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Tenant mismatch while preparing shipment delete', {\n shipmentId: snapshot.id,\n snapshotTenantId: snapshot.tenantId,\n authTenantId: ctx.auth?.tenantId ?? null,\n })\n throw error\n }\n try {\n ensureOrganizationScope(ctx, snapshot.organizationId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Organization mismatch while preparing shipment delete', {\n shipmentId: snapshot.id,\n snapshotOrganizationId: snapshot.organizationId,\n selectedOrganizationId: ctx.selectedOrganizationId ?? null,\n authOrganizationId: ctx.auth?.orgId ?? null,\n })\n throw error\n }\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const { translate } = await resolveTranslations()\n const payload = shipmentUpdateSchema\n .pick({ id: true, orderId: true, organizationId: true, tenantId: true })\n .parse(rawInput ?? {})\n try {\n ensureTenantScope(ctx, payload.tenantId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Tenant mismatch while executing shipment delete', {\n shipmentId: payload.id,\n payloadTenantId: payload.tenantId,\n authTenantId: ctx.auth?.tenantId ?? null,\n })\n throw error\n }\n try {\n ensureOrganizationScope(ctx, payload.organizationId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Organization mismatch while executing shipment delete', {\n shipmentId: payload.id,\n payloadOrganizationId: payload.organizationId,\n selectedOrganizationId: ctx.selectedOrganizationId ?? null,\n authOrganizationId: ctx.auth?.orgId ?? null,\n })\n throw error\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n\n const { shipment, shipmentItems } = await em.transactional(async (tx) => {\n const shipmentEntity = await findOneWithDecryption(\n tx,\n SalesShipment,\n { id: payload.id },\n { populate: ['order'] },\n { tenantId: payload.tenantId, organizationId: payload.organizationId },\n )\n if (!shipmentEntity || !shipmentEntity.order) {\n throw new CrudHttpError(404, { error: translate('sales.shipments.not_found', 'Shipment not found') })\n }\n try {\n ensureSameScope(shipmentEntity, payload.organizationId, payload.tenantId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Shipment scope mismatch against payload', {\n shipmentId: payload.id,\n shipmentOrganizationId: shipmentEntity.organizationId,\n shipmentTenantId: shipmentEntity.tenantId,\n payloadOrganizationId: payload.organizationId,\n payloadTenantId: payload.tenantId,\n })\n throw error\n }\n const order = shipmentEntity.order as SalesOrder\n if (order.id !== payload.orderId) {\n throw new CrudHttpError(400, { error: translate('sales.shipments.invalid_order', 'Shipment does not belong to this order') })\n }\n const scope = { tenantId: shipmentEntity.tenantId, organizationId: shipmentEntity.organizationId }\n const items = await findWithDecryption(tx, SalesShipmentItem, { shipment: shipmentEntity }, {}, scope)\n items.forEach((item) => tx.remove(item))\n tx.remove(shipmentEntity)\n await tx.flush()\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n return { shipment: shipmentEntity, shipmentItems: items }\n })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: shipment,\n identifiers: {\n id: shipment.id,\n organizationId: shipment.organizationId,\n tenantId: shipment.tenantId,\n },\n indexer: { entityType: E.sales.sales_shipment },\n events: shipmentCrudEvents,\n })\n if (shipmentItems.length) {\n await Promise.all(\n shipmentItems.map((item) =>\n emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: item,\n identifiers: {\n id: item.id,\n organizationId: item.organizationId ?? null,\n tenantId: item.tenantId ?? null,\n },\n indexer: { entityType: E.sales.sales_shipment_item },\n })\n )\n )\n }\n return { shipmentId: shipment.id }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ShipmentUndoPayload>(logEntry)\n const snapshot = payload?.before ?? null\n if (!snapshot) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await em.transactional(async (tx) => {\n await restoreShipmentSnapshot(tx, snapshot)\n const order = await findOneWithDecryption(tx, SalesOrder, { id: snapshot.orderId }, {}, { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId })\n await tx.flush()\n if (order) {\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n }\n })\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as ShipmentSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('sales.audit.shipments.delete', 'Delete shipment'),\n resourceKind: 'sales.shipment',\n resourceId: before.id ?? null,\n parentResourceKind: 'sales.order',\n parentResourceId: before.orderId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: { before } satisfies ShipmentUndoPayload,\n },\n }\n },\n}\n\nregisterCommand(createShipmentCommand)\nregisterCommand(updateShipmentCommand)\nregisterCommand(deleteShipmentCommand)\n\nexport const shipmentCommands = [createShipmentCommand, updateShipmentCommand, deleteShipmentCommand]\n"],
|
|
5
|
-
"mappings": "AAEA,SAAS,kBAAkB;AAC3B,SAAS,uBAA4C;AACrD,SAAS,gBAAgB;AAEzB,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AACtC,SAAS,6BAA6B;AACtC,SAAS,SAAS;AAClB,SAAS,YAAY,gBAAgB,eAAe,yBAAyB;AAC7E;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE,0BAA0B;AAAA,EAC1B;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mCAAmC;AAC5C,SAAS,2BAA2B;AAEpC,SAAS,2BAA2B;AAEpC,SAAS,uBAAuB,0BAA0B;AAE1D,MAAM,qBAAuC;AAAA,EAC3C,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,EAC5B;AACF;AAEA,MAAM,uBAAuB;AAgC7B,MAAM,+BAA+B,CAAC,cAAqD;AAAA,EACzF,SAAS,SAAS;AAAA,EAClB,gBAAgB,SAAS;AAAA,EACzB,UAAU,SAAS;AAAA,EACnB,gBAAgB,SAAS,kBAAkB;AAAA,EAC3C,kBAAkB,SAAS,oBAAoB;AAAA,EAC/C,eAAe,SAAS,iBAAiB;AAAA,EACzC,aAAa,SAAS,eAAe;AAAA,EACrC,iBAAiB,SAAS,mBAAmB;AAAA,EAC7C,WAAW,SAAS,YAAY,IAAI,KAAK,SAAS,SAAS,IAAI;AAAA,EAC/D,aAAa,SAAS,cAAc,IAAI,KAAK,SAAS,WAAW,IAAI;AAAA,EACrE,aAAa,SAAS,eAAe;AAAA,EACrC,YAAY,SAAS,cAAc;AAAA,EACnC,kBAAkB,SAAS,oBAAoB;AAAA,EAC/C,oBAAoB,SAAS,sBAAsB;AAAA,EACnD,cAAc,SAAS,gBAAgB;AAAA,EACvC,OAAO,SAAS,aAAa;AAAA,EAC7B,UAAU,SAAS,WAAW,UAAU,SAAS,QAAQ,IAAI;AAAA,EAC7D,cAAc,SAAS,eAAe,UAAU,SAAS,YAAY,IAAI;AAAA,EACzE,OAAO,SAAS,MAAM,IAAI,CAAC,UAAU;AAAA,IACnC,aAAa,KAAK;AAAA,IAClB,UAAU,KAAK;AAAA,IACf,UAAU,KAAK,WAAW,UAAU,KAAK,QAAQ,IAAI;AAAA,EACvD,EAAE;AACJ;AAEA,MAAM,uBAAuB,CAAC,UAAoC;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MACb,MAAM,QAAQ,EACd,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACrC,WAAO,QAAQ,SAAS,UAAU;AAAA,EACpC;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAM,UAAU,MACb,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI,EAAG,EAC9D,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACrC,WAAO,QAAQ,SAAS,UAAU;AAAA,EACpC;AACA,SAAO;AACT;AAEA,MAAM,6BAA6B,CAAC,UAClC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAK,QAAoC,CAAC;AAEtG,MAAM,gBAAgB,CAAC,QAAsE;AAC3F,QAAM,YAAY,KAAK;AACvB,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,eAAe,WAAW,QAAQ,UAAU;AAClD,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,kBAAkB,OAAO,UAAU,oBAAoB,aAAa,UAAU,gBAAgB,KAAK,SAAS,IAAI;AACtH,MAAI,kBAAkB,QAAQ,GAAG;AAC/B,UAAM,SAAS,UAAU,QAAQ,QAAQ;AACzC,QAAI,QAAQ,KAAM,QAAO;AAAA,EAC3B;AACA,MAAI,kBAAkB,YAAY,GAAG;AACnC,UAAM,SAAS,UAAU,QAAQ,YAAY;AAC7C,QAAI,QAAQ,KAAM,QAAO;AAAA,EAC3B;AACA,SAAO;AACT;AAEA,MAAM,kCAAkC,CACtC,KACA,QACA,SACS;AACT,QAAM,SAAS,cAAc,GAAG;AAChC,QAAM,UAAU,EAAE,GAAG,MAAM,SAAS,yBAAyB;AAC7D,MAAI,QAAQ,MAAM;AAChB,WAAO,KAAK,SAAS,MAAM;AAC3B;AAAA,EACF;AAEA,UAAQ,KAAK,4BAA4B,MAAM,IAAI,OAAO;AAC5D;AAEA,eAAsB,qBAAqB,IAAmB,IAA8C;AAC1G,QAAM,WAAW,MAAM,GAAG;AAAA,IACxB;AAAA,IACA,EAAE,GAAG;AAAA,IACL,EAAE,UAAU,CAAC,SAAS,SAAS,iBAAiB,EAAE;AAAA,EACpD;AACA,MAAI,CAAC,YAAY,CAAC,SAAS,MAAO,QAAO;AACzC,QAAM,iBAAiB;AAAA,IACpB,SAAiB,iBAAkB,SAAiB,kBAAkB;AAAA,EACzE;AACA,QAAM,UAAU,IAAI;AAAA,IAClB,MAAM,KAAK,SAAS,SAAS,CAAC,CAAC,EAC5B,IAAI,CAAC,SAAS;AACb,YAAM,OAAO,OAAO,KAAK,cAAc,WAAW,OAAQ,KAAK;AAC/D,aAAO,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI;AAAA,IAClC,CAAC,EACA,OAAO,CAAC,UAA6C,QAAQ,KAAK,CAAC;AAAA,EACxE;AACA,QAAM,gBAAgB,2BAA2B,MAAM,KAAK,SAAS,SAAS,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC;AAC9F,QAAM,gBAAgB,eAAe,SAAS,iBAAiB;AAC/D,QAAM,oBAAoB,MAAM,sBAAsB;AAAA,IACpD;AAAA,IACA,UAAU,EAAE,MAAM;AAAA,IAClB,WAAW,CAAC,SAAS,EAAE;AAAA,IACvB,kBAAkB,EAAE,CAAC,SAAS,EAAE,GAAG,SAAS,YAAY,KAAK;AAAA,IAC7D,wBAAwB,EAAE,CAAC,SAAS,EAAE,GAAG,SAAS,kBAAkB,KAAK;AAAA,EAC3E,CAAC;AACD,QAAM,eAAe,kBAAkB,SAAS,EAAE;AAClD,SAAO;AAAA,IACL,IAAI,SAAS;AAAA,IACb,SAAS,OAAO,SAAS,UAAU,WAAW,SAAS,QAAQ,SAAS,MAAM;AAAA,IAC9E,gBAAgB,SAAS;AAAA,IACzB,UAAU,SAAS;AAAA,IACnB,gBAAgB,SAAS,kBAAkB;AAAA,IAC3C,kBAAkB,SAAS,oBAAoB;AAAA,IAC/C,eAAe,SAAS,iBAAiB;AAAA,IACzC,QAAQ,SAAS,UAAU;AAAA,IAC3B,aAAa,SAAS,eAAe;AAAA,IACrC,iBAAiB,SAAS,kBAAkB,CAAC,GAAG,SAAS,eAAe,IAAI;AAAA,IAC5E,WAAW,SAAS,YAAY,SAAS,UAAU,YAAY,IAAI;AAAA,IACnE,aAAa,SAAS,cAAc,SAAS,YAAY,YAAY,IAAI;AAAA,IACzE,aAAa,SAAS,gBAAgB,UAAa,SAAS,gBAAgB,OAAO,OAAO,SAAS,WAAW,IAAI;AAAA,IAClH,YAAY,SAAS,cAAc;AAAA,IACnC,kBACE,SAAS,qBAAqB,UAAa,SAAS,qBAAqB,OACrE,OAAO,SAAS,gBAAgB,IAChC;AAAA,IACN,oBACE,SAAS,uBAAuB,UAAa,SAAS,uBAAuB,OACzE,OAAO,SAAS,kBAAkB,IAClC;AAAA,IACN,cAAc,SAAS,gBAAgB;AAAA,IACvC,WAAW,SAAS,aAAa;AAAA,IACjC,UAAU,SAAS,WAAW,UAAU,SAAS,QAAQ,IAAI;AAAA,IAC7D,cAAc,gBAAgB,OAAO,KAAK,YAAY,EAAE,SAAS,eAAe;AAAA,IAChF,OAAO;AAAA,IACP;AAAA,EACF;AACF;AAEA,eAAsB,wBAAwB,IAAmB,UAA2C;AAC1G,QAAM,QAAQ,MAAM,sBAAsB,IAAI,YAAY,EAAE,IAAI,SAAS,QAAQ,GAAG,CAAC,GAAG,EAAE,UAAU,SAAS,UAAU,gBAAgB,SAAS,eAAe,CAAC;AAChK,MAAI,CAAC,MAAO;AACZ,QAAM,WAAW,MAAM,GAAG,QAAQ,eAAe,EAAE,IAAI,SAAS,GAAG,CAAC;AACpE,QAAM,SACJ,YACA,GAAG,OAAO,eAAe;AAAA,IACvB,IAAI,SAAS;AAAA,IACb,WAAW,oBAAI,KAAK;AAAA,IACpB,gBAAgB,SAAS;AAAA,IACzB,UAAU,SAAS;AAAA,EACrB,CAAC;AACH,SAAO,QAAQ;AACf,SAAO,iBAAiB,SAAS;AACjC,SAAO,WAAW,SAAS;AAC3B,SAAO,iBAAiB,SAAS,kBAAkB;AACnD,SAAO,mBAAmB,SAAS,oBAAoB;AACvD,SAAO,gBAAgB,SAAS,iBAAiB;AACjD,SAAO,SAAS,SAAS,UAAU;AACnC,SAAO,cAAc,SAAS,eAAe;AAC7C,SAAO,kBAAkB,SAAS,kBAAkB,CAAC,GAAG,SAAS,eAAe,IAAI;AACpF,SAAO,YAAY,SAAS,YAAY,IAAI,KAAK,SAAS,SAAS,IAAI;AACvE,SAAO,cAAc,SAAS,cAAc,IAAI,KAAK,SAAS,WAAW,IAAI;AAC7E,SAAO,cAAc,SAAS,gBAAgB,OAAO,SAAS,YAAY,SAAS,IAAI;AACvF,SAAO,aAAa,SAAS,cAAc;AAC3C,SAAO,mBAAmB,SAAS,qBAAqB,OAAO,SAAS,iBAAiB,SAAS,IAAI;AACtG,SAAO,qBAAqB,SAAS,uBAAuB,OAAO,SAAS,mBAAmB,SAAS,IAAI;AAC5G,SAAO,eAAe,SAAS,gBAAgB;AAC/C,SAAO,YAAY,SAAS,aAAa;AACzC,SAAO,WAAW,SAAS,WAAW,UAAU,SAAS,QAAQ,IAAI;AACrE,SAAO,YAAY,oBAAI,KAAK;AAC5B,KAAG,QAAQ,MAAM;AACjB,QAAM,GAAG,MAAM;AAEf,QAAM,gBAAgB,MAAM,GAAG,KAAK,mBAAmB,EAAE,UAAU,OAAO,CAAC;AAC3E,gBAAc,QAAQ,CAAC,SAAS,GAAG,OAAO,IAAI,CAAC;AAC/C,QAAM,QAAQ,MAAM,QAAQ,SAAS,KAAK,IAAI,SAAS,QAAQ,CAAC;AAChE,QAAM,UAAU,MACb,IAAI,CAAC,SAAS,KAAK,WAAW,EAC9B,OAAO,CAAC,OAAqB,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC;AACvE,QAAM,QAAQ,QAAQ,SAClB,MAAM,GAAG,KAAK,gBAAgB,EAAE,IAAI,EAAE,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG,CAAC,IACvE,CAAC;AACL,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC5D,QAAM,gBAAwC,CAAC;AAC/C,QAAM,QAAQ,CAAC,SAAS;AACtB,UAAM,OAAO,QAAQ,IAAI,KAAK,WAAW;AACzC,QAAI,CAAC,KAAM;AACX,kBAAc,KAAK,IAAI;AACvB,UAAM,UAAU,GAAG,aAAa,gBAAgB,KAAK,EAAE;AACvD,UAAM,eAAe,GAAG,OAAO,mBAAmB;AAAA,MAChD,IAAI,KAAK,MAAM,WAAW;AAAA,MAC1B,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB,SAAS;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,UAAU,KAAK,SAAS,SAAS;AAAA,MACjC,UAAU,KAAK,WAAW,UAAU,KAAK,QAAQ,IAAI;AAAA,IACvD,CAAC;AACD,OAAG,QAAQ,YAAY;AAAA,EACzB,CAAC;AACD,QAAM,iBAAiB,SAAS,iBAAiB,eAAe;AAAA,IAAO,CAAC,UACtE,OAAO,cAAc,QAAQ,IAAI,MAAM,WAAW,IAAI;AAAA,EACxD;AACA,SAAO,gBAAgB,iBAAiB,cAAc,SAAS,UAAU,aAAa,IAAI;AAC1F,MAAI,CAAC,OAAO,eAAe;AACzB,UAAM,6BAA6B,IAAI,MAAM;AAAA,EAC/C;AACA,MAAK,SAAiB,iBAAiB,QAAW;AAChD,UAAM,sBAAsB,IAAI;AAAA,MAC9B,UAAU,EAAE,MAAM;AAAA,MAClB,UAAU,OAAO;AAAA,MACjB,gBAAgB,SAAS;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,QAAQ,2BAA4B,SAAiB,YAAY;AAAA,IACnE,CAAC;AAAA,EACH;AACA,KAAG,QAAQ,MAAM;AACnB;AAEA,eAAe,wBAAwB,IAAmB,UAAwC;AAChG,QAAM,QAAQ,EAAE,UAAU,SAAS,UAAU,gBAAgB,SAAS,eAAe;AACrF,QAAM,QAAQ,MAAM,mBAAmB,IAAI,mBAAmB,EAAE,SAAS,GAAG,CAAC,GAAG,KAAK;AACrF,QAAM,QAAQ,CAAC,SAAS,GAAG,OAAO,IAAI,CAAC;AACvC,KAAG,OAAO,QAAQ;AAClB,QAAM,GAAG,MAAM;AACjB;AAEA,eAAe,6BAA6B,IAAmB,OAAkC;AAC/F,QAAM,QAAQ,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAC/E,QAAM,YAAY,MAAM,mBAAmB,IAAI,eAAe,EAAE,OAAO,WAAW,KAAK,GAAG,CAAC,GAAG,KAAK;AACnG,QAAM,cAAc,UAAU,IAAI,CAAC,UAAU,MAAM,EAAE;AACrD,QAAM,gBAAgB,YAAY,SAC9B,MAAM,mBAAmB,IAAI,mBAAmB,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,GAAG,CAAC,GAAG,KAAK,IAC7F,CAAC;AACL,QAAM,SAAS,cAAc,OAA4B,CAAC,KAAK,SAAS;AACtE,UAAM,SACJ,OAAO,KAAK,cAAc,WACtB,KAAK,YACL,KAAK,WAAW,MAAO,KAAa,eAAe;AACzD,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,QAAQ,IAAI,IAAI,MAAM,KAAK,KAAK,SAAS,KAAK,QAAQ;AAC5D,QAAI,IAAI,QAAQ,IAAI;AACpB,WAAO;AAAA,EACT,GAAG,oBAAI,IAAI,CAAC;AACZ,QAAM,QAAQ,MAAM,mBAAmB,IAAI,gBAAgB,EAAE,MAAM,GAAG,EAAE,UAAU,SAAS,kBAAkB,GAAG,KAAK;AACrH,QAAM,QAAQ,CAAC,SAAS;AACtB,UAAM,UAAU,OAAO,IAAI,KAAK,EAAE,KAAK;AACvC,SAAK,oBAAoB,QAAQ,SAAS;AAAA,EAC5C,CAAC;AACH;AAEA,eAAe,UACb,IACA,IACA,OACqB;AACrB,QAAM,QAAQ,MAAM,sBAAsB,IAAI,YAAY,EAAE,IAAI,WAAW,KAAK,GAAG,CAAC,GAAG,KAAK;AAC5F,MAAI,CAAC,MAAO,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,4BAA4B,CAAC;AAC/E,SAAO;AACT;AAEA,eAAe,kBACb,IACA,OACA,mBAC8B;AAC9B,QAAM,QAAQ,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAC/E,QAAM,YAAY,MAAM,mBAAmB,IAAI,eAAe,EAAE,OAAO,WAAW,KAAK,GAAG,CAAC,GAAG,KAAK;AACnG,QAAM,cAAc,UACjB,IAAI,CAAC,UAAU,MAAM,EAAE,EACvB,OAAO,CAAC,OAAO,CAAC,qBAAqB,OAAO,iBAAiB;AAChE,MAAI,CAAC,YAAY,OAAQ,QAAO,oBAAI,IAAI;AACxC,QAAM,QAAQ,MAAM,mBAAmB,IAAI,mBAAmB,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,GAAG,CAAC,GAAG,KAAK;AAC3G,SAAO,MAAM,OAA4B,CAAC,KAAK,SAAS;AACtD,UAAM,SACJ,OAAO,KAAK,cAAc,WACtB,KAAK,YACL,KAAK,WAAW,MAAO,KAAa,eAAe;AACzD,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,QAAQ,IAAI,IAAI,MAAM,KAAK,KAAK,SAAS,KAAK,QAAQ;AAC5D,QAAI,IAAI,QAAQ,IAAI;AACpB,WAAO;AAAA,EACT,GAAG,oBAAI,IAAI,CAAC;AACd;AAEA,eAAe,sBAAsB,QASlC;AACD,QAAM,EAAE,IAAI,OAAO,OAAO,mBAAmB,eAAe,IAAI;AAChE,QAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,MAAI,CAAC,SAAS,CAAC,MAAM,QAAQ;AAC3B,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,kCAAkC,gCAAgC,EAAE,CAAC;AAAA,EACvH;AACA,QAAM,QAAQ,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAC/E,QAAM,aAAa,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA,EAAE,MAAM;AAAA,IACR,iBAAiB,EAAE,UAAU,SAAS,kBAAkB,IAAI;AAAA,IAC5D;AAAA,EACF;AACA,QAAM,UAAU,IAAI,IAAI,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AACjE,QAAM,gBAAgB,MAAM,kBAAkB,IAAI,OAAO,iBAAiB;AAC1E,QAAM,kBAAkB,oBAAI,IAAoB;AAEhD,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,KAAK;AACpB,UAAM,WAAW,SAAS,KAAK,QAAQ;AACvC,QAAI,CAAC,UAAU,YAAY,GAAG;AAC5B,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,kCAAkC,gCAAgC,EAAE,CAAC;AAAA,IACvH;AACA,UAAM,OAAO,QAAQ,IAAI,MAAM;AAC/B,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,gCAAgC,uBAAuB,EAAE,CAAC;AAAA,IAC5G;AACA,UAAM,YAAY,SAAS,KAAK,QAAQ;AACxC,UAAM,iBAAiB,cAAc,IAAI,MAAM,KAAK;AACpD,UAAM,aAAa,gBAAgB,IAAI,MAAM,KAAK,KAAK;AACvD,QAAI,YAAY,iBAAiB,OAAO,WAAW;AACjD,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,qCAAqC,+CAA+C,EAAE,CAAC;AAAA,IACzI;AACA,oBAAgB,IAAI,QAAQ,SAAS;AAAA,EACvC;AAEA,SAAO;AAAA,IACL,OAAO,MAAM,IAAI,CAAC,UAAU;AAAA,MAC1B,aAAa,KAAK;AAAA,MAClB,UAAU,SAAS,KAAK,QAAQ;AAAA,MAChC,UAAU,KAAK,WAAW,UAAU,KAAK,QAAQ,IAAI;AAAA,IACvD,EAAE;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,qBACP,cACA,UACgC;AAChC,QAAM,WAAW,eAAe,EAAE,GAAG,aAAa,IAAI,CAAC;AACvD,MAAI,YAAY,OAAO,aAAa,UAAU;AAC5C,aAAS,oBAAoB,IAAI,UAAU,QAAQ;AAAA,EACrD;AACA,SAAO,OAAO,KAAK,QAAQ,EAAE,SAAS,WAAW;AACnD;AAEA,MAAM,wBAAqF;AAAA,EACzF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,qBAAqB,MAAM,YAAY,CAAC,CAAC;AACvD,sBAAkB,KAAK,MAAM,QAAQ;AACrC,4BAAwB,KAAK,MAAM,cAAc;AACjD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,WAAW,MAAM,GAAG,cAAc,OAAO,OAAO;AACpD,YAAM,QAAQ,MAAM,UAAU,IAAI,MAAM,SAAS,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe,CAAC;AACnH,sBAAgB,OAAO,MAAM,gBAAgB,MAAM,QAAQ;AAC3D,YAAM,EAAE,OAAO,iBAAiB,QAAQ,IAAI,MAAM,sBAAsB;AAAA,QACtE,IAAI;AAAA,QACJ;AAAA,QACA,OAAO,MAAM;AAAA,QACb,gBAAgB;AAAA,MAClB,CAAC;AACD,YAAM,cAAc,MAAM,4BAA4B,IAAI,MAAM,iBAAiB,MAAM,EAAE,UAAU,MAAM,SAAS,CAAC;AACnH,YAAM,kBAAkB,qBAAqB,MAAM,eAAe,KAAK;AACvE,YAAM,WACJ;AAAA,QACE,MAAM,WAAW,UAAU,MAAM,QAAQ,IAAI;AAAA,QAC7C,MAAM,2BAA2B,MAAM,2BAA2B;AAAA,MACpE,KAAK;AAEP,YAAM,aAAa,WAAW;AAC9B,YAAM,SAAS,GAAG,OAAO,eAAe;AAAA,QACtC,IAAI;AAAA,QACJ;AAAA,QACA,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB,gBAAgB,MAAM,kBAAkB;AAAA,QACxC,kBAAkB,MAAM,oBAAoB;AAAA,QAC5C,eAAe,MAAM,iBAAiB;AAAA,QACtC,QAAQ;AAAA,QACR,aAAa,MAAM,eAAe;AAAA,QAClC;AAAA,QACA,WAAW,MAAM,aAAa;AAAA,QAC9B,aAAa,MAAM,eAAe;AAAA,QAClC,aAAa,MAAM,gBAAgB,SAAY,MAAM,YAAY,SAAS,IAAI;AAAA,QAC9E,YAAY,MAAM,cAAc;AAAA,QAChC,kBAAkB,MAAM,qBAAqB,SAAY,MAAM,iBAAiB,SAAS,IAAI;AAAA,QAC7F,oBAAoB,MAAM,uBAAuB,SAAY,MAAM,mBAAmB,SAAS,IAAI;AAAA,QACnG,cAAc,MAAM,gBAAgB,MAAM,gBAAgB;AAAA,QAC1D,WAAW,MAAM,SAAS;AAAA,QAC1B;AAAA,QACA,WAAW,oBAAI,KAAK;AAAA,QACpB,WAAW,oBAAI,KAAK;AAAA,MACtB,CAAC;AACD,YAAM,eAAoC,CAAC;AAC3C,sBAAgB,QAAQ,CAAC,SAAS;AAChC,cAAM,UAAU,GAAG,aAAa,gBAAgB,KAAK,WAAW;AAChE,cAAM,eAAe,GAAG,OAAO,mBAAmB;AAAA,UAChD,IAAI,WAAW;AAAA,UACf,UAAU;AAAA,UACV,WAAW;AAAA,UACX,gBAAgB,MAAM;AAAA,UACtB,UAAU,MAAM;AAAA,UAChB,UAAU,KAAK,SAAS,SAAS;AAAA,UACjC,UAAU,KAAK,WAAW,UAAU,KAAK,QAAQ,IAAI;AAAA,QACvD,CAAC;AACD,qBAAa,KAAK,YAAY;AAC9B,WAAG,QAAQ,YAAY;AAAA,MACzB,CAAC;AACD,SAAG,QAAQ,MAAM;AACjB,UAAI,MAAM,iBAAiB,QAAW;AACpC,cAAM,sBAAsB,IAAI;AAAA,UAC9B,UAAU,EAAE,MAAM;AAAA,UAClB,UAAU,OAAO;AAAA,UACjB,gBAAgB,MAAM;AAAA,UACtB,UAAU,MAAM;AAAA,UAChB,QAAQ,2BAA2B,MAAM,YAAY;AAAA,QACvD,CAAC;AAAA,MACH;AACA,UAAI,MAAM,0BAA0B,QAAW;AAC7C,cAAM,cAAc,MAAM,4BAA4B,IAAI,MAAM,yBAAyB,MAAM,EAAE,UAAU,MAAM,SAAS,CAAC;AAC3H,YAAI,MAAM,yBAAyB,CAAC,aAAa;AAC/C,gBAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,wCAAwC,qCAAqC,EAAE,CAAC;AAAA,QAClI;AACA,cAAM,gBAAgB,MAAM,yBAAyB;AACrD,cAAM,SAAS;AACf,cAAM,YAAY,oBAAI,KAAK;AAAA,MAC7B;AACA,UAAI,MAAM,sBAAsB,QAAW;AACzC,cAAM,aAAa,MAAM,4BAA4B,IAAI,MAAM,qBAAqB,MAAM,EAAE,UAAU,MAAM,SAAS,CAAC;AACtH,YAAI,MAAM,qBAAqB,CAAC,YAAY;AAC1C,gBAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,wCAAwC,qCAAqC,EAAE,CAAC;AAAA,QAClI;AACA,cAAM,gBAAgB,MAAM,KAAK,IAAI,IAAI,gBAAgB,IAAI,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC;AACzF,sBAAc,QAAQ,CAAC,WAAW;AAChC,gBAAM,OAAO,QAAQ,IAAI,MAAM;AAC/B,cAAI,CAAC,KAAM;AACX,eAAK,gBAAgB,MAAM,qBAAqB;AAChD,eAAK,SAAS;AACd,eAAK,YAAY,oBAAI,KAAK;AAAA,QAC5B,CAAC;AAAA,MACH;AACA,YAAM,6BAA6B,IAAI,QAAQ,EAAE,OAAO,cAAc,QAAQ,CAAC;AAC/E,YAAM,GAAG,MAAM;AACf,YAAM,6BAA6B,IAAI,KAAK;AAC5C,YAAM,GAAG,MAAM;AACf,aAAO;AAAA,IACT,CAAC;AAED,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,SAAS;AAAA,QACb,gBAAgB,SAAS;AAAA,QACzB,UAAU,SAAS;AAAA,MACrB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe;AAAA,MAC9C,QAAQ;AAAA,IACV,CAAC;AAED,WAAO,EAAE,YAAY,SAAS,GAAG;AAAA,EACnC;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,qBAAqB,IAAI,OAAO,UAAU;AAAA,EACnD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,QAAQ,UAAU;AACxB,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,WAAO;AAAA,MACL,aAAa,UAAU,gCAAgC,iBAAiB;AAAA,MACxE,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,MAAM,WAAW;AAAA,MACnC,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,eAAe;AAAA,MACf,SAAS;AAAA,QACP,MAAM,EAAE,MAAM;AAAA,QACd,aAAa,6BAA6B,KAAK;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAwC,QAAQ;AAChE,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,MAAO;AACZ,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,GAAG,cAAc,OAAO,OAAO;AACnC,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA;AAAA,QACA,EAAE,IAAI,MAAM,GAAG;AAAA,QACf,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,QACtB,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,MACnE;AACA,UAAI,CAAC,SAAU;AACf,YAAM,QAAQ,SAAS;AACvB,YAAM,wBAAwB,IAAI,QAAQ;AAC1C,UAAI,OAAO;AACT,cAAM,6BAA6B,IAAI,KAAK;AAC5C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,MAAM,OAAO,EAAE,KAAK,SAAS,MAAM;AACjC,UAAM,QAAQ,oBAAsC,QAAQ;AAC5D,UAAM,aAAa,OAAO,MAAM,SAAS,cAAc;AACvD,QAAI,CAAC,SAAS,CAAC,YAAY;AACzB,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,kEAAkE,CAAC;AAAA,IAC3G;AACA,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,GAAG,cAAc,OAAO,OAAO;AACnC,YAAM,wBAAwB,IAAI,KAAK;AACvC,YAAM,QAAQ,MAAM,sBAAsB,IAAI,YAAY,EAAE,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe,CAAC;AACvJ,YAAM,GAAG,MAAM;AACf,UAAI,OAAO;AACT,cAAM,6BAA6B,IAAI,KAAK;AAC5C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF,CAAC;AAED,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,MAAM,GAAG;AAAA,MACf,CAAC;AAAA,MACD,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,IACnE;AACA,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,MAAM;AAAA,QACV,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,MAClB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe;AAAA,MAC9C,QAAQ;AAAA,IACV,CAAC;AAED,WAAO,EAAE,YAAY,MAAM,GAAG;AAAA,EAChC;AACF;AAEA,MAAM,wBAAqF;AAAA,EACzF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,qBAAqB,MAAM,YAAY,CAAC,CAAC;AACxD,QAAI,CAAC,OAAO,GAAI,QAAO,CAAC;AACxB,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,UAAM,WAAW,MAAM,qBAAqB,IAAI,OAAO,EAAE;AACzD,QAAI,UAAU;AACZ,wBAAkB,KAAK,SAAS,QAAQ;AACxC,8BAAwB,KAAK,SAAS,cAAc;AAAA,IACtD;AACA,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,qBAAqB,MAAM,YAAY,CAAC,CAAC;AACvD,sBAAkB,KAAK,MAAM,QAAQ;AACrC,4BAAwB,KAAK,MAAM,cAAc;AACjD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAEhD,UAAM,WAAW,MAAM,GAAG,cAAc,OAAO,OAAO;AACpD,YAAM,iBAAiB,MAAM;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,EAAE,IAAI,MAAM,GAAG;AAAA,QACf,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,QACtB,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,MACnE;AACA,UAAI,CAAC,kBAAkB,CAAC,eAAe,OAAO;AAC5C,cAAM,IAAI,cAAc,KAAK,EAAE,OAAO,4BAA4B,CAAC;AAAA,MACrE;AACA,sBAAgB,gBAAgB,MAAM,gBAAgB,MAAM,QAAQ;AACpE,YAAM,QAAQ,eAAe;AAC7B,UAAI,MAAM,WAAW,MAAM,YAAY,MAAM,IAAI;AAC/C,cAAM,IAAI,cAAc,KAAK,EAAE,OAAO,gCAAgC,CAAC;AAAA,MACzE;AAGA,YAAM,aAAa,WAAW,MAAM,mBAAmB,GAAG;AAC1D,YAAM,iBAAiB,WAAW,MAAM,uBAAuB,GAAG;AAClE,YAAM,aAAa,WAAW,MAAM,yBAAyB,GAAG;AAChE,YAAM,YAAY;AAGlB,YAAM,kBAAkB,kBAAkB,aAAa;AACvD,UAAI,iBAAiB;AACnB,cAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,kCAAkC,iDAAiD,EAAE,CAAC;AAAA,MACxI;AAGA,YAAM,cAAc,cAAc,aAAa;AAC/C,UAAI,aAAa;AACf,cAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,qCAAqC,oDAAoD,EAAE,CAAC;AAAA,MAC9I;AACA,YAAM,iBAAiB,MAAM,QACzB,MAAM,sBAAsB;AAAA,QAC1B,IAAI;AAAA,QACJ;AAAA,QACA,OAAO,MAAM;AAAA,QACb,mBAAmB,eAAe;AAAA,MACpC,CAAC,IACD;AACJ,YAAM,kBAAkB,gBAAgB,SAAS;AACjD,YAAM,UAAU,gBAAgB,WAAW,oBAAI,IAA4B;AAI3E,YAAM,yBAAyB,MAAM,kBAAkB,SACnD,MAAM,4BAA4B,IAAI,MAAM,iBAAiB,MAAM,EAAE,UAAU,eAAe,SAAS,CAAC,IACxG;AACJ,UAAI,MAAM,mBAAmB,OAAW,gBAAe,iBAAiB,MAAM,kBAAkB;AAChG,UAAI,MAAM,qBAAqB,OAAW,gBAAe,mBAAmB,MAAM,oBAAoB;AACtG,UAAI,MAAM,kBAAkB,QAAW;AACrC,uBAAe,gBAAgB,MAAM,iBAAiB;AACtD,uBAAe,SAAS,0BAA0B;AAAA,MACpD;AACA,UAAI,MAAM,gBAAgB,OAAW,gBAAe,cAAc,MAAM,eAAe;AACvF,UAAI,MAAM,oBAAoB,OAAW,gBAAe,kBAAkB,qBAAqB,MAAM,eAAe;AACpH,UAAI,MAAM,cAAc,OAAW,gBAAe,YAAY,MAAM,aAAa;AACjF,UAAI,MAAM,gBAAgB,OAAW,gBAAe,cAAc,MAAM,eAAe;AACvF,UAAI,MAAM,gBAAgB,OAAW,gBAAe,cAAc,MAAM,gBAAgB,OAAO,MAAM,YAAY,SAAS,IAAI;AAC9H,UAAI,MAAM,eAAe,OAAW,gBAAe,aAAa,MAAM,cAAc;AACpF,UAAI,MAAM,qBAAqB,QAAW;AACxC,uBAAe,mBAAmB,MAAM,qBAAqB,OAAO,MAAM,iBAAiB,SAAS,IAAI;AAAA,MAC1G;AACA,UAAI,MAAM,uBAAuB,QAAW;AAC1C,uBAAe,qBAAqB,MAAM,uBAAuB,OAAO,MAAM,mBAAmB,SAAS,IAAI;AAAA,MAChH;AACA,UAAI,MAAM,iBAAiB,OAAW,gBAAe,eAAe,MAAM,gBAAgB;AAC1F,UAAI,MAAM,UAAU,OAAW,gBAAe,YAAY,MAAM,SAAS;AACzE,UAAI,MAAM,aAAa,UAAa,MAAM,4BAA4B,QAAW;AAC/E,uBAAe,WAAW;AAAA,UACxB,MAAM,WAAW,UAAU,MAAM,QAAQ,IAAI,eAAe,YAAY;AAAA,UACxE,MAAM;AAAA,QACR;AAAA,MACF;AACA,qBAAe,YAAY,oBAAI,KAAK;AAOpC,YAAM,GAAG,MAAM;AAEf,YAAM,kBAAkB,QAAQ,mBAAmB,MAAM,sBAAsB,MAAS;AACxF,YAAM,gBAAgB,kBAAkB,MAAM,mBAAmB,IAAI,mBAAmB,EAAE,UAAU,eAAe,GAAG,CAAC,GAAG,EAAE,UAAU,eAAe,UAAU,gBAAgB,eAAe,eAAe,CAAC,IAAI,CAAC;AACnN,YAAM,WAAgC,CAAC;AACvC,UAAI,iBAAiB;AACnB,sBAAc,QAAQ,CAAC,SAAS,GAAG,OAAO,IAAI,CAAC;AAC/C,wBAAgB,QAAQ,CAAC,SAAS;AAChC,gBAAM,UAAU,GAAG,aAAa,gBAAgB,KAAK,WAAW;AAChE,gBAAM,eAAe,GAAG,OAAO,mBAAmB;AAAA,YAChD,IAAI,WAAW;AAAA,YACf,UAAU;AAAA,YACV,WAAW;AAAA,YACX,gBAAgB,eAAe;AAAA,YAC/B,UAAU,eAAe;AAAA,YACzB,UAAU,KAAK,SAAS,SAAS;AAAA,YACjC,UAAU,KAAK,WAAW,UAAU,KAAK,QAAQ,IAAI;AAAA,UACvD,CAAC;AACD,mBAAS,KAAK,YAAY;AAC1B,aAAG,QAAQ,YAAY;AAAA,QACzB,CAAC;AAAA,MACH;AAEA,UAAI,MAAM,iBAAiB,QAAW;AACpC,cAAM,sBAAsB,IAAI;AAAA,UAC9B,UAAU,EAAE,MAAM;AAAA,UAClB,UAAU,eAAe;AAAA,UACzB,gBAAgB,eAAe;AAAA,UAC/B,UAAU,eAAe;AAAA,UACzB,QAAQ,2BAA2B,MAAM,YAAY;AAAA,QACvD,CAAC;AAAA,MACH;AACA,UAAI,MAAM,0BAA0B,QAAW;AAC7C,cAAM,cAAc,MAAM,4BAA4B,IAAI,MAAM,yBAAyB,MAAM,EAAE,UAAU,eAAe,SAAS,CAAC;AACpI,YAAI,MAAM,yBAAyB,CAAC,aAAa;AAC/C,gBAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,wCAAwC,qCAAqC,EAAE,CAAC;AAAA,QAClI;AACA,cAAM,gBAAgB,MAAM,yBAAyB;AACrD,cAAM,SAAS;AACf,cAAM,YAAY,oBAAI,KAAK;AAAA,MAC7B;AACA,UAAI,MAAM,sBAAsB,QAAW;AACzC,cAAM,aAAa,MAAM,4BAA4B,IAAI,MAAM,qBAAqB,MAAM,EAAE,UAAU,eAAe,SAAS,CAAC;AAC/H,YAAI,MAAM,qBAAqB,CAAC,YAAY;AAC1C,gBAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,wCAAwC,qCAAqC,EAAE,CAAC;AAAA,QAClI;AACA,cAAM,gBAAgB,kBAClB,MAAM,KAAK,IAAI,IAAI,gBAAgB,IAAI,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,IACnE,MAAM;AAAA,UACJ,IAAI;AAAA,YACF,cACG;AAAA,cAAI,CAAC,SACJ,OAAO,KAAK,cAAc,WACtB,KAAK,YACJ,KAAK,WAAqC,MAAM;AAAA,YACvD,EACC,OAAO,CAAC,OAAqB,QAAQ,EAAE,CAAC;AAAA,UAC7C;AAAA,QACF;AACJ,YAAI,cAAc,QAAQ;AACxB,gBAAM,UAAU,cAAc,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;AAC7D,cAAI,QAAQ,QAAQ;AAClB,kBAAM,UAAU,MAAM,GAAG,KAAK,gBAAgB,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;AACtE,oBAAQ,QAAQ,CAAC,SAAS,QAAQ,IAAI,KAAK,IAAI,IAAI,CAAC;AAAA,UACtD;AACA,wBAAc,QAAQ,CAAC,WAAW;AAChC,kBAAM,OAAO,QAAQ,IAAI,MAAM;AAC/B,gBAAI,CAAC,KAAM;AACX,iBAAK,gBAAgB,MAAM,qBAAqB;AAChD,iBAAK,SAAS;AACd,iBAAK,YAAY,oBAAI,KAAK;AAAA,UAC5B,CAAC;AAAA,QACH;AAAA,MACF;AAIA,YAAM,GAAG,MAAM;AACf,YAAM,mBACJ,mBAAmB,kBACd,kBAAkB,WAAW,gBAC9B,MAAM,mBAAmB,IAAI,mBAAmB,EAAE,UAAU,eAAe,GAAG,CAAC,GAAG,EAAE,UAAU,eAAe,UAAU,gBAAgB,eAAe,eAAe,CAAC;AAC5K,YAAM,6BAA6B,IAAI,gBAAgB,EAAE,OAAO,kBAAkB,QAAQ,CAAC;AAC3F,YAAM,GAAG,MAAM;AACf,YAAM,6BAA6B,IAAI,KAAK;AAC5C,YAAM,GAAG,MAAM;AACf,aAAO;AAAA,IACT,CAAC;AAED,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,SAAS;AAAA,QACb,gBAAgB,SAAS;AAAA,QACzB,UAAU,SAAS;AAAA,MACrB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe;AAAA,MAC9C,QAAQ;AAAA,IACV,CAAC;AAED,WAAO,EAAE,YAAY,SAAS,GAAG;AAAA,EACnC;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,qBAAqB,IAAI,OAAO,UAAU;AAAA,EACnD;AAAA,EACA,UAAU,OAAO,EAAE,WAAW,OAAO,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,UAAM,QAAQ,UAAU;AACxB,WAAO;AAAA,MACL,aAAa,UAAU,gCAAgC,iBAAiB;AAAA,MACxE,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,WAAW,QAAQ,WAAW;AAAA,MACvD,UAAU,OAAO,YAAY,QAAQ,YAAY;AAAA,MACjD,gBAAgB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,MACnE,gBAAgB,UAAU;AAAA,MAC1B,eAAe,SAAS;AAAA,MACxB,SAAS;AAAA,QACP,MAAM,EAAE,QAAQ,MAAM;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAwC,QAAQ;AAChE,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,GAAG,cAAc,OAAO,OAAO;AACnC,YAAM,wBAAwB,IAAI,MAAM;AACxC,YAAM,QAAQ,MAAM,sBAAsB,IAAI,YAAY,EAAE,IAAI,OAAO,QAAQ,GAAG,CAAC,GAAG,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe,CAAC;AAC1J,YAAM,GAAG,MAAM;AACf,UAAI,OAAO;AACT,cAAM,6BAA6B,IAAI,KAAK;AAC5C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,MAAM,wBAGF;AAAA,EACF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,qBAAqB,MAAM,YAAY,CAAC,CAAC;AACxD,QAAI,CAAC,OAAO,GAAI,QAAO,CAAC;AACxB,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,UAAM,WAAW,MAAM,qBAAqB,IAAI,OAAO,EAAE;AACzD,QAAI,UAAU;AACZ,UAAI;AACF,0BAAkB,KAAK,SAAS,QAAQ;AAAA,MAC1C,SAAS,OAAO;AACd,wCAAgC,KAAK,mDAAmD;AAAA,UACtF,YAAY,SAAS;AAAA,UACrB,kBAAkB,SAAS;AAAA,UAC3B,cAAc,IAAI,MAAM,YAAY;AAAA,QACtC,CAAC;AACD,cAAM;AAAA,MACR;AACA,UAAI;AACF,gCAAwB,KAAK,SAAS,cAAc;AAAA,MACtD,SAAS,OAAO;AACd,wCAAgC,KAAK,yDAAyD;AAAA,UAC5F,YAAY,SAAS;AAAA,UACrB,wBAAwB,SAAS;AAAA,UACjC,wBAAwB,IAAI,0BAA0B;AAAA,UACtD,oBAAoB,IAAI,MAAM,SAAS;AAAA,QACzC,CAAC;AACD,cAAM;AAAA,MACR;AAAA,IACF;AACA,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,UAAU,qBACb,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,gBAAgB,MAAM,UAAU,KAAK,CAAC,EACtE,MAAM,YAAY,CAAC,CAAC;AACvB,QAAI;AACF,wBAAkB,KAAK,QAAQ,QAAQ;AAAA,IACzC,SAAS,OAAO;AACd,sCAAgC,KAAK,mDAAmD;AAAA,QACtF,YAAY,QAAQ;AAAA,QACpB,iBAAiB,QAAQ;AAAA,QACzB,cAAc,IAAI,MAAM,YAAY;AAAA,MACtC,CAAC;AACD,YAAM;AAAA,IACR;AACA,QAAI;AACF,8BAAwB,KAAK,QAAQ,cAAc;AAAA,IACrD,SAAS,OAAO;AACd,sCAAgC,KAAK,yDAAyD;AAAA,QAC5F,YAAY,QAAQ;AAAA,QACpB,uBAAuB,QAAQ;AAAA,QAC/B,wBAAwB,IAAI,0BAA0B;AAAA,QACtD,oBAAoB,IAAI,MAAM,SAAS;AAAA,MACzC,CAAC;AACD,YAAM;AAAA,IACR;AACA,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAE/D,UAAM,EAAE,UAAU,cAAc,IAAI,MAAM,GAAG,cAAc,OAAO,OAAO;AACvE,YAAM,iBAAiB,MAAM;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,EAAE,IAAI,QAAQ,GAAG;AAAA,QACjB,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,QACtB,EAAE,UAAU,QAAQ,UAAU,gBAAgB,QAAQ,eAAe;AAAA,MACvE;AACA,UAAI,CAAC,kBAAkB,CAAC,eAAe,OAAO;AAC5C,cAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,6BAA6B,oBAAoB,EAAE,CAAC;AAAA,MACtG;AACA,UAAI;AACF,wBAAgB,gBAAgB,QAAQ,gBAAgB,QAAQ,QAAQ;AAAA,MAC1E,SAAS,OAAO;AACd,wCAAgC,KAAK,2CAA2C;AAAA,UAC9E,YAAY,QAAQ;AAAA,UACpB,wBAAwB,eAAe;AAAA,UACvC,kBAAkB,eAAe;AAAA,UACjC,uBAAuB,QAAQ;AAAA,UAC/B,iBAAiB,QAAQ;AAAA,QAC3B,CAAC;AACD,cAAM;AAAA,MACR;AACA,YAAM,QAAQ,eAAe;AAC7B,UAAI,MAAM,OAAO,QAAQ,SAAS;AAChC,cAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,iCAAiC,wCAAwC,EAAE,CAAC;AAAA,MAC9H;AACA,YAAM,QAAQ,EAAE,UAAU,eAAe,UAAU,gBAAgB,eAAe,eAAe;AACjG,YAAM,QAAQ,MAAM,mBAAmB,IAAI,mBAAmB,EAAE,UAAU,eAAe,GAAG,CAAC,GAAG,KAAK;AACrG,YAAM,QAAQ,CAAC,SAAS,GAAG,OAAO,IAAI,CAAC;AACvC,SAAG,OAAO,cAAc;AACxB,YAAM,GAAG,MAAM;AACf,YAAM,6BAA6B,IAAI,KAAK;AAC5C,YAAM,GAAG,MAAM;AACf,aAAO,EAAE,UAAU,gBAAgB,eAAe,MAAM;AAAA,IAC1D,CAAC;AAED,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,SAAS;AAAA,QACb,gBAAgB,SAAS;AAAA,QACzB,UAAU,SAAS;AAAA,MACrB;AAAA,MACA,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe;AAAA,MAC9C,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,cAAc,QAAQ;AACxB,YAAM,QAAQ;AAAA,QACZ,cAAc;AAAA,UAAI,CAAC,SACjB,oBAAoB;AAAA,YAClB;AAAA,YACA,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,aAAa;AAAA,cACX,IAAI,KAAK;AAAA,cACT,gBAAgB,KAAK,kBAAkB;AAAA,cACvC,UAAU,KAAK,YAAY;AAAA,YAC7B;AAAA,YACA,SAAS,EAAE,YAAY,EAAE,MAAM,oBAAoB;AAAA,UACrD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,YAAY,SAAS,GAAG;AAAA,EACnC;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAwC,QAAQ;AAChE,UAAM,WAAW,SAAS,UAAU;AACpC,QAAI,CAAC,SAAU;AACf,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,GAAG,cAAc,OAAO,OAAO;AACnC,YAAM,wBAAwB,IAAI,QAAQ;AAC1C,YAAM,QAAQ,MAAM,sBAAsB,IAAI,YAAY,EAAE,IAAI,SAAS,QAAQ,GAAG,CAAC,GAAG,EAAE,UAAU,SAAS,UAAU,gBAAgB,SAAS,eAAe,CAAC;AAChK,YAAM,GAAG,MAAM;AACf,UAAI,OAAO;AACT,cAAM,6BAA6B,IAAI,KAAK;AAC5C,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,UAAU,OAAO,EAAE,UAAU,MAAM;AACjC,UAAM,SAAS,UAAU;AACzB,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,WAAO;AAAA,MACL,aAAa,UAAU,gCAAgC,iBAAiB;AAAA,MACxE,cAAc;AAAA,MACd,YAAY,OAAO,MAAM;AAAA,MACzB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,WAAW;AAAA,MACpC,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,gBAAgB;AAAA,MAChB,SAAS;AAAA,QACP,MAAM,EAAE,OAAO;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEA,gBAAgB,qBAAqB;AACrC,gBAAgB,qBAAqB;AACrC,gBAAgB,qBAAqB;AAE9B,MAAM,mBAAmB,CAAC,uBAAuB,uBAAuB,qBAAqB;",
|
|
4
|
+
"sourcesContent": ["// @ts-nocheck\n\nimport { randomUUID } from 'crypto'\nimport { registerCommand, type CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { LockMode } from '@mikro-orm/core'\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 { SalesOrder, SalesOrderLine, SalesShipment, SalesShipmentItem } from '../data/entities'\nimport {\n shipmentCreateSchema,\n shipmentUpdateSchema,\n type ShipmentCreateInput,\n type ShipmentUpdateInput,\n} from '../data/validators'\nimport {\n coerceShipmentQuantity as toNumber,\n readShipmentItemsSnapshot,\n refreshShipmentItemsSnapshot,\n type ShipmentItemSnapshot,\n buildShipmentItemSnapshots,\n} from '../lib/shipments/snapshots'\nimport {\n cloneJson,\n ensureOrganizationScope,\n ensureSameScope,\n ensureTenantScope,\n extractUndoPayload,\n enforceSalesDocumentOptimisticLock,\n SALES_RESOURCE_KIND_ORDER,\n} from './shared'\nimport { resolveDictionaryEntryValue } from '../lib/dictionaries'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst shipmentCrudEvents: CrudEventsConfig = {\n module: 'sales',\n entity: 'shipment',\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 ADDRESS_SNAPSHOT_KEY = 'shipmentAddressSnapshot'\n\nexport type ShipmentSnapshot = {\n id: string\n orderId: string\n organizationId: string\n tenantId: string\n shipmentNumber: string | null\n shippingMethodId: string | null\n statusEntryId: string | null\n status: string | null\n carrierName: string | null\n trackingNumbers: string[] | null\n shippedAt: string | null\n deliveredAt: string | null\n weightValue: number | null\n weightUnit: string | null\n declaredValueNet: number | null\n declaredValueGross: number | null\n currencyCode: string | null\n notesText: string | null\n metadata: Record<string, unknown> | null\n customFields?: Record<string, unknown> | null\n items: ShipmentItemSnapshot[]\n itemsSnapshot?: ShipmentItemSnapshot[] | null\n}\n\ntype ShipmentUndoPayload = {\n before?: ShipmentSnapshot | null\n after?: ShipmentSnapshot | null\n}\n\nconst buildShipmentCreateRedoInput = (snapshot: ShipmentSnapshot): ShipmentCreateInput => ({\n orderId: snapshot.orderId,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n shipmentNumber: snapshot.shipmentNumber ?? undefined,\n shippingMethodId: snapshot.shippingMethodId ?? undefined,\n statusEntryId: snapshot.statusEntryId ?? undefined,\n carrierName: snapshot.carrierName ?? undefined,\n trackingNumbers: snapshot.trackingNumbers ?? undefined,\n shippedAt: snapshot.shippedAt ? new Date(snapshot.shippedAt) : undefined,\n deliveredAt: snapshot.deliveredAt ? new Date(snapshot.deliveredAt) : undefined,\n weightValue: snapshot.weightValue ?? undefined,\n weightUnit: snapshot.weightUnit ?? undefined,\n declaredValueNet: snapshot.declaredValueNet ?? undefined,\n declaredValueGross: snapshot.declaredValueGross ?? undefined,\n currencyCode: snapshot.currencyCode ?? undefined,\n notes: snapshot.notesText ?? undefined,\n metadata: snapshot.metadata ? cloneJson(snapshot.metadata) : undefined,\n customFields: snapshot.customFields ? cloneJson(snapshot.customFields) : undefined,\n items: snapshot.items.map((item) => ({\n orderLineId: item.orderLineId,\n quantity: item.quantity,\n metadata: item.metadata ? cloneJson(item.metadata) : undefined,\n })),\n})\n\nconst parseTrackingNumbers = (input: unknown): string[] | null => {\n if (typeof input === 'string') {\n const entries = input\n .split(/[\\n,]/g)\n .map((value) => value.trim())\n .filter((value) => value.length > 0)\n return entries.length ? entries : null\n }\n if (Array.isArray(input)) {\n const entries = input\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value) => value.length > 0)\n return entries.length ? entries : null\n }\n return null\n}\n\nconst normalizeCustomFieldsInput = (input: unknown): Record<string, unknown> =>\n input && typeof input === 'object' && !Array.isArray(input) ? (input as Record<string, unknown>) : {}\n\nconst resolveLogger = (ctx: any): { warn?: (meta: any, message?: string) => void } | null => {\n const container = ctx?.container as any\n if (!container) return null\n const cradleLogger = container?.cradle?.logger ?? null\n if (cradleLogger?.warn) return cradleLogger\n const hasRegistration = typeof container.hasRegistration === 'function' ? container.hasRegistration.bind(container) : null\n if (hasRegistration?.('logger')) {\n const logger = container.resolve('logger')\n if (logger?.warn) return logger\n }\n if (hasRegistration?.('coreLogger')) {\n const logger = container.resolve('coreLogger')\n if (logger?.warn) return logger\n }\n return null\n}\n\nconst logShipmentDeleteScopeRejection = (\n ctx: any,\n reason: string,\n meta: Record<string, unknown>\n): void => {\n const logger = resolveLogger(ctx)\n const payload = { ...meta, command: 'sales.shipments.delete' }\n if (logger?.warn) {\n logger.warn(payload, reason)\n return\n }\n // eslint-disable-next-line no-console\n console.warn(`[sales.shipments.delete] ${reason}`, payload)\n}\n\nexport async function loadShipmentSnapshot(em: EntityManager, id: string): Promise<ShipmentSnapshot | null> {\n const shipment = await em.findOne(\n SalesShipment,\n { id },\n { populate: ['order', 'items', 'items.orderLine'] }\n )\n if (!shipment || !shipment.order) return null\n const storedSnapshot = readShipmentItemsSnapshot(\n (shipment as any).itemsSnapshot ?? (shipment as any).items_snapshot ?? null\n )\n const lineMap = new Map(\n Array.from(shipment.items ?? [])\n .map((item) => {\n const line = typeof item.orderLine === 'string' ? null : (item.orderLine as SalesOrderLine | null)\n return line ? [line.id, line] : null\n })\n .filter((entry): entry is [string, SalesOrderLine] => Boolean(entry))\n )\n const fallbackItems = buildShipmentItemSnapshots(Array.from(shipment.items ?? []), { lineMap })\n const itemsSnapshot = storedSnapshot.length ? storedSnapshot : fallbackItems\n const customFieldValues = await loadCustomFieldValues({\n em,\n entityId: E.sales.sales_shipment,\n recordIds: [shipment.id],\n tenantIdByRecord: { [shipment.id]: shipment.tenantId ?? null },\n organizationIdByRecord: { [shipment.id]: shipment.organizationId ?? null },\n })\n const customFields = customFieldValues[shipment.id]\n return {\n id: shipment.id,\n orderId: typeof shipment.order === 'string' ? shipment.order : shipment.order.id,\n organizationId: shipment.organizationId,\n tenantId: shipment.tenantId,\n shipmentNumber: shipment.shipmentNumber ?? null,\n shippingMethodId: shipment.shippingMethodId ?? null,\n statusEntryId: shipment.statusEntryId ?? null,\n status: shipment.status ?? null,\n carrierName: shipment.carrierName ?? null,\n trackingNumbers: shipment.trackingNumbers ? [...shipment.trackingNumbers] : null,\n shippedAt: shipment.shippedAt ? shipment.shippedAt.toISOString() : null,\n deliveredAt: shipment.deliveredAt ? shipment.deliveredAt.toISOString() : null,\n weightValue: shipment.weightValue !== undefined && shipment.weightValue !== null ? Number(shipment.weightValue) : null,\n weightUnit: shipment.weightUnit ?? null,\n declaredValueNet:\n shipment.declaredValueNet !== undefined && shipment.declaredValueNet !== null\n ? Number(shipment.declaredValueNet)\n : null,\n declaredValueGross:\n shipment.declaredValueGross !== undefined && shipment.declaredValueGross !== null\n ? Number(shipment.declaredValueGross)\n : null,\n currencyCode: shipment.currencyCode ?? null,\n notesText: shipment.notesText ?? null,\n metadata: shipment.metadata ? cloneJson(shipment.metadata) : null,\n customFields: customFields && Object.keys(customFields).length ? customFields : null,\n items: itemsSnapshot,\n itemsSnapshot,\n }\n}\n\nexport async function restoreShipmentSnapshot(em: EntityManager, snapshot: ShipmentSnapshot): Promise<void> {\n const order = await findOneWithDecryption(em, SalesOrder, { id: snapshot.orderId }, {}, { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId })\n if (!order) return\n const existing = await em.findOne(SalesShipment, { id: snapshot.id })\n const entity =\n existing ??\n em.create(SalesShipment, {\n id: snapshot.id,\n createdAt: new Date(),\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n })\n entity.order = order\n entity.organizationId = snapshot.organizationId\n entity.tenantId = snapshot.tenantId\n entity.shipmentNumber = snapshot.shipmentNumber ?? null\n entity.shippingMethodId = snapshot.shippingMethodId ?? null\n entity.statusEntryId = snapshot.statusEntryId ?? null\n entity.status = snapshot.status ?? null\n entity.carrierName = snapshot.carrierName ?? null\n entity.trackingNumbers = snapshot.trackingNumbers ? [...snapshot.trackingNumbers] : null\n entity.shippedAt = snapshot.shippedAt ? new Date(snapshot.shippedAt) : null\n entity.deliveredAt = snapshot.deliveredAt ? new Date(snapshot.deliveredAt) : null\n entity.weightValue = snapshot.weightValue !== null ? snapshot.weightValue.toString() : null\n entity.weightUnit = snapshot.weightUnit ?? null\n entity.declaredValueNet = snapshot.declaredValueNet !== null ? snapshot.declaredValueNet.toString() : null\n entity.declaredValueGross = snapshot.declaredValueGross !== null ? snapshot.declaredValueGross.toString() : null\n entity.currencyCode = snapshot.currencyCode ?? null\n entity.notesText = snapshot.notesText ?? null\n entity.metadata = snapshot.metadata ? cloneJson(snapshot.metadata) : null\n entity.updatedAt = new Date()\n em.persist(entity)\n await em.flush()\n\n const existingItems = await em.find(SalesShipmentItem, { shipment: entity })\n existingItems.forEach((item) => em.remove(item))\n const items = Array.isArray(snapshot.items) ? snapshot.items : []\n const lineIds = items\n .map((item) => item.orderLineId)\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n const lines = lineIds.length\n ? await em.find(SalesOrderLine, { id: { $in: lineIds }, order: order.id })\n : []\n const lineMap = new Map(lines.map((line) => [line.id, line]))\n const restoredItems: ShipmentItemSnapshot[] = []\n items.forEach((item) => {\n const line = lineMap.get(item.orderLineId)\n if (!line) return\n restoredItems.push(item)\n const lineRef = em.getReference(SalesOrderLine, line.id)\n const shipmentItem = em.create(SalesShipmentItem, {\n id: item.id ?? randomUUID(),\n shipment: entity,\n orderLine: lineRef,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n quantity: item.quantity.toString(),\n metadata: item.metadata ? cloneJson(item.metadata) : null,\n })\n em.persist(shipmentItem)\n })\n const snapshotItems = (snapshot.itemsSnapshot ?? restoredItems).filter((entry) =>\n entry?.orderLineId ? lineMap.has(entry.orderLineId) : false\n )\n entity.itemsSnapshot = snapshotItems && snapshotItems.length ? cloneJson(snapshotItems) : null\n if (!entity.itemsSnapshot) {\n await refreshShipmentItemsSnapshot(em, entity)\n }\n if ((snapshot as any).customFields !== undefined) {\n await setRecordCustomFields(em, {\n entityId: E.sales.sales_shipment,\n recordId: entity.id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n values: normalizeCustomFieldsInput((snapshot as any).customFields),\n })\n }\n em.persist(entity)\n}\n\nasync function deleteShipmentWithItems(em: EntityManager, shipment: SalesShipment): Promise<void> {\n const scope = { tenantId: shipment.tenantId, organizationId: shipment.organizationId }\n const items = await findWithDecryption(em, SalesShipmentItem, { shipment }, {}, scope)\n items.forEach((item) => em.remove(item))\n em.remove(shipment)\n await em.flush()\n}\n\nasync function recomputeFulfilledQuantities(em: EntityManager, order: SalesOrder): Promise<void> {\n const scope = { tenantId: order.tenantId, organizationId: order.organizationId }\n const shipments = await findWithDecryption(em, SalesShipment, { order, deletedAt: null }, {}, scope)\n const shipmentIds = shipments.map((entry) => entry.id)\n const shipmentItems = shipmentIds.length\n ? await findWithDecryption(em, SalesShipmentItem, { shipment: { $in: shipmentIds } }, {}, scope)\n : []\n const totals = shipmentItems.reduce<Map<string, number>>((acc, item) => {\n const lineId =\n typeof item.orderLine === 'string'\n ? item.orderLine\n : item.orderLine?.id ?? (item as any).orderLineId ?? null\n if (!lineId) return acc\n const next = (acc.get(lineId) ?? 0) + toNumber(item.quantity)\n acc.set(lineId, next)\n return acc\n }, new Map())\n const lines = await findWithDecryption(em, SalesOrderLine, { order }, { lockMode: LockMode.PESSIMISTIC_WRITE }, scope)\n lines.forEach((line) => {\n const shipped = totals.get(line.id) ?? 0\n line.fulfilledQuantity = shipped.toString()\n })\n}\n\nasync function loadOrder(\n em: EntityManager,\n id: string,\n scope?: { tenantId: string; organizationId: string }\n): Promise<SalesOrder> {\n const order = await findOneWithDecryption(em, SalesOrder, { id, deletedAt: null }, {}, scope)\n if (!order) throw new CrudHttpError(404, { error: 'sales.shipments.not_found' })\n return order\n}\n\nasync function loadShippedTotals(\n em: EntityManager,\n order: SalesOrder,\n excludeShipmentId?: string | null\n): Promise<Map<string, number>> {\n const scope = { tenantId: order.tenantId, organizationId: order.organizationId }\n const shipments = await findWithDecryption(em, SalesShipment, { order, deletedAt: null }, {}, scope)\n const shipmentIds = shipments\n .map((entry) => entry.id)\n .filter((id) => !excludeShipmentId || id !== excludeShipmentId)\n if (!shipmentIds.length) return new Map()\n const items = await findWithDecryption(em, SalesShipmentItem, { shipment: { $in: shipmentIds } }, {}, scope)\n return items.reduce<Map<string, number>>((acc, item) => {\n const lineId =\n typeof item.orderLine === 'string'\n ? item.orderLine\n : item.orderLine?.id ?? (item as any).orderLineId ?? null\n if (!lineId) return acc\n const next = (acc.get(lineId) ?? 0) + toNumber(item.quantity)\n acc.set(lineId, next)\n return acc\n }, new Map())\n}\n\nasync function validateShipmentItems(params: {\n em: EntityManager\n order: SalesOrder\n items?: ShipmentCreateInput['items']\n excludeShipmentId?: string | null\n lockOrderLines?: boolean\n}): Promise<{\n items: Array<{ orderLineId: string; quantity: number; metadata: Record<string, unknown> | null }>\n lineMap: Map<string, SalesOrderLine>\n}> {\n const { em, order, items, excludeShipmentId, lockOrderLines } = params\n const { translate } = await resolveTranslations()\n if (!items || !items.length) {\n throw new CrudHttpError(400, { error: translate('sales.shipments.items_required', 'Add at least one line to ship.') })\n }\n const scope = { tenantId: order.tenantId, organizationId: order.organizationId }\n const orderLines = await findWithDecryption(\n em,\n SalesOrderLine,\n { order },\n lockOrderLines ? { lockMode: LockMode.PESSIMISTIC_WRITE } : undefined,\n scope,\n )\n const lineMap = new Map(orderLines.map((line) => [line.id, line]))\n const shippedTotals = await loadShippedTotals(em, order, excludeShipmentId)\n const requestedTotals = new Map<string, number>()\n\n for (const item of items) {\n const lineId = item.orderLineId\n const quantity = toNumber(item.quantity)\n if (!lineId || quantity <= 0) {\n throw new CrudHttpError(400, { error: translate('sales.shipments.items_required', 'Add at least one line to ship.') })\n }\n const line = lineMap.get(lineId)\n if (!line) {\n throw new CrudHttpError(404, { error: translate('sales.shipments.line_missing', 'Order line not found.') })\n }\n const lineTotal = toNumber(line.quantity)\n const alreadyShipped = shippedTotals.get(lineId) ?? 0\n const nextTotal = (requestedTotals.get(lineId) ?? 0) + quantity\n if (nextTotal + alreadyShipped - 1e-6 > lineTotal) {\n throw new CrudHttpError(400, { error: translate('sales.shipments.quantity_exceeded', 'Cannot ship more than the remaining quantity.') })\n }\n requestedTotals.set(lineId, nextTotal)\n }\n\n return {\n items: items.map((item) => ({\n orderLineId: item.orderLineId,\n quantity: toNumber(item.quantity),\n metadata: item.metadata ? cloneJson(item.metadata) : null,\n })),\n lineMap,\n }\n}\n\nfunction mergeAddressSnapshot(\n baseMetadata: Record<string, unknown> | null | undefined,\n snapshot: Record<string, unknown> | null | undefined\n): Record<string, unknown> | null {\n const metadata = baseMetadata ? { ...baseMetadata } : {}\n if (snapshot && typeof snapshot === 'object') {\n metadata[ADDRESS_SNAPSHOT_KEY] = cloneJson(snapshot)\n }\n return Object.keys(metadata).length ? metadata : null\n}\n\nconst createShipmentCommand: CommandHandler<ShipmentCreateInput, { shipmentId: string }> = {\n id: 'sales.shipments.create',\n async execute(rawInput, ctx) {\n const input = shipmentCreateSchema.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 const shipment = await em.transactional(async (tx) => {\n const order = await loadOrder(tx, input.orderId, { tenantId: input.tenantId, organizationId: input.organizationId })\n ensureSameScope(order, input.organizationId, input.tenantId)\n // Guard the parent order's aggregate version (Gap B): a shipment mutation\n // recalculates the order's fulfilled quantities, so a stale parent must 409\n // before we touch it.\n await enforceSalesDocumentOptimisticLock(ctx, order, SALES_RESOURCE_KIND_ORDER)\n const { items: normalizedItems, lineMap } = await validateShipmentItems({\n em: tx,\n order,\n items: input.items,\n lockOrderLines: true,\n })\n const statusValue = await resolveDictionaryEntryValue(tx, input.statusEntryId ?? null, { tenantId: input.tenantId })\n const trackingNumbers = parseTrackingNumbers(input.trackingNumbers) ?? null\n const metadata =\n mergeAddressSnapshot(\n input.metadata ? cloneJson(input.metadata) : null,\n input.shipmentAddressSnapshot ?? order.shippingAddressSnapshot ?? null\n ) ?? null\n\n const shipmentId = randomUUID()\n const entity = tx.create(SalesShipment, {\n id: shipmentId,\n order,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n shipmentNumber: input.shipmentNumber ?? null,\n shippingMethodId: input.shippingMethodId ?? null,\n statusEntryId: input.statusEntryId ?? null,\n status: statusValue,\n carrierName: input.carrierName ?? null,\n trackingNumbers,\n shippedAt: input.shippedAt ?? null,\n deliveredAt: input.deliveredAt ?? null,\n weightValue: input.weightValue !== undefined ? input.weightValue.toString() : null,\n weightUnit: input.weightUnit ?? null,\n declaredValueNet: input.declaredValueNet !== undefined ? input.declaredValueNet.toString() : null,\n declaredValueGross: input.declaredValueGross !== undefined ? input.declaredValueGross.toString() : null,\n currencyCode: input.currencyCode ?? order.currencyCode ?? null,\n notesText: input.notes ?? null,\n metadata,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n const createdItems: SalesShipmentItem[] = []\n normalizedItems.forEach((item) => {\n const lineRef = tx.getReference(SalesOrderLine, item.orderLineId)\n const shipmentItem = tx.create(SalesShipmentItem, {\n id: randomUUID(),\n shipment: entity,\n orderLine: lineRef,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n quantity: item.quantity.toString(),\n metadata: item.metadata ? cloneJson(item.metadata) : null,\n })\n createdItems.push(shipmentItem)\n tx.persist(shipmentItem)\n })\n tx.persist(entity)\n if (input.customFields !== undefined) {\n await setRecordCustomFields(tx, {\n entityId: E.sales.sales_shipment,\n recordId: entity.id,\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n values: normalizeCustomFieldsInput(input.customFields),\n })\n }\n if (input.documentStatusEntryId !== undefined) {\n const orderStatus = await resolveDictionaryEntryValue(tx, input.documentStatusEntryId ?? null, { tenantId: input.tenantId })\n if (input.documentStatusEntryId && !orderStatus) {\n throw new CrudHttpError(400, { error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.') })\n }\n order.statusEntryId = input.documentStatusEntryId ?? null\n order.status = orderStatus\n order.updatedAt = new Date()\n }\n if (input.lineStatusEntryId !== undefined) {\n const lineStatus = await resolveDictionaryEntryValue(tx, input.lineStatusEntryId ?? null, { tenantId: input.tenantId })\n if (input.lineStatusEntryId && !lineStatus) {\n throw new CrudHttpError(400, { error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.') })\n }\n const uniqueLineIds = Array.from(new Set(normalizedItems.map((item) => item.orderLineId)))\n uniqueLineIds.forEach((lineId) => {\n const line = lineMap.get(lineId)\n if (!line) return\n line.statusEntryId = input.lineStatusEntryId ?? null\n line.status = lineStatus\n line.updatedAt = new Date()\n })\n }\n await refreshShipmentItemsSnapshot(tx, entity, { items: createdItems, lineMap })\n await tx.flush()\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n return entity\n })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'created',\n entity: shipment,\n identifiers: {\n id: shipment.id,\n organizationId: shipment.organizationId,\n tenantId: shipment.tenantId,\n },\n indexer: { entityType: E.sales.sales_shipment },\n events: shipmentCrudEvents,\n })\n\n return { shipmentId: shipment.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadShipmentSnapshot(em, result.shipmentId)\n },\n buildLog: async ({ result, snapshots }) => {\n const after = snapshots.after as ShipmentSnapshot | undefined\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('sales.audit.shipments.create', 'Create shipment'),\n resourceKind: 'sales.shipment',\n resourceId: result.shipmentId,\n parentResourceKind: 'sales.order',\n parentResourceId: after.orderId ?? null,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n snapshotAfter: after,\n payload: {\n undo: { after } satisfies ShipmentUndoPayload,\n __redoInput: buildShipmentCreateRedoInput(after),\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ShipmentUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await em.transactional(async (tx) => {\n const existing = await findOneWithDecryption(\n tx,\n SalesShipment,\n { id: after.id },\n { populate: ['order'] },\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n if (!existing) return\n const order = existing.order as SalesOrder | null\n await deleteShipmentWithItems(tx, existing)\n if (order) {\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n }\n })\n },\n redo: async ({ ctx, logEntry }) => {\n const after = resolveRedoSnapshot<ShipmentSnapshot>(logEntry)\n const shipmentId = after?.id ?? logEntry.resourceId ?? null\n if (!after || !shipmentId) {\n throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for sales.shipments.create' })\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await em.transactional(async (tx) => {\n await restoreShipmentSnapshot(tx, after)\n const order = await findOneWithDecryption(tx, SalesOrder, { id: after.orderId }, {}, { tenantId: after.tenantId, organizationId: after.organizationId })\n await tx.flush()\n if (order) {\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n }\n })\n\n const shipment = await findOneWithDecryption(\n em,\n SalesShipment,\n { id: after.id },\n {},\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'created',\n entity: shipment,\n identifiers: {\n id: after.id,\n organizationId: after.organizationId,\n tenantId: after.tenantId,\n },\n indexer: { entityType: E.sales.sales_shipment },\n events: shipmentCrudEvents,\n })\n\n return { shipmentId: after.id }\n },\n}\n\nconst updateShipmentCommand: CommandHandler<ShipmentUpdateInput, { shipmentId: string }> = {\n id: 'sales.shipments.update',\n async prepare(rawInput, ctx) {\n const parsed = shipmentUpdateSchema.parse(rawInput ?? {})\n if (!parsed.id) return {}\n const em = ctx.container.resolve('em') as EntityManager\n const snapshot = await loadShipmentSnapshot(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 = shipmentUpdateSchema.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\n const shipment = await em.transactional(async (tx) => {\n const shipmentEntity = await findOneWithDecryption(\n tx,\n SalesShipment,\n { id: input.id },\n { populate: ['order'] },\n { tenantId: input.tenantId, organizationId: input.organizationId },\n )\n if (!shipmentEntity || !shipmentEntity.order) {\n throw new CrudHttpError(404, { error: 'sales.shipments.not_found' })\n }\n ensureSameScope(shipmentEntity, input.organizationId, input.tenantId)\n const order = shipmentEntity.order as SalesOrder\n if (input.orderId && input.orderId !== order.id) {\n throw new CrudHttpError(400, { error: 'sales.shipments.invalid_order' })\n }\n // Guard the parent order's aggregate version (Gap B): updating a shipment\n // recalculates the order's fulfilled quantities, so a stale parent must 409\n // before we touch it.\n await enforceSalesDocumentOptimisticLock(ctx, order, SALES_RESOURCE_KIND_ORDER)\n\n // Check if order is financially closed - prevent modifications to shipments\n const paidAmount = parseFloat(order.paidTotalAmount || '0')\n const refundedAmount = parseFloat(order.refundedTotalAmount || '0')\n const grandTotal = parseFloat(order.grandTotalGrossAmount || '0')\n const tolerance = 1e-4 // Tolerance for floating-point comparisons\n\n // Check for full refund first (higher priority than payment)\n const isFullyRefunded = refundedAmount >= grandTotal - tolerance\n if (isFullyRefunded) {\n throw new CrudHttpError(422, { error: translate('sales.shipments.fully_returned', 'Cannot modify shipment: order is fully returned') })\n }\n\n // Check for completed payment\n const isFullyPaid = paidAmount >= grandTotal - tolerance\n if (isFullyPaid) {\n throw new CrudHttpError(422, { error: translate('sales.shipments.payment_completed', 'Cannot modify shipment: order payment is completed') })\n }\n const validatedItems = input.items\n ? await validateShipmentItems({\n em: tx,\n order,\n items: input.items,\n excludeShipmentId: shipmentEntity.id,\n })\n : null\n const normalizedItems = validatedItems?.items ?? null\n const lineMap = validatedItems?.lineMap ?? new Map<string, SalesOrderLine>()\n // Resolve the status label BEFORE mutating shipment scalars so this\n // dictionary read does not interleave with (and drop) the pending\n // shipment changeset under MikroORM v7 (SPEC-018 / #2453 class).\n const resolvedShipmentStatus = input.statusEntryId !== undefined\n ? await resolveDictionaryEntryValue(tx, input.statusEntryId ?? null, { tenantId: shipmentEntity.tenantId })\n : undefined\n if (input.shipmentNumber !== undefined) shipmentEntity.shipmentNumber = input.shipmentNumber ?? null\n if (input.shippingMethodId !== undefined) shipmentEntity.shippingMethodId = input.shippingMethodId ?? null\n if (input.statusEntryId !== undefined) {\n shipmentEntity.statusEntryId = input.statusEntryId ?? null\n shipmentEntity.status = resolvedShipmentStatus ?? null\n }\n if (input.carrierName !== undefined) shipmentEntity.carrierName = input.carrierName ?? null\n if (input.trackingNumbers !== undefined) shipmentEntity.trackingNumbers = parseTrackingNumbers(input.trackingNumbers)\n if (input.shippedAt !== undefined) shipmentEntity.shippedAt = input.shippedAt ?? null\n if (input.deliveredAt !== undefined) shipmentEntity.deliveredAt = input.deliveredAt ?? null\n if (input.weightValue !== undefined) shipmentEntity.weightValue = input.weightValue !== null ? input.weightValue.toString() : null\n if (input.weightUnit !== undefined) shipmentEntity.weightUnit = input.weightUnit ?? null\n if (input.declaredValueNet !== undefined) {\n shipmentEntity.declaredValueNet = input.declaredValueNet !== null ? input.declaredValueNet.toString() : null\n }\n if (input.declaredValueGross !== undefined) {\n shipmentEntity.declaredValueGross = input.declaredValueGross !== null ? input.declaredValueGross.toString() : null\n }\n if (input.currencyCode !== undefined) shipmentEntity.currencyCode = input.currencyCode ?? null\n if (input.notes !== undefined) shipmentEntity.notesText = input.notes ?? null\n if (input.metadata !== undefined || input.shipmentAddressSnapshot !== undefined) {\n shipmentEntity.metadata = mergeAddressSnapshot(\n input.metadata ? cloneJson(input.metadata) : shipmentEntity.metadata ?? null,\n input.shipmentAddressSnapshot\n )\n }\n shipmentEntity.updatedAt = new Date()\n\n // Persist the shipment scalar mutations before the item reads below run on\n // the same EntityManager. Under MikroORM v7 an interleaved query (the\n // findWithDecryption on SalesShipmentItem here and in the snapshot step)\n // resets the identity-map changeset, so shippingMethodId/status/carrier/etc.\n // would silently not persist even though the write returns 200 (#2453).\n await tx.flush()\n\n const shouldLoadItems = Boolean(normalizedItems || input.lineStatusEntryId !== undefined)\n const existingItems = shouldLoadItems ? await findWithDecryption(tx, SalesShipmentItem, { shipment: shipmentEntity }, {}, { tenantId: shipmentEntity.tenantId, organizationId: shipmentEntity.organizationId }) : []\n const newItems: SalesShipmentItem[] = []\n if (normalizedItems) {\n existingItems.forEach((item) => tx.remove(item))\n normalizedItems.forEach((item) => {\n const lineRef = tx.getReference(SalesOrderLine, item.orderLineId)\n const shipmentItem = tx.create(SalesShipmentItem, {\n id: randomUUID(),\n shipment: shipmentEntity,\n orderLine: lineRef,\n organizationId: shipmentEntity.organizationId,\n tenantId: shipmentEntity.tenantId,\n quantity: item.quantity.toString(),\n metadata: item.metadata ? cloneJson(item.metadata) : null,\n })\n newItems.push(shipmentItem)\n tx.persist(shipmentItem)\n })\n }\n\n if (input.customFields !== undefined) {\n await setRecordCustomFields(tx, {\n entityId: E.sales.sales_shipment,\n recordId: shipmentEntity.id,\n organizationId: shipmentEntity.organizationId,\n tenantId: shipmentEntity.tenantId,\n values: normalizeCustomFieldsInput(input.customFields),\n })\n }\n if (input.documentStatusEntryId !== undefined) {\n const orderStatus = await resolveDictionaryEntryValue(tx, input.documentStatusEntryId ?? null, { tenantId: shipmentEntity.tenantId })\n if (input.documentStatusEntryId && !orderStatus) {\n throw new CrudHttpError(400, { error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.') })\n }\n order.statusEntryId = input.documentStatusEntryId ?? null\n order.status = orderStatus\n order.updatedAt = new Date()\n }\n if (input.lineStatusEntryId !== undefined) {\n const lineStatus = await resolveDictionaryEntryValue(tx, input.lineStatusEntryId ?? null, { tenantId: shipmentEntity.tenantId })\n if (input.lineStatusEntryId && !lineStatus) {\n throw new CrudHttpError(400, { error: translate('sales.documents.detail.statusInvalid', 'Selected status could not be found.') })\n }\n const targetLineIds = normalizedItems\n ? Array.from(new Set(normalizedItems.map((item) => item.orderLineId)))\n : Array.from(\n new Set(\n existingItems\n .map((item) =>\n typeof item.orderLine === 'string'\n ? item.orderLine\n : (item.orderLine as SalesOrderLine | null)?.id ?? null\n )\n .filter((id): id is string => Boolean(id))\n )\n )\n if (targetLineIds.length) {\n const missing = targetLineIds.filter((id) => !lineMap.has(id))\n if (missing.length) {\n const fetched = await tx.find(SalesOrderLine, { id: { $in: missing } })\n fetched.forEach((line) => lineMap.set(line.id, line))\n }\n targetLineIds.forEach((lineId) => {\n const line = lineMap.get(lineId)\n if (!line) return\n line.statusEntryId = input.lineStatusEntryId ?? null\n line.status = lineStatus\n line.updatedAt = new Date()\n })\n }\n }\n\n // Flush any order/line status mutations applied above before the snapshot\n // read below queries the same EntityManager (same interleaved-read hazard).\n await tx.flush()\n const itemsForSnapshot =\n normalizedItems || shouldLoadItems\n ? (normalizedItems ? newItems : existingItems)\n : await findWithDecryption(tx, SalesShipmentItem, { shipment: shipmentEntity }, {}, { tenantId: shipmentEntity.tenantId, organizationId: shipmentEntity.organizationId })\n await refreshShipmentItemsSnapshot(tx, shipmentEntity, { items: itemsForSnapshot, lineMap })\n await tx.flush()\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n return shipmentEntity\n })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'updated',\n entity: shipment,\n identifiers: {\n id: shipment.id,\n organizationId: shipment.organizationId,\n tenantId: shipment.tenantId,\n },\n indexer: { entityType: E.sales.sales_shipment },\n events: shipmentCrudEvents,\n })\n\n return { shipmentId: shipment.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadShipmentSnapshot(em, result.shipmentId)\n },\n buildLog: async ({ snapshots, result }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as ShipmentSnapshot | undefined\n const after = snapshots.after as ShipmentSnapshot | undefined\n return {\n actionLabel: translate('sales.audit.shipments.update', 'Update shipment'),\n resourceKind: 'sales.shipment',\n resourceId: result.shipmentId,\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: {\n undo: { before, after } satisfies ShipmentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ShipmentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await em.transactional(async (tx) => {\n await restoreShipmentSnapshot(tx, before)\n const order = await findOneWithDecryption(tx, SalesOrder, { id: before.orderId }, {}, { tenantId: before.tenantId, organizationId: before.organizationId })\n await tx.flush()\n if (order) {\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n }\n })\n },\n}\n\nconst deleteShipmentCommand: CommandHandler<\n { id: string; orderId: string; organizationId: string; tenantId: string },\n { shipmentId: string }\n> = {\n id: 'sales.shipments.delete',\n async prepare(rawInput, ctx) {\n const parsed = shipmentUpdateSchema.parse(rawInput ?? {})\n if (!parsed.id) return {}\n const em = ctx.container.resolve('em') as EntityManager\n const snapshot = await loadShipmentSnapshot(em, parsed.id)\n if (snapshot) {\n try {\n ensureTenantScope(ctx, snapshot.tenantId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Tenant mismatch while preparing shipment delete', {\n shipmentId: snapshot.id,\n snapshotTenantId: snapshot.tenantId,\n authTenantId: ctx.auth?.tenantId ?? null,\n })\n throw error\n }\n try {\n ensureOrganizationScope(ctx, snapshot.organizationId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Organization mismatch while preparing shipment delete', {\n shipmentId: snapshot.id,\n snapshotOrganizationId: snapshot.organizationId,\n selectedOrganizationId: ctx.selectedOrganizationId ?? null,\n authOrganizationId: ctx.auth?.orgId ?? null,\n })\n throw error\n }\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const { translate } = await resolveTranslations()\n const payload = shipmentUpdateSchema\n .pick({ id: true, orderId: true, organizationId: true, tenantId: true })\n .parse(rawInput ?? {})\n try {\n ensureTenantScope(ctx, payload.tenantId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Tenant mismatch while executing shipment delete', {\n shipmentId: payload.id,\n payloadTenantId: payload.tenantId,\n authTenantId: ctx.auth?.tenantId ?? null,\n })\n throw error\n }\n try {\n ensureOrganizationScope(ctx, payload.organizationId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Organization mismatch while executing shipment delete', {\n shipmentId: payload.id,\n payloadOrganizationId: payload.organizationId,\n selectedOrganizationId: ctx.selectedOrganizationId ?? null,\n authOrganizationId: ctx.auth?.orgId ?? null,\n })\n throw error\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n\n const { shipment, shipmentItems } = await em.transactional(async (tx) => {\n const shipmentEntity = await findOneWithDecryption(\n tx,\n SalesShipment,\n { id: payload.id },\n { populate: ['order'] },\n { tenantId: payload.tenantId, organizationId: payload.organizationId },\n )\n if (!shipmentEntity || !shipmentEntity.order) {\n throw new CrudHttpError(404, { error: translate('sales.shipments.not_found', 'Shipment not found') })\n }\n try {\n ensureSameScope(shipmentEntity, payload.organizationId, payload.tenantId)\n } catch (error) {\n logShipmentDeleteScopeRejection(ctx, 'Shipment scope mismatch against payload', {\n shipmentId: payload.id,\n shipmentOrganizationId: shipmentEntity.organizationId,\n shipmentTenantId: shipmentEntity.tenantId,\n payloadOrganizationId: payload.organizationId,\n payloadTenantId: payload.tenantId,\n })\n throw error\n }\n const order = shipmentEntity.order as SalesOrder\n if (order.id !== payload.orderId) {\n throw new CrudHttpError(400, { error: translate('sales.shipments.invalid_order', 'Shipment does not belong to this order') })\n }\n // Guard the parent order's aggregate version (Gap B): deleting a shipment\n // recalculates the order's fulfilled quantities, so a stale parent must 409\n // before we touch it.\n await enforceSalesDocumentOptimisticLock(ctx, order, SALES_RESOURCE_KIND_ORDER)\n const scope = { tenantId: shipmentEntity.tenantId, organizationId: shipmentEntity.organizationId }\n const items = await findWithDecryption(tx, SalesShipmentItem, { shipment: shipmentEntity }, {}, scope)\n items.forEach((item) => tx.remove(item))\n tx.remove(shipmentEntity)\n await tx.flush()\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n return { shipment: shipmentEntity, shipmentItems: items }\n })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: shipment,\n identifiers: {\n id: shipment.id,\n organizationId: shipment.organizationId,\n tenantId: shipment.tenantId,\n },\n indexer: { entityType: E.sales.sales_shipment },\n events: shipmentCrudEvents,\n })\n if (shipmentItems.length) {\n await Promise.all(\n shipmentItems.map((item) =>\n emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: item,\n identifiers: {\n id: item.id,\n organizationId: item.organizationId ?? null,\n tenantId: item.tenantId ?? null,\n },\n indexer: { entityType: E.sales.sales_shipment_item },\n })\n )\n )\n }\n return { shipmentId: shipment.id }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<ShipmentUndoPayload>(logEntry)\n const snapshot = payload?.before ?? null\n if (!snapshot) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n await em.transactional(async (tx) => {\n await restoreShipmentSnapshot(tx, snapshot)\n const order = await findOneWithDecryption(tx, SalesOrder, { id: snapshot.orderId }, {}, { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId })\n await tx.flush()\n if (order) {\n await recomputeFulfilledQuantities(tx, order)\n await tx.flush()\n }\n })\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as ShipmentSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('sales.audit.shipments.delete', 'Delete shipment'),\n resourceKind: 'sales.shipment',\n resourceId: before.id ?? null,\n parentResourceKind: 'sales.order',\n parentResourceId: before.orderId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: { before } satisfies ShipmentUndoPayload,\n },\n }\n },\n}\n\nregisterCommand(createShipmentCommand)\nregisterCommand(updateShipmentCommand)\nregisterCommand(deleteShipmentCommand)\n\nexport const shipmentCommands = [createShipmentCommand, updateShipmentCommand, deleteShipmentCommand]\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -9,7 +9,7 @@ import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimi
|
|
|
9
9
|
import { collectCustomFieldValues } from "@open-mercato/ui/backend/utils/customFieldValues";
|
|
10
10
|
import { createCrud, updateCrud } from "@open-mercato/ui/backend/utils/crud";
|
|
11
11
|
import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
|
|
12
|
-
import { handleSectionMutationError
|
|
12
|
+
import { handleSectionMutationError } from "./optimisticLock.js";
|
|
13
13
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@open-mercato/ui/primitives/dialog";
|
|
14
14
|
import { useDialogKeyHandler } from "@open-mercato/ui/hooks/useDialogKeyHandler";
|
|
15
15
|
import { Input } from "@open-mercato/ui/primitives/input";
|
|
@@ -33,6 +33,7 @@ function PaymentDialog({
|
|
|
33
33
|
orderId,
|
|
34
34
|
organizationId,
|
|
35
35
|
tenantId,
|
|
36
|
+
documentUpdatedAt,
|
|
36
37
|
onOpenChange,
|
|
37
38
|
onSaved
|
|
38
39
|
}) {
|
|
@@ -428,7 +429,9 @@ function PaymentDialog({
|
|
|
428
429
|
const action = payment?.id ? updateCrud : createCrud;
|
|
429
430
|
try {
|
|
430
431
|
const result = await withScopedApiRequestHeaders(
|
|
431
|
-
|
|
432
|
+
// The server guards the PARENT order's aggregate version (Gap A) for
|
|
433
|
+
// both create and update, so send the order's `updated_at`.
|
|
434
|
+
buildOptimisticLockHeader(documentUpdatedAt ?? void 0),
|
|
432
435
|
() => action(
|
|
433
436
|
"sales/payments",
|
|
434
437
|
payment?.id ? { id: payment.id, ...payload } : payload,
|
|
@@ -455,7 +458,7 @@ function PaymentDialog({
|
|
|
455
458
|
throw err;
|
|
456
459
|
}
|
|
457
460
|
},
|
|
458
|
-
[currencyCode, mode, onOpenChange, onSaved, orderId, organizationId, payment?.id,
|
|
461
|
+
[currencyCode, documentUpdatedAt, mode, onOpenChange, onSaved, orderId, organizationId, payment?.id, t, tenantId]
|
|
459
462
|
);
|
|
460
463
|
const handleSubmitForm = React.useCallback(
|
|
461
464
|
() => dialogContentRef.current?.querySelector("form")?.requestSubmit(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/sales/components/documents/PaymentDialog.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { CreditCard } from 'lucide-react'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { LookupSelect, type LookupSelectItem } from '@open-mercato/ui/backend/inputs'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { createCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { handleSectionMutationError, rowOptimisticVersion } from './optimisticLock'\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { useDialogKeyHandler } from '@open-mercato/ui/hooks/useDialogKeyHandler'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { E } from '#generated/entities.ids.generated'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { normalizeCustomFieldSubmitValue, extractCustomFieldValues } from './customFieldHelpers'\n\nexport type PaymentTotals = {\n paidTotalAmount?: number | null\n refundedTotalAmount?: number | null\n outstandingAmount?: number | null\n}\n\nexport type PaymentFormData = {\n id?: string | null\n updatedAt?: string | null\n amount?: number | string | null\n paymentMethodId?: string | null\n paymentReference?: string | null\n receivedAt?: string | null\n currencyCode?: string | null\n statusEntryId?: string | null\n customValues?: Record<string, unknown> | null\n customFieldSetId?: string | null\n}\n\ntype PaymentMethodOption = {\n id: string\n name: string\n code: string\n}\n\ntype StatusOption = {\n id: string\n value: string\n label: string\n color: string | null\n}\n\ntype PaymentDialogProps = {\n open: boolean\n mode: 'create' | 'edit'\n payment?: PaymentFormData | null\n currencyCode: string | null | undefined\n orderId: string\n organizationId: string | null\n tenantId: string | null\n onOpenChange: (open: boolean) => void\n onSaved?: (totals?: PaymentTotals | null) => void | Promise<void>\n}\n\nconst 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\nexport function PaymentDialog({\n open,\n mode,\n payment,\n currencyCode,\n orderId,\n organizationId,\n tenantId,\n onOpenChange,\n onSaved,\n}: PaymentDialogProps) {\n const t = useT()\n const dialogContentRef = React.useRef<HTMLDivElement | null>(null)\n const [formResetKey, setFormResetKey] = React.useState(0)\n const [paymentMethods, setPaymentMethods] = React.useState<PaymentMethodOption[]>([])\n const [methodsLoading, setMethodsLoading] = React.useState(false)\n const [paymentStatuses, setPaymentStatuses] = React.useState<StatusOption[]>([])\n const [paymentStatusLoading, setPaymentStatusLoading] = React.useState(false)\n const [documentStatuses, setDocumentStatuses] = React.useState<StatusOption[]>([])\n const [documentStatusLoading, setDocumentStatusLoading] = React.useState(false)\n\n const currencyLabel = React.useMemo(() => {\n const code = currencyCode ? currencyCode.toUpperCase() : ''\n if (!code) return t('sales.documents.detail.empty', 'Not set')\n return code\n }, [currencyCode, t])\n\n const initialValues = React.useMemo(\n () => ({\n amount: payment?.amount ?? '',\n paymentMethodId: payment?.paymentMethodId ?? '',\n paymentReference: payment?.paymentReference ?? '',\n receivedAt: payment?.receivedAt ? payment.receivedAt.slice(0, 10) : '',\n statusEntryId: payment?.statusEntryId ?? '',\n documentStatusEntryId: '',\n customFieldSetId: payment?.customFieldSetId ?? '',\n ...extractCustomFieldValues(payment),\n }),\n [\n payment?.amount,\n payment?.customFieldSetId,\n payment?.customValues,\n payment?.paymentMethodId,\n payment?.paymentReference,\n payment?.receivedAt,\n payment?.statusEntryId,\n ],\n )\n\n const loadPaymentMethods = React.useCallback(\n async (query?: string): Promise<PaymentMethodOption[]> => {\n setMethodsLoading(true)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', isActive: 'true' })\n if (query && query.trim().length) params.set('search', query.trim())\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/payment-methods?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n if (response.ok && Array.isArray(response.result?.items)) {\n const options = response.result.items\n .map((item) => {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const name = typeof item.name === 'string' ? item.name : null\n const code = typeof item.code === 'string' ? item.code : null\n return {\n id,\n name: name ?? code ?? id,\n code: code ?? id,\n }\n })\n .filter((entry): entry is PaymentMethodOption => !!entry)\n if (!query) setPaymentMethods(options)\n return options\n }\n if (!query) setPaymentMethods([])\n return []\n } catch (err) {\n console.error('sales.payments.methods.load', err)\n return []\n } finally {\n setMethodsLoading(false)\n }\n },\n []\n )\n\n const fetchPaymentMethodItems = React.useCallback(\n async (query?: string): Promise<LookupSelectItem[]> => {\n const options =\n paymentMethods.length && !query\n ? paymentMethods\n : await loadPaymentMethods(query)\n const term = query?.trim().toLowerCase() ?? ''\n return options\n .filter(\n (option) =>\n !term.length ||\n option.name.toLowerCase().includes(term) ||\n option.code.toLowerCase().includes(term)\n )\n .map<LookupSelectItem>((option) => ({\n id: option.id,\n title: option.name,\n subtitle: option.code,\n icon: <CreditCard className=\"h-4 w-4 text-muted-foreground\" />,\n }))\n },\n [loadPaymentMethods, paymentMethods]\n )\n\n const shortcutLabel = t('sales.documents.payments.saveShortcut', 'Save \u2318\u23CE / Ctrl+Enter')\n const renderStatusIcon = React.useCallback(\n (color?: string | null) => (\n <span\n className=\"h-2.5 w-2.5 rounded-full border border-border/70\"\n style={color ? { backgroundColor: color, borderColor: color } : undefined}\n />\n ),\n [],\n )\n\n const loadDocumentStatuses = React.useCallback(async (): Promise<StatusOption[]> => {\n setDocumentStatusLoading(true)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/order-statuses?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const mapped = items\n .map((entry) => {\n const id = typeof entry.id === 'string' ? entry.id : null\n const value = typeof entry.value === 'string' ? entry.value : null\n if (!id || !value) return null\n const label =\n typeof entry.label === 'string' && entry.label.trim().length\n ? entry.label\n : value\n const color =\n typeof entry.color === 'string' && entry.color.trim().length ? entry.color : null\n return { id, value, label, color }\n })\n .filter((entry): entry is StatusOption => Boolean(entry))\n setDocumentStatuses(mapped)\n return mapped\n } catch (err) {\n console.error('sales.payments.statuses.load', err)\n setDocumentStatuses([])\n return []\n } finally {\n setDocumentStatusLoading(false)\n }\n }, [])\n\n const loadPaymentStatuses = React.useCallback(async (): Promise<StatusOption[]> => {\n setPaymentStatusLoading(true)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/payment-statuses?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const mapped = items\n .map((entry) => {\n const id = typeof entry.id === 'string' ? entry.id : null\n const value = typeof entry.value === 'string' ? entry.value : null\n if (!id || !value) return null\n const label =\n typeof entry.label === 'string' && entry.label.trim().length\n ? entry.label\n : value\n const color =\n typeof entry.color === 'string' && entry.color.trim().length ? entry.color : null\n return { id, value, label, color }\n })\n .filter((entry): entry is StatusOption => Boolean(entry))\n setPaymentStatuses(mapped)\n return mapped\n } catch (err) {\n console.error('sales.payments.statuses.load', err)\n setPaymentStatuses([])\n return []\n } finally {\n setPaymentStatusLoading(false)\n }\n }, [])\n\n React.useEffect(() => {\n if (!open) return\n setFormResetKey((prev) => prev + 1)\n if (!paymentMethods.length) {\n void loadPaymentMethods()\n }\n if (!paymentStatuses.length) {\n void loadPaymentStatuses()\n }\n if (mode === 'create') {\n if (!documentStatuses.length) {\n void loadDocumentStatuses()\n }\n }\n }, [\n documentStatuses.length,\n loadDocumentStatuses,\n loadPaymentStatuses,\n loadPaymentMethods,\n mode,\n open,\n payment?.id,\n paymentStatuses.length,\n paymentMethods.length,\n ])\n\n const fetchDocumentStatusItems = React.useCallback(\n async (query?: string): Promise<LookupSelectItem[]> => {\n const options =\n documentStatuses.length && !query ? documentStatuses : await loadDocumentStatuses()\n const term = query?.trim().toLowerCase() ?? ''\n return options\n .filter(\n (option) =>\n !term.length ||\n option.label.toLowerCase().includes(term) ||\n option.value.toLowerCase().includes(term),\n )\n .map<LookupSelectItem>((option) => ({\n id: option.id,\n title: option.label,\n subtitle: option.value,\n icon: renderStatusIcon(option.color),\n }))\n },\n [documentStatuses, loadDocumentStatuses, renderStatusIcon],\n )\n\n const fetchPaymentStatusItems = React.useCallback(\n async (query?: string): Promise<LookupSelectItem[]> => {\n const options =\n paymentStatuses.length && !query ? paymentStatuses : await loadPaymentStatuses()\n const term = query?.trim().toLowerCase() ?? ''\n return options\n .filter(\n (option) =>\n !term.length ||\n option.label.toLowerCase().includes(term) ||\n option.value.toLowerCase().includes(term),\n )\n .map<LookupSelectItem>((option) => ({\n id: option.id,\n title: option.label,\n subtitle: option.value,\n icon: renderStatusIcon(option.color),\n }))\n },\n [loadPaymentStatuses, paymentStatuses, renderStatusIcon],\n )\n\n const fields = React.useMemo<CrudField[]>(\n () => [\n {\n id: 'amount',\n label: t('sales.documents.payments.amount', 'Amount'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => {\n const normalized = typeof value === 'number' ? value : typeof value === 'string' ? value : ''\n return (\n <div className=\"flex items-center gap-2\">\n <Input\n type=\"number\"\n inputMode=\"decimal\"\n step=\"0.01\"\n value={normalized as string | number}\n onChange={(event) => setValue(event.target.value)}\n placeholder=\"0.00\"\n />\n <span className=\"rounded-full border border-border/70 bg-muted/50 px-3 py-1 text-xs font-semibold uppercase text-foreground\">\n {currencyLabel}\n </span>\n </div>\n )\n },\n },\n {\n id: 'paymentMethodId',\n label: t('sales.documents.payments.method', 'Method'),\n type: 'custom',\n component: ({ value, setValue }) => {\n const currentValue = typeof value === 'string' && value.length ? value : null\n return (\n <LookupSelect\n value={currentValue}\n onChange={(next) => setValue(next ?? '')}\n fetchItems={fetchPaymentMethodItems}\n searchPlaceholder={t('sales.documents.payments.methodPlaceholder', 'Search payment method')}\n emptyLabel={t('sales.documents.payments.methodsEmpty', 'No payment methods')}\n loadingLabel={t('sales.documents.payments.loadingMethods', 'Loading payment methods\u2026')}\n selectedHintLabel={(id) =>\n t('sales.documents.payments.methodSelected', 'Selected method: {{id}}', { id })\n }\n minQuery={0}\n />\n )\n },\n },\n {\n id: 'statusEntryId',\n label: t('sales.documents.payments.status', 'Status'),\n type: 'custom',\n component: ({ value, setValue }) => {\n const currentValue = typeof value === 'string' && value.length ? value : null\n return (\n <LookupSelect\n value={currentValue}\n onChange={(next) => setValue(next ?? '')}\n fetchItems={fetchPaymentStatusItems}\n placeholder={t('sales.documents.payments.statusPlaceholder', 'Select status')}\n loading={paymentStatusLoading}\n minQuery={0}\n />\n )\n },\n },\n ...(mode === 'create'\n ? ([\n {\n id: 'documentStatusEntryId',\n label: t('sales.documents.status.changeDocument', 'Change order/quote status'),\n type: 'custom',\n component: ({ value, setValue }) => {\n const currentValue = typeof value === 'string' && value.length ? value : null\n return (\n <LookupSelect\n value={currentValue}\n onChange={(next) => setValue(next ?? '')}\n fetchItems={fetchDocumentStatusItems}\n placeholder={t(\n 'sales.documents.status.documentPlaceholder',\n 'Select new order/quote status',\n )}\n loading={documentStatusLoading}\n minQuery={0}\n />\n )\n },\n },\n ] as CrudField[])\n : []),\n {\n id: 'paymentReference',\n label: t('sales.documents.payments.reference', 'Reference'),\n type: 'text',\n placeholder: t('sales.documents.payments.referencePlaceholder', 'External reference or note'),\n },\n {\n id: 'receivedAt',\n label: t('sales.documents.payments.receivedAt', 'Received at'),\n type: 'date',\n },\n ],\n [\n currencyLabel,\n documentStatusLoading,\n fetchPaymentStatusItems,\n fetchDocumentStatusItems,\n fetchPaymentMethodItems,\n paymentStatusLoading,\n mode,\n t,\n ],\n )\n\n const groups = React.useMemo<CrudFormGroup[]>(\n () => {\n const base: CrudFormGroup[] = [\n {\n id: 'paymentDetails',\n title: t('sales.documents.payments.form.title', 'Payment details'),\n column: 1,\n fields: ['amount', 'paymentMethodId', 'statusEntryId'],\n },\n ]\n if (mode === 'create') {\n base.push({\n id: 'statusChanges',\n title: t('sales.documents.status.sectionTitle', 'Status changes'),\n column: 1,\n fields: ['documentStatusEntryId'],\n })\n }\n base.push({\n id: 'paymentReference',\n title: t('sales.documents.payments.reference', 'Reference'),\n column: 2,\n fields: ['paymentReference', 'receivedAt'],\n })\n base.push({\n id: 'paymentCustomFields',\n title: t('entities.customFields.title', 'Custom fields'),\n column: 2,\n kind: 'customFields',\n })\n return base\n },\n [mode, t],\n )\n\n const handleSubmit = React.useCallback(\n async (values: Record<string, unknown>) => {\n const resolvedCurrency = currencyCode ? currencyCode.toUpperCase() : ''\n const amountValue = normalizeNumber(values.amount)\n if (!resolvedCurrency.trim()) {\n throw createCrudFormError(t('sales.documents.payments.currencyRequired', 'Currency is required.'))\n }\n if (amountValue <= 0) {\n throw createCrudFormError(t('sales.documents.payments.amountRequired', 'Enter a positive amount.'), {\n amount: t('sales.documents.payments.amountRequired', 'Enter a positive amount.'),\n })\n }\n\n const payload: Record<string, unknown> = {\n orderId,\n amount: amountValue,\n currencyCode: resolvedCurrency,\n paymentReference:\n typeof values.paymentReference === 'string' && values.paymentReference.trim().length\n ? values.paymentReference.trim()\n : undefined,\n paymentMethodId:\n typeof values.paymentMethodId === 'string' && values.paymentMethodId.trim().length\n ? values.paymentMethodId\n : undefined,\n statusEntryId:\n typeof values.statusEntryId === 'string' && values.statusEntryId.trim().length\n ? values.statusEntryId\n : undefined,\n customFieldSetId:\n typeof values.customFieldSetId === 'string' && values.customFieldSetId.trim().length\n ? values.customFieldSetId.trim()\n : undefined,\n organizationId: organizationId ?? undefined,\n tenantId: tenantId ?? undefined,\n }\n const documentStatusEntryId =\n typeof values.documentStatusEntryId === 'string' && values.documentStatusEntryId.trim().length\n ? values.documentStatusEntryId\n : null\n if (documentStatusEntryId) {\n payload.documentStatusEntryId = documentStatusEntryId\n }\n if (typeof values.receivedAt === 'string' && values.receivedAt.trim().length) {\n payload.receivedAt = new Date(values.receivedAt)\n }\n const customFields = collectCustomFieldValues(values, {\n transform: normalizeCustomFieldSubmitValue,\n })\n if (Object.keys(customFields).length) payload.customFields = customFields\n\n const action = payment?.id ? updateCrud : createCrud\n try {\n const result = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(payment?.id ? rowOptimisticVersion(payment) : undefined),\n () =>\n action(\n 'sales/payments',\n payment?.id ? { id: payment.id, ...payload } : payload,\n {\n errorMessage: t('sales.documents.payments.errorSave', 'Failed to save payment.'),\n }\n )\n )\n if (result.ok) {\n const totals = (result.result as any)?.orderTotals as PaymentTotals | undefined\n if (onSaved) {\n await onSaved(totals ?? null)\n }\n setFormResetKey((prev) => prev + 1)\n onOpenChange(false)\n }\n } catch (err) {\n if (\n handleSectionMutationError(err, t, () => {\n if (onSaved) void onSaved()\n })\n ) {\n onOpenChange(false)\n return\n }\n throw err\n }\n },\n [currencyCode, mode, onOpenChange, onSaved, orderId, organizationId, payment?.id, payment?.updatedAt, t, tenantId]\n )\n\n const handleSubmitForm = React.useCallback(\n () => dialogContentRef.current?.querySelector('form')?.requestSubmit(),\n [],\n )\n const handleKeyDown = useDialogKeyHandler({\n onConfirm: handleSubmitForm,\n onCancel: () => onOpenChange(false),\n })\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n ref={dialogContentRef}\n className=\"sm:max-w-5xl\"\n onKeyDown={handleKeyDown}\n >\n <DialogHeader>\n <DialogTitle>\n {mode === 'edit'\n ? t('sales.documents.payments.edit', 'Edit payment')\n : t('sales.documents.payments.add', 'Add payment')}\n </DialogTitle>\n </DialogHeader>\n <CrudForm\n key={formResetKey}\n embedded\n entityId={E.sales.sales_payment}\n fields={fields}\n groups={groups}\n initialValues={initialValues}\n customFieldsetBindings={{ [E.sales.sales_payment]: { valueKey: 'customFieldSetId' } }}\n submitLabel={shortcutLabel}\n onSubmit={handleSubmit}\n loadingMessage={t('sales.documents.payments.loading', 'Loading payments\u2026')}\n customFieldsLoadingMessage={t('ui.forms.loading', 'Loading data...')}\n contentHeader={\n methodsLoading ? (\n <p className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <Spinner className=\"h-3.5 w-3.5 animate-spin\" />\n {t('sales.documents.payments.loadingMethods', 'Loading payment methods\u2026')}\n </p>\n ) : null\n }\n />\n </DialogContent>\n </Dialog>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { CreditCard } from 'lucide-react'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { LookupSelect, type LookupSelectItem } from '@open-mercato/ui/backend/inputs'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { createCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { handleSectionMutationError } from './optimisticLock'\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { useDialogKeyHandler } from '@open-mercato/ui/hooks/useDialogKeyHandler'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { E } from '#generated/entities.ids.generated'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { normalizeCustomFieldSubmitValue, extractCustomFieldValues } from './customFieldHelpers'\n\nexport type PaymentTotals = {\n paidTotalAmount?: number | null\n refundedTotalAmount?: number | null\n outstandingAmount?: number | null\n}\n\nexport type PaymentFormData = {\n id?: string | null\n updatedAt?: string | null\n amount?: number | string | null\n paymentMethodId?: string | null\n paymentReference?: string | null\n receivedAt?: string | null\n currencyCode?: string | null\n statusEntryId?: string | null\n customValues?: Record<string, unknown> | null\n customFieldSetId?: string | null\n}\n\ntype PaymentMethodOption = {\n id: string\n name: string\n code: string\n}\n\ntype StatusOption = {\n id: string\n value: string\n label: string\n color: string | null\n}\n\ntype PaymentDialogProps = {\n open: boolean\n mode: 'create' | 'edit'\n payment?: PaymentFormData | null\n currencyCode: string | null | undefined\n orderId: string\n organizationId: string | null\n tenantId: string | null\n documentUpdatedAt?: string | null\n onOpenChange: (open: boolean) => void\n onSaved?: (totals?: PaymentTotals | null) => void | Promise<void>\n}\n\nconst 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\nexport function PaymentDialog({\n open,\n mode,\n payment,\n currencyCode,\n orderId,\n organizationId,\n tenantId,\n documentUpdatedAt,\n onOpenChange,\n onSaved,\n}: PaymentDialogProps) {\n const t = useT()\n const dialogContentRef = React.useRef<HTMLDivElement | null>(null)\n const [formResetKey, setFormResetKey] = React.useState(0)\n const [paymentMethods, setPaymentMethods] = React.useState<PaymentMethodOption[]>([])\n const [methodsLoading, setMethodsLoading] = React.useState(false)\n const [paymentStatuses, setPaymentStatuses] = React.useState<StatusOption[]>([])\n const [paymentStatusLoading, setPaymentStatusLoading] = React.useState(false)\n const [documentStatuses, setDocumentStatuses] = React.useState<StatusOption[]>([])\n const [documentStatusLoading, setDocumentStatusLoading] = React.useState(false)\n\n const currencyLabel = React.useMemo(() => {\n const code = currencyCode ? currencyCode.toUpperCase() : ''\n if (!code) return t('sales.documents.detail.empty', 'Not set')\n return code\n }, [currencyCode, t])\n\n const initialValues = React.useMemo(\n () => ({\n amount: payment?.amount ?? '',\n paymentMethodId: payment?.paymentMethodId ?? '',\n paymentReference: payment?.paymentReference ?? '',\n receivedAt: payment?.receivedAt ? payment.receivedAt.slice(0, 10) : '',\n statusEntryId: payment?.statusEntryId ?? '',\n documentStatusEntryId: '',\n customFieldSetId: payment?.customFieldSetId ?? '',\n ...extractCustomFieldValues(payment),\n }),\n [\n payment?.amount,\n payment?.customFieldSetId,\n payment?.customValues,\n payment?.paymentMethodId,\n payment?.paymentReference,\n payment?.receivedAt,\n payment?.statusEntryId,\n ],\n )\n\n const loadPaymentMethods = React.useCallback(\n async (query?: string): Promise<PaymentMethodOption[]> => {\n setMethodsLoading(true)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100', isActive: 'true' })\n if (query && query.trim().length) params.set('search', query.trim())\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/payment-methods?${params.toString()}`,\n undefined,\n { fallback: { items: [] } }\n )\n if (response.ok && Array.isArray(response.result?.items)) {\n const options = response.result.items\n .map((item) => {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const name = typeof item.name === 'string' ? item.name : null\n const code = typeof item.code === 'string' ? item.code : null\n return {\n id,\n name: name ?? code ?? id,\n code: code ?? id,\n }\n })\n .filter((entry): entry is PaymentMethodOption => !!entry)\n if (!query) setPaymentMethods(options)\n return options\n }\n if (!query) setPaymentMethods([])\n return []\n } catch (err) {\n console.error('sales.payments.methods.load', err)\n return []\n } finally {\n setMethodsLoading(false)\n }\n },\n []\n )\n\n const fetchPaymentMethodItems = React.useCallback(\n async (query?: string): Promise<LookupSelectItem[]> => {\n const options =\n paymentMethods.length && !query\n ? paymentMethods\n : await loadPaymentMethods(query)\n const term = query?.trim().toLowerCase() ?? ''\n return options\n .filter(\n (option) =>\n !term.length ||\n option.name.toLowerCase().includes(term) ||\n option.code.toLowerCase().includes(term)\n )\n .map<LookupSelectItem>((option) => ({\n id: option.id,\n title: option.name,\n subtitle: option.code,\n icon: <CreditCard className=\"h-4 w-4 text-muted-foreground\" />,\n }))\n },\n [loadPaymentMethods, paymentMethods]\n )\n\n const shortcutLabel = t('sales.documents.payments.saveShortcut', 'Save \u2318\u23CE / Ctrl+Enter')\n const renderStatusIcon = React.useCallback(\n (color?: string | null) => (\n <span\n className=\"h-2.5 w-2.5 rounded-full border border-border/70\"\n style={color ? { backgroundColor: color, borderColor: color } : undefined}\n />\n ),\n [],\n )\n\n const loadDocumentStatuses = React.useCallback(async (): Promise<StatusOption[]> => {\n setDocumentStatusLoading(true)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/order-statuses?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const mapped = items\n .map((entry) => {\n const id = typeof entry.id === 'string' ? entry.id : null\n const value = typeof entry.value === 'string' ? entry.value : null\n if (!id || !value) return null\n const label =\n typeof entry.label === 'string' && entry.label.trim().length\n ? entry.label\n : value\n const color =\n typeof entry.color === 'string' && entry.color.trim().length ? entry.color : null\n return { id, value, label, color }\n })\n .filter((entry): entry is StatusOption => Boolean(entry))\n setDocumentStatuses(mapped)\n return mapped\n } catch (err) {\n console.error('sales.payments.statuses.load', err)\n setDocumentStatuses([])\n return []\n } finally {\n setDocumentStatusLoading(false)\n }\n }, [])\n\n const loadPaymentStatuses = React.useCallback(async (): Promise<StatusOption[]> => {\n setPaymentStatusLoading(true)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/payment-statuses?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const mapped = items\n .map((entry) => {\n const id = typeof entry.id === 'string' ? entry.id : null\n const value = typeof entry.value === 'string' ? entry.value : null\n if (!id || !value) return null\n const label =\n typeof entry.label === 'string' && entry.label.trim().length\n ? entry.label\n : value\n const color =\n typeof entry.color === 'string' && entry.color.trim().length ? entry.color : null\n return { id, value, label, color }\n })\n .filter((entry): entry is StatusOption => Boolean(entry))\n setPaymentStatuses(mapped)\n return mapped\n } catch (err) {\n console.error('sales.payments.statuses.load', err)\n setPaymentStatuses([])\n return []\n } finally {\n setPaymentStatusLoading(false)\n }\n }, [])\n\n React.useEffect(() => {\n if (!open) return\n setFormResetKey((prev) => prev + 1)\n if (!paymentMethods.length) {\n void loadPaymentMethods()\n }\n if (!paymentStatuses.length) {\n void loadPaymentStatuses()\n }\n if (mode === 'create') {\n if (!documentStatuses.length) {\n void loadDocumentStatuses()\n }\n }\n }, [\n documentStatuses.length,\n loadDocumentStatuses,\n loadPaymentStatuses,\n loadPaymentMethods,\n mode,\n open,\n payment?.id,\n paymentStatuses.length,\n paymentMethods.length,\n ])\n\n const fetchDocumentStatusItems = React.useCallback(\n async (query?: string): Promise<LookupSelectItem[]> => {\n const options =\n documentStatuses.length && !query ? documentStatuses : await loadDocumentStatuses()\n const term = query?.trim().toLowerCase() ?? ''\n return options\n .filter(\n (option) =>\n !term.length ||\n option.label.toLowerCase().includes(term) ||\n option.value.toLowerCase().includes(term),\n )\n .map<LookupSelectItem>((option) => ({\n id: option.id,\n title: option.label,\n subtitle: option.value,\n icon: renderStatusIcon(option.color),\n }))\n },\n [documentStatuses, loadDocumentStatuses, renderStatusIcon],\n )\n\n const fetchPaymentStatusItems = React.useCallback(\n async (query?: string): Promise<LookupSelectItem[]> => {\n const options =\n paymentStatuses.length && !query ? paymentStatuses : await loadPaymentStatuses()\n const term = query?.trim().toLowerCase() ?? ''\n return options\n .filter(\n (option) =>\n !term.length ||\n option.label.toLowerCase().includes(term) ||\n option.value.toLowerCase().includes(term),\n )\n .map<LookupSelectItem>((option) => ({\n id: option.id,\n title: option.label,\n subtitle: option.value,\n icon: renderStatusIcon(option.color),\n }))\n },\n [loadPaymentStatuses, paymentStatuses, renderStatusIcon],\n )\n\n const fields = React.useMemo<CrudField[]>(\n () => [\n {\n id: 'amount',\n label: t('sales.documents.payments.amount', 'Amount'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => {\n const normalized = typeof value === 'number' ? value : typeof value === 'string' ? value : ''\n return (\n <div className=\"flex items-center gap-2\">\n <Input\n type=\"number\"\n inputMode=\"decimal\"\n step=\"0.01\"\n value={normalized as string | number}\n onChange={(event) => setValue(event.target.value)}\n placeholder=\"0.00\"\n />\n <span className=\"rounded-full border border-border/70 bg-muted/50 px-3 py-1 text-xs font-semibold uppercase text-foreground\">\n {currencyLabel}\n </span>\n </div>\n )\n },\n },\n {\n id: 'paymentMethodId',\n label: t('sales.documents.payments.method', 'Method'),\n type: 'custom',\n component: ({ value, setValue }) => {\n const currentValue = typeof value === 'string' && value.length ? value : null\n return (\n <LookupSelect\n value={currentValue}\n onChange={(next) => setValue(next ?? '')}\n fetchItems={fetchPaymentMethodItems}\n searchPlaceholder={t('sales.documents.payments.methodPlaceholder', 'Search payment method')}\n emptyLabel={t('sales.documents.payments.methodsEmpty', 'No payment methods')}\n loadingLabel={t('sales.documents.payments.loadingMethods', 'Loading payment methods\u2026')}\n selectedHintLabel={(id) =>\n t('sales.documents.payments.methodSelected', 'Selected method: {{id}}', { id })\n }\n minQuery={0}\n />\n )\n },\n },\n {\n id: 'statusEntryId',\n label: t('sales.documents.payments.status', 'Status'),\n type: 'custom',\n component: ({ value, setValue }) => {\n const currentValue = typeof value === 'string' && value.length ? value : null\n return (\n <LookupSelect\n value={currentValue}\n onChange={(next) => setValue(next ?? '')}\n fetchItems={fetchPaymentStatusItems}\n placeholder={t('sales.documents.payments.statusPlaceholder', 'Select status')}\n loading={paymentStatusLoading}\n minQuery={0}\n />\n )\n },\n },\n ...(mode === 'create'\n ? ([\n {\n id: 'documentStatusEntryId',\n label: t('sales.documents.status.changeDocument', 'Change order/quote status'),\n type: 'custom',\n component: ({ value, setValue }) => {\n const currentValue = typeof value === 'string' && value.length ? value : null\n return (\n <LookupSelect\n value={currentValue}\n onChange={(next) => setValue(next ?? '')}\n fetchItems={fetchDocumentStatusItems}\n placeholder={t(\n 'sales.documents.status.documentPlaceholder',\n 'Select new order/quote status',\n )}\n loading={documentStatusLoading}\n minQuery={0}\n />\n )\n },\n },\n ] as CrudField[])\n : []),\n {\n id: 'paymentReference',\n label: t('sales.documents.payments.reference', 'Reference'),\n type: 'text',\n placeholder: t('sales.documents.payments.referencePlaceholder', 'External reference or note'),\n },\n {\n id: 'receivedAt',\n label: t('sales.documents.payments.receivedAt', 'Received at'),\n type: 'date',\n },\n ],\n [\n currencyLabel,\n documentStatusLoading,\n fetchPaymentStatusItems,\n fetchDocumentStatusItems,\n fetchPaymentMethodItems,\n paymentStatusLoading,\n mode,\n t,\n ],\n )\n\n const groups = React.useMemo<CrudFormGroup[]>(\n () => {\n const base: CrudFormGroup[] = [\n {\n id: 'paymentDetails',\n title: t('sales.documents.payments.form.title', 'Payment details'),\n column: 1,\n fields: ['amount', 'paymentMethodId', 'statusEntryId'],\n },\n ]\n if (mode === 'create') {\n base.push({\n id: 'statusChanges',\n title: t('sales.documents.status.sectionTitle', 'Status changes'),\n column: 1,\n fields: ['documentStatusEntryId'],\n })\n }\n base.push({\n id: 'paymentReference',\n title: t('sales.documents.payments.reference', 'Reference'),\n column: 2,\n fields: ['paymentReference', 'receivedAt'],\n })\n base.push({\n id: 'paymentCustomFields',\n title: t('entities.customFields.title', 'Custom fields'),\n column: 2,\n kind: 'customFields',\n })\n return base\n },\n [mode, t],\n )\n\n const handleSubmit = React.useCallback(\n async (values: Record<string, unknown>) => {\n const resolvedCurrency = currencyCode ? currencyCode.toUpperCase() : ''\n const amountValue = normalizeNumber(values.amount)\n if (!resolvedCurrency.trim()) {\n throw createCrudFormError(t('sales.documents.payments.currencyRequired', 'Currency is required.'))\n }\n if (amountValue <= 0) {\n throw createCrudFormError(t('sales.documents.payments.amountRequired', 'Enter a positive amount.'), {\n amount: t('sales.documents.payments.amountRequired', 'Enter a positive amount.'),\n })\n }\n\n const payload: Record<string, unknown> = {\n orderId,\n amount: amountValue,\n currencyCode: resolvedCurrency,\n paymentReference:\n typeof values.paymentReference === 'string' && values.paymentReference.trim().length\n ? values.paymentReference.trim()\n : undefined,\n paymentMethodId:\n typeof values.paymentMethodId === 'string' && values.paymentMethodId.trim().length\n ? values.paymentMethodId\n : undefined,\n statusEntryId:\n typeof values.statusEntryId === 'string' && values.statusEntryId.trim().length\n ? values.statusEntryId\n : undefined,\n customFieldSetId:\n typeof values.customFieldSetId === 'string' && values.customFieldSetId.trim().length\n ? values.customFieldSetId.trim()\n : undefined,\n organizationId: organizationId ?? undefined,\n tenantId: tenantId ?? undefined,\n }\n const documentStatusEntryId =\n typeof values.documentStatusEntryId === 'string' && values.documentStatusEntryId.trim().length\n ? values.documentStatusEntryId\n : null\n if (documentStatusEntryId) {\n payload.documentStatusEntryId = documentStatusEntryId\n }\n if (typeof values.receivedAt === 'string' && values.receivedAt.trim().length) {\n payload.receivedAt = new Date(values.receivedAt)\n }\n const customFields = collectCustomFieldValues(values, {\n transform: normalizeCustomFieldSubmitValue,\n })\n if (Object.keys(customFields).length) payload.customFields = customFields\n\n const action = payment?.id ? updateCrud : createCrud\n try {\n const result = await withScopedApiRequestHeaders(\n // The server guards the PARENT order's aggregate version (Gap A) for\n // both create and update, so send the order's `updated_at`.\n buildOptimisticLockHeader(documentUpdatedAt ?? undefined),\n () =>\n action(\n 'sales/payments',\n payment?.id ? { id: payment.id, ...payload } : payload,\n {\n errorMessage: t('sales.documents.payments.errorSave', 'Failed to save payment.'),\n }\n )\n )\n if (result.ok) {\n const totals = (result.result as any)?.orderTotals as PaymentTotals | undefined\n if (onSaved) {\n await onSaved(totals ?? null)\n }\n setFormResetKey((prev) => prev + 1)\n onOpenChange(false)\n }\n } catch (err) {\n if (\n handleSectionMutationError(err, t, () => {\n if (onSaved) void onSaved()\n })\n ) {\n onOpenChange(false)\n return\n }\n throw err\n }\n },\n [currencyCode, documentUpdatedAt, mode, onOpenChange, onSaved, orderId, organizationId, payment?.id, t, tenantId]\n )\n\n const handleSubmitForm = React.useCallback(\n () => dialogContentRef.current?.querySelector('form')?.requestSubmit(),\n [],\n )\n const handleKeyDown = useDialogKeyHandler({\n onConfirm: handleSubmitForm,\n onCancel: () => onOpenChange(false),\n })\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n ref={dialogContentRef}\n className=\"sm:max-w-5xl\"\n onKeyDown={handleKeyDown}\n >\n <DialogHeader>\n <DialogTitle>\n {mode === 'edit'\n ? t('sales.documents.payments.edit', 'Edit payment')\n : t('sales.documents.payments.add', 'Add payment')}\n </DialogTitle>\n </DialogHeader>\n <CrudForm\n key={formResetKey}\n embedded\n entityId={E.sales.sales_payment}\n fields={fields}\n groups={groups}\n initialValues={initialValues}\n customFieldsetBindings={{ [E.sales.sales_payment]: { valueKey: 'customFieldSetId' } }}\n submitLabel={shortcutLabel}\n onSubmit={handleSubmit}\n loadingMessage={t('sales.documents.payments.loading', 'Loading payments\u2026')}\n customFieldsLoadingMessage={t('ui.forms.loading', 'Loading data...')}\n contentHeader={\n methodsLoading ? (\n <p className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <Spinner className=\"h-3.5 w-3.5 animate-spin\" />\n {t('sales.documents.payments.loadingMethods', 'Loading payment methods\u2026')}\n </p>\n ) : null\n }\n />\n </DialogContent>\n </Dialog>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|