@open-mercato/core 0.4.8-develop-d16e2f51dc → 0.4.8-develop-4b58cde65d
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/generated/entities/sales_return/index.js +31 -0
- package/dist/generated/entities/sales_return/index.js.map +7 -0
- package/dist/generated/entities/sales_return_line/index.js +29 -0
- package/dist/generated/entities/sales_return_line/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +2 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +4 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/sales/acl.js +2 -0
- package/dist/modules/sales/acl.js.map +2 -2
- package/dist/modules/sales/api/document-history/route.js +20 -2
- package/dist/modules/sales/api/document-history/route.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +34 -0
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/dist/modules/sales/api/returns/[id]/route.js +147 -0
- package/dist/modules/sales/api/returns/[id]/route.js.map +7 -0
- package/dist/modules/sales/api/returns/route.js +158 -0
- package/dist/modules/sales/api/returns/route.js.map +7 -0
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +20 -1
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/index.js +1 -0
- package/dist/modules/sales/commands/index.js.map +2 -2
- package/dist/modules/sales/commands/returns.js +467 -0
- package/dist/modules/sales/commands/returns.js.map +7 -0
- package/dist/modules/sales/components/documents/ReturnDialog.js +176 -0
- package/dist/modules/sales/components/documents/ReturnDialog.js.map +7 -0
- package/dist/modules/sales/components/documents/ReturnsSection.js +188 -0
- package/dist/modules/sales/components/documents/ReturnsSection.js.map +7 -0
- package/dist/modules/sales/data/entities.js +115 -1
- package/dist/modules/sales/data/entities.js.map +2 -2
- package/dist/modules/sales/data/validators.js +13 -0
- package/dist/modules/sales/data/validators.js.map +2 -2
- package/dist/modules/sales/events.js +4 -0
- package/dist/modules/sales/events.js.map +2 -2
- package/dist/modules/sales/lib/calculations.js +7 -0
- package/dist/modules/sales/lib/calculations.js.map +2 -2
- package/dist/modules/sales/lib/dictionaries.js +1 -0
- package/dist/modules/sales/lib/dictionaries.js.map +2 -2
- package/dist/modules/sales/lib/documentNumberTokens.js +2 -0
- package/dist/modules/sales/lib/documentNumberTokens.js.map +2 -2
- package/dist/modules/sales/lib/historyHelpers.js +15 -7
- package/dist/modules/sales/lib/historyHelpers.js.map +2 -2
- package/dist/modules/sales/lib/makeSalesLineRoute.js +42 -37
- package/dist/modules/sales/lib/makeSalesLineRoute.js.map +2 -2
- package/dist/modules/sales/migrations/Migration20260309073310.js +23 -0
- package/dist/modules/sales/migrations/Migration20260309073310.js.map +7 -0
- package/dist/modules/sales/services/salesDocumentNumberGenerator.js +8 -6
- package/dist/modules/sales/services/salesDocumentNumberGenerator.js.map +2 -2
- package/dist/modules/sales/setup.js +1 -1
- package/dist/modules/sales/setup.js.map +2 -2
- package/dist/modules/sales/widgets/injection/document-history/widget.client.js +25 -16
- package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
- package/generated/entities/sales_return/index.ts +14 -0
- package/generated/entities/sales_return_line/index.ts +13 -0
- package/generated/entities.ids.generated.ts +2 -0
- package/generated/entity-fields-registry.ts +4 -0
- package/package.json +3 -3
- package/src/modules/sales/AGENTS.md +1 -0
- package/src/modules/sales/acl.ts +2 -0
- package/src/modules/sales/api/document-history/route.ts +25 -1
- package/src/modules/sales/api/documents/factory.ts +35 -0
- package/src/modules/sales/api/returns/[id]/route.ts +156 -0
- package/src/modules/sales/api/returns/route.ts +171 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +18 -0
- package/src/modules/sales/commands/index.ts +1 -0
- package/src/modules/sales/commands/returns.ts +540 -0
- package/src/modules/sales/components/documents/ReturnDialog.tsx +216 -0
- package/src/modules/sales/components/documents/ReturnsSection.tsx +270 -0
- package/src/modules/sales/data/entities.ts +99 -3
- package/src/modules/sales/data/validators.ts +16 -0
- package/src/modules/sales/events.ts +5 -0
- package/src/modules/sales/i18n/de.json +32 -0
- package/src/modules/sales/i18n/en.json +32 -0
- package/src/modules/sales/i18n/es.json +32 -0
- package/src/modules/sales/i18n/pl.json +32 -0
- package/src/modules/sales/lib/calculations.ts +9 -0
- package/src/modules/sales/lib/dictionaries.ts +1 -0
- package/src/modules/sales/lib/documentNumberTokens.ts +2 -1
- package/src/modules/sales/lib/historyHelpers.ts +20 -9
- package/src/modules/sales/lib/makeSalesLineRoute.ts +42 -37
- package/src/modules/sales/migrations/.snapshot-open-mercato.json +398 -0
- package/src/modules/sales/migrations/Migration20260309073310.ts +26 -0
- package/src/modules/sales/services/salesDocumentNumberGenerator.ts +15 -4
- package/src/modules/sales/setup.ts +1 -1
- package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +26 -17
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/sales/api/documents/factory.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod'\nimport { makeCrudRoute, type CrudCtx } from '@open-mercato/shared/lib/crud/factory'\nimport { splitCustomFieldPayload, extractAllCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { E } from '#generated/entities.ids.generated'\nimport type { SalesOrder, SalesQuote } from '../../data/entities'\nimport { SalesDocumentTagAssignment } from '../../data/entities'\nimport {\n orderCreateSchema,\n quoteCreateSchema,\n} from '../../data/validators'\nimport {\n createPagedListResponseSchema,\n createSalesCrudOpenApi,\n defaultDeleteRequestSchema,\n} from '../openapi'\nimport { parseScopedCommandInput, resolveCrudRecordId } from '../utils'\nimport { documentUpdateSchema } from '../../commands/documents'\nimport { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\n\ntype DocumentKind = 'order' | 'quote'\n\ntype DocumentBinding = {\n kind: DocumentKind\n entity: typeof SalesOrder | typeof SalesQuote\n entityId: (typeof E.sales)[keyof typeof E.sales]\n numberField: 'orderNumber' | 'quoteNumber'\n createCommandId: string\n updateCommandId: string\n deleteCommandId: string\n manageFeature: string\n viewFeature: string\n}\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst resolveCustomerName = (snapshot: Record<string, unknown> | null, fallback?: string | null) => {\n if (!snapshot) return fallback ?? null\n const customer = snapshot.customer as Record<string, unknown> | undefined\n const contact = snapshot.contact as Record<string, unknown> | undefined\n const displayName = typeof customer?.displayName === 'string' ? customer.displayName : null\n if (displayName) return displayName\n const first = typeof contact?.firstName === 'string' ? contact.firstName : null\n const last = typeof contact?.lastName === 'string' ? contact.lastName : null\n const preferred = typeof contact?.preferredName === 'string' ? contact.preferredName : null\n const parts = [preferred ?? first, last].filter((part) => part && part.trim().length)\n if (parts.length) return parts.join(' ')\n return fallback ?? null\n}\n\nconst resolveCustomerEmail = (snapshot: Record<string, unknown> | null) => {\n if (!snapshot) return null\n const customer = snapshot.customer as Record<string, unknown> | undefined\n const primary = typeof customer?.primaryEmail === 'string' ? customer.primaryEmail : null\n return primary ?? null\n}\n\nconst listSchema = z\n .object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n search: z.string().optional(),\n id: z.string().uuid().optional(),\n customerId: z.string().uuid().optional(),\n channelId: z.string().uuid().optional(),\n lineItemCountMin: z.coerce.number().min(0).optional(),\n lineItemCountMax: z.coerce.number().min(0).optional(),\n totalNetMin: z.coerce.number().optional(),\n totalNetMax: z.coerce.number().optional(),\n totalGrossMin: z.coerce.number().optional(),\n totalGrossMax: z.coerce.number().optional(),\n dateFrom: z.string().optional(),\n dateTo: z.string().optional(),\n tagIds: z.string().optional(),\n tagIdsEmpty: z.string().optional(),\n sortField: z.string().optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n withDeleted: z.coerce.boolean().optional(),\n })\n .passthrough()\n\ntype ListQuery = z.infer<typeof listSchema>\n\nfunction buildFilters(query: ListQuery, numberColumn: string, kind: DocumentKind) {\n const filters: Record<string, unknown> = {}\n if (query.id) filters.id = { $eq: query.id }\n if (query.search && query.search.trim().length > 0) {\n const term = `%${escapeLikePattern(query.search.trim())}%`\n filters[numberColumn] = { $ilike: term }\n }\n if (query.customerId) {\n filters.customer_entity_id = { $eq: query.customerId }\n }\n if (query.channelId) {\n filters.channel_id = { $eq: query.channelId }\n }\n const lineRange: Record<string, number> = {}\n if (typeof query.lineItemCountMin === 'number') lineRange.$gte = query.lineItemCountMin\n if (typeof query.lineItemCountMax === 'number') lineRange.$lte = query.lineItemCountMax\n if (Object.keys(lineRange).length) {\n filters.line_item_count = lineRange\n }\n const netRange: Record<string, number> = {}\n if (typeof query.totalNetMin === 'number') netRange.$gte = query.totalNetMin\n if (typeof query.totalNetMax === 'number') netRange.$lte = query.totalNetMax\n if (Object.keys(netRange).length) {\n filters.grand_total_net_amount = netRange\n }\n const grossRange: Record<string, number> = {}\n if (typeof query.totalGrossMin === 'number') grossRange.$gte = query.totalGrossMin\n if (typeof query.totalGrossMax === 'number') grossRange.$lte = query.totalGrossMax\n if (Object.keys(grossRange).length) {\n filters.grand_total_gross_amount = grossRange\n }\n const dateRange: Record<string, Date> = {}\n if (query.dateFrom) {\n const from = new Date(query.dateFrom)\n if (!Number.isNaN(from.getTime())) dateRange.$gte = from\n }\n if (query.dateTo) {\n const to = new Date(query.dateTo)\n if (!Number.isNaN(to.getTime())) dateRange.$lte = to\n }\n if (Object.keys(dateRange).length) {\n filters.created_at = dateRange\n }\n const tagIdsRaw = typeof query.tagIds === 'string' ? query.tagIds : ''\n const tagIds = tagIdsRaw\n .split(',')\n .map((value) => value.trim())\n .filter((value) => value.length > 0)\n if (parseBooleanToken(query.tagIdsEmpty) === true) {\n filters.id = { $eq: '00000000-0000-0000-0000-000000000000' }\n } else if (tagIds.length) {\n filters['tag_assignments.tag_id'] = { $in: tagIds }\n filters['tag_assignments.document_kind'] = { $eq: kind }\n }\n return filters\n}\n\nfunction buildSortMap(numberColumn: string) {\n return {\n id: 'id',\n number: numberColumn,\n placedAt: 'placed_at',\n lineItemCount: 'line_item_count',\n grandTotalNetAmount: 'grand_total_net_amount',\n grandTotalGrossAmount: 'grand_total_gross_amount',\n createdAt: 'created_at',\n updatedAt: 'updated_at',\n }\n}\n\nconst mapUpdateResponse = (entity: any) => ({\n id: entity?.id ?? null,\n orderNumber: entity?.orderNumber ?? null,\n quoteNumber: entity?.quoteNumber ?? null,\n customerEntityId: entity?.customerEntityId ?? null,\n customerContactId: entity?.customerContactId ?? null,\n customerSnapshot: entity?.customerSnapshot ?? null,\n metadata: entity?.metadata ?? null,\n externalReference: entity?.externalReference ?? null,\n customerReference: entity?.customerReference ?? null,\n comment: entity?.comments ?? null,\n statusEntryId: (entity as any)?.statusEntryId ?? null,\n status: (entity as any)?.status ?? null,\n channelId: (entity as any)?.channelId ?? null,\n customerName: resolveCustomerName(entity?.customerSnapshot ?? null, entity?.customerEntityId ?? null),\n contactEmail:\n resolveCustomerEmail(entity?.customerSnapshot ?? null) ??\n (typeof entity?.metadata?.customerEmail === 'string' ? entity.metadata.customerEmail : null),\n currencyCode: entity?.currencyCode ?? null,\n placedAt: entity?.placedAt ? entity.placedAt.toISOString() : null,\n expectedDeliveryAt: entity?.expectedDeliveryAt ? entity.expectedDeliveryAt.toISOString() : null,\n shippingAddressId: entity?.shippingAddressId ?? null,\n billingAddressId: entity?.billingAddressId ?? null,\n shippingAddressSnapshot: entity?.shippingAddressSnapshot ?? null,\n billingAddressSnapshot: entity?.billingAddressSnapshot ?? null,\n shippingMethodId: entity?.shippingMethodId ?? null,\n shippingMethodCode: entity?.shippingMethodCode ?? null,\n shippingMethodSnapshot: entity?.shippingMethodSnapshot ?? null,\n paymentMethodId: entity?.paymentMethodId ?? null,\n paymentMethodCode: entity?.paymentMethodCode ?? null,\n paymentMethodSnapshot: entity?.paymentMethodSnapshot ?? null,\n})\n\nconst attachTags = async (payload: any, ctx: any) => {\n const items = Array.isArray(payload?.items) ? (payload.items as Array<Record<string, any>>) : []\n if (!items.length) return\n const ids = items\n .map((item) => (item && typeof item.id === 'string' ? item.id : null))\n .filter((id): id is string => !!id)\n if (!ids.length) return\n const em = ctx?.container?.resolve ? (ctx.container.resolve('em') as any) : null\n if (!em) return\n const where: Record<string, unknown> = {\n documentId: { $in: ids },\n documentKind: ctx?.bindingKind ?? null,\n }\n if (ctx?.auth?.tenantId) where.tenantId = ctx.auth.tenantId\n const orgIds =\n Array.isArray(ctx?.organizationIds) && ctx.organizationIds.length\n ? ctx.organizationIds.filter((val: string | null) => !!val)\n : ctx?.selectedOrganizationId\n ? [ctx.selectedOrganizationId]\n : []\n if (orgIds.length) where.organizationId = { $in: orgIds }\n const assignments = await em.find(\n SalesDocumentTagAssignment,\n where,\n { populate: ['tag'] },\n )\n const grouped = new Map<string, Array<{ id: string; label: string; color: string | null }>>()\n assignments.forEach((assignment: any) => {\n const tag = assignment?.tag\n const documentId = assignment?.documentId\n if (!tag || typeof tag.id !== 'string' || typeof documentId !== 'string') return\n const entry = {\n id: tag.id,\n label: typeof tag.label === 'string' && tag.label.trim().length ? tag.label : tag.slug ?? tag.id,\n color: typeof tag.color === 'string' && tag.color.trim().length ? tag.color : null,\n }\n const list = grouped.get(documentId) ?? []\n list.push(entry)\n grouped.set(documentId, list)\n })\n items.forEach((item: Record<string, any>) => {\n const id = item && typeof item.id === 'string' ? item.id : null\n if (!id) return\n const list = grouped.get(id)\n if (list) item.tags = list\n })\n}\n\nasync function ensureNumberEditPermission(\n ctx: CrudCtx,\n translate: (key: string, fallback?: string) => string\n) {\n const rbac = ctx.container?.resolve?.('rbacService') as RbacService | null\n const auth = ctx.auth\n if (!rbac || !auth?.sub) return\n const ok = await rbac.userHasAllFeatures(auth.sub, ['sales.documents.number.edit'], {\n tenantId: auth.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? auth.orgId ?? null,\n })\n if (!ok) {\n throw new CrudHttpError(403, {\n error: translate('sales.documents.errors.number_edit_forbidden', 'You cannot edit document numbers.'),\n })\n }\n}\n\nexport function buildDocumentCrudOptions(binding: DocumentBinding) {\n const numberColumn = binding.numberField === 'orderNumber' ? 'order_number' : 'quote_number'\n const createSchema = binding.kind === 'order' ? orderCreateSchema : quoteCreateSchema\n\n const routeMetadata = {\n GET: { requireAuth: true, requireFeatures: [binding.viewFeature] },\n POST: { requireAuth: true, requireFeatures: [binding.manageFeature] },\n PUT: { requireAuth: true, requireFeatures: [binding.manageFeature] },\n DELETE: { requireAuth: true, requireFeatures: [binding.manageFeature] },\n }\n\n const commonFields = [\n 'id',\n numberColumn,\n 'status',\n 'status_entry_id',\n 'customer_entity_id',\n 'customer_contact_id',\n 'billing_address_id',\n 'shipping_address_id',\n 'customer_snapshot',\n 'billing_address_snapshot',\n 'shipping_address_snapshot',\n 'shipping_method_id',\n 'shipping_method_code',\n 'shipping_method_snapshot',\n 'payment_method_id',\n 'payment_method_code',\n 'payment_method_snapshot',\n 'customer_reference',\n 'metadata',\n 'external_reference',\n 'currency_code',\n 'comments',\n 'channel_id',\n 'placed_at',\n 'line_item_count',\n 'subtotal_net_amount',\n 'subtotal_gross_amount',\n 'tax_total_amount',\n 'discount_total_amount',\n 'grand_total_net_amount',\n 'grand_total_gross_amount',\n 'totals_snapshot',\n 'organization_id',\n 'tenant_id',\n 'created_at',\n 'updated_at',\n ]\n\n const orderOnlyFields = [\n 'expected_delivery_at',\n 'shipping_net_amount',\n 'shipping_gross_amount',\n 'surcharge_total_amount',\n 'paid_total_amount',\n 'refunded_total_amount',\n 'outstanding_amount',\n ]\n\n const quoteOnlyFields = ['valid_from', 'valid_until']\n\n const listFields = [\n ...commonFields,\n ...(binding.kind === 'order' ? orderOnlyFields : quoteOnlyFields),\n ]\n\n return {\n metadata: routeMetadata,\n orm: {\n entity: binding.entity as any,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n indexer: {\n entityType: binding.entityId,\n },\n list: {\n schema: listSchema,\n entityId: binding.entityId,\n fields: listFields,\n sortFieldMap: buildSortMap(numberColumn),\n buildFilters: async (query: any) => buildFilters(query, numberColumn, binding.kind),\n decorateCustomFields: { entityIds: [binding.entityId] },\n joins: [\n {\n alias: 'tag_assignments',\n table: 'sales_document_tag_assignments',\n from: { field: 'id' },\n to: { field: 'document_id' },\n type: 'left' as const,\n },\n ],\n transformItem: (item: any) => {\n const toNumber = (value: unknown): number | null => {\n if (typeof value === 'number') return Number.isNaN(value) ? null : value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? null : parsed\n }\n return null\n }\n const base = {\n id: item.id,\n [binding.numberField]: item[numberColumn] ?? null,\n status: item.status ?? null,\n statusEntryId: item.status_entry_id ?? null,\n customerEntityId: item.customer_entity_id ?? null,\n customerContactId: item.customer_contact_id ?? null,\n billingAddressId: item.billing_address_id ?? null,\n shippingAddressId: item.shipping_address_id ?? null,\n shippingMethodId: item.shipping_method_id ?? null,\n shippingMethodCode: item.shipping_method_code ?? null,\n shippingMethodSnapshot: item.shipping_method_snapshot ?? null,\n paymentMethodId: item.payment_method_id ?? null,\n paymentMethodCode: item.payment_method_code ?? null,\n paymentMethodSnapshot: item.payment_method_snapshot ?? null,\n currencyCode: item.currency_code ?? null,\n channelId: item.channel_id ?? null,\n externalReference: item.external_reference ?? null,\n customerReference: item.customer_reference ?? null,\n placedAt: item.placed_at ?? null,\n expectedDeliveryAt: item.expected_delivery_at ?? null,\n comment: item.comments ?? null,\n validFrom: item.valid_from ?? null,\n validUntil: item.valid_until ?? null,\n lineItemCount: toNumber(item.line_item_count),\n subtotalNetAmount: toNumber(item.subtotal_net_amount),\n subtotalGrossAmount: toNumber(item.subtotal_gross_amount),\n discountTotalAmount: toNumber(item.discount_total_amount),\n taxTotalAmount: toNumber(item.tax_total_amount),\n shippingNetAmount: toNumber(item.shipping_net_amount),\n shippingGrossAmount: toNumber(item.shipping_gross_amount),\n surchargeTotalAmount: toNumber(item.surcharge_total_amount),\n grandTotalNetAmount: toNumber(item.grand_total_net_amount),\n grandTotalGrossAmount: toNumber(item.grand_total_gross_amount),\n paidTotalAmount: toNumber(item.paid_total_amount),\n refundedTotalAmount: toNumber(item.refunded_total_amount),\n outstandingAmount: toNumber(item.outstanding_amount),\n customerSnapshot: item.customer_snapshot ?? null,\n billingAddressSnapshot: item.billing_address_snapshot ?? null,\n shippingAddressSnapshot: item.shipping_address_snapshot ?? null,\n metadata: item.metadata ?? null,\n organizationId: item.organization_id ?? null,\n tenantId: item.tenant_id ?? null,\n createdAt: item.created_at,\n updatedAt: item.updated_at,\n }\n const cfEntries = extractAllCustomFieldEntries(item as Record<string, unknown>)\n const normalized = { ...base }\n Object.keys(normalized).forEach((key) => {\n if (key.startsWith('cf:')) delete (normalized as any)[key]\n })\n return Object.keys(cfEntries).length ? { ...normalized, ...cfEntries } : normalized\n },\n },\n actions: {\n create: {\n commandId: binding.createCommandId,\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }: { raw: unknown; ctx: CrudCtx }) => {\n const { translate } = await resolveTranslations()\n const { base, custom } = splitCustomFieldPayload(raw ?? {})\n const parsed = parseScopedCommandInput(\n createSchema,\n Object.keys(custom).length ? { ...base, customFields: custom } : base,\n ctx,\n translate,\n )\n return parsed\n },\n response: ({ result }: { result: any }) => ({ id: result?.orderId ?? result?.quoteId ?? result?.id ?? null }),\n status: 201,\n },\n update: {\n commandId: binding.updateCommandId,\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }: { raw: unknown; ctx: CrudCtx }) => {\n const { translate } = await resolveTranslations()\n const { base, custom } = splitCustomFieldPayload(raw ?? {})\n const numberValue =\n binding.kind === 'order'\n ? (base as Record<string, unknown>).orderNumber\n : (base as Record<string, unknown>).quoteNumber\n if (typeof numberValue === 'string') {\n await ensureNumberEditPermission(ctx, translate)\n }\n const parsed = parseScopedCommandInput(\n documentUpdateSchema,\n Object.keys(custom).length ? { ...base, customFields: custom } : base,\n ctx,\n translate,\n )\n return parsed\n },\n response: ({ result }: { result: any }) =>\n mapUpdateResponse((result as any)?.order ?? (result as any)?.quote ?? result),\n },\n delete: {\n commandId: binding.deleteCommandId,\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }: { parsed: any; ctx: CrudCtx }) => {\n const { translate } = await resolveTranslations()\n const id = resolveCrudRecordId(parsed, ctx, translate)\n return { id }\n },\n response: () => ({ ok: true }),\n },\n },\n hooks: {\n afterList: async (payload: any, ctx: CrudCtx) => {\n await attachTags(payload, { ...ctx, bindingKind: binding.kind })\n },\n },\n }\n}\n\nexport function buildDocumentOpenApi(binding: DocumentBinding) {\n const createSchema = binding.kind === 'order' ? orderCreateSchema : quoteCreateSchema\n const itemSchema = z.object({\n id: z.string().uuid(),\n [binding.numberField]: z.string().nullable(),\n status: z.string().nullable(),\n statusEntryId: z.string().uuid().nullable().optional(),\n customerEntityId: z.string().uuid().nullable(),\n customerContactId: z.string().uuid().nullable(),\n billingAddressId: z.string().uuid().nullable(),\n shippingAddressId: z.string().uuid().nullable(),\n customerReference: z.string().nullable().optional(),\n externalReference: z.string().nullable().optional(),\n comment: z.string().nullable().optional(),\n placedAt: z.string().nullable().optional(),\n expectedDeliveryAt: z.string().nullable().optional(),\n customerSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n billingAddressSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n shippingAddressSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n shippingMethodId: z.string().uuid().nullable().optional(),\n shippingMethodCode: z.string().nullable().optional(),\n shippingMethodSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n paymentMethodId: z.string().uuid().nullable().optional(),\n paymentMethodCode: z.string().nullable().optional(),\n paymentMethodSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n currencyCode: z.string().nullable(),\n channelId: z.string().uuid().nullable(),\n organizationId: z.string().uuid().nullable(),\n tenantId: z.string().uuid().nullable(),\n validFrom: z.string().nullable().optional(),\n validUntil: z.string().nullable().optional(),\n lineItemCount: z.number().nullable().optional(),\n subtotalNetAmount: z.number().nullable().optional(),\n subtotalGrossAmount: z.number().nullable().optional(),\n discountTotalAmount: z.number().nullable().optional(),\n taxTotalAmount: z.number().nullable().optional(),\n shippingNetAmount: z.number().nullable().optional(),\n shippingGrossAmount: z.number().nullable().optional(),\n surchargeTotalAmount: z.number().nullable().optional(),\n grandTotalNetAmount: z.number().nullable().optional(),\n grandTotalGrossAmount: z.number().nullable().optional(),\n paidTotalAmount: z.number().nullable().optional(),\n refundedTotalAmount: z.number().nullable().optional(),\n outstandingAmount: z.number().nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n customValues: z.record(z.string(), z.unknown()).optional(),\n })\n\n const listResponseSchema = createPagedListResponseSchema(itemSchema)\n\n return createSalesCrudOpenApi({\n resourceName: binding.kind === 'order' ? 'Order' : 'Quote',\n querySchema: listSchema,\n listResponseSchema,\n create: {\n schema: createSchema,\n responseSchema: z.object({ id: z.string().uuid().nullable() }),\n description: `Creates a new sales ${binding.kind}.`,\n },\n del: {\n schema: defaultDeleteRequestSchema,\n responseSchema: z.object({ ok: z.boolean() }),\n description: `Deletes a sales ${binding.kind}.`,\n },\n })\n}\n\n// Compatibility wrapper\nexport function createDocumentCrudRoute(binding: DocumentBinding) {\n const crud = makeCrudRoute(buildDocumentCrudOptions(binding))\n const { GET, POST, PUT, DELETE } = crud\n return { GET, POST, PUT, DELETE, openApi: buildDocumentOpenApi(binding), metadata: crud.metadata }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { makeCrudRoute, type CrudCtx } from '@open-mercato/shared/lib/crud/factory'\nimport { splitCustomFieldPayload, extractAllCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { E } from '#generated/entities.ids.generated'\nimport type { SalesOrder, SalesQuote } from '../../data/entities'\nimport { SalesDocumentTagAssignment } from '../../data/entities'\nimport {\n orderCreateSchema,\n quoteCreateSchema,\n} from '../../data/validators'\nimport {\n createPagedListResponseSchema,\n createSalesCrudOpenApi,\n defaultDeleteRequestSchema,\n} from '../openapi'\nimport { parseScopedCommandInput, resolveCrudRecordId } from '../utils'\nimport { documentUpdateSchema } from '../../commands/documents'\nimport { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport { recalculateOrderTotalsForDisplay } from '../../commands/returns'\n\ntype DocumentKind = 'order' | 'quote'\n\ntype DocumentBinding = {\n kind: DocumentKind\n entity: typeof SalesOrder | typeof SalesQuote\n entityId: (typeof E.sales)[keyof typeof E.sales]\n numberField: 'orderNumber' | 'quoteNumber'\n createCommandId: string\n updateCommandId: string\n deleteCommandId: string\n manageFeature: string\n viewFeature: string\n}\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst resolveCustomerName = (snapshot: Record<string, unknown> | null, fallback?: string | null) => {\n if (!snapshot) return fallback ?? null\n const customer = snapshot.customer as Record<string, unknown> | undefined\n const contact = snapshot.contact as Record<string, unknown> | undefined\n const displayName = typeof customer?.displayName === 'string' ? customer.displayName : null\n if (displayName) return displayName\n const first = typeof contact?.firstName === 'string' ? contact.firstName : null\n const last = typeof contact?.lastName === 'string' ? contact.lastName : null\n const preferred = typeof contact?.preferredName === 'string' ? contact.preferredName : null\n const parts = [preferred ?? first, last].filter((part) => part && part.trim().length)\n if (parts.length) return parts.join(' ')\n return fallback ?? null\n}\n\nconst resolveCustomerEmail = (snapshot: Record<string, unknown> | null) => {\n if (!snapshot) return null\n const customer = snapshot.customer as Record<string, unknown> | undefined\n const primary = typeof customer?.primaryEmail === 'string' ? customer.primaryEmail : null\n return primary ?? null\n}\n\nconst listSchema = z\n .object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n search: z.string().optional(),\n id: z.string().uuid().optional(),\n customerId: z.string().uuid().optional(),\n channelId: z.string().uuid().optional(),\n lineItemCountMin: z.coerce.number().min(0).optional(),\n lineItemCountMax: z.coerce.number().min(0).optional(),\n totalNetMin: z.coerce.number().optional(),\n totalNetMax: z.coerce.number().optional(),\n totalGrossMin: z.coerce.number().optional(),\n totalGrossMax: z.coerce.number().optional(),\n dateFrom: z.string().optional(),\n dateTo: z.string().optional(),\n tagIds: z.string().optional(),\n tagIdsEmpty: z.string().optional(),\n sortField: z.string().optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n withDeleted: z.coerce.boolean().optional(),\n })\n .passthrough()\n\ntype ListQuery = z.infer<typeof listSchema>\n\nfunction buildFilters(query: ListQuery, numberColumn: string, kind: DocumentKind) {\n const filters: Record<string, unknown> = {}\n if (query.id) filters.id = { $eq: query.id }\n if (query.search && query.search.trim().length > 0) {\n const term = `%${escapeLikePattern(query.search.trim())}%`\n filters[numberColumn] = { $ilike: term }\n }\n if (query.customerId) {\n filters.customer_entity_id = { $eq: query.customerId }\n }\n if (query.channelId) {\n filters.channel_id = { $eq: query.channelId }\n }\n const lineRange: Record<string, number> = {}\n if (typeof query.lineItemCountMin === 'number') lineRange.$gte = query.lineItemCountMin\n if (typeof query.lineItemCountMax === 'number') lineRange.$lte = query.lineItemCountMax\n if (Object.keys(lineRange).length) {\n filters.line_item_count = lineRange\n }\n const netRange: Record<string, number> = {}\n if (typeof query.totalNetMin === 'number') netRange.$gte = query.totalNetMin\n if (typeof query.totalNetMax === 'number') netRange.$lte = query.totalNetMax\n if (Object.keys(netRange).length) {\n filters.grand_total_net_amount = netRange\n }\n const grossRange: Record<string, number> = {}\n if (typeof query.totalGrossMin === 'number') grossRange.$gte = query.totalGrossMin\n if (typeof query.totalGrossMax === 'number') grossRange.$lte = query.totalGrossMax\n if (Object.keys(grossRange).length) {\n filters.grand_total_gross_amount = grossRange\n }\n const dateRange: Record<string, Date> = {}\n if (query.dateFrom) {\n const from = new Date(query.dateFrom)\n if (!Number.isNaN(from.getTime())) dateRange.$gte = from\n }\n if (query.dateTo) {\n const to = new Date(query.dateTo)\n if (!Number.isNaN(to.getTime())) dateRange.$lte = to\n }\n if (Object.keys(dateRange).length) {\n filters.created_at = dateRange\n }\n const tagIdsRaw = typeof query.tagIds === 'string' ? query.tagIds : ''\n const tagIds = tagIdsRaw\n .split(',')\n .map((value) => value.trim())\n .filter((value) => value.length > 0)\n if (parseBooleanToken(query.tagIdsEmpty) === true) {\n filters.id = { $eq: '00000000-0000-0000-0000-000000000000' }\n } else if (tagIds.length) {\n filters['tag_assignments.tag_id'] = { $in: tagIds }\n filters['tag_assignments.document_kind'] = { $eq: kind }\n }\n return filters\n}\n\nfunction buildSortMap(numberColumn: string) {\n return {\n id: 'id',\n number: numberColumn,\n placedAt: 'placed_at',\n lineItemCount: 'line_item_count',\n grandTotalNetAmount: 'grand_total_net_amount',\n grandTotalGrossAmount: 'grand_total_gross_amount',\n createdAt: 'created_at',\n updatedAt: 'updated_at',\n }\n}\n\nconst mapUpdateResponse = (entity: any) => ({\n id: entity?.id ?? null,\n orderNumber: entity?.orderNumber ?? null,\n quoteNumber: entity?.quoteNumber ?? null,\n customerEntityId: entity?.customerEntityId ?? null,\n customerContactId: entity?.customerContactId ?? null,\n customerSnapshot: entity?.customerSnapshot ?? null,\n metadata: entity?.metadata ?? null,\n externalReference: entity?.externalReference ?? null,\n customerReference: entity?.customerReference ?? null,\n comment: entity?.comments ?? null,\n statusEntryId: (entity as any)?.statusEntryId ?? null,\n status: (entity as any)?.status ?? null,\n channelId: (entity as any)?.channelId ?? null,\n customerName: resolveCustomerName(entity?.customerSnapshot ?? null, entity?.customerEntityId ?? null),\n contactEmail:\n resolveCustomerEmail(entity?.customerSnapshot ?? null) ??\n (typeof entity?.metadata?.customerEmail === 'string' ? entity.metadata.customerEmail : null),\n currencyCode: entity?.currencyCode ?? null,\n placedAt: entity?.placedAt ? entity.placedAt.toISOString() : null,\n expectedDeliveryAt: entity?.expectedDeliveryAt ? entity.expectedDeliveryAt.toISOString() : null,\n shippingAddressId: entity?.shippingAddressId ?? null,\n billingAddressId: entity?.billingAddressId ?? null,\n shippingAddressSnapshot: entity?.shippingAddressSnapshot ?? null,\n billingAddressSnapshot: entity?.billingAddressSnapshot ?? null,\n shippingMethodId: entity?.shippingMethodId ?? null,\n shippingMethodCode: entity?.shippingMethodCode ?? null,\n shippingMethodSnapshot: entity?.shippingMethodSnapshot ?? null,\n paymentMethodId: entity?.paymentMethodId ?? null,\n paymentMethodCode: entity?.paymentMethodCode ?? null,\n paymentMethodSnapshot: entity?.paymentMethodSnapshot ?? null,\n})\n\nconst attachTags = async (payload: any, ctx: any) => {\n const items = Array.isArray(payload?.items) ? (payload.items as Array<Record<string, any>>) : []\n if (!items.length) return\n const ids = items\n .map((item) => (item && typeof item.id === 'string' ? item.id : null))\n .filter((id): id is string => !!id)\n if (!ids.length) return\n const em = ctx?.container?.resolve ? (ctx.container.resolve('em') as any) : null\n if (!em) return\n const where: Record<string, unknown> = {\n documentId: { $in: ids },\n documentKind: ctx?.bindingKind ?? null,\n }\n if (ctx?.auth?.tenantId) where.tenantId = ctx.auth.tenantId\n const orgIds =\n Array.isArray(ctx?.organizationIds) && ctx.organizationIds.length\n ? ctx.organizationIds.filter((val: string | null) => !!val)\n : ctx?.selectedOrganizationId\n ? [ctx.selectedOrganizationId]\n : []\n if (orgIds.length) where.organizationId = { $in: orgIds }\n const assignments = await em.find(\n SalesDocumentTagAssignment,\n where,\n { populate: ['tag'] },\n )\n const grouped = new Map<string, Array<{ id: string; label: string; color: string | null }>>()\n assignments.forEach((assignment: any) => {\n const tag = assignment?.tag\n const documentId = assignment?.documentId\n if (!tag || typeof tag.id !== 'string' || typeof documentId !== 'string') return\n const entry = {\n id: tag.id,\n label: typeof tag.label === 'string' && tag.label.trim().length ? tag.label : tag.slug ?? tag.id,\n color: typeof tag.color === 'string' && tag.color.trim().length ? tag.color : null,\n }\n const list = grouped.get(documentId) ?? []\n list.push(entry)\n grouped.set(documentId, list)\n })\n items.forEach((item: Record<string, any>) => {\n const id = item && typeof item.id === 'string' ? item.id : null\n if (!id) return\n const list = grouped.get(id)\n if (list) item.tags = list\n })\n}\n\nasync function ensureNumberEditPermission(\n ctx: CrudCtx,\n translate: (key: string, fallback?: string) => string\n) {\n const rbac = ctx.container?.resolve?.('rbacService') as RbacService | null\n const auth = ctx.auth\n if (!rbac || !auth?.sub) return\n const ok = await rbac.userHasAllFeatures(auth.sub, ['sales.documents.number.edit'], {\n tenantId: auth.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? auth.orgId ?? null,\n })\n if (!ok) {\n throw new CrudHttpError(403, {\n error: translate('sales.documents.errors.number_edit_forbidden', 'You cannot edit document numbers.'),\n })\n }\n}\n\nexport function buildDocumentCrudOptions(binding: DocumentBinding) {\n const numberColumn = binding.numberField === 'orderNumber' ? 'order_number' : 'quote_number'\n const createSchema = binding.kind === 'order' ? orderCreateSchema : quoteCreateSchema\n\n const routeMetadata = {\n GET: { requireAuth: true, requireFeatures: [binding.viewFeature] },\n POST: { requireAuth: true, requireFeatures: [binding.manageFeature] },\n PUT: { requireAuth: true, requireFeatures: [binding.manageFeature] },\n DELETE: { requireAuth: true, requireFeatures: [binding.manageFeature] },\n }\n\n const commonFields = [\n 'id',\n numberColumn,\n 'status',\n 'status_entry_id',\n 'customer_entity_id',\n 'customer_contact_id',\n 'billing_address_id',\n 'shipping_address_id',\n 'customer_snapshot',\n 'billing_address_snapshot',\n 'shipping_address_snapshot',\n 'shipping_method_id',\n 'shipping_method_code',\n 'shipping_method_snapshot',\n 'payment_method_id',\n 'payment_method_code',\n 'payment_method_snapshot',\n 'customer_reference',\n 'metadata',\n 'external_reference',\n 'currency_code',\n 'comments',\n 'channel_id',\n 'placed_at',\n 'line_item_count',\n 'subtotal_net_amount',\n 'subtotal_gross_amount',\n 'tax_total_amount',\n 'discount_total_amount',\n 'grand_total_net_amount',\n 'grand_total_gross_amount',\n 'totals_snapshot',\n 'organization_id',\n 'tenant_id',\n 'created_at',\n 'updated_at',\n ]\n\n const orderOnlyFields = [\n 'expected_delivery_at',\n 'shipping_net_amount',\n 'shipping_gross_amount',\n 'surcharge_total_amount',\n 'paid_total_amount',\n 'refunded_total_amount',\n 'outstanding_amount',\n ]\n\n const quoteOnlyFields = ['valid_from', 'valid_until']\n\n const listFields = [\n ...commonFields,\n ...(binding.kind === 'order' ? orderOnlyFields : quoteOnlyFields),\n ]\n\n return {\n metadata: routeMetadata,\n orm: {\n entity: binding.entity as any,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n indexer: {\n entityType: binding.entityId,\n },\n list: {\n schema: listSchema,\n entityId: binding.entityId,\n fields: listFields,\n sortFieldMap: buildSortMap(numberColumn),\n buildFilters: async (query: any) => buildFilters(query, numberColumn, binding.kind),\n decorateCustomFields: { entityIds: [binding.entityId] },\n joins: [\n {\n alias: 'tag_assignments',\n table: 'sales_document_tag_assignments',\n from: { field: 'id' },\n to: { field: 'document_id' },\n type: 'left' as const,\n },\n ],\n transformItem: (item: any) => {\n const toNumber = (value: unknown): number | null => {\n if (typeof value === 'number') return Number.isNaN(value) ? null : value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? null : parsed\n }\n return null\n }\n const base = {\n id: item.id,\n [binding.numberField]: item[numberColumn] ?? null,\n status: item.status ?? null,\n statusEntryId: item.status_entry_id ?? null,\n customerEntityId: item.customer_entity_id ?? null,\n customerContactId: item.customer_contact_id ?? null,\n billingAddressId: item.billing_address_id ?? null,\n shippingAddressId: item.shipping_address_id ?? null,\n shippingMethodId: item.shipping_method_id ?? null,\n shippingMethodCode: item.shipping_method_code ?? null,\n shippingMethodSnapshot: item.shipping_method_snapshot ?? null,\n paymentMethodId: item.payment_method_id ?? null,\n paymentMethodCode: item.payment_method_code ?? null,\n paymentMethodSnapshot: item.payment_method_snapshot ?? null,\n currencyCode: item.currency_code ?? null,\n channelId: item.channel_id ?? null,\n externalReference: item.external_reference ?? null,\n customerReference: item.customer_reference ?? null,\n placedAt: item.placed_at ?? null,\n expectedDeliveryAt: item.expected_delivery_at ?? null,\n comment: item.comments ?? null,\n validFrom: item.valid_from ?? null,\n validUntil: item.valid_until ?? null,\n lineItemCount: toNumber(item.line_item_count),\n subtotalNetAmount: toNumber(item.subtotal_net_amount),\n subtotalGrossAmount: toNumber(item.subtotal_gross_amount),\n discountTotalAmount: toNumber(item.discount_total_amount),\n taxTotalAmount: toNumber(item.tax_total_amount),\n shippingNetAmount: toNumber(item.shipping_net_amount),\n shippingGrossAmount: toNumber(item.shipping_gross_amount),\n surchargeTotalAmount: toNumber(item.surcharge_total_amount),\n grandTotalNetAmount: toNumber(item.grand_total_net_amount),\n grandTotalGrossAmount: toNumber(item.grand_total_gross_amount),\n paidTotalAmount: toNumber(item.paid_total_amount),\n refundedTotalAmount: toNumber(item.refunded_total_amount),\n outstandingAmount: toNumber(item.outstanding_amount),\n customerSnapshot: item.customer_snapshot ?? null,\n billingAddressSnapshot: item.billing_address_snapshot ?? null,\n shippingAddressSnapshot: item.shipping_address_snapshot ?? null,\n metadata: item.metadata ?? null,\n organizationId: item.organization_id ?? null,\n tenantId: item.tenant_id ?? null,\n createdAt: item.created_at,\n updatedAt: item.updated_at,\n }\n const cfEntries = extractAllCustomFieldEntries(item as Record<string, unknown>)\n const normalized = { ...base }\n Object.keys(normalized).forEach((key) => {\n if (key.startsWith('cf:')) delete (normalized as any)[key]\n })\n return Object.keys(cfEntries).length ? { ...normalized, ...cfEntries } : normalized\n },\n },\n actions: {\n create: {\n commandId: binding.createCommandId,\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }: { raw: unknown; ctx: CrudCtx }) => {\n const { translate } = await resolveTranslations()\n const { base, custom } = splitCustomFieldPayload(raw ?? {})\n const parsed = parseScopedCommandInput(\n createSchema,\n Object.keys(custom).length ? { ...base, customFields: custom } : base,\n ctx,\n translate,\n )\n return parsed\n },\n response: ({ result }: { result: any }) => ({ id: result?.orderId ?? result?.quoteId ?? result?.id ?? null }),\n status: 201,\n },\n update: {\n commandId: binding.updateCommandId,\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }: { raw: unknown; ctx: CrudCtx }) => {\n const { translate } = await resolveTranslations()\n const { base, custom } = splitCustomFieldPayload(raw ?? {})\n const numberValue =\n binding.kind === 'order'\n ? (base as Record<string, unknown>).orderNumber\n : (base as Record<string, unknown>).quoteNumber\n if (typeof numberValue === 'string') {\n await ensureNumberEditPermission(ctx, translate)\n }\n const parsed = parseScopedCommandInput(\n documentUpdateSchema,\n Object.keys(custom).length ? { ...base, customFields: custom } : base,\n ctx,\n translate,\n )\n return parsed\n },\n response: ({ result }: { result: any }) =>\n mapUpdateResponse((result as any)?.order ?? (result as any)?.quote ?? result),\n },\n delete: {\n commandId: binding.deleteCommandId,\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }: { parsed: any; ctx: CrudCtx }) => {\n const { translate } = await resolveTranslations()\n const id = resolveCrudRecordId(parsed, ctx, translate)\n return { id }\n },\n response: () => ({ ok: true }),\n },\n },\n hooks: {\n afterList: async (payload: any, ctx: CrudCtx) => {\n await attachTags(payload, { ...ctx, bindingKind: binding.kind })\n if (binding.kind === 'order' && Array.isArray(payload?.items) && payload.items.length === 1) {\n const item = payload.items[0] as Record<string, unknown>\n const orderId = typeof item?.id === 'string' ? item.id : null\n const tenantId = typeof item?.tenantId === 'string' ? item.tenantId : ctx?.auth?.tenantId ?? null\n const organizationId =\n typeof item?.organizationId === 'string' ? item.organizationId : ctx?.selectedOrganizationId ?? ctx?.auth?.orgId ?? null\n if (orderId && tenantId && organizationId) {\n const em = ctx?.container?.resolve?.('em') as import('@mikro-orm/postgresql').EntityManager | undefined\n if (em) {\n const totals = await recalculateOrderTotalsForDisplay(\n em,\n ctx.container,\n orderId,\n { tenantId, organizationId },\n )\n if (totals) {\n Object.assign(item, {\n subtotalNetAmount: totals.subtotalNetAmount,\n subtotalGrossAmount: totals.subtotalGrossAmount,\n discountTotalAmount: totals.discountTotalAmount,\n taxTotalAmount: totals.taxTotalAmount,\n shippingNetAmount: totals.shippingNetAmount,\n shippingGrossAmount: totals.shippingGrossAmount,\n surchargeTotalAmount: totals.surchargeTotalAmount,\n grandTotalNetAmount: totals.grandTotalNetAmount,\n grandTotalGrossAmount: totals.grandTotalGrossAmount,\n paidTotalAmount: totals.paidTotalAmount,\n refundedTotalAmount: totals.refundedTotalAmount,\n outstandingAmount: totals.outstandingAmount,\n })\n }\n }\n }\n }\n },\n },\n }\n}\n\nexport function buildDocumentOpenApi(binding: DocumentBinding) {\n const createSchema = binding.kind === 'order' ? orderCreateSchema : quoteCreateSchema\n const itemSchema = z.object({\n id: z.string().uuid(),\n [binding.numberField]: z.string().nullable(),\n status: z.string().nullable(),\n statusEntryId: z.string().uuid().nullable().optional(),\n customerEntityId: z.string().uuid().nullable(),\n customerContactId: z.string().uuid().nullable(),\n billingAddressId: z.string().uuid().nullable(),\n shippingAddressId: z.string().uuid().nullable(),\n customerReference: z.string().nullable().optional(),\n externalReference: z.string().nullable().optional(),\n comment: z.string().nullable().optional(),\n placedAt: z.string().nullable().optional(),\n expectedDeliveryAt: z.string().nullable().optional(),\n customerSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n billingAddressSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n shippingAddressSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n shippingMethodId: z.string().uuid().nullable().optional(),\n shippingMethodCode: z.string().nullable().optional(),\n shippingMethodSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n paymentMethodId: z.string().uuid().nullable().optional(),\n paymentMethodCode: z.string().nullable().optional(),\n paymentMethodSnapshot: z.record(z.string(), z.unknown()).nullable().optional(),\n currencyCode: z.string().nullable(),\n channelId: z.string().uuid().nullable(),\n organizationId: z.string().uuid().nullable(),\n tenantId: z.string().uuid().nullable(),\n validFrom: z.string().nullable().optional(),\n validUntil: z.string().nullable().optional(),\n lineItemCount: z.number().nullable().optional(),\n subtotalNetAmount: z.number().nullable().optional(),\n subtotalGrossAmount: z.number().nullable().optional(),\n discountTotalAmount: z.number().nullable().optional(),\n taxTotalAmount: z.number().nullable().optional(),\n shippingNetAmount: z.number().nullable().optional(),\n shippingGrossAmount: z.number().nullable().optional(),\n surchargeTotalAmount: z.number().nullable().optional(),\n grandTotalNetAmount: z.number().nullable().optional(),\n grandTotalGrossAmount: z.number().nullable().optional(),\n paidTotalAmount: z.number().nullable().optional(),\n refundedTotalAmount: z.number().nullable().optional(),\n outstandingAmount: z.number().nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n customValues: z.record(z.string(), z.unknown()).optional(),\n })\n\n const listResponseSchema = createPagedListResponseSchema(itemSchema)\n\n return createSalesCrudOpenApi({\n resourceName: binding.kind === 'order' ? 'Order' : 'Quote',\n querySchema: listSchema,\n listResponseSchema,\n create: {\n schema: createSchema,\n responseSchema: z.object({ id: z.string().uuid().nullable() }),\n description: `Creates a new sales ${binding.kind}.`,\n },\n del: {\n schema: defaultDeleteRequestSchema,\n responseSchema: z.object({ ok: z.boolean() }),\n description: `Deletes a sales ${binding.kind}.`,\n },\n })\n}\n\n// Compatibility wrapper\nexport function createDocumentCrudRoute(binding: DocumentBinding) {\n const crud = makeCrudRoute(buildDocumentCrudOptions(binding))\n const { GET, POST, PUT, DELETE } = crud\n return { GET, POST, PUT, DELETE, openApi: buildDocumentOpenApi(binding), metadata: crud.metadata }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { NextResponse } from "next/server";
|
|
3
|
+
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
|
|
4
|
+
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
|
|
5
|
+
import { resolveOrganizationScopeForRequest } from "@open-mercato/core/modules/directory/utils/organizationScope";
|
|
6
|
+
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
7
|
+
import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
|
|
8
|
+
import { findOneWithDecryption, findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
9
|
+
import { SalesReturn, SalesReturnLine } from "../../../data/entities.js";
|
|
10
|
+
const metadata = {
|
|
11
|
+
GET: { requireAuth: true, requireFeatures: ["sales.returns.view"] }
|
|
12
|
+
};
|
|
13
|
+
const paramsSchema = z.object({ id: z.string().uuid() });
|
|
14
|
+
const toNumber = (value) => {
|
|
15
|
+
if (typeof value === "number") return value;
|
|
16
|
+
if (typeof value === "string") {
|
|
17
|
+
const parsed = Number(value);
|
|
18
|
+
if (!Number.isNaN(parsed)) return parsed;
|
|
19
|
+
}
|
|
20
|
+
return 0;
|
|
21
|
+
};
|
|
22
|
+
async function GET(req, ctx) {
|
|
23
|
+
try {
|
|
24
|
+
const { id } = paramsSchema.parse(ctx.params ?? {});
|
|
25
|
+
const container = await createRequestContainer();
|
|
26
|
+
const auth = await getAuthFromRequest(req);
|
|
27
|
+
const { translate } = await resolveTranslations();
|
|
28
|
+
if (!auth || !auth.tenantId) {
|
|
29
|
+
throw new CrudHttpError(401, { error: translate("sales.documents.errors.unauthorized", "Unauthorized") });
|
|
30
|
+
}
|
|
31
|
+
const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req });
|
|
32
|
+
const organizationId = scope?.selectedId ?? auth.orgId ?? null;
|
|
33
|
+
if (!organizationId) {
|
|
34
|
+
throw new CrudHttpError(400, {
|
|
35
|
+
error: translate("sales.documents.errors.organization_required", "Organization context is required")
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const em = container.resolve("em").fork();
|
|
39
|
+
const header = await findOneWithDecryption(
|
|
40
|
+
em,
|
|
41
|
+
SalesReturn,
|
|
42
|
+
{ id, deletedAt: null, tenantId: auth.tenantId, organizationId },
|
|
43
|
+
{ populate: ["order"] },
|
|
44
|
+
{ tenantId: auth.tenantId, organizationId }
|
|
45
|
+
);
|
|
46
|
+
if (!header || !header.order) {
|
|
47
|
+
throw new CrudHttpError(404, { error: translate("sales.returns.notFound", "Return not found.") });
|
|
48
|
+
}
|
|
49
|
+
const lines = await findWithDecryption(
|
|
50
|
+
em,
|
|
51
|
+
SalesReturnLine,
|
|
52
|
+
{ salesReturn: header.id, deletedAt: null },
|
|
53
|
+
{ populate: ["orderLine"] },
|
|
54
|
+
{ tenantId: auth.tenantId, organizationId }
|
|
55
|
+
);
|
|
56
|
+
const totals = lines.reduce(
|
|
57
|
+
(acc, line) => {
|
|
58
|
+
acc.net += toNumber(line.totalNetAmount);
|
|
59
|
+
acc.gross += toNumber(line.totalGrossAmount);
|
|
60
|
+
return acc;
|
|
61
|
+
},
|
|
62
|
+
{ net: 0, gross: 0 }
|
|
63
|
+
);
|
|
64
|
+
return NextResponse.json({
|
|
65
|
+
return: {
|
|
66
|
+
id: header.id,
|
|
67
|
+
orderId: typeof header.order === "string" ? header.order : header.order.id,
|
|
68
|
+
returnNumber: header.returnNumber,
|
|
69
|
+
statusEntryId: header.statusEntryId ?? null,
|
|
70
|
+
status: header.status ?? null,
|
|
71
|
+
reason: header.reason ?? null,
|
|
72
|
+
notes: header.notes ?? null,
|
|
73
|
+
returnedAt: header.returnedAt ? header.returnedAt.toISOString() : null,
|
|
74
|
+
createdAt: header.createdAt ? header.createdAt.toISOString() : null,
|
|
75
|
+
updatedAt: header.updatedAt ? header.updatedAt.toISOString() : null,
|
|
76
|
+
totalNetAmount: totals.net,
|
|
77
|
+
totalGrossAmount: totals.gross
|
|
78
|
+
},
|
|
79
|
+
lines: lines.map((line) => ({
|
|
80
|
+
id: line.id,
|
|
81
|
+
orderLineId: typeof line.orderLine === "string" ? line.orderLine : line.orderLine?.id ?? null,
|
|
82
|
+
quantityReturned: line.quantityReturned,
|
|
83
|
+
unitPriceNet: line.unitPriceNet,
|
|
84
|
+
unitPriceGross: line.unitPriceGross,
|
|
85
|
+
totalNetAmount: line.totalNetAmount,
|
|
86
|
+
totalGrossAmount: line.totalGrossAmount
|
|
87
|
+
}))
|
|
88
|
+
});
|
|
89
|
+
} catch (err) {
|
|
90
|
+
if (err instanceof CrudHttpError) {
|
|
91
|
+
return NextResponse.json(err.body, { status: err.status });
|
|
92
|
+
}
|
|
93
|
+
console.error("sales.returns.get failed", err);
|
|
94
|
+
const { translate } = await resolveTranslations();
|
|
95
|
+
return NextResponse.json({ error: translate("sales.returns.error", "Failed to load return.") }, { status: 400 });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const returnLineSchema = z.object({
|
|
99
|
+
id: z.string().uuid(),
|
|
100
|
+
orderLineId: z.string().uuid().nullable(),
|
|
101
|
+
quantityReturned: z.string(),
|
|
102
|
+
unitPriceNet: z.string(),
|
|
103
|
+
unitPriceGross: z.string(),
|
|
104
|
+
totalNetAmount: z.string(),
|
|
105
|
+
totalGrossAmount: z.string()
|
|
106
|
+
});
|
|
107
|
+
const openApi = {
|
|
108
|
+
tag: "Sales",
|
|
109
|
+
summary: "Get a return",
|
|
110
|
+
pathParams: paramsSchema,
|
|
111
|
+
methods: {
|
|
112
|
+
GET: {
|
|
113
|
+
summary: "Get return details",
|
|
114
|
+
responses: [
|
|
115
|
+
{
|
|
116
|
+
status: 200,
|
|
117
|
+
description: "Return details",
|
|
118
|
+
schema: z.object({
|
|
119
|
+
return: z.object({
|
|
120
|
+
id: z.string().uuid(),
|
|
121
|
+
orderId: z.string().uuid(),
|
|
122
|
+
returnNumber: z.string(),
|
|
123
|
+
statusEntryId: z.string().uuid().nullable(),
|
|
124
|
+
status: z.string().nullable(),
|
|
125
|
+
reason: z.string().nullable(),
|
|
126
|
+
notes: z.string().nullable(),
|
|
127
|
+
returnedAt: z.string().nullable(),
|
|
128
|
+
createdAt: z.string().nullable(),
|
|
129
|
+
updatedAt: z.string().nullable(),
|
|
130
|
+
totalNetAmount: z.number(),
|
|
131
|
+
totalGrossAmount: z.number()
|
|
132
|
+
}),
|
|
133
|
+
lines: z.array(returnLineSchema)
|
|
134
|
+
})
|
|
135
|
+
},
|
|
136
|
+
{ status: 401, description: "Unauthorized", schema: z.object({ error: z.string() }) },
|
|
137
|
+
{ status: 404, description: "Not found", schema: z.object({ error: z.string() }) }
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
export {
|
|
143
|
+
GET,
|
|
144
|
+
metadata,
|
|
145
|
+
openApi
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/sales/api/returns/%5Bid%5D/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { NextResponse } from 'next/server'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { SalesReturn, SalesReturnLine } from '../../../data/entities'\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.returns.view'] },\n}\n\nconst paramsSchema = z.object({ id: z.string().uuid() })\n\nconst toNumber = (value: unknown): number => {\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nexport async function GET(req: Request, ctx: { params: { id: string } }) {\n try {\n const { id } = paramsSchema.parse(ctx.params ?? {})\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: translate('sales.documents.errors.unauthorized', 'Unauthorized') })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationId = scope?.selectedId ?? auth.orgId ?? null\n if (!organizationId) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.errors.organization_required', 'Organization context is required'),\n })\n }\n\n const em = (container.resolve('em') as EntityManager).fork()\n const header = await findOneWithDecryption(\n em,\n SalesReturn,\n { id, deletedAt: null, tenantId: auth.tenantId, organizationId },\n { populate: ['order'] },\n { tenantId: auth.tenantId, organizationId },\n )\n if (!header || !header.order) {\n throw new CrudHttpError(404, { error: translate('sales.returns.notFound', 'Return not found.') })\n }\n\n const lines = await findWithDecryption(\n em,\n SalesReturnLine,\n { salesReturn: header.id, deletedAt: null },\n { populate: ['orderLine'] },\n { tenantId: auth.tenantId, organizationId },\n )\n\n const totals = lines.reduce(\n (acc, line) => {\n acc.net += toNumber(line.totalNetAmount)\n acc.gross += toNumber(line.totalGrossAmount)\n return acc\n },\n { net: 0, gross: 0 },\n )\n\n return NextResponse.json({\n return: {\n id: header.id,\n orderId: typeof header.order === 'string' ? header.order : header.order.id,\n returnNumber: header.returnNumber,\n statusEntryId: header.statusEntryId ?? null,\n status: header.status ?? null,\n reason: header.reason ?? null,\n notes: header.notes ?? null,\n returnedAt: header.returnedAt ? header.returnedAt.toISOString() : null,\n createdAt: header.createdAt ? header.createdAt.toISOString() : null,\n updatedAt: header.updatedAt ? header.updatedAt.toISOString() : null,\n totalNetAmount: totals.net,\n totalGrossAmount: totals.gross,\n },\n lines: lines.map((line) => ({\n id: line.id,\n orderLineId: typeof line.orderLine === 'string' ? line.orderLine : line.orderLine?.id ?? null,\n quantityReturned: line.quantityReturned,\n unitPriceNet: line.unitPriceNet,\n unitPriceGross: line.unitPriceGross,\n totalNetAmount: line.totalNetAmount,\n totalGrossAmount: line.totalGrossAmount,\n })),\n })\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n console.error('sales.returns.get failed', err)\n const { translate } = await resolveTranslations()\n return NextResponse.json({ error: translate('sales.returns.error', 'Failed to load return.') }, { status: 400 })\n }\n}\n\nconst returnLineSchema = z.object({\n id: z.string().uuid(),\n orderLineId: z.string().uuid().nullable(),\n quantityReturned: z.string(),\n unitPriceNet: z.string(),\n unitPriceGross: z.string(),\n totalNetAmount: z.string(),\n totalGrossAmount: z.string(),\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Sales',\n summary: 'Get a return',\n pathParams: paramsSchema,\n methods: {\n GET: {\n summary: 'Get return details',\n responses: [\n {\n status: 200,\n description: 'Return details',\n schema: z.object({\n return: z.object({\n id: z.string().uuid(),\n orderId: z.string().uuid(),\n returnNumber: z.string(),\n statusEntryId: z.string().uuid().nullable(),\n status: z.string().nullable(),\n reason: z.string().nullable(),\n notes: z.string().nullable(),\n returnedAt: z.string().nullable(),\n createdAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n totalNetAmount: z.number(),\n totalGrossAmount: z.number(),\n }),\n lines: z.array(returnLineSchema),\n }),\n },\n { status: 401, description: 'Unauthorized', schema: z.object({ error: z.string() }) },\n { status: 404, description: 'Not found', schema: z.object({ error: z.string() }) },\n ],\n },\n },\n}\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { makeCrudRoute } from "@open-mercato/shared/lib/crud/factory";
|
|
3
|
+
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
4
|
+
import { splitCustomFieldPayload } from "@open-mercato/shared/lib/crud/custom-fields";
|
|
5
|
+
import { withScopedPayload } from "../utils.js";
|
|
6
|
+
import { SalesReturn, SalesReturnLine } from "../../data/entities.js";
|
|
7
|
+
import { returnCreateSchema } from "../../data/validators.js";
|
|
8
|
+
import { E } from "../../../../generated/entities.ids.generated.js";
|
|
9
|
+
import * as F from "../../../../generated/entities/sales_return/index.js";
|
|
10
|
+
import { createPagedListResponseSchema } from "../openapi.js";
|
|
11
|
+
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
12
|
+
const rawBodySchema = z.object({}).passthrough();
|
|
13
|
+
const listSchema = z.object({
|
|
14
|
+
page: z.coerce.number().min(1).default(1),
|
|
15
|
+
pageSize: z.coerce.number().min(1).max(200).default(50),
|
|
16
|
+
orderId: z.string().uuid().optional(),
|
|
17
|
+
sortField: z.string().optional(),
|
|
18
|
+
sortDir: z.enum(["asc", "desc"]).optional()
|
|
19
|
+
}).passthrough();
|
|
20
|
+
const routeMetadata = {
|
|
21
|
+
GET: { requireAuth: true, requireFeatures: ["sales.returns.view"] },
|
|
22
|
+
POST: { requireAuth: true, requireFeatures: ["sales.returns.create"] }
|
|
23
|
+
};
|
|
24
|
+
const toNumber = (value) => {
|
|
25
|
+
if (typeof value === "number") return value;
|
|
26
|
+
if (typeof value === "string") {
|
|
27
|
+
const parsed = Number(value);
|
|
28
|
+
if (!Number.isNaN(parsed)) return parsed;
|
|
29
|
+
}
|
|
30
|
+
return 0;
|
|
31
|
+
};
|
|
32
|
+
const crud = makeCrudRoute({
|
|
33
|
+
metadata: routeMetadata,
|
|
34
|
+
orm: {
|
|
35
|
+
entity: SalesReturn,
|
|
36
|
+
idField: "id",
|
|
37
|
+
orgField: "organizationId",
|
|
38
|
+
tenantField: "tenantId",
|
|
39
|
+
softDeleteField: "deletedAt"
|
|
40
|
+
},
|
|
41
|
+
indexer: {
|
|
42
|
+
entityType: E.sales.sales_return
|
|
43
|
+
},
|
|
44
|
+
list: {
|
|
45
|
+
schema: listSchema,
|
|
46
|
+
entityId: E.sales.sales_return,
|
|
47
|
+
fields: [
|
|
48
|
+
F.id,
|
|
49
|
+
"order_id",
|
|
50
|
+
F.return_number,
|
|
51
|
+
F.status_entry_id,
|
|
52
|
+
F.status,
|
|
53
|
+
F.reason,
|
|
54
|
+
F.notes,
|
|
55
|
+
F.returned_at,
|
|
56
|
+
F.created_at,
|
|
57
|
+
F.updated_at
|
|
58
|
+
],
|
|
59
|
+
sortFieldMap: {
|
|
60
|
+
createdAt: F.created_at,
|
|
61
|
+
updatedAt: F.updated_at,
|
|
62
|
+
returnedAt: F.returned_at
|
|
63
|
+
},
|
|
64
|
+
buildFilters: async (query) => {
|
|
65
|
+
const filters = {};
|
|
66
|
+
if (typeof query.orderId === "string" && query.orderId.length > 0) {
|
|
67
|
+
filters.order_id = { $eq: query.orderId };
|
|
68
|
+
}
|
|
69
|
+
return filters;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
actions: {
|
|
73
|
+
create: {
|
|
74
|
+
commandId: "sales.returns.create",
|
|
75
|
+
schema: rawBodySchema,
|
|
76
|
+
mapInput: async ({ raw, ctx }) => {
|
|
77
|
+
const { translate } = await resolveTranslations();
|
|
78
|
+
const scoped = withScopedPayload(raw ?? {}, ctx, translate);
|
|
79
|
+
const { base } = splitCustomFieldPayload(scoped);
|
|
80
|
+
return returnCreateSchema.parse(base);
|
|
81
|
+
},
|
|
82
|
+
response: ({ result }) => ({ id: result?.returnId ?? null }),
|
|
83
|
+
status: 201
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
hooks: {
|
|
87
|
+
afterList: async (payload, ctx) => {
|
|
88
|
+
const items = Array.isArray(payload.items) ? payload.items : [];
|
|
89
|
+
if (!items.length) return;
|
|
90
|
+
const returnIds = items.map((item) => item && typeof item === "object" ? item.id : null).filter((value) => typeof value === "string");
|
|
91
|
+
if (!returnIds.length) return;
|
|
92
|
+
const em = ctx.container.resolve("em");
|
|
93
|
+
const lines = await findWithDecryption(
|
|
94
|
+
em,
|
|
95
|
+
SalesReturnLine,
|
|
96
|
+
{ salesReturn: { $in: returnIds }, deletedAt: null },
|
|
97
|
+
{},
|
|
98
|
+
{ tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null }
|
|
99
|
+
);
|
|
100
|
+
const totals = lines.reduce((acc, line) => {
|
|
101
|
+
const returnId = typeof line.salesReturn === "string" ? line.salesReturn : line.salesReturn?.id ?? null;
|
|
102
|
+
if (!returnId) return acc;
|
|
103
|
+
const current = acc.get(returnId) ?? { net: 0, gross: 0 };
|
|
104
|
+
current.net += toNumber(line.totalNetAmount);
|
|
105
|
+
current.gross += toNumber(line.totalGrossAmount);
|
|
106
|
+
acc.set(returnId, current);
|
|
107
|
+
return acc;
|
|
108
|
+
}, /* @__PURE__ */ new Map());
|
|
109
|
+
items.forEach((item) => {
|
|
110
|
+
if (!item || typeof item !== "object") return;
|
|
111
|
+
const map = item;
|
|
112
|
+
const id = map.id;
|
|
113
|
+
if (typeof id !== "string") return;
|
|
114
|
+
const sum = totals.get(id);
|
|
115
|
+
if (!sum) return;
|
|
116
|
+
map["total_net_amount"] = sum.net;
|
|
117
|
+
map["total_gross_amount"] = sum.gross;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
const { GET, POST } = crud;
|
|
123
|
+
const returnSchema = z.object({
|
|
124
|
+
id: z.string().uuid(),
|
|
125
|
+
order_id: z.string().uuid(),
|
|
126
|
+
return_number: z.string(),
|
|
127
|
+
status_entry_id: z.string().uuid().nullable().optional(),
|
|
128
|
+
status: z.string().nullable().optional(),
|
|
129
|
+
reason: z.string().nullable().optional(),
|
|
130
|
+
notes: z.string().nullable().optional(),
|
|
131
|
+
returned_at: z.string().nullable().optional(),
|
|
132
|
+
created_at: z.string(),
|
|
133
|
+
updated_at: z.string(),
|
|
134
|
+
total_net_amount: z.number().optional(),
|
|
135
|
+
total_gross_amount: z.number().optional()
|
|
136
|
+
}).passthrough();
|
|
137
|
+
const openApi = {
|
|
138
|
+
tag: "Sales",
|
|
139
|
+
summary: "Manage order returns",
|
|
140
|
+
methods: {
|
|
141
|
+
GET: {
|
|
142
|
+
summary: "List returns",
|
|
143
|
+
query: listSchema,
|
|
144
|
+
responses: [{ status: 200, description: "Returns list", schema: createPagedListResponseSchema(returnSchema) }]
|
|
145
|
+
},
|
|
146
|
+
POST: {
|
|
147
|
+
summary: "Create return",
|
|
148
|
+
requestBody: { schema: returnCreateSchema },
|
|
149
|
+
responses: [{ status: 201, description: "Return created", schema: z.object({ id: z.string().uuid().nullable() }) }]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
export {
|
|
154
|
+
GET,
|
|
155
|
+
POST,
|
|
156
|
+
openApi
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/sales/api/returns/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { splitCustomFieldPayload } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { withScopedPayload } from '../utils'\nimport { SalesReturn, SalesReturnLine } from '../../data/entities'\nimport { returnCreateSchema } from '../../data/validators'\nimport { E } from '#generated/entities.ids.generated'\nimport * as F from '#generated/entities/sales_return'\nimport { createPagedListResponseSchema } from '../openapi'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst listSchema = z\n .object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(200).default(50),\n orderId: z.string().uuid().optional(),\n sortField: z.string().optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n })\n .passthrough()\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.returns.view'] },\n POST: { requireAuth: true, requireFeatures: ['sales.returns.create'] },\n}\n\nconst toNumber = (value: unknown): number => {\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: SalesReturn,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n indexer: {\n entityType: E.sales.sales_return,\n },\n list: {\n schema: listSchema,\n entityId: E.sales.sales_return,\n fields: [\n F.id,\n 'order_id',\n F.return_number,\n F.status_entry_id,\n F.status,\n F.reason,\n F.notes,\n F.returned_at,\n F.created_at,\n F.updated_at,\n ],\n sortFieldMap: {\n createdAt: F.created_at,\n updatedAt: F.updated_at,\n returnedAt: F.returned_at,\n },\n buildFilters: async (query: Record<string, unknown>) => {\n const filters: Record<string, unknown> = {}\n if (typeof query.orderId === 'string' && query.orderId.length > 0) {\n filters.order_id = { $eq: query.orderId }\n }\n return filters\n },\n },\n actions: {\n create: {\n commandId: 'sales.returns.create',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const scoped = withScopedPayload(raw ?? {}, ctx, translate)\n const { base } = splitCustomFieldPayload(scoped)\n return returnCreateSchema.parse(base)\n },\n response: ({ result }) => ({ id: result?.returnId ?? null }),\n status: 201,\n },\n },\n hooks: {\n afterList: async (payload, ctx) => {\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!items.length) return\n const returnIds = items\n .map((item: unknown) => (item && typeof item === 'object' ? (item as Record<string, unknown>).id : null))\n .filter((value: string | null): value is string => typeof value === 'string')\n if (!returnIds.length) return\n const em = ctx.container.resolve('em') as EntityManager\n const lines = await findWithDecryption(\n em,\n SalesReturnLine,\n { salesReturn: { $in: returnIds }, deletedAt: null },\n {},\n { tenantId: ctx.auth?.tenantId ?? null, organizationId: ctx.auth?.orgId ?? null },\n )\n const totals = lines.reduce<Map<string, { net: number; gross: number }>>((acc, line) => {\n const returnId = typeof line.salesReturn === 'string' ? line.salesReturn : line.salesReturn?.id ?? null\n if (!returnId) return acc\n const current = acc.get(returnId) ?? { net: 0, gross: 0 }\n current.net += toNumber(line.totalNetAmount)\n current.gross += toNumber(line.totalGrossAmount)\n acc.set(returnId, current)\n return acc\n }, new Map())\n items.forEach((item: unknown) => {\n if (!item || typeof item !== 'object') return\n const map = item as Record<string, unknown>\n const id = map.id\n if (typeof id !== 'string') return\n const sum = totals.get(id)\n if (!sum) return\n map['total_net_amount'] = sum.net\n map['total_gross_amount'] = sum.gross\n })\n },\n },\n})\n\nconst { GET, POST } = crud\n\nexport { GET, POST }\n\nconst returnSchema = z\n .object({\n id: z.string().uuid(),\n order_id: z.string().uuid(),\n return_number: z.string(),\n status_entry_id: z.string().uuid().nullable().optional(),\n status: z.string().nullable().optional(),\n reason: z.string().nullable().optional(),\n notes: z.string().nullable().optional(),\n returned_at: z.string().nullable().optional(),\n created_at: z.string(),\n updated_at: z.string(),\n total_net_amount: z.number().optional(),\n total_gross_amount: z.number().optional(),\n })\n .passthrough()\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Sales',\n summary: 'Manage order returns',\n methods: {\n GET: {\n summary: 'List returns',\n query: listSchema,\n responses: [{ status: 200, description: 'Returns list', schema: createPagedListResponseSchema(returnSchema) }],\n },\n POST: {\n summary: 'Create return',\n requestBody: { schema: returnCreateSchema },\n responses: [{ status: 201, description: 'Return created', schema: z.object({ id: z.string().uuid().nullable() }) }],\n },\n },\n}\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -36,6 +36,7 @@ import { SalesDocumentItemsSection } from "@open-mercato/core/modules/sales/comp
|
|
|
36
36
|
import { SalesDocumentPaymentsSection } from "@open-mercato/core/modules/sales/components/documents/PaymentsSection";
|
|
37
37
|
import { SalesDocumentAdjustmentsSection } from "@open-mercato/core/modules/sales/components/documents/AdjustmentsSection";
|
|
38
38
|
import { SalesShipmentsSection } from "@open-mercato/core/modules/sales/components/documents/ShipmentsSection";
|
|
39
|
+
import { SalesReturnsSection } from "@open-mercato/core/modules/sales/components/documents/ReturnsSection";
|
|
39
40
|
import { DocumentTotals } from "@open-mercato/core/modules/sales/components/documents/DocumentTotals";
|
|
40
41
|
import { E } from "../../../../../../generated/entities.ids.generated.js";
|
|
41
42
|
import { useCurrencyDictionary } from "@open-mercato/core/modules/customers/components/detail/hooks/useCurrencyDictionary";
|
|
@@ -3230,7 +3231,8 @@ function SalesDocumentDetailPage({
|
|
|
3230
3231
|
if (kind === "order") {
|
|
3231
3232
|
tabs.push(
|
|
3232
3233
|
{ id: "shipments", label: t("sales.documents.detail.tabs.shipments", "Shipments") },
|
|
3233
|
-
{ id: "payments", label: t("sales.documents.detail.tabs.payments", "Payments") }
|
|
3234
|
+
{ id: "payments", label: t("sales.documents.detail.tabs.payments", "Payments") },
|
|
3235
|
+
{ id: "returns", label: t("sales.documents.detail.tabs.returns", "Returns") }
|
|
3234
3236
|
);
|
|
3235
3237
|
}
|
|
3236
3238
|
tabs.push({ id: "adjustments", label: t("sales.documents.detail.tabs.adjustments", "Adjustments") });
|
|
@@ -3361,6 +3363,10 @@ function SalesDocumentDetailPage({
|
|
|
3361
3363
|
title: t("sales.documents.detail.empty.payments.title", "No payments yet."),
|
|
3362
3364
|
description: t("sales.documents.detail.empty.payments.description", "Payments are work in progress.")
|
|
3363
3365
|
},
|
|
3366
|
+
returns: {
|
|
3367
|
+
title: t("sales.returns.empty.title", "No returns yet."),
|
|
3368
|
+
description: t("sales.returns.empty.description", "Create a return to generate credit adjustments for returned items.")
|
|
3369
|
+
},
|
|
3364
3370
|
adjustments: {
|
|
3365
3371
|
title: t("sales.documents.detail.empty.adjustments.title", "No adjustments yet."),
|
|
3366
3372
|
description: t(
|
|
@@ -3455,6 +3461,19 @@ function SalesDocumentDetailPage({
|
|
|
3455
3461
|
}
|
|
3456
3462
|
);
|
|
3457
3463
|
}
|
|
3464
|
+
if (activeTab === "returns") {
|
|
3465
|
+
if (kind !== "order") {
|
|
3466
|
+
const placeholder2 = tabEmptyStates.returns;
|
|
3467
|
+
return /* @__PURE__ */ jsx(TabEmptyState, { title: placeholder2.title, description: placeholder2.description });
|
|
3468
|
+
}
|
|
3469
|
+
return /* @__PURE__ */ jsx(
|
|
3470
|
+
SalesReturnsSection,
|
|
3471
|
+
{
|
|
3472
|
+
orderId: record.id,
|
|
3473
|
+
currencyCode: record.currencyCode ?? null
|
|
3474
|
+
}
|
|
3475
|
+
);
|
|
3476
|
+
}
|
|
3458
3477
|
if (activeTab === "adjustments") {
|
|
3459
3478
|
return /* @__PURE__ */ jsx(
|
|
3460
3479
|
SalesDocumentAdjustmentsSection,
|