@endora-commerce/mod-quote-requests 0.100.0

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.
Files changed (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/admin/index.d.ts +26 -0
  4. package/dist/admin/index.d.ts.map +1 -0
  5. package/dist/admin/index.js +56 -0
  6. package/dist/admin/index.js.map +1 -0
  7. package/dist/admin/pages/RfqCreatePage.d.ts +9 -0
  8. package/dist/admin/pages/RfqCreatePage.d.ts.map +1 -0
  9. package/dist/admin/pages/RfqCreatePage.js +163 -0
  10. package/dist/admin/pages/RfqCreatePage.js.map +1 -0
  11. package/dist/admin/pages/RfqDetail.d.ts +9 -0
  12. package/dist/admin/pages/RfqDetail.d.ts.map +1 -0
  13. package/dist/admin/pages/RfqDetail.js +399 -0
  14. package/dist/admin/pages/RfqDetail.js.map +1 -0
  15. package/dist/admin/pages/RfqList.d.ts +9 -0
  16. package/dist/admin/pages/RfqList.d.ts.map +1 -0
  17. package/dist/admin/pages/RfqList.js +214 -0
  18. package/dist/admin/pages/RfqList.js.map +1 -0
  19. package/dist/admin/validity.d.ts +52 -0
  20. package/dist/admin/validity.d.ts.map +1 -0
  21. package/dist/admin/validity.js +61 -0
  22. package/dist/admin/validity.js.map +1 -0
  23. package/dist/backend/entities/quote-request-event.entity.d.ts +24 -0
  24. package/dist/backend/entities/quote-request-event.entity.d.ts.map +1 -0
  25. package/dist/backend/entities/quote-request-event.entity.js +67 -0
  26. package/dist/backend/entities/quote-request-event.entity.js.map +1 -0
  27. package/dist/backend/entities/quote-request-item.entity.d.ts +34 -0
  28. package/dist/backend/entities/quote-request-item.entity.d.ts.map +1 -0
  29. package/dist/backend/entities/quote-request-item.entity.js +119 -0
  30. package/dist/backend/entities/quote-request-item.entity.js.map +1 -0
  31. package/dist/backend/entities/quote-request-notification-event.entity.d.ts +23 -0
  32. package/dist/backend/entities/quote-request-notification-event.entity.d.ts.map +1 -0
  33. package/dist/backend/entities/quote-request-notification-event.entity.js +72 -0
  34. package/dist/backend/entities/quote-request-notification-event.entity.js.map +1 -0
  35. package/dist/backend/entities/quote-request-revision.entity.d.ts +35 -0
  36. package/dist/backend/entities/quote-request-revision.entity.d.ts.map +1 -0
  37. package/dist/backend/entities/quote-request-revision.entity.js +67 -0
  38. package/dist/backend/entities/quote-request-revision.entity.js.map +1 -0
  39. package/dist/backend/entities/quote-request.entity.d.ts +90 -0
  40. package/dist/backend/entities/quote-request.entity.d.ts.map +1 -0
  41. package/dist/backend/entities/quote-request.entity.js +191 -0
  42. package/dist/backend/entities/quote-request.entity.js.map +1 -0
  43. package/dist/backend/index.d.ts +120 -0
  44. package/dist/backend/index.d.ts.map +1 -0
  45. package/dist/backend/index.js +361 -0
  46. package/dist/backend/index.js.map +1 -0
  47. package/dist/backend/plugin.d.ts +95 -0
  48. package/dist/backend/plugin.d.ts.map +1 -0
  49. package/dist/backend/plugin.js +152 -0
  50. package/dist/backend/plugin.js.map +1 -0
  51. package/dist/backend/routes.admin.d.ts +13 -0
  52. package/dist/backend/routes.admin.d.ts.map +1 -0
  53. package/dist/backend/routes.admin.js +82 -0
  54. package/dist/backend/routes.admin.js.map +1 -0
  55. package/dist/backend/routes.customer.d.ts +18 -0
  56. package/dist/backend/routes.customer.d.ts.map +1 -0
  57. package/dist/backend/routes.customer.js +98 -0
  58. package/dist/backend/routes.customer.js.map +1 -0
  59. package/dist/backend/routes.sales-reps.d.ts +12 -0
  60. package/dist/backend/routes.sales-reps.d.ts.map +1 -0
  61. package/dist/backend/routes.sales-reps.js +57 -0
  62. package/dist/backend/routes.sales-reps.js.map +1 -0
  63. package/dist/backend/services/order-completion-reactor.d.ts +32 -0
  64. package/dist/backend/services/order-completion-reactor.d.ts.map +1 -0
  65. package/dist/backend/services/order-completion-reactor.js +57 -0
  66. package/dist/backend/services/order-completion-reactor.js.map +1 -0
  67. package/dist/backend/services/quote-request-business-id-generator.d.ts +46 -0
  68. package/dist/backend/services/quote-request-business-id-generator.d.ts.map +1 -0
  69. package/dist/backend/services/quote-request-business-id-generator.js +69 -0
  70. package/dist/backend/services/quote-request-business-id-generator.js.map +1 -0
  71. package/dist/backend/services/quote-request-read-port.d.ts +36 -0
  72. package/dist/backend/services/quote-request-read-port.d.ts.map +1 -0
  73. package/dist/backend/services/quote-request-read-port.js +96 -0
  74. package/dist/backend/services/quote-request-read-port.js.map +1 -0
  75. package/dist/backend/services/raised-on-channel.d.ts +23 -0
  76. package/dist/backend/services/raised-on-channel.d.ts.map +1 -0
  77. package/dist/backend/services/raised-on-channel.js +26 -0
  78. package/dist/backend/services/raised-on-channel.js.map +1 -0
  79. package/dist/backend/services/rfq-admin-service.d.ts +75 -0
  80. package/dist/backend/services/rfq-admin-service.d.ts.map +1 -0
  81. package/dist/backend/services/rfq-admin-service.js +487 -0
  82. package/dist/backend/services/rfq-admin-service.js.map +1 -0
  83. package/dist/backend/services/rfq-event-service.d.ts +32 -0
  84. package/dist/backend/services/rfq-event-service.d.ts.map +1 -0
  85. package/dist/backend/services/rfq-event-service.js +28 -0
  86. package/dist/backend/services/rfq-event-service.js.map +1 -0
  87. package/dist/backend/services/rfq-expiry-worker.d.ts +50 -0
  88. package/dist/backend/services/rfq-expiry-worker.d.ts.map +1 -0
  89. package/dist/backend/services/rfq-expiry-worker.js +70 -0
  90. package/dist/backend/services/rfq-expiry-worker.js.map +1 -0
  91. package/dist/backend/services/rfq-notification-service.d.ts +36 -0
  92. package/dist/backend/services/rfq-notification-service.d.ts.map +1 -0
  93. package/dist/backend/services/rfq-notification-service.js +52 -0
  94. package/dist/backend/services/rfq-notification-service.js.map +1 -0
  95. package/dist/backend/services/rfq-revision-service.d.ts +70 -0
  96. package/dist/backend/services/rfq-revision-service.d.ts.map +1 -0
  97. package/dist/backend/services/rfq-revision-service.js +120 -0
  98. package/dist/backend/services/rfq-revision-service.js.map +1 -0
  99. package/dist/backend/services/rfq-service.d.ts +140 -0
  100. package/dist/backend/services/rfq-service.d.ts.map +1 -0
  101. package/dist/backend/services/rfq-service.js +786 -0
  102. package/dist/backend/services/rfq-service.js.map +1 -0
  103. package/dist/backend/services/sales-channel-attributions.d.ts +38 -0
  104. package/dist/backend/services/sales-channel-attributions.d.ts.map +1 -0
  105. package/dist/backend/services/sales-channel-attributions.js +48 -0
  106. package/dist/backend/services/sales-channel-attributions.js.map +1 -0
  107. package/dist/manifest.d.ts +203 -0
  108. package/dist/manifest.d.ts.map +1 -0
  109. package/dist/manifest.js +277 -0
  110. package/dist/manifest.js.map +1 -0
  111. package/dist/migrations/20260424T190112_quote_requests_init.d.ts +19 -0
  112. package/dist/migrations/20260424T190112_quote_requests_init.d.ts.map +1 -0
  113. package/dist/migrations/20260424T190112_quote_requests_init.js +65 -0
  114. package/dist/migrations/20260424T190112_quote_requests_init.js.map +1 -0
  115. package/dist/migrations/20260503T141344_quote_requests_workflow.d.ts +37 -0
  116. package/dist/migrations/20260503T141344_quote_requests_workflow.d.ts.map +1 -0
  117. package/dist/migrations/20260503T141344_quote_requests_workflow.js +251 -0
  118. package/dist/migrations/20260503T141344_quote_requests_workflow.js.map +1 -0
  119. package/dist/migrations/20260611T140415_quote_requests_qr_item_packaging.d.ts +10 -0
  120. package/dist/migrations/20260611T140415_quote_requests_qr_item_packaging.d.ts.map +1 -0
  121. package/dist/migrations/20260611T140415_quote_requests_qr_item_packaging.js +16 -0
  122. package/dist/migrations/20260611T140415_quote_requests_qr_item_packaging.js.map +1 -0
  123. package/dist/migrations/20260611T140417_quote_requests_business_id.d.ts +24 -0
  124. package/dist/migrations/20260611T140417_quote_requests_business_id.d.ts.map +1 -0
  125. package/dist/migrations/20260611T140417_quote_requests_business_id.js +34 -0
  126. package/dist/migrations/20260611T140417_quote_requests_business_id.js.map +1 -0
  127. package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.d.ts +21 -0
  128. package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.d.ts.map +1 -0
  129. package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.js +29 -0
  130. package/dist/migrations/20260617T095510_quote_requests_backfill_admin_created_awaiting.js.map +1 -0
  131. package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.d.ts +12 -0
  132. package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.d.ts.map +1 -0
  133. package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.js +16 -0
  134. package/dist/migrations/20260718T200342_quote_requests_quote_request_custom_field_values.js.map +1 -0
  135. package/dist/migrations/20260912T125614_quote_requests_quote_request_channel_attribution.d.ts +34 -0
  136. package/dist/migrations/20260912T125614_quote_requests_quote_request_channel_attribution.d.ts.map +1 -0
  137. package/dist/migrations/20260912T125614_quote_requests_quote_request_channel_attribution.js +57 -0
  138. package/dist/migrations/20260912T125614_quote_requests_quote_request_channel_attribution.js.map +1 -0
  139. package/dist/migrations/index.d.ts +53 -0
  140. package/dist/migrations/index.d.ts.map +1 -0
  141. package/dist/migrations/index.js +61 -0
  142. package/dist/migrations/index.js.map +1 -0
  143. package/dist/migrations/status-mapping.d.ts +18 -0
  144. package/dist/migrations/status-mapping.d.ts.map +1 -0
  145. package/dist/migrations/status-mapping.js +28 -0
  146. package/dist/migrations/status-mapping.js.map +1 -0
  147. package/docs/quote_requests.md +168 -0
  148. package/i18n/en.json +14 -0
  149. package/i18n/pl.json +14 -0
  150. package/package.json +99 -0
  151. package/tailwind.css +14 -0
@@ -0,0 +1,214 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useState } from 'react';
3
+ import { Link, useSearchParams } from 'react-router-dom';
4
+ import { ArrowRight, Columns3, Plus, Search, SlidersHorizontal, X } from 'lucide-react';
5
+ import { apiClient, ApiError, formatDateTime, normalize, useAuth, usePageSizePreference } from '@endora-commerce/admin-kit/lib';
6
+ import { Alert, AlertDescription, Badge, Button, Card, CardContent, Label, MultiSelect, PageHeader, Select } from '@endora-commerce/admin-kit/ui';
7
+ import { OrganizationPicker, PaginationFooter, ResponsiveTable } from '@endora-commerce/admin-kit/components';
8
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
9
+ const RFQ_STATUSES = [
10
+ 'Created from admin',
11
+ 'Pending',
12
+ 'Canceled',
13
+ 'Approved',
14
+ 'Completed',
15
+ 'Expired',
16
+ ];
17
+ const STATUS_VARIANT = {
18
+ 'Created from admin': 'warning',
19
+ Pending: 'warning',
20
+ Approved: 'success',
21
+ Completed: 'default',
22
+ Canceled: 'destructive',
23
+ Expired: 'secondary',
24
+ };
25
+ // Pickable columns in display order. The actions column is structural and is
26
+ // always rendered, so it is not part of the picker.
27
+ const COLUMN_IDS = ['rfq', 'updated', 'org', 'customer', 'status', 'lines', 'total'];
28
+ const DEFAULT_VISIBLE = ['rfq', 'org', 'customer', 'status', 'lines', 'total'];
29
+ function rowTotal(r) {
30
+ return r.totalAtAgreedPrice ?? r.totalAtCustomerPrice;
31
+ }
32
+ function formatTotal(r) {
33
+ const total = rowTotal(r);
34
+ if (total === null)
35
+ return '—';
36
+ return `${total.toLocaleString('pl-PL', { minimumFractionDigits: 2 })} ${r.currency}`;
37
+ }
38
+ export function RfqList() {
39
+ const t = useTranslation('core');
40
+ const { me } = useAuth();
41
+ const { pageSize, setPageSize } = usePageSizePreference('quote-requests');
42
+ const [searchParams] = useSearchParams();
43
+ // A platform admin sees every organization's requests, so the per-user "mine"
44
+ // scope would show them nothing — default their Visibility filter to "all".
45
+ const isPlatformAdmin = me?.role?.code === 'platform_admin';
46
+ const [rows, setRows] = useState([]);
47
+ const [loading, setLoading] = useState(true);
48
+ const [error, setError] = useState(null);
49
+ const [page, setPage] = useState(0);
50
+ // Server-side filters (bound caller visibility / dataset size).
51
+ const [scope, setScope] = useState(() => {
52
+ const fromUrl = searchParams.get('scope');
53
+ if (fromUrl === 'all' || fromUrl === 'unassigned' || fromUrl === 'mine')
54
+ return fromUrl;
55
+ return isPlatformAdmin ? 'all' : 'mine';
56
+ });
57
+ const [organizationId, setOrganizationId] = useState('');
58
+ // Client-side filters.
59
+ const [statusCodes, setStatusCodes] = useState(() => {
60
+ const fromUrl = searchParams.get('status');
61
+ return fromUrl !== null && RFQ_STATUSES.includes(fromUrl) ? [fromUrl] : [];
62
+ });
63
+ const [q, setQ] = useState('');
64
+ const [sort, setSort] = useState('updatedAt:desc');
65
+ const [filtersOpen, setFiltersOpen] = useState(false);
66
+ const [visibleColumnIds, setVisibleColumnIds] = useState(DEFAULT_VISIBLE);
67
+ const refresh = useCallback(async () => {
68
+ setLoading(true);
69
+ setError(null);
70
+ try {
71
+ const params = new URLSearchParams();
72
+ if (scope)
73
+ params.set('assignmentScope', scope);
74
+ if (organizationId)
75
+ params.set('organizationId', organizationId);
76
+ const path = '/api/v1/admin/quote-requests' + (params.toString() ? `?${params.toString()}` : '');
77
+ const res = await apiClient.get(path);
78
+ setRows(res.data);
79
+ }
80
+ catch (err) {
81
+ setError(err instanceof ApiError ? err.envelope.error.message : t('rfq.list.error.load'));
82
+ }
83
+ finally {
84
+ setLoading(false);
85
+ }
86
+ }, [scope, organizationId, t]);
87
+ useEffect(() => {
88
+ void refresh();
89
+ }, [refresh]);
90
+ // Reset to the first page whenever a filter narrows the result set.
91
+ useEffect(() => {
92
+ setPage(0);
93
+ }, [scope, organizationId, statusCodes, q, sort, pageSize]);
94
+ // Apply the client-side filters + sort, then paginate.
95
+ const filtered = useMemo(() => {
96
+ const needle = normalize(q);
97
+ const statusSet = new Set(statusCodes);
98
+ let out = rows.filter((r) => {
99
+ if (statusSet.size > 0 && !statusSet.has(r.status))
100
+ return false;
101
+ if (needle) {
102
+ const hay = [
103
+ r.businessId ?? '',
104
+ r.id,
105
+ r.organizationName ?? '',
106
+ r.customerDisplayName ?? '',
107
+ ]
108
+ .map(normalize)
109
+ .join(' ');
110
+ if (!hay.includes(needle))
111
+ return false;
112
+ }
113
+ return true;
114
+ });
115
+ const [field, dir] = sort.split(':');
116
+ const mul = dir === 'asc' ? 1 : -1;
117
+ out = [...out].sort((a, b) => {
118
+ if (field === 'total')
119
+ return ((rowTotal(a) ?? 0) - (rowTotal(b) ?? 0)) * mul;
120
+ return (Date.parse(a.updatedAt) - Date.parse(b.updatedAt)) * mul;
121
+ });
122
+ return out;
123
+ }, [rows, q, statusCodes, sort]);
124
+ const total = filtered.length;
125
+ const pageRows = useMemo(() => filtered.slice(page * pageSize, page * pageSize + pageSize), [filtered, page, pageSize]);
126
+ const statusOptions = RFQ_STATUSES.map((s) => ({ value: s, label: s }));
127
+ const columnOptions = COLUMN_IDS.map((id) => ({
128
+ value: id,
129
+ label: t(`rfq.list.column.${id}`),
130
+ }));
131
+ const advancedActiveCount = (scope !== 'mine' ? 1 : 0) + (organizationId ? 1 : 0);
132
+ const filterChips = [
133
+ ...statusCodes.map((code) => ({
134
+ key: `status:${code}`,
135
+ label: `${t('rfq.list.field.status')}: ${code}`,
136
+ onRemove: () => setStatusCodes((p) => p.filter((c) => c !== code)),
137
+ })),
138
+ ...(organizationId
139
+ ? [
140
+ {
141
+ key: 'org',
142
+ label: `${t('rfq.list.field.organizationId')}: ${rows.find((r) => r.organizationId === organizationId)?.organizationName ??
143
+ organizationId.slice(0, 8)}`,
144
+ onRemove: () => setOrganizationId(''),
145
+ },
146
+ ]
147
+ : []),
148
+ ...(scope !== 'mine'
149
+ ? [
150
+ {
151
+ key: 'scope',
152
+ label: `${t('rfq.list.field.visibility')}: ${t(`rfq.list.scope.${scope}`)}`,
153
+ onRemove: () => setScope('mine'),
154
+ },
155
+ ]
156
+ : []),
157
+ ];
158
+ const clearAllFilters = () => {
159
+ setStatusCodes([]);
160
+ setOrganizationId('');
161
+ setScope('mine');
162
+ setQ('');
163
+ };
164
+ const columnDefs = {
165
+ rfq: {
166
+ id: 'rfq',
167
+ header: t('rfq.list.column.rfq'),
168
+ primary: true,
169
+ render: (r) => (_jsxs(Link, { to: `/quote-requests/${r.id}`, className: "font-mono text-xs underline underline-offset-2", children: ["#", r.businessId ?? r.id.slice(0, 8)] })),
170
+ meta: (r) => formatDateTime(r.updatedAt),
171
+ },
172
+ updated: {
173
+ id: 'updated',
174
+ header: t('rfq.list.column.updated'),
175
+ render: (r) => formatDateTime(r.updatedAt),
176
+ },
177
+ org: {
178
+ id: 'org',
179
+ header: t('rfq.list.column.organization'),
180
+ render: (r) => r.organizationName ?? r.organizationId.slice(0, 8),
181
+ },
182
+ customer: {
183
+ id: 'customer',
184
+ header: t('rfq.list.column.customer'),
185
+ render: (r) => r.customerDisplayName ?? '—',
186
+ },
187
+ status: {
188
+ id: 'status',
189
+ header: t('rfq.list.column.status'),
190
+ render: (r) => (_jsxs(_Fragment, { children: [_jsx(Badge, { variant: STATUS_VARIANT[r.status] ?? 'default', children: r.status }), r.awaitingCustomerRevisionAcceptance ? (_jsx(Badge, { variant: "warning", className: "ml-1", children: t('rfq.list.badge.awaitingCustomer') })) : null] })),
191
+ },
192
+ lines: {
193
+ id: 'lines',
194
+ header: t('rfq.list.column.lines'),
195
+ hideOnMobile: true,
196
+ render: (r) => r.lineCount,
197
+ },
198
+ total: {
199
+ id: 'total',
200
+ header: t('rfq.list.column.total'),
201
+ render: (r) => _jsx("span", { className: "tabular-nums", children: formatTotal(r) }),
202
+ },
203
+ };
204
+ const visibleSet = new Set(visibleColumnIds);
205
+ const tableColumns = COLUMN_IDS.filter((id) => visibleSet.has(id)).map((id) => columnDefs[id]);
206
+ return (_jsxs(_Fragment, { children: [_jsx(PageHeader, { title: t('rfq.list.title'), description: t('rfq.list.description'), actions: _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/quote-requests/new", children: [_jsx(Plus, {}), t('rfq.list.create')] }) }) }), error ? (_jsx(Alert, { variant: "destructive", className: "mb-4", children: _jsx(AlertDescription, { children: error }) })) : null, _jsx(Card, { className: "mb-4", children: _jsxs(CardContent, { className: "space-y-3 pt-6", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "relative min-w-[220px] flex-1", children: [_jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }), _jsx("input", { id: "rfqsearch", className: "h-9 w-full rounded-md border pl-8 pr-3 text-sm", value: q, onChange: (e) => setQ(e.target.value), placeholder: t('rfq.list.search.placeholder'), "aria-label": t('rfq.list.field.search') })] }), _jsx(MultiSelect, { className: "w-44", ariaLabel: t('rfq.list.field.status'), placeholder: t('rfq.list.field.status'), options: statusOptions, selected: statusCodes, onChange: setStatusCodes }), _jsxs(Select, { id: "rfqsort", "aria-label": t('rfq.list.field.sort'), value: sort, onChange: (e) => setSort(e.target.value), className: "w-auto", children: [_jsx("option", { value: "updatedAt:desc", children: t('rfq.list.sort.newest') }), _jsx("option", { value: "updatedAt:asc", children: t('rfq.list.sort.oldest') }), _jsx("option", { value: "total:desc", children: t('rfq.list.sort.totalDesc') })] }), _jsxs("div", { className: "ml-auto flex items-center gap-2", children: [_jsxs(Button, { type: "button", size: "sm", variant: filtersOpen || advancedActiveCount > 0 ? 'default' : 'outline', "aria-expanded": filtersOpen, onClick: () => setFiltersOpen((o) => !o), children: [_jsx(SlidersHorizontal, {}), t('rfq.list.filter.toggle'), advancedActiveCount > 0 ? ` (${advancedActiveCount})` : ''] }), _jsx(MultiSelect, { className: "w-40", ariaLabel: t('rfq.list.columns.label'), placeholder: t('rfq.list.columns.label'), icon: _jsx(Columns3, { className: "size-4 opacity-70" }), options: columnOptions, selected: visibleColumnIds, onChange: (next) => setVisibleColumnIds(next.filter((c) => COLUMN_IDS.includes(c))) })] })] }), filterChips.length > 0 ? (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [filterChips.map((chip) => (_jsxs("button", { type: "button", onClick: chip.onRemove, className: "inline-flex items-center gap-1 rounded-full border bg-muted/40 px-2.5 py-1 text-xs hover:bg-muted", children: [_jsx("span", { children: chip.label }), _jsx(X, { className: "size-3 opacity-70" })] }, chip.key))), _jsx("button", { type: "button", onClick: clearAllFilters, className: "text-xs text-muted-foreground underline underline-offset-2 hover:text-foreground", children: t('rfq.list.filter.clearAll') })] })) : null, filtersOpen ? (_jsxs("div", { className: "grid grid-cols-2 gap-3 border-t pt-3 sm:grid-cols-3 lg:grid-cols-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { htmlFor: "rfq-scope", children: t('rfq.list.field.visibility') }), _jsxs(Select, { id: "rfq-scope", value: scope, onChange: (e) => setScope(e.target.value), children: [_jsx("option", { value: "mine", children: t('rfq.list.scope.mine') }), _jsx("option", { value: "unassigned", children: t('rfq.list.scope.unassigned') }), _jsx("option", { value: "all", children: t('rfq.list.scope.all') })] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { htmlFor: "rfq-org", children: t('rfq.list.field.organizationId') }), _jsx(OrganizationPicker, { id: "rfq-org", value: organizationId || null, onChange: (v) => setOrganizationId(v ?? '') })] })] })) : null] }) }), _jsx(Card, { children: _jsxs(CardContent, { className: "pt-6", children: [loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('rfq.list.loading') })) : total === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('rfq.list.empty') })) : (_jsx(ResponsiveTable, { data: pageRows, keyExtractor: (r) => r.id, columns: tableColumns, renderActions: (r) => (_jsx(Button, { asChild: true, variant: "outline", size: "sm", className: "min-h-11", children: _jsxs(Link, { to: `/quote-requests/${r.id}`, children: [t('rfq.list.open'), _jsx(ArrowRight, {})] }) })) })), _jsx(PaginationFooter, { page: page, pageSize: pageSize, total: total, onPageSizeChange: setPageSize, onPrev: () => setPage((p) => Math.max(0, p - 1)), onNext: () => setPage((p) => p + 1) })] }) })] }));
207
+ }
208
+ /**
209
+ * The registry loads a route component through a dynamic-import factory and
210
+ * reads its default export (feature 091, FR-013). The named export stays: it is
211
+ * the spelling this module's own code and its tests use.
212
+ */
213
+ export default RfqList;
214
+ //# sourceMappingURL=RfqList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RfqList.js","sourceRoot":"","sources":["../../../src/admin/pages/RfqList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The per-request validity deadline (`expiresAt`) an operator sets through
3
+ * `expiresInDays`, read as the three states the detail screen has to tell
4
+ * apart. Kept out of `RfqDetail.tsx` so the arithmetic can be unit-tested
5
+ * without mounting the screen.
6
+ *
7
+ * The deadline is a rule and not decoration: past it the customer is refused
8
+ * `410 RFQ_EXPIRED` on accept-revision and `410 QUOTE_VALIDITY_ENDED` on
9
+ * convert-to-order. An absent deadline means the operator set none, which
10
+ * refuses nothing — so "none" and "lapsed" are different answers about the
11
+ * same field and neither may be rendered as the other.
12
+ */
13
+ /** One day in milliseconds — the unit `expiresInDays` is counted in. */
14
+ export declare const MS_PER_DAY = 86400000;
15
+ export type RfqValidity = {
16
+ kind: 'none';
17
+ } | {
18
+ kind: 'active';
19
+ expiresAt: string;
20
+ } | {
21
+ kind: 'lapsed';
22
+ expiresAt: string;
23
+ };
24
+ /**
25
+ * Classifies a request's `expiresAt` against a reference instant.
26
+ *
27
+ * An unparsable timestamp answers `active`: the screen may not tell an
28
+ * operator that a customer is being refused unless it can show the date they
29
+ * are refused from. The server is the authority in either case.
30
+ */
31
+ export declare function rfqValidity(expiresAt: string | null | undefined, now: Date): RfqValidity;
32
+ /**
33
+ * The deadline the API will store for a typed `expiresInDays`, computed with
34
+ * the arithmetic the server uses (`RfqAdminService.modify`:
35
+ * `new Date(Date.now() + expiresInDays * 86_400_000)`).
36
+ *
37
+ * The preview this feeds is the operator's only sight of the date before it
38
+ * becomes a commitment the customer is held to, so it has to be the server's
39
+ * own answer rather than an approximation of it.
40
+ *
41
+ * Returns `null` for input the contract would reject
42
+ * (`z.number().int().nonnegative()`) and for a blank field, which means "leave
43
+ * the deadline as it is" — the caller distinguishes the two by looking at the
44
+ * raw string, because they are different sentences on screen.
45
+ */
46
+ export declare function deadlineForDays(raw: string, now: Date): Date | null;
47
+ /**
48
+ * Whether a non-blank `expiresInDays` field would be refused by the contract.
49
+ * Blank is not an error — it is the "keep the current deadline" case.
50
+ */
51
+ export declare function isValidityDaysInvalid(raw: string, now: Date): boolean;
52
+ //# sourceMappingURL=validity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validity.d.ts","sourceRoot":"","sources":["../../src/admin/validity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,wEAAwE;AACxE,eAAO,MAAM,UAAU,WAAa,CAAC;AAErC,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,WAAW,CAOxF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAMnE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAErE"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * The per-request validity deadline (`expiresAt`) an operator sets through
3
+ * `expiresInDays`, read as the three states the detail screen has to tell
4
+ * apart. Kept out of `RfqDetail.tsx` so the arithmetic can be unit-tested
5
+ * without mounting the screen.
6
+ *
7
+ * The deadline is a rule and not decoration: past it the customer is refused
8
+ * `410 RFQ_EXPIRED` on accept-revision and `410 QUOTE_VALIDITY_ENDED` on
9
+ * convert-to-order. An absent deadline means the operator set none, which
10
+ * refuses nothing — so "none" and "lapsed" are different answers about the
11
+ * same field and neither may be rendered as the other.
12
+ */
13
+ /** One day in milliseconds — the unit `expiresInDays` is counted in. */
14
+ export const MS_PER_DAY = 86_400_000;
15
+ /**
16
+ * Classifies a request's `expiresAt` against a reference instant.
17
+ *
18
+ * An unparsable timestamp answers `active`: the screen may not tell an
19
+ * operator that a customer is being refused unless it can show the date they
20
+ * are refused from. The server is the authority in either case.
21
+ */
22
+ export function rfqValidity(expiresAt, now) {
23
+ if (expiresAt === null || expiresAt === undefined || expiresAt === '')
24
+ return { kind: 'none' };
25
+ const at = new Date(expiresAt);
26
+ // `NaN <= now` is false, so an unparsable value falls through to `active`.
27
+ return at.getTime() <= now.getTime()
28
+ ? { kind: 'lapsed', expiresAt }
29
+ : { kind: 'active', expiresAt };
30
+ }
31
+ /**
32
+ * The deadline the API will store for a typed `expiresInDays`, computed with
33
+ * the arithmetic the server uses (`RfqAdminService.modify`:
34
+ * `new Date(Date.now() + expiresInDays * 86_400_000)`).
35
+ *
36
+ * The preview this feeds is the operator's only sight of the date before it
37
+ * becomes a commitment the customer is held to, so it has to be the server's
38
+ * own answer rather than an approximation of it.
39
+ *
40
+ * Returns `null` for input the contract would reject
41
+ * (`z.number().int().nonnegative()`) and for a blank field, which means "leave
42
+ * the deadline as it is" — the caller distinguishes the two by looking at the
43
+ * raw string, because they are different sentences on screen.
44
+ */
45
+ export function deadlineForDays(raw, now) {
46
+ const trimmed = raw.trim();
47
+ if (trimmed === '')
48
+ return null;
49
+ const days = Number(trimmed);
50
+ if (!Number.isInteger(days) || days < 0)
51
+ return null;
52
+ return new Date(now.getTime() + days * MS_PER_DAY);
53
+ }
54
+ /**
55
+ * Whether a non-blank `expiresInDays` field would be refused by the contract.
56
+ * Blank is not an error — it is the "keep the current deadline" case.
57
+ */
58
+ export function isValidityDaysInvalid(raw, now) {
59
+ return raw.trim() !== '' && deadlineForDays(raw, now) === null;
60
+ }
61
+ //# sourceMappingURL=validity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validity.js","sourceRoot":"","sources":["../../src/admin/validity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,wEAAwE;AACxE,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC;AAOrC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,SAAoC,EAAE,GAAS;IACzE,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC/F,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/B,2EAA2E;IAC3E,OAAO,EAAE,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE;QAClC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE;QAC/B,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,GAAS;IACpD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrD,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,UAAU,CAAC,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW,EAAE,GAAS;IAC1D,OAAO,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;AACjE,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ /**
3
+ * QuoteRequestEvent — append-only change log driving the storefront
4
+ * and admin history block (FR-035 / FR-037).
5
+ *
6
+ * `payload` is a discriminated union shaped per data-model.md §4.1.
7
+ * The DB schema does NOT enforce the union shape (jsonb); the service
8
+ * layer must validate it at write time via Zod. The service-side
9
+ * helper is in rfq-event-service.ts.
10
+ */
11
+ export type QuoteRequestEventType = 'created' | 'submitted' | 'modified' | 'approved' | 'canceled' | 'expired' | 'completed' | 'customer-accepted-revision' | 'customer-rejected-revision' | 're-submitted' | 'note-added';
12
+ export declare class QuoteRequestEvent {
13
+ [OptionalProps]?: 'id' | 'createdAt' | 'actorAdminUserId' | 'actorCustomerAccountId' | 'actorRoleLabel' | 'revisionId';
14
+ id: string;
15
+ quoteRequestId: string;
16
+ eventType: QuoteRequestEventType;
17
+ actorAdminUserId?: string | null;
18
+ actorCustomerAccountId?: string | null;
19
+ actorRoleLabel?: string | null;
20
+ payload: Record<string, unknown>;
21
+ revisionId?: string | null;
22
+ createdAt: Date;
23
+ }
24
+ //# sourceMappingURL=quote-request-event.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-request-event.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/quote-request-event.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAwB,MAAM,iBAAiB,CAAC;AAIrF;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,WAAW,GACX,UAAU,GACV,UAAU,GACV,UAAU,GACV,SAAS,GACT,WAAW,GACX,4BAA4B,GAC5B,4BAA4B,GAC5B,cAAc,GACd,YAAY,CAAC;AAEjB,qBAEa,iBAAiB;IAC5B,CAAC,aAAa,CAAC,CAAC,EACZ,IAAI,GACJ,WAAW,GACX,kBAAkB,GAClB,wBAAwB,GACxB,gBAAgB,GAChB,YAAY,CAAC;IAGjB,EAAE,EAAE,MAAM,CAAgB;IAI1B,cAAc,EAAG,MAAM,CAAC;IAGxB,SAAS,EAAG,qBAAqB,CAAC;IAGlC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGjC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGvC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG/B,OAAO,EAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGlC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG3B,SAAS,EAAE,IAAI,CAAc;CAC9B"}
@@ -0,0 +1,67 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, Index, OptionalProps, PrimaryKey, Property } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ let QuoteRequestEvent = class QuoteRequestEvent {
14
+ [OptionalProps];
15
+ id = randomUUID();
16
+ quoteRequestId;
17
+ eventType;
18
+ actorAdminUserId;
19
+ actorCustomerAccountId;
20
+ actorRoleLabel;
21
+ payload;
22
+ revisionId;
23
+ createdAt = new Date();
24
+ };
25
+ __decorate([
26
+ PrimaryKey({ type: 'uuid' }),
27
+ __metadata("design:type", String)
28
+ ], QuoteRequestEvent.prototype, "id", void 0);
29
+ __decorate([
30
+ Property({ type: 'uuid' }),
31
+ Index(),
32
+ __metadata("design:type", String)
33
+ ], QuoteRequestEvent.prototype, "quoteRequestId", void 0);
34
+ __decorate([
35
+ Property({ type: 'string', length: 64 }),
36
+ __metadata("design:type", String)
37
+ ], QuoteRequestEvent.prototype, "eventType", void 0);
38
+ __decorate([
39
+ Property({ type: 'uuid', nullable: true }),
40
+ __metadata("design:type", Object)
41
+ ], QuoteRequestEvent.prototype, "actorAdminUserId", void 0);
42
+ __decorate([
43
+ Property({ type: 'uuid', nullable: true }),
44
+ __metadata("design:type", Object)
45
+ ], QuoteRequestEvent.prototype, "actorCustomerAccountId", void 0);
46
+ __decorate([
47
+ Property({ type: 'string', length: 64, nullable: true }),
48
+ __metadata("design:type", Object)
49
+ ], QuoteRequestEvent.prototype, "actorRoleLabel", void 0);
50
+ __decorate([
51
+ Property({ type: 'json' }),
52
+ __metadata("design:type", Object)
53
+ ], QuoteRequestEvent.prototype, "payload", void 0);
54
+ __decorate([
55
+ Property({ type: 'uuid', nullable: true }),
56
+ __metadata("design:type", Object)
57
+ ], QuoteRequestEvent.prototype, "revisionId", void 0);
58
+ __decorate([
59
+ Property({ type: 'datetime', onCreate: () => new Date() }),
60
+ __metadata("design:type", Date)
61
+ ], QuoteRequestEvent.prototype, "createdAt", void 0);
62
+ QuoteRequestEvent = __decorate([
63
+ GlobalEntity(),
64
+ Entity({ tableName: 'quote_request_events' })
65
+ ], QuoteRequestEvent);
66
+ export { QuoteRequestEvent };
67
+ //# sourceMappingURL=quote-request-event.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-request-event.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/quote-request-event.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AA0B7B,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAC5B,CAAC,aAAa,CAAC,CAME;IAGjB,EAAE,GAAW,UAAU,EAAE,CAAC;IAI1B,cAAc,CAAU;IAGxB,SAAS,CAAyB;IAGlC,gBAAgB,CAAiB;IAGjC,sBAAsB,CAAiB;IAGvC,cAAc,CAAiB;IAG/B,OAAO,CAA2B;IAGlC,UAAU,CAAiB;IAG3B,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AA1BC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;6CACH;AAI1B;IAFC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,EAAE;;yDACgB;AAGxB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;;oDACP;AAGlC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;2DACV;AAGjC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;iEACJ;AAGvC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;yDAC1B;AAG/B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;kDACO;AAGlC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;qDAChB;AAG3B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BAChD,IAAI;oDAAc;AAnClB,iBAAiB;IAF7B,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,sBAAsB,EAAE,CAAC;GACjC,iBAAiB,CAoC7B"}
@@ -0,0 +1,34 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ /**
3
+ * QuoteRequestItem — a line on a Quote Request (feature 008).
4
+ * Snapshots productName + productSlug so an archived product still
5
+ * renders on a historical RFQ. `desiredUnitPrice` is the customer's
6
+ * non-binding wish; the sales rep populates `agreedUnitPrice` on
7
+ * approve / modify. `lineCurrency` snapshots the customer's price-list
8
+ * currency at line creation time.
9
+ */
10
+ export declare class QuoteRequestItem {
11
+ [OptionalProps]?: 'id' | 'createdAt' | 'updatedAt' | 'variantId' | 'variantLabel' | 'productSlug' | 'lineNote' | 'desiredUnitPrice' | 'agreedUnitPrice' | 'discountPercent' | 'packagingUnitName' | 'packagingUnitBaseQuantity';
12
+ id: string;
13
+ quoteRequestId: string;
14
+ productId: string;
15
+ productName: string;
16
+ productSlug?: string | null;
17
+ variantId?: string | null;
18
+ variantLabel?: string | null;
19
+ quantity: number;
20
+ /**
21
+ * Feature 043 — set when the line was added as a packaging unit. The unit
22
+ * name is also appended to `productName` so RFQ views show the suffix.
23
+ */
24
+ packagingUnitName?: string | null;
25
+ packagingUnitBaseQuantity?: number | null;
26
+ lineNote?: string | null;
27
+ desiredUnitPrice?: string | null;
28
+ agreedUnitPrice?: string | null;
29
+ discountPercent?: string | null;
30
+ lineCurrency: string;
31
+ createdAt: Date;
32
+ updatedAt: Date;
33
+ }
34
+ //# sourceMappingURL=quote-request-item.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-request-item.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/quote-request-item.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAwB,MAAM,iBAAiB,CAAC;AAIrF;;;;;;;GAOG;AACH,qBAEa,gBAAgB;IAC3B,CAAC,aAAa,CAAC,CAAC,EACZ,IAAI,GACJ,WAAW,GACX,WAAW,GACX,WAAW,GACX,cAAc,GACd,aAAa,GACb,UAAU,GACV,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,GACjB,mBAAmB,GACnB,2BAA2B,CAAC;IAGhC,EAAE,EAAE,MAAM,CAAgB;IAI1B,cAAc,EAAG,MAAM,CAAC;IAGxB,SAAS,EAAG,MAAM,CAAC;IAGnB,WAAW,EAAG,MAAM,CAAC;IAGrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG1B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG7B,QAAQ,EAAG,MAAM,CAAC;IAElB;;;OAGG;IAEH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGlC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG1C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGzB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,YAAY,EAAG,MAAM,CAAC;IAGtB,SAAS,EAAE,IAAI,CAAc;IAG7B,SAAS,EAAE,IAAI,CAAc;CAC9B"}
@@ -0,0 +1,119 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, Index, OptionalProps, PrimaryKey, Property } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ /**
14
+ * QuoteRequestItem — a line on a Quote Request (feature 008).
15
+ * Snapshots productName + productSlug so an archived product still
16
+ * renders on a historical RFQ. `desiredUnitPrice` is the customer's
17
+ * non-binding wish; the sales rep populates `agreedUnitPrice` on
18
+ * approve / modify. `lineCurrency` snapshots the customer's price-list
19
+ * currency at line creation time.
20
+ */
21
+ let QuoteRequestItem = class QuoteRequestItem {
22
+ [OptionalProps];
23
+ id = randomUUID();
24
+ quoteRequestId;
25
+ productId;
26
+ productName;
27
+ productSlug;
28
+ variantId;
29
+ variantLabel;
30
+ quantity;
31
+ /**
32
+ * Feature 043 — set when the line was added as a packaging unit. The unit
33
+ * name is also appended to `productName` so RFQ views show the suffix.
34
+ */
35
+ packagingUnitName;
36
+ packagingUnitBaseQuantity;
37
+ lineNote;
38
+ desiredUnitPrice;
39
+ agreedUnitPrice;
40
+ discountPercent;
41
+ lineCurrency;
42
+ createdAt = new Date();
43
+ updatedAt = new Date();
44
+ };
45
+ __decorate([
46
+ PrimaryKey({ type: 'uuid' }),
47
+ __metadata("design:type", String)
48
+ ], QuoteRequestItem.prototype, "id", void 0);
49
+ __decorate([
50
+ Property({ type: 'uuid' }),
51
+ Index(),
52
+ __metadata("design:type", String)
53
+ ], QuoteRequestItem.prototype, "quoteRequestId", void 0);
54
+ __decorate([
55
+ Property({ type: 'uuid' }),
56
+ __metadata("design:type", String)
57
+ ], QuoteRequestItem.prototype, "productId", void 0);
58
+ __decorate([
59
+ Property({ type: 'string', length: 255 }),
60
+ __metadata("design:type", String)
61
+ ], QuoteRequestItem.prototype, "productName", void 0);
62
+ __decorate([
63
+ Property({ type: 'string', length: 255, nullable: true }),
64
+ __metadata("design:type", Object)
65
+ ], QuoteRequestItem.prototype, "productSlug", void 0);
66
+ __decorate([
67
+ Property({ type: 'uuid', nullable: true }),
68
+ __metadata("design:type", Object)
69
+ ], QuoteRequestItem.prototype, "variantId", void 0);
70
+ __decorate([
71
+ Property({ type: 'string', length: 255, nullable: true }),
72
+ __metadata("design:type", Object)
73
+ ], QuoteRequestItem.prototype, "variantLabel", void 0);
74
+ __decorate([
75
+ Property({ type: 'integer' }),
76
+ __metadata("design:type", Number)
77
+ ], QuoteRequestItem.prototype, "quantity", void 0);
78
+ __decorate([
79
+ Property({ type: 'string', length: 160, nullable: true }),
80
+ __metadata("design:type", Object)
81
+ ], QuoteRequestItem.prototype, "packagingUnitName", void 0);
82
+ __decorate([
83
+ Property({ type: 'integer', nullable: true }),
84
+ __metadata("design:type", Object)
85
+ ], QuoteRequestItem.prototype, "packagingUnitBaseQuantity", void 0);
86
+ __decorate([
87
+ Property({ type: 'text', nullable: true }),
88
+ __metadata("design:type", Object)
89
+ ], QuoteRequestItem.prototype, "lineNote", void 0);
90
+ __decorate([
91
+ Property({ type: 'decimal', precision: 12, scale: 2, nullable: true }),
92
+ __metadata("design:type", Object)
93
+ ], QuoteRequestItem.prototype, "desiredUnitPrice", void 0);
94
+ __decorate([
95
+ Property({ type: 'decimal', precision: 12, scale: 2, nullable: true }),
96
+ __metadata("design:type", Object)
97
+ ], QuoteRequestItem.prototype, "agreedUnitPrice", void 0);
98
+ __decorate([
99
+ Property({ type: 'decimal', precision: 5, scale: 2, nullable: true }),
100
+ __metadata("design:type", Object)
101
+ ], QuoteRequestItem.prototype, "discountPercent", void 0);
102
+ __decorate([
103
+ Property({ type: 'string', length: 3 }),
104
+ __metadata("design:type", String)
105
+ ], QuoteRequestItem.prototype, "lineCurrency", void 0);
106
+ __decorate([
107
+ Property({ type: 'datetime', onCreate: () => new Date() }),
108
+ __metadata("design:type", Date)
109
+ ], QuoteRequestItem.prototype, "createdAt", void 0);
110
+ __decorate([
111
+ Property({ type: 'datetime', onUpdate: () => new Date() }),
112
+ __metadata("design:type", Date)
113
+ ], QuoteRequestItem.prototype, "updatedAt", void 0);
114
+ QuoteRequestItem = __decorate([
115
+ GlobalEntity(),
116
+ Entity({ tableName: 'quote_request_items' })
117
+ ], QuoteRequestItem);
118
+ export { QuoteRequestItem };
119
+ //# sourceMappingURL=quote-request-item.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-request-item.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/quote-request-item.entity.ts"],"names":[],"mappings":"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"}