@open-mercato/core 0.4.5-develop-3ce83a8b24 → 0.4.5-develop-539cff4960
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/catalog_product/index.js +16 -0
- package/dist/generated/entities/catalog_product/index.js.map +2 -2
- package/dist/generated/entities/catalog_product_unit_conversion/index.js +27 -0
- package/dist/generated/entities/catalog_product_unit_conversion/index.js.map +7 -0
- package/dist/generated/entities/sales_credit_memo_line/index.js +7 -1
- package/dist/generated/entities/sales_credit_memo_line/index.js.map +2 -2
- package/dist/generated/entities/sales_invoice_line/index.js +7 -1
- package/dist/generated/entities/sales_invoice_line/index.js.map +2 -2
- package/dist/generated/entities/sales_order_line/index.js +6 -0
- package/dist/generated/entities/sales_order_line/index.js.map +2 -2
- package/dist/generated/entities/sales_quote_line/index.js +6 -0
- package/dist/generated/entities/sales_quote_line/index.js.map +2 -2
- package/dist/generated/entities.ids.generated.js +1 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +2 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/catalog/api/prices/route.js +123 -8
- package/dist/modules/catalog/api/prices/route.js.map +2 -2
- package/dist/modules/catalog/api/product-unit-conversions/route.js +194 -0
- package/dist/modules/catalog/api/product-unit-conversions/route.js.map +7 -0
- package/dist/modules/catalog/api/products/route.js +351 -201
- package/dist/modules/catalog/api/products/route.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +1267 -497
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +733 -210
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/commands/index.js +1 -0
- package/dist/modules/catalog/commands/index.js.map +2 -2
- package/dist/modules/catalog/commands/productUnitConversions.js +503 -0
- package/dist/modules/catalog/commands/productUnitConversions.js.map +7 -0
- package/dist/modules/catalog/commands/products.js +355 -73
- package/dist/modules/catalog/commands/products.js.map +2 -2
- package/dist/modules/catalog/commands/shared.js +18 -4
- package/dist/modules/catalog/commands/shared.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductUomSection.js +591 -0
- package/dist/modules/catalog/components/products/ProductUomSection.js.map +7 -0
- package/dist/modules/catalog/components/products/productForm.js +66 -5
- package/dist/modules/catalog/components/products/productForm.js.map +2 -2
- package/dist/modules/catalog/components/products/productFormUtils.js +68 -0
- package/dist/modules/catalog/components/products/productFormUtils.js.map +7 -0
- package/dist/modules/catalog/data/entities.js +86 -0
- package/dist/modules/catalog/data/entities.js.map +2 -2
- package/dist/modules/catalog/data/validators.js +65 -3
- package/dist/modules/catalog/data/validators.js.map +2 -2
- package/dist/modules/catalog/events.js +3 -0
- package/dist/modules/catalog/events.js.map +2 -2
- package/dist/modules/catalog/lib/unitCodes.js +7 -0
- package/dist/modules/catalog/lib/unitCodes.js.map +7 -0
- package/dist/modules/catalog/lib/unitResolution.js +53 -0
- package/dist/modules/catalog/lib/unitResolution.js.map +7 -0
- package/dist/modules/catalog/migrations/Migration20260218225422.js +19 -0
- package/dist/modules/catalog/migrations/Migration20260218225422.js.map +7 -0
- package/dist/modules/catalog/migrations/Migration20260219084500.js +27 -0
- package/dist/modules/catalog/migrations/Migration20260219084500.js.map +7 -0
- package/dist/modules/catalog/search.js +69 -1
- package/dist/modules/catalog/search.js.map +2 -2
- package/dist/modules/catalog/seed/examples.js +91 -42
- package/dist/modules/catalog/seed/examples.js.map +2 -2
- package/dist/modules/dashboards/seed/analytics.js +3 -0
- package/dist/modules/dashboards/seed/analytics.js.map +2 -2
- package/dist/modules/sales/api/order-lines/route.js +98 -15
- package/dist/modules/sales/api/order-lines/route.js.map +2 -2
- package/dist/modules/sales/api/quote-lines/route.js +101 -14
- package/dist/modules/sales/api/quote-lines/route.js.map +2 -2
- package/dist/modules/sales/api/quotes/public/[token]/route.js +87 -12
- package/dist/modules/sales/api/quotes/public/[token]/route.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +1424 -260
- package/dist/modules/sales/commands/documents.js.map +3 -3
- package/dist/modules/sales/commands/shared.js +6 -2
- package/dist/modules/sales/commands/shared.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +216 -86
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +913 -241
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +3 -3
- package/dist/modules/sales/components/documents/ShipmentsSection.js +15 -3
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/data/entities.js +59 -3
- package/dist/modules/sales/data/entities.js.map +2 -2
- package/dist/modules/sales/data/validators.js +35 -0
- package/dist/modules/sales/data/validators.js.map +2 -2
- package/dist/modules/sales/frontend/quote/[token]/page.js +15 -1
- package/dist/modules/sales/frontend/quote/[token]/page.js.map +2 -2
- package/dist/modules/sales/migrations/Migration20260218225423.js +31 -0
- package/dist/modules/sales/migrations/Migration20260218225423.js.map +7 -0
- package/dist/modules/sales/migrations/Migration20260219084501.js +71 -0
- package/dist/modules/sales/migrations/Migration20260219084501.js.map +7 -0
- package/dist/modules/sales/search.js +28 -0
- package/dist/modules/sales/search.js.map +2 -2
- package/dist/modules/sales/seed/examples.js +14 -1
- package/dist/modules/sales/seed/examples.js.map +2 -2
- package/dist/modules/sales/widgets/injection/document-history/widget.client.js +1 -1
- package/dist/modules/sales/widgets/injection/document-history/widget.client.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +28 -15
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/translations.js +9 -0
- package/dist/modules/staff/translations.js.map +7 -0
- package/dist/modules/translations/components/TranslationDrawerAction.js +97 -0
- package/dist/modules/translations/components/TranslationDrawerAction.js.map +7 -0
- package/dist/modules/translations/lib/extract-record-id.js +31 -2
- package/dist/modules/translations/lib/extract-record-id.js.map +2 -2
- package/dist/modules/translations/lib/resolve-field-list.js +3 -0
- package/dist/modules/translations/lib/resolve-field-list.js.map +2 -2
- package/dist/modules/translations/widgets/injection/translation-manager/widget.client.js +105 -36
- package/dist/modules/translations/widgets/injection/translation-manager/widget.client.js.map +2 -2
- package/dist/modules/translations/widgets/injection-table.js +18 -29
- package/dist/modules/translations/widgets/injection-table.js.map +2 -2
- package/generated/entities/catalog_product/index.ts +8 -0
- package/generated/entities/catalog_product_unit_conversion/index.ts +12 -0
- package/generated/entities/sales_credit_memo_line/index.ts +3 -0
- package/generated/entities/sales_invoice_line/index.ts +3 -0
- package/generated/entities/sales_order_line/index.ts +3 -0
- package/generated/entities/sales_quote_line/index.ts +3 -0
- package/generated/entities.ids.generated.ts +1 -0
- package/generated/entity-fields-registry.ts +2 -0
- package/package.json +2 -2
- package/src/modules/auth/i18n/de.json +1 -1
- package/src/modules/auth/i18n/en.json +1 -1
- package/src/modules/auth/i18n/es.json +1 -1
- package/src/modules/auth/i18n/pl.json +1 -1
- package/src/modules/catalog/api/prices/route.ts +213 -81
- package/src/modules/catalog/api/product-unit-conversions/route.ts +195 -0
- package/src/modules/catalog/api/products/route.ts +638 -402
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +2085 -1072
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +1288 -593
- package/src/modules/catalog/commands/index.ts +1 -0
- package/src/modules/catalog/commands/productUnitConversions.ts +626 -0
- package/src/modules/catalog/commands/products.ts +1151 -693
- package/src/modules/catalog/commands/shared.ts +19 -5
- package/src/modules/catalog/components/products/ProductUomSection.tsx +745 -0
- package/src/modules/catalog/components/products/productForm.ts +369 -256
- package/src/modules/catalog/components/products/productFormUtils.ts +82 -0
- package/src/modules/catalog/data/entities.ts +82 -1
- package/src/modules/catalog/data/validators.ts +118 -34
- package/src/modules/catalog/events.ts +3 -0
- package/src/modules/catalog/i18n/de.json +56 -0
- package/src/modules/catalog/i18n/en.json +56 -0
- package/src/modules/catalog/i18n/es.json +56 -0
- package/src/modules/catalog/i18n/pl.json +56 -0
- package/src/modules/catalog/lib/unitCodes.ts +1 -0
- package/src/modules/catalog/lib/unitResolution.ts +62 -0
- package/src/modules/catalog/migrations/.snapshot-open-mercato.json +245 -0
- package/src/modules/catalog/migrations/Migration20260218225422.ts +21 -0
- package/src/modules/catalog/migrations/Migration20260219084500.ts +26 -0
- package/src/modules/catalog/search.ts +73 -1
- package/src/modules/catalog/seed/examples.ts +552 -479
- package/src/modules/dashboards/i18n/de.json +1 -1
- package/src/modules/dashboards/i18n/en.json +1 -1
- package/src/modules/dashboards/i18n/es.json +1 -1
- package/src/modules/dashboards/i18n/pl.json +1 -1
- package/src/modules/dashboards/seed/analytics.ts +3 -0
- package/src/modules/sales/api/order-lines/route.ts +158 -68
- package/src/modules/sales/api/quote-lines/route.ts +161 -67
- package/src/modules/sales/api/quotes/public/[token]/route.ts +122 -36
- package/src/modules/sales/commands/documents.ts +4250 -2424
- package/src/modules/sales/commands/shared.ts +7 -2
- package/src/modules/sales/components/documents/ItemsSection.tsx +580 -310
- package/src/modules/sales/components/documents/LineItemDialog.tsx +1988 -833
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +17 -3
- package/src/modules/sales/components/documents/lineItemTypes.ts +6 -0
- package/src/modules/sales/data/entities.ts +53 -0
- package/src/modules/sales/data/validators.ts +36 -0
- package/src/modules/sales/frontend/quote/[token]/page.tsx +25 -1
- package/src/modules/sales/i18n/de.json +23 -3
- package/src/modules/sales/i18n/en.json +23 -3
- package/src/modules/sales/i18n/es.json +23 -3
- package/src/modules/sales/i18n/pl.json +23 -3
- package/src/modules/sales/lib/types.ts +30 -0
- package/src/modules/sales/migrations/.snapshot-open-mercato.json +172 -0
- package/src/modules/sales/migrations/Migration20260218225423.ts +37 -0
- package/src/modules/sales/migrations/Migration20260219084501.ts +73 -0
- package/src/modules/sales/search.ts +28 -0
- package/src/modules/sales/seed/examples.ts +20 -1
- package/src/modules/sales/widgets/injection/document-history/widget.client.tsx +1 -1
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +8 -0
- package/src/modules/staff/translations.ts +5 -0
- package/src/modules/translations/components/TranslationDrawerAction.tsx +107 -0
- package/src/modules/translations/lib/extract-record-id.ts +47 -3
- package/src/modules/translations/lib/resolve-field-list.ts +4 -0
- package/src/modules/translations/widgets/injection/translation-manager/widget.client.tsx +108 -36
- package/src/modules/translations/widgets/injection-table.ts +19 -33
- package/src/modules/workflows/i18n/de.json +4 -4
- package/src/modules/workflows/i18n/en.json +4 -4
- package/src/modules/workflows/i18n/es.json +4 -4
- package/src/modules/workflows/i18n/pl.json +4 -4
|
@@ -11,7 +11,10 @@ import { deleteCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
|
11
11
|
import { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
|
|
12
12
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
13
13
|
import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
emitSalesDocumentTotalsRefresh,
|
|
16
|
+
subscribeSalesDocumentTotalsRefresh,
|
|
17
|
+
} from '@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents'
|
|
15
18
|
import type { SectionAction } from '@open-mercato/core/modules/customers/components/detail/types'
|
|
16
19
|
import { generateTempId } from '@open-mercato/core/modules/customers/lib/detailHelpers'
|
|
17
20
|
import { formatAddressString, type AddressValue } from '@open-mercato/core/modules/customers/utils/addressFormat'
|
|
@@ -157,7 +160,7 @@ export function SalesShipmentsSection({
|
|
|
157
160
|
)
|
|
158
161
|
|
|
159
162
|
const loadLines = React.useCallback(async () => {
|
|
160
|
-
const params = new URLSearchParams({ page: '1', pageSize: '
|
|
163
|
+
const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })
|
|
161
164
|
const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(
|
|
162
165
|
`/api/sales/order-lines?${params.toString()}`,
|
|
163
166
|
undefined,
|
|
@@ -204,7 +207,7 @@ export function SalesShipmentsSection({
|
|
|
204
207
|
setLoading(true)
|
|
205
208
|
setError(null)
|
|
206
209
|
try {
|
|
207
|
-
const params = new URLSearchParams({ page: '1', pageSize: '
|
|
210
|
+
const params = new URLSearchParams({ page: '1', pageSize: '100', orderId })
|
|
208
211
|
const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(
|
|
209
212
|
`/api/sales/shipments?${params.toString()}`,
|
|
210
213
|
undefined,
|
|
@@ -357,6 +360,17 @@ export function SalesShipmentsSection({
|
|
|
357
360
|
void loadShipments()
|
|
358
361
|
}, [loadLines, loadShipments])
|
|
359
362
|
|
|
363
|
+
React.useEffect(
|
|
364
|
+
() =>
|
|
365
|
+
subscribeSalesDocumentTotalsRefresh((detail) => {
|
|
366
|
+
if (detail.documentId !== orderId) return
|
|
367
|
+
if (detail.kind && detail.kind !== 'order') return
|
|
368
|
+
void loadLines()
|
|
369
|
+
void loadShipments()
|
|
370
|
+
}),
|
|
371
|
+
[loadLines, loadShipments, orderId],
|
|
372
|
+
)
|
|
373
|
+
|
|
360
374
|
const handleOpenCreate = React.useCallback(() => {
|
|
361
375
|
setDialogState({ mode: 'create', shipment: null })
|
|
362
376
|
}, [])
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import type { SalesLineUomSnapshot } from '../../lib/types'
|
|
2
|
+
|
|
1
3
|
export type SalesLineRecord = {
|
|
2
4
|
id: string
|
|
3
5
|
name: string | null
|
|
4
6
|
productId: string | null
|
|
5
7
|
productVariantId: string | null
|
|
6
8
|
quantity: number
|
|
9
|
+
quantityUnit: string | null
|
|
10
|
+
normalizedQuantity: number
|
|
11
|
+
normalizedUnit: string | null
|
|
7
12
|
currencyCode: string | null
|
|
8
13
|
unitPriceNet: number
|
|
9
14
|
unitPriceGross: number
|
|
@@ -11,6 +16,7 @@ export type SalesLineRecord = {
|
|
|
11
16
|
totalNet: number
|
|
12
17
|
totalGross: number
|
|
13
18
|
priceMode: 'net' | 'gross'
|
|
19
|
+
uomSnapshot: SalesLineUomSnapshot | null
|
|
14
20
|
metadata: Record<string, unknown> | null
|
|
15
21
|
catalogSnapshot: Record<string, unknown> | null
|
|
16
22
|
customFieldSetId?: string | null
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from '@mikro-orm/core'
|
|
12
12
|
import { DEFAULT_ORDER_NUMBER_FORMAT, DEFAULT_QUOTE_NUMBER_FORMAT } from '../lib/documentNumberTokens'
|
|
13
13
|
import type { ShipmentItemSnapshot } from '../lib/shipments/types'
|
|
14
|
+
import type { SalesLineUomSnapshot } from '../lib/types'
|
|
14
15
|
|
|
15
16
|
export type SalesDocumentKind = 'order' | 'quote' | 'invoice' | 'credit_memo'
|
|
16
17
|
export type SalesLineKind = 'product' | 'service' | 'shipping' | 'discount' | 'adjustment'
|
|
@@ -556,6 +557,10 @@ export class SalesOrder {
|
|
|
556
557
|
@Entity({ tableName: 'sales_order_lines' })
|
|
557
558
|
@Index({ name: 'sales_order_lines_scope_idx', properties: ['order', 'organizationId', 'tenantId'] })
|
|
558
559
|
@Index({ name: 'sales_order_lines_status_idx', properties: ['organizationId', 'tenantId', 'status'] })
|
|
560
|
+
@Index({
|
|
561
|
+
name: 'sales_order_lines_normalized_idx',
|
|
562
|
+
properties: ['organizationId', 'tenantId', 'normalizedUnit', 'normalizedQuantity'],
|
|
563
|
+
})
|
|
559
564
|
export class SalesOrderLine {
|
|
560
565
|
@PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
|
|
561
566
|
id!: string
|
|
@@ -605,6 +610,15 @@ export class SalesOrderLine {
|
|
|
605
610
|
@Property({ name: 'quantity_unit', type: 'text', nullable: true })
|
|
606
611
|
quantityUnit?: string | null
|
|
607
612
|
|
|
613
|
+
@Property({ name: 'normalized_quantity', type: 'numeric', precision: 18, scale: 6, default: '0' })
|
|
614
|
+
normalizedQuantity: string = '0'
|
|
615
|
+
|
|
616
|
+
@Property({ name: 'normalized_unit', type: 'text', nullable: true })
|
|
617
|
+
normalizedUnit?: string | null
|
|
618
|
+
|
|
619
|
+
@Property({ name: 'uom_snapshot', type: 'jsonb', nullable: true })
|
|
620
|
+
uomSnapshot?: SalesLineUomSnapshot | null
|
|
621
|
+
|
|
608
622
|
@Property({ name: 'reserved_quantity', type: 'numeric', precision: 18, scale: 4, default: '0' })
|
|
609
623
|
reservedQuantity: string = '0'
|
|
610
624
|
|
|
@@ -992,6 +1006,10 @@ export class SalesQuote {
|
|
|
992
1006
|
@Entity({ tableName: 'sales_quote_lines' })
|
|
993
1007
|
@Index({ name: 'sales_quote_lines_scope_idx', properties: ['quote', 'organizationId', 'tenantId'] })
|
|
994
1008
|
@Index({ name: 'sales_quote_lines_status_idx', properties: ['organizationId', 'tenantId', 'status'] })
|
|
1009
|
+
@Index({
|
|
1010
|
+
name: 'sales_quote_lines_normalized_idx',
|
|
1011
|
+
properties: ['organizationId', 'tenantId', 'normalizedUnit', 'normalizedQuantity'],
|
|
1012
|
+
})
|
|
995
1013
|
export class SalesQuoteLine {
|
|
996
1014
|
@PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
|
|
997
1015
|
id!: string
|
|
@@ -1041,6 +1059,15 @@ export class SalesQuoteLine {
|
|
|
1041
1059
|
@Property({ name: 'quantity_unit', type: 'text', nullable: true })
|
|
1042
1060
|
quantityUnit?: string | null
|
|
1043
1061
|
|
|
1062
|
+
@Property({ name: 'normalized_quantity', type: 'numeric', precision: 18, scale: 6, default: '0' })
|
|
1063
|
+
normalizedQuantity: string = '0'
|
|
1064
|
+
|
|
1065
|
+
@Property({ name: 'normalized_unit', type: 'text', nullable: true })
|
|
1066
|
+
normalizedUnit?: string | null
|
|
1067
|
+
|
|
1068
|
+
@Property({ name: 'uom_snapshot', type: 'jsonb', nullable: true })
|
|
1069
|
+
uomSnapshot?: SalesLineUomSnapshot | null
|
|
1070
|
+
|
|
1044
1071
|
@Property({ name: 'currency_code', type: 'text' })
|
|
1045
1072
|
currencyCode!: string
|
|
1046
1073
|
|
|
@@ -1345,6 +1372,10 @@ export class SalesInvoice {
|
|
|
1345
1372
|
|
|
1346
1373
|
@Entity({ tableName: 'sales_invoice_lines' })
|
|
1347
1374
|
@Index({ name: 'sales_invoice_lines_scope_idx', properties: ['invoice', 'organizationId', 'tenantId'] })
|
|
1375
|
+
@Index({
|
|
1376
|
+
name: 'sales_invoice_lines_normalized_idx',
|
|
1377
|
+
properties: ['organizationId', 'tenantId', 'normalizedUnit', 'normalizedQuantity'],
|
|
1378
|
+
})
|
|
1348
1379
|
export class SalesInvoiceLine {
|
|
1349
1380
|
@PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
|
|
1350
1381
|
id!: string
|
|
@@ -1376,6 +1407,15 @@ export class SalesInvoiceLine {
|
|
|
1376
1407
|
@Property({ name: 'quantity_unit', type: 'text', nullable: true })
|
|
1377
1408
|
quantityUnit?: string | null
|
|
1378
1409
|
|
|
1410
|
+
@Property({ name: 'normalized_quantity', type: 'numeric', precision: 18, scale: 6, default: '0' })
|
|
1411
|
+
normalizedQuantity: string = '0'
|
|
1412
|
+
|
|
1413
|
+
@Property({ name: 'normalized_unit', type: 'text', nullable: true })
|
|
1414
|
+
normalizedUnit?: string | null
|
|
1415
|
+
|
|
1416
|
+
@Property({ name: 'uom_snapshot', type: 'jsonb', nullable: true })
|
|
1417
|
+
uomSnapshot?: SalesLineUomSnapshot | null
|
|
1418
|
+
|
|
1379
1419
|
@Property({ name: 'currency_code', type: 'text' })
|
|
1380
1420
|
currencyCode!: string
|
|
1381
1421
|
|
|
@@ -1484,6 +1524,10 @@ export class SalesCreditMemo {
|
|
|
1484
1524
|
name: 'sales_credit_memo_lines_scope_idx',
|
|
1485
1525
|
properties: ['creditMemo', 'organizationId', 'tenantId'],
|
|
1486
1526
|
})
|
|
1527
|
+
@Index({
|
|
1528
|
+
name: 'sales_credit_memo_lines_normalized_idx',
|
|
1529
|
+
properties: ['organizationId', 'tenantId', 'normalizedUnit', 'normalizedQuantity'],
|
|
1530
|
+
})
|
|
1487
1531
|
export class SalesCreditMemoLine {
|
|
1488
1532
|
@PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
|
|
1489
1533
|
id!: string
|
|
@@ -1512,6 +1556,15 @@ export class SalesCreditMemoLine {
|
|
|
1512
1556
|
@Property({ name: 'quantity_unit', type: 'text', nullable: true })
|
|
1513
1557
|
quantityUnit?: string | null
|
|
1514
1558
|
|
|
1559
|
+
@Property({ name: 'normalized_quantity', type: 'numeric', precision: 18, scale: 6, default: '0' })
|
|
1560
|
+
normalizedQuantity: string = '0'
|
|
1561
|
+
|
|
1562
|
+
@Property({ name: 'normalized_unit', type: 'text', nullable: true })
|
|
1563
|
+
normalizedUnit?: string | null
|
|
1564
|
+
|
|
1565
|
+
@Property({ name: 'uom_snapshot', type: 'jsonb', nullable: true })
|
|
1566
|
+
uomSnapshot?: SalesLineUomSnapshot | null
|
|
1567
|
+
|
|
1515
1568
|
@Property({ name: 'currency_code', type: 'text' })
|
|
1516
1569
|
currencyCode!: string
|
|
1517
1570
|
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
updateDictionaryEntrySchema,
|
|
5
5
|
} from '@open-mercato/core/modules/dictionaries/data/validators'
|
|
6
6
|
import { getPaymentProvider, getShippingProvider } from '../lib/providers'
|
|
7
|
+
import { REFERENCE_UNIT_CODES } from '@open-mercato/shared/lib/units/unitCodes'
|
|
7
8
|
|
|
8
9
|
const uuid = () => z.string().uuid()
|
|
9
10
|
|
|
@@ -292,6 +293,8 @@ const adjustmentKindSchema = z.string().trim().min(1).max(150)
|
|
|
292
293
|
const linePricingSchema = z.object({
|
|
293
294
|
quantity: decimal({ min: 0 }),
|
|
294
295
|
quantityUnit: z.string().trim().max(25).optional(),
|
|
296
|
+
normalizedQuantity: decimal({ min: 0 }).optional(),
|
|
297
|
+
normalizedUnit: z.string().trim().max(25).nullable().optional(),
|
|
295
298
|
unitPriceNet: decimal({ min: 0 }).optional(),
|
|
296
299
|
unitPriceGross: decimal({ min: 0 }).optional(),
|
|
297
300
|
priceId: uuid().optional(),
|
|
@@ -305,6 +308,32 @@ const linePricingSchema = z.object({
|
|
|
305
308
|
totalGrossAmount: decimal({ min: 0 }).optional(),
|
|
306
309
|
})
|
|
307
310
|
|
|
311
|
+
const uomSnapshotSchema = z.object({
|
|
312
|
+
version: z.literal(1),
|
|
313
|
+
productId: z.string().nullable(),
|
|
314
|
+
productVariantId: z.string().nullable(),
|
|
315
|
+
baseUnitCode: z.string().nullable(),
|
|
316
|
+
enteredUnitCode: z.string().nullable(),
|
|
317
|
+
enteredQuantity: z.string(),
|
|
318
|
+
toBaseFactor: z.string(),
|
|
319
|
+
normalizedQuantity: z.string(),
|
|
320
|
+
rounding: z.object({
|
|
321
|
+
mode: z.enum(['half_up', 'down', 'up']),
|
|
322
|
+
scale: z.number().int(),
|
|
323
|
+
}),
|
|
324
|
+
source: z.object({
|
|
325
|
+
conversionId: z.string().nullable(),
|
|
326
|
+
resolvedAt: z.string(),
|
|
327
|
+
}),
|
|
328
|
+
unitPriceReference: z.object({
|
|
329
|
+
enabled: z.boolean(),
|
|
330
|
+
referenceUnitCode: z.enum(REFERENCE_UNIT_CODES).nullable(),
|
|
331
|
+
baseQuantity: z.string().nullable(),
|
|
332
|
+
grossPerReference: z.string().nullable().optional(),
|
|
333
|
+
netPerReference: z.string().nullable().optional(),
|
|
334
|
+
}).optional(),
|
|
335
|
+
}).nullable().optional()
|
|
336
|
+
|
|
308
337
|
const lineSharedSchema = z.object({
|
|
309
338
|
kind: lineKindSchema.optional(),
|
|
310
339
|
statusEntryId: uuid().optional(),
|
|
@@ -317,6 +346,7 @@ const lineSharedSchema = z.object({
|
|
|
317
346
|
configuration: z.record(z.string(), z.unknown()).optional(),
|
|
318
347
|
promotionCode: z.string().trim().max(120).optional(),
|
|
319
348
|
promotionSnapshot: z.record(z.string(), z.unknown()).optional(),
|
|
349
|
+
uomSnapshot: uomSnapshotSchema,
|
|
320
350
|
metadata,
|
|
321
351
|
customFieldSetId: uuid().optional(),
|
|
322
352
|
customFields: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -604,6 +634,9 @@ export const invoiceCreateSchema = scoped.extend({
|
|
|
604
634
|
description: z.string().trim().max(4000).optional(),
|
|
605
635
|
quantity: decimal({ min: 0 }),
|
|
606
636
|
quantityUnit: z.string().trim().max(25).optional(),
|
|
637
|
+
normalizedQuantity: decimal({ min: 0 }).optional(),
|
|
638
|
+
normalizedUnit: z.string().trim().max(25).nullable().optional(),
|
|
639
|
+
uomSnapshot: uomSnapshotSchema,
|
|
607
640
|
currencyCode,
|
|
608
641
|
unitPriceNet: decimal({ min: 0 }).optional(),
|
|
609
642
|
unitPriceGross: decimal({ min: 0 }).optional(),
|
|
@@ -650,6 +683,9 @@ export const creditMemoCreateSchema = scoped.extend({
|
|
|
650
683
|
description: z.string().trim().max(4000).optional(),
|
|
651
684
|
quantity: decimal({ min: 0 }),
|
|
652
685
|
quantityUnit: z.string().trim().max(25).optional(),
|
|
686
|
+
normalizedQuantity: decimal({ min: 0 }).optional(),
|
|
687
|
+
normalizedUnit: z.string().trim().max(25).nullable().optional(),
|
|
688
|
+
uomSnapshot: uomSnapshotSchema,
|
|
653
689
|
currencyCode,
|
|
654
690
|
unitPriceNet: decimal({ min: 0 }).optional(),
|
|
655
691
|
unitPriceGross: decimal({ min: 0 }).optional(),
|
|
@@ -27,6 +27,14 @@ type PublicQuoteResponse = {
|
|
|
27
27
|
description: string | null
|
|
28
28
|
quantity: string
|
|
29
29
|
quantityUnit: string | null
|
|
30
|
+
normalizedQuantity: string
|
|
31
|
+
normalizedUnit: string | null
|
|
32
|
+
unitPriceReference?: {
|
|
33
|
+
referenceUnitCode?: string | null
|
|
34
|
+
referenceUnit?: string | null
|
|
35
|
+
grossPerReference?: string | null
|
|
36
|
+
netPerReference?: string | null
|
|
37
|
+
} | null
|
|
30
38
|
currencyCode: string
|
|
31
39
|
totalGrossAmount: string
|
|
32
40
|
}>
|
|
@@ -144,6 +152,23 @@ export default function QuotePublicPage({ params }: { params: { token: string }
|
|
|
144
152
|
{t('sales.quotes.public.qty', { quantity: line.quantity })}
|
|
145
153
|
{line.quantityUnit ? ` ${line.quantityUnit}` : ''}
|
|
146
154
|
</p>
|
|
155
|
+
{line.normalizedUnit && (line.normalizedUnit !== line.quantityUnit || line.normalizedQuantity !== line.quantity) ? (
|
|
156
|
+
<p className="text-xs text-muted-foreground">
|
|
157
|
+
{line.normalizedQuantity} {line.normalizedUnit}
|
|
158
|
+
</p>
|
|
159
|
+
) : null}
|
|
160
|
+
{(line.unitPriceReference?.grossPerReference || line.unitPriceReference?.netPerReference) ? (
|
|
161
|
+
<p className="text-xs text-muted-foreground">
|
|
162
|
+
{(line.unitPriceReference?.grossPerReference ?? line.unitPriceReference?.netPerReference) ?? ''}{' '}
|
|
163
|
+
{line.currencyCode}{' '}
|
|
164
|
+
{t('sales.quotes.public.perReferenceUnit', 'per 1 {{unit}}', {
|
|
165
|
+
unit:
|
|
166
|
+
line.unitPriceReference?.referenceUnitCode ??
|
|
167
|
+
line.unitPriceReference?.referenceUnit ??
|
|
168
|
+
t('sales.quotes.public.defaultUnit', 'unit'),
|
|
169
|
+
})}
|
|
170
|
+
</p>
|
|
171
|
+
) : null}
|
|
147
172
|
</div>
|
|
148
173
|
<div className="text-right text-sm">
|
|
149
174
|
<p>
|
|
@@ -196,4 +221,3 @@ export default function QuotePublicPage({ params }: { params: { token: string }
|
|
|
196
221
|
)
|
|
197
222
|
}
|
|
198
223
|
|
|
199
|
-
|
|
@@ -894,6 +894,7 @@
|
|
|
894
894
|
"sales.documents.items.add": "Position hinzufügen",
|
|
895
895
|
"sales.documents.items.addLine": "Position hinzufügen",
|
|
896
896
|
"sales.documents.items.addTitle": "Position hinzufügen",
|
|
897
|
+
"sales.documents.items.baseUnitTag": "Basis",
|
|
897
898
|
"sales.documents.items.cancel": "Abbrechen",
|
|
898
899
|
"sales.documents.items.created": "Position hinzugefügt.",
|
|
899
900
|
"sales.documents.items.deleteConfirm": "Diese Position löschen?",
|
|
@@ -911,6 +912,13 @@
|
|
|
911
912
|
"sales.documents.items.errorScope": "Organisation und Mandant sind erforderlich.",
|
|
912
913
|
"sales.documents.items.errorUnitPrice": "Der Stückpreis muss größer als 0 sein.",
|
|
913
914
|
"sales.documents.items.errorVariantRequired": "Wähle eine Variante aus, um fortzufahren.",
|
|
915
|
+
"sales.documents.items.errors.uom.conversionNotFound": "Keine Einheitenumrechnung für dieses Produkt gefunden.",
|
|
916
|
+
"sales.documents.items.errors.uom.defaultUnitMissing": "Dem Produkt fehlt eine Standard-Basiseinheit.",
|
|
917
|
+
"sales.documents.items.errors.uom.duplicateConversion": "Eine Umrechnung für diese Einheit existiert bereits.",
|
|
918
|
+
"sales.documents.items.errors.uom.invalidFactor": "Der Umrechnungsfaktor muss eine positive Zahl sein.",
|
|
919
|
+
"sales.documents.items.errors.uom.precisionOverflow": "Das Ergebnis überschreitet die zulässige Dezimalgenauigkeit.",
|
|
920
|
+
"sales.documents.items.errors.uom.referenceConfigInvalid": "Die Konfiguration des Einheitspreisreferenz ist ungültig.",
|
|
921
|
+
"sales.documents.items.errors.uom.unitNotFound": "Der angegebene Einheitencode wurde nicht gefunden.",
|
|
914
922
|
"sales.documents.items.lineMode.catalog": "Katalogprodukt",
|
|
915
923
|
"sales.documents.items.lineMode.custom": "Benutzerdefinierte Position",
|
|
916
924
|
"sales.documents.items.lineMode.helper": "Nutze Katalogprodukte oder erstelle eine freie Position mit eigenem Preis.",
|
|
@@ -919,6 +927,9 @@
|
|
|
919
927
|
"sales.documents.items.name": "Name",
|
|
920
928
|
"sales.documents.items.namePlaceholder": "Optionaler Positionsname",
|
|
921
929
|
"sales.documents.items.price": "Preis",
|
|
930
|
+
"sales.documents.items.priceBasisManual": "Manueller Stückpreismodus. Der Preis wird nicht automatisch umgerechnet, bis ein Katalogpreis ausgewählt wird.",
|
|
931
|
+
"sales.documents.items.priceBasisMissingConversion": "Die Grundlage des Katalogpreises ist die Basiseinheit, aber die Umrechnung für die ausgewählte Einheit fehlt.",
|
|
932
|
+
"sales.documents.items.priceBasisTemplate": "Katalogpreis-Basis: {{baseAmount}} / {{baseUnit}}. Umgerechnet für {{unit}}: {{baseAmount}} × {{factor}} = {{convertedAmount}}.",
|
|
922
933
|
"sales.documents.items.priceGross": "Brutto",
|
|
923
934
|
"sales.documents.items.priceNet": "Netto",
|
|
924
935
|
"sales.documents.items.priceScope.channel": "Kanal",
|
|
@@ -934,6 +945,9 @@
|
|
|
934
945
|
"sales.documents.items.product": "Produkt",
|
|
935
946
|
"sales.documents.items.productSearch": "Produkt suchen",
|
|
936
947
|
"sales.documents.items.quantity": "Menge",
|
|
948
|
+
"sales.documents.items.quantityUnit": "Einheit",
|
|
949
|
+
"sales.documents.items.quantityUnitPlaceholder": "z. B. Stk.",
|
|
950
|
+
"sales.documents.items.quantityUnitSelect": "Einheit wählen",
|
|
937
951
|
"sales.documents.items.save": "Änderungen speichern",
|
|
938
952
|
"sales.documents.items.selectedProduct": "Ausgewählt {{id}}",
|
|
939
953
|
"sales.documents.items.selectedVariant": "Ausgewählt {{id}}",
|
|
@@ -952,12 +966,17 @@
|
|
|
952
966
|
"sales.documents.items.table.statusEmpty": "Kein Status",
|
|
953
967
|
"sales.documents.items.table.total": "Gesamt",
|
|
954
968
|
"sales.documents.items.table.unit": "Stückpreis",
|
|
969
|
+
"sales.documents.items.table.unitPriceReference": "{{value}} pro 1 {{unit}}",
|
|
955
970
|
"sales.documents.items.taxRate": "Steuerklasse",
|
|
956
971
|
"sales.documents.items.taxRate.empty": "Keine Steuerklassen verfügbar",
|
|
957
972
|
"sales.documents.items.taxRate.none": "Keine Steuerklasse ausgewählt",
|
|
958
973
|
"sales.documents.items.title": "Positionen",
|
|
959
974
|
"sales.documents.items.unitPrice": "Stückpreis",
|
|
960
975
|
"sales.documents.items.untitled": "Ohne Titel",
|
|
976
|
+
"sales.documents.items.uomPreview": "Normalisierte Menge",
|
|
977
|
+
"sales.documents.items.uomPreviewEmpty": "Einheit und Menge wählen, um die Normalisierung anzuzeigen.",
|
|
978
|
+
"sales.documents.items.uomPreviewTemplate": "{{quantity}} {{unit}} → {{normalized}} {{baseUnit}}",
|
|
979
|
+
"sales.documents.items.uomPreviewUnavailable": "Fehlende Umrechnung zur Basiseinheit.",
|
|
961
980
|
"sales.documents.items.updated": "Position aktualisiert.",
|
|
962
981
|
"sales.documents.items.variant": "Variante",
|
|
963
982
|
"sales.documents.items.variantSearch": "Variante suchen",
|
|
@@ -1197,7 +1216,7 @@
|
|
|
1197
1216
|
"sales.quotes.list.title": "Angebote",
|
|
1198
1217
|
"sales.quotes.public.acceptButton": "Angebot annehmen",
|
|
1199
1218
|
"sales.quotes.public.acceptFailed": "Angebot konnte nicht angenommen werden.",
|
|
1200
|
-
"sales.quotes.public.acceptedMessage": "Auftrag erstellt: {orderNumber}",
|
|
1219
|
+
"sales.quotes.public.acceptedMessage": "Auftrag erstellt: {{orderNumber}}",
|
|
1201
1220
|
"sales.quotes.public.acceptedTitle": "Angebot angenommen",
|
|
1202
1221
|
"sales.quotes.public.discount": "Rabatt",
|
|
1203
1222
|
"sales.quotes.public.expired": "Dieses Angebot ist abgelaufen.",
|
|
@@ -1209,12 +1228,13 @@
|
|
|
1209
1228
|
"sales.quotes.public.noValidityDate": "Kein Gültigkeitsdatum",
|
|
1210
1229
|
"sales.quotes.public.notFound": "Angebot nicht gefunden.",
|
|
1211
1230
|
"sales.quotes.public.pageTitle": "Angebot",
|
|
1212
|
-
"sales.quotes.public.
|
|
1231
|
+
"sales.quotes.public.perReferenceUnit": "pro 1 {{unit}}",
|
|
1232
|
+
"sales.quotes.public.qty": "Menge: {{quantity}}",
|
|
1213
1233
|
"sales.quotes.public.subtotalGross": "Zwischensumme (brutto)",
|
|
1214
1234
|
"sales.quotes.public.tax": "Steuer",
|
|
1215
1235
|
"sales.quotes.public.total": "Gesamt",
|
|
1216
1236
|
"sales.quotes.public.totals": "Summen",
|
|
1217
|
-
"sales.quotes.public.validUntil": "Gültig bis {date}",
|
|
1237
|
+
"sales.quotes.public.validUntil": "Gültig bis {{date}}",
|
|
1218
1238
|
"sales.quotes.send.action": "An Kunden senden",
|
|
1219
1239
|
"sales.quotes.send.cancel": "Abbrechen",
|
|
1220
1240
|
"sales.quotes.send.canceled": "Stornierte Angebote können nicht gesendet werden.",
|
|
@@ -894,6 +894,7 @@
|
|
|
894
894
|
"sales.documents.items.add": "Add item",
|
|
895
895
|
"sales.documents.items.addLine": "Add item",
|
|
896
896
|
"sales.documents.items.addTitle": "Add line",
|
|
897
|
+
"sales.documents.items.baseUnitTag": "base",
|
|
897
898
|
"sales.documents.items.cancel": "Cancel",
|
|
898
899
|
"sales.documents.items.created": "Line added.",
|
|
899
900
|
"sales.documents.items.deleteConfirm": "Delete this line item?",
|
|
@@ -911,6 +912,13 @@
|
|
|
911
912
|
"sales.documents.items.errorScope": "Organization and tenant are required.",
|
|
912
913
|
"sales.documents.items.errorUnitPrice": "Unit price must be greater than 0.",
|
|
913
914
|
"sales.documents.items.errorVariantRequired": "Select a variant to continue.",
|
|
915
|
+
"sales.documents.items.errors.uom.conversionNotFound": "No unit conversion found for this product.",
|
|
916
|
+
"sales.documents.items.errors.uom.defaultUnitMissing": "Product is missing a default base unit.",
|
|
917
|
+
"sales.documents.items.errors.uom.duplicateConversion": "A conversion for this unit already exists.",
|
|
918
|
+
"sales.documents.items.errors.uom.invalidFactor": "Conversion factor must be a positive number.",
|
|
919
|
+
"sales.documents.items.errors.uom.precisionOverflow": "Result exceeds the allowed decimal precision.",
|
|
920
|
+
"sales.documents.items.errors.uom.referenceConfigInvalid": "Unit price reference configuration is invalid.",
|
|
921
|
+
"sales.documents.items.errors.uom.unitNotFound": "The specified unit code was not found.",
|
|
914
922
|
"sales.documents.items.lineMode.catalog": "Catalog item",
|
|
915
923
|
"sales.documents.items.lineMode.custom": "Custom line",
|
|
916
924
|
"sales.documents.items.lineMode.helper": "Use catalog products or create a freeform line with your own price.",
|
|
@@ -919,6 +927,9 @@
|
|
|
919
927
|
"sales.documents.items.name": "Name",
|
|
920
928
|
"sales.documents.items.namePlaceholder": "Optional line name",
|
|
921
929
|
"sales.documents.items.price": "Price",
|
|
930
|
+
"sales.documents.items.priceBasisManual": "Manual unit price mode. Price will not auto-convert until you select a catalog price.",
|
|
931
|
+
"sales.documents.items.priceBasisMissingConversion": "Catalog price basis is base unit, but conversion for selected unit is missing.",
|
|
932
|
+
"sales.documents.items.priceBasisTemplate": "Catalog price basis: {{baseAmount}} / {{baseUnit}}. Converted for {{unit}}: {{baseAmount}} × {{factor}} = {{convertedAmount}}.",
|
|
922
933
|
"sales.documents.items.priceGross": "Gross",
|
|
923
934
|
"sales.documents.items.priceNet": "Net",
|
|
924
935
|
"sales.documents.items.priceScope.channel": "Channel",
|
|
@@ -934,6 +945,9 @@
|
|
|
934
945
|
"sales.documents.items.product": "Product",
|
|
935
946
|
"sales.documents.items.productSearch": "Search product",
|
|
936
947
|
"sales.documents.items.quantity": "Quantity",
|
|
948
|
+
"sales.documents.items.quantityUnit": "Unit",
|
|
949
|
+
"sales.documents.items.quantityUnitPlaceholder": "e.g. pc",
|
|
950
|
+
"sales.documents.items.quantityUnitSelect": "Select unit",
|
|
937
951
|
"sales.documents.items.save": "Save changes",
|
|
938
952
|
"sales.documents.items.selectedProduct": "Selected {{id}}",
|
|
939
953
|
"sales.documents.items.selectedVariant": "Selected {{id}}",
|
|
@@ -952,12 +966,17 @@
|
|
|
952
966
|
"sales.documents.items.table.statusEmpty": "No status",
|
|
953
967
|
"sales.documents.items.table.total": "Total",
|
|
954
968
|
"sales.documents.items.table.unit": "Unit price",
|
|
969
|
+
"sales.documents.items.table.unitPriceReference": "{{value}} per 1 {{unit}}",
|
|
955
970
|
"sales.documents.items.taxRate": "Tax class",
|
|
956
971
|
"sales.documents.items.taxRate.empty": "No tax classes available",
|
|
957
972
|
"sales.documents.items.taxRate.none": "No tax class selected",
|
|
958
973
|
"sales.documents.items.title": "Items",
|
|
959
974
|
"sales.documents.items.unitPrice": "Unit price",
|
|
960
975
|
"sales.documents.items.untitled": "Untitled",
|
|
976
|
+
"sales.documents.items.uomPreview": "Normalized quantity",
|
|
977
|
+
"sales.documents.items.uomPreviewEmpty": "Select unit and quantity to preview normalization.",
|
|
978
|
+
"sales.documents.items.uomPreviewTemplate": "{{quantity}} {{unit}} → {{normalized}} {{baseUnit}}",
|
|
979
|
+
"sales.documents.items.uomPreviewUnavailable": "Missing conversion to base unit.",
|
|
961
980
|
"sales.documents.items.updated": "Line updated.",
|
|
962
981
|
"sales.documents.items.variant": "Variant",
|
|
963
982
|
"sales.documents.items.variantSearch": "Search variant",
|
|
@@ -1197,7 +1216,7 @@
|
|
|
1197
1216
|
"sales.quotes.list.title": "Quotes",
|
|
1198
1217
|
"sales.quotes.public.acceptButton": "Accept quote",
|
|
1199
1218
|
"sales.quotes.public.acceptFailed": "Failed to accept quote.",
|
|
1200
|
-
"sales.quotes.public.acceptedMessage": "Order created: {orderNumber}",
|
|
1219
|
+
"sales.quotes.public.acceptedMessage": "Order created: {{orderNumber}}",
|
|
1201
1220
|
"sales.quotes.public.acceptedTitle": "Quote accepted",
|
|
1202
1221
|
"sales.quotes.public.discount": "Discount",
|
|
1203
1222
|
"sales.quotes.public.expired": "This quote has expired.",
|
|
@@ -1209,12 +1228,13 @@
|
|
|
1209
1228
|
"sales.quotes.public.noValidityDate": "No validity date",
|
|
1210
1229
|
"sales.quotes.public.notFound": "Quote not found.",
|
|
1211
1230
|
"sales.quotes.public.pageTitle": "Quote",
|
|
1212
|
-
"sales.quotes.public.
|
|
1231
|
+
"sales.quotes.public.perReferenceUnit": "per 1 {{unit}}",
|
|
1232
|
+
"sales.quotes.public.qty": "Qty: {{quantity}}",
|
|
1213
1233
|
"sales.quotes.public.subtotalGross": "Subtotal (gross)",
|
|
1214
1234
|
"sales.quotes.public.tax": "Tax",
|
|
1215
1235
|
"sales.quotes.public.total": "Total",
|
|
1216
1236
|
"sales.quotes.public.totals": "Totals",
|
|
1217
|
-
"sales.quotes.public.validUntil": "Valid until {date}",
|
|
1237
|
+
"sales.quotes.public.validUntil": "Valid until {{date}}",
|
|
1218
1238
|
"sales.quotes.send.action": "Send to customer",
|
|
1219
1239
|
"sales.quotes.send.cancel": "Cancel",
|
|
1220
1240
|
"sales.quotes.send.canceled": "Canceled quotes cannot be sent.",
|
|
@@ -894,6 +894,7 @@
|
|
|
894
894
|
"sales.documents.items.add": "Agregar artículo",
|
|
895
895
|
"sales.documents.items.addLine": "Agregar artículo",
|
|
896
896
|
"sales.documents.items.addTitle": "Agregar línea",
|
|
897
|
+
"sales.documents.items.baseUnitTag": "base",
|
|
897
898
|
"sales.documents.items.cancel": "Cancelar",
|
|
898
899
|
"sales.documents.items.created": "Línea agregada.",
|
|
899
900
|
"sales.documents.items.deleteConfirm": "¿Eliminar esta línea de artículo?",
|
|
@@ -911,6 +912,13 @@
|
|
|
911
912
|
"sales.documents.items.errorScope": "Se requieren organización e inquilino.",
|
|
912
913
|
"sales.documents.items.errorUnitPrice": "El precio unitario debe ser mayor que 0.",
|
|
913
914
|
"sales.documents.items.errorVariantRequired": "Selecciona una variante para continuar.",
|
|
915
|
+
"sales.documents.items.errors.uom.conversionNotFound": "No se encontró conversión de unidad para este producto.",
|
|
916
|
+
"sales.documents.items.errors.uom.defaultUnitMissing": "El producto no tiene una unidad base predeterminada.",
|
|
917
|
+
"sales.documents.items.errors.uom.duplicateConversion": "Ya existe una conversión para esta unidad.",
|
|
918
|
+
"sales.documents.items.errors.uom.invalidFactor": "El factor de conversión debe ser un número positivo.",
|
|
919
|
+
"sales.documents.items.errors.uom.precisionOverflow": "El resultado excede la precisión decimal permitida.",
|
|
920
|
+
"sales.documents.items.errors.uom.referenceConfigInvalid": "La configuración de precio unitario de referencia no es válida.",
|
|
921
|
+
"sales.documents.items.errors.uom.unitNotFound": "No se encontró el código de unidad especificado.",
|
|
914
922
|
"sales.documents.items.lineMode.catalog": "Artículo del catálogo",
|
|
915
923
|
"sales.documents.items.lineMode.custom": "Línea personalizada",
|
|
916
924
|
"sales.documents.items.lineMode.helper": "Usa productos del catálogo o crea una línea libre con tu propio precio.",
|
|
@@ -919,6 +927,9 @@
|
|
|
919
927
|
"sales.documents.items.name": "Nombre",
|
|
920
928
|
"sales.documents.items.namePlaceholder": "Nombre opcional de la línea",
|
|
921
929
|
"sales.documents.items.price": "Precio",
|
|
930
|
+
"sales.documents.items.priceBasisManual": "Modo de precio unitario manual. El precio no se convertirá automáticamente hasta que selecciones un precio del catálogo.",
|
|
931
|
+
"sales.documents.items.priceBasisMissingConversion": "La base del precio del catálogo está en la unidad base, pero falta la conversión para la unidad seleccionada.",
|
|
932
|
+
"sales.documents.items.priceBasisTemplate": "Base del precio del catálogo: {{baseAmount}} / {{baseUnit}}. Convertido para {{unit}}: {{baseAmount}} × {{factor}} = {{convertedAmount}}.",
|
|
922
933
|
"sales.documents.items.priceGross": "Bruto",
|
|
923
934
|
"sales.documents.items.priceNet": "Neto",
|
|
924
935
|
"sales.documents.items.priceScope.channel": "Canal",
|
|
@@ -934,6 +945,9 @@
|
|
|
934
945
|
"sales.documents.items.product": "Producto",
|
|
935
946
|
"sales.documents.items.productSearch": "Buscar producto",
|
|
936
947
|
"sales.documents.items.quantity": "Cantidad",
|
|
948
|
+
"sales.documents.items.quantityUnit": "Unidad",
|
|
949
|
+
"sales.documents.items.quantityUnitPlaceholder": "p. ej. ud",
|
|
950
|
+
"sales.documents.items.quantityUnitSelect": "Seleccionar unidad",
|
|
937
951
|
"sales.documents.items.save": "Guardar cambios",
|
|
938
952
|
"sales.documents.items.selectedProduct": "Seleccionado {{id}}",
|
|
939
953
|
"sales.documents.items.selectedVariant": "Seleccionado {{id}}",
|
|
@@ -952,12 +966,17 @@
|
|
|
952
966
|
"sales.documents.items.table.statusEmpty": "Sin estado",
|
|
953
967
|
"sales.documents.items.table.total": "Total",
|
|
954
968
|
"sales.documents.items.table.unit": "Precio unitario",
|
|
969
|
+
"sales.documents.items.table.unitPriceReference": "{{value}} por 1 {{unit}}",
|
|
955
970
|
"sales.documents.items.taxRate": "Clase de impuesto",
|
|
956
971
|
"sales.documents.items.taxRate.empty": "No hay clases de impuestos disponibles",
|
|
957
972
|
"sales.documents.items.taxRate.none": "Ninguna clase seleccionada",
|
|
958
973
|
"sales.documents.items.title": "Artículos",
|
|
959
974
|
"sales.documents.items.unitPrice": "Precio unitario",
|
|
960
975
|
"sales.documents.items.untitled": "Sin título",
|
|
976
|
+
"sales.documents.items.uomPreview": "Cantidad normalizada",
|
|
977
|
+
"sales.documents.items.uomPreviewEmpty": "Selecciona unidad y cantidad para ver la normalización.",
|
|
978
|
+
"sales.documents.items.uomPreviewTemplate": "{{quantity}} {{unit}} → {{normalized}} {{baseUnit}}",
|
|
979
|
+
"sales.documents.items.uomPreviewUnavailable": "Falta la conversión a unidad base.",
|
|
961
980
|
"sales.documents.items.updated": "Línea actualizada.",
|
|
962
981
|
"sales.documents.items.variant": "Variante",
|
|
963
982
|
"sales.documents.items.variantSearch": "Buscar variante",
|
|
@@ -1197,7 +1216,7 @@
|
|
|
1197
1216
|
"sales.quotes.list.title": "Cotizaciones",
|
|
1198
1217
|
"sales.quotes.public.acceptButton": "Aceptar cotización",
|
|
1199
1218
|
"sales.quotes.public.acceptFailed": "No se pudo aceptar la cotización.",
|
|
1200
|
-
"sales.quotes.public.acceptedMessage": "Pedido creado: {orderNumber}",
|
|
1219
|
+
"sales.quotes.public.acceptedMessage": "Pedido creado: {{orderNumber}}",
|
|
1201
1220
|
"sales.quotes.public.acceptedTitle": "Cotización aceptada",
|
|
1202
1221
|
"sales.quotes.public.discount": "Descuento",
|
|
1203
1222
|
"sales.quotes.public.expired": "Esta cotización ha expirado.",
|
|
@@ -1209,12 +1228,13 @@
|
|
|
1209
1228
|
"sales.quotes.public.noValidityDate": "Sin fecha de validez",
|
|
1210
1229
|
"sales.quotes.public.notFound": "Cotización no encontrada.",
|
|
1211
1230
|
"sales.quotes.public.pageTitle": "Cotización",
|
|
1212
|
-
"sales.quotes.public.
|
|
1231
|
+
"sales.quotes.public.perReferenceUnit": "por 1 {{unit}}",
|
|
1232
|
+
"sales.quotes.public.qty": "Cant.: {{quantity}}",
|
|
1213
1233
|
"sales.quotes.public.subtotalGross": "Subtotal (bruto)",
|
|
1214
1234
|
"sales.quotes.public.tax": "Impuesto",
|
|
1215
1235
|
"sales.quotes.public.total": "Total",
|
|
1216
1236
|
"sales.quotes.public.totals": "Totales",
|
|
1217
|
-
"sales.quotes.public.validUntil": "Válida hasta {date}",
|
|
1237
|
+
"sales.quotes.public.validUntil": "Válida hasta {{date}}",
|
|
1218
1238
|
"sales.quotes.send.action": "Enviar al cliente",
|
|
1219
1239
|
"sales.quotes.send.cancel": "Cancelar",
|
|
1220
1240
|
"sales.quotes.send.canceled": "No se pueden enviar cotizaciones canceladas.",
|
|
@@ -894,6 +894,7 @@
|
|
|
894
894
|
"sales.documents.items.add": "Dodaj pozycję",
|
|
895
895
|
"sales.documents.items.addLine": "Dodaj pozycję",
|
|
896
896
|
"sales.documents.items.addTitle": "Dodaj pozycję",
|
|
897
|
+
"sales.documents.items.baseUnitTag": "bazowa",
|
|
897
898
|
"sales.documents.items.cancel": "Anuluj",
|
|
898
899
|
"sales.documents.items.created": "Pozycja dodana.",
|
|
899
900
|
"sales.documents.items.deleteConfirm": "Usunąć tę pozycję?",
|
|
@@ -911,6 +912,13 @@
|
|
|
911
912
|
"sales.documents.items.errorScope": "Wymagane są organizacja i najemca.",
|
|
912
913
|
"sales.documents.items.errorUnitPrice": "Cena jednostkowa musi być większa niż 0.",
|
|
913
914
|
"sales.documents.items.errorVariantRequired": "Wybierz wariant, aby kontynuować.",
|
|
915
|
+
"sales.documents.items.errors.uom.conversionNotFound": "Nie znaleziono przelicznika jednostek dla tego produktu.",
|
|
916
|
+
"sales.documents.items.errors.uom.defaultUnitMissing": "Produkt nie ma zdefiniowanej domyślnej jednostki bazowej.",
|
|
917
|
+
"sales.documents.items.errors.uom.duplicateConversion": "Przelicznik dla tej jednostki już istnieje.",
|
|
918
|
+
"sales.documents.items.errors.uom.invalidFactor": "Współczynnik przeliczenia musi być liczbą dodatnią.",
|
|
919
|
+
"sales.documents.items.errors.uom.precisionOverflow": "Wynik przekracza dozwoloną precyzję dziesiętną.",
|
|
920
|
+
"sales.documents.items.errors.uom.referenceConfigInvalid": "Konfiguracja ceny jednostkowej referencyjnej jest nieprawidłowa.",
|
|
921
|
+
"sales.documents.items.errors.uom.unitNotFound": "Podany kod jednostki nie został znaleziony.",
|
|
914
922
|
"sales.documents.items.lineMode.catalog": "Produkt z katalogu",
|
|
915
923
|
"sales.documents.items.lineMode.custom": "Pozycja niestandardowa",
|
|
916
924
|
"sales.documents.items.lineMode.helper": "Użyj produktów z katalogu albo dodaj własną pozycję z ceną ręcznie.",
|
|
@@ -919,6 +927,9 @@
|
|
|
919
927
|
"sales.documents.items.name": "Nazwa",
|
|
920
928
|
"sales.documents.items.namePlaceholder": "Opcjonalna nazwa pozycji",
|
|
921
929
|
"sales.documents.items.price": "Cena",
|
|
930
|
+
"sales.documents.items.priceBasisManual": "Tryb ręcznej ceny jednostkowej. Cena nie przeliczy się automatycznie, dopóki nie wybierzesz ceny katalogowej.",
|
|
931
|
+
"sales.documents.items.priceBasisMissingConversion": "Podstawa ceny katalogowej jest w jednostce bazowej, ale brakuje konwersji dla wybranej jednostki.",
|
|
932
|
+
"sales.documents.items.priceBasisTemplate": "Podstawa ceny katalogowej: {{baseAmount}} / {{baseUnit}}. Przeliczenie dla {{unit}}: {{baseAmount}} × {{factor}} = {{convertedAmount}}.",
|
|
922
933
|
"sales.documents.items.priceGross": "Brutto",
|
|
923
934
|
"sales.documents.items.priceNet": "Netto",
|
|
924
935
|
"sales.documents.items.priceScope.channel": "Kanał",
|
|
@@ -934,6 +945,9 @@
|
|
|
934
945
|
"sales.documents.items.product": "Produkt",
|
|
935
946
|
"sales.documents.items.productSearch": "Szukaj produktu",
|
|
936
947
|
"sales.documents.items.quantity": "Ilość",
|
|
948
|
+
"sales.documents.items.quantityUnit": "Jednostka",
|
|
949
|
+
"sales.documents.items.quantityUnitPlaceholder": "np. szt.",
|
|
950
|
+
"sales.documents.items.quantityUnitSelect": "Wybierz jednostkę",
|
|
937
951
|
"sales.documents.items.save": "Zapisz zmiany",
|
|
938
952
|
"sales.documents.items.selectedProduct": "Wybrano {{id}}",
|
|
939
953
|
"sales.documents.items.selectedVariant": "Wybrano {{id}}",
|
|
@@ -952,12 +966,17 @@
|
|
|
952
966
|
"sales.documents.items.table.statusEmpty": "Brak statusu",
|
|
953
967
|
"sales.documents.items.table.total": "Suma",
|
|
954
968
|
"sales.documents.items.table.unit": "Cena jednostkowa",
|
|
969
|
+
"sales.documents.items.table.unitPriceReference": "{{value}} za 1 {{unit}}",
|
|
955
970
|
"sales.documents.items.taxRate": "Klasa podatkowa",
|
|
956
971
|
"sales.documents.items.taxRate.empty": "Brak dostępnych klas podatkowych",
|
|
957
972
|
"sales.documents.items.taxRate.none": "Brak wybranej klasy podatkowej",
|
|
958
973
|
"sales.documents.items.title": "Pozycje",
|
|
959
974
|
"sales.documents.items.unitPrice": "Cena jednostkowa",
|
|
960
975
|
"sales.documents.items.untitled": "Bez nazwy",
|
|
976
|
+
"sales.documents.items.uomPreview": "Ilość po normalizacji",
|
|
977
|
+
"sales.documents.items.uomPreviewEmpty": "Wybierz jednostkę i ilość, aby zobaczyć podgląd normalizacji.",
|
|
978
|
+
"sales.documents.items.uomPreviewTemplate": "{{quantity}} {{unit}} → {{normalized}} {{baseUnit}}",
|
|
979
|
+
"sales.documents.items.uomPreviewUnavailable": "Brak konwersji do jednostki bazowej.",
|
|
961
980
|
"sales.documents.items.updated": "Pozycja zaktualizowana.",
|
|
962
981
|
"sales.documents.items.variant": "Wariant",
|
|
963
982
|
"sales.documents.items.variantSearch": "Szukaj wariantu",
|
|
@@ -1197,7 +1216,7 @@
|
|
|
1197
1216
|
"sales.quotes.list.title": "Oferty",
|
|
1198
1217
|
"sales.quotes.public.acceptButton": "Zaakceptuj ofertę",
|
|
1199
1218
|
"sales.quotes.public.acceptFailed": "Nie udało się zaakceptować oferty.",
|
|
1200
|
-
"sales.quotes.public.acceptedMessage": "Utworzono zamówienie: {orderNumber}",
|
|
1219
|
+
"sales.quotes.public.acceptedMessage": "Utworzono zamówienie: {{orderNumber}}",
|
|
1201
1220
|
"sales.quotes.public.acceptedTitle": "Oferta zaakceptowana",
|
|
1202
1221
|
"sales.quotes.public.discount": "Rabat",
|
|
1203
1222
|
"sales.quotes.public.expired": "Ta oferta wygasła.",
|
|
@@ -1209,12 +1228,13 @@
|
|
|
1209
1228
|
"sales.quotes.public.noValidityDate": "Brak daty ważności",
|
|
1210
1229
|
"sales.quotes.public.notFound": "Nie znaleziono oferty.",
|
|
1211
1230
|
"sales.quotes.public.pageTitle": "Oferta",
|
|
1212
|
-
"sales.quotes.public.
|
|
1231
|
+
"sales.quotes.public.perReferenceUnit": "za 1 {{unit}}",
|
|
1232
|
+
"sales.quotes.public.qty": "Ilość: {{quantity}}",
|
|
1213
1233
|
"sales.quotes.public.subtotalGross": "Suma częściowa (brutto)",
|
|
1214
1234
|
"sales.quotes.public.tax": "Podatek",
|
|
1215
1235
|
"sales.quotes.public.total": "Suma",
|
|
1216
1236
|
"sales.quotes.public.totals": "Sumy",
|
|
1217
|
-
"sales.quotes.public.validUntil": "Ważna do {date}",
|
|
1237
|
+
"sales.quotes.public.validUntil": "Ważna do {{date}}",
|
|
1218
1238
|
"sales.quotes.send.action": "Wyślij do klienta",
|
|
1219
1239
|
"sales.quotes.send.cancel": "Anuluj",
|
|
1220
1240
|
"sales.quotes.send.canceled": "Anulowanych ofert nie można wysłać.",
|