@open-mercato/core 0.6.6-develop.6317.1.b3be10ab84 → 0.6.6-develop.6331.1.a33b8e99b7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +3 -0
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +2 -2
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +2 -2
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +12 -0
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +12 -0
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/data/entities.js +2 -2
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/business_rules/api/rules/route.js +3 -3
- package/dist/modules/business_rules/api/rules/route.js.map +2 -2
- package/dist/modules/business_rules/api/sets/route.js +3 -3
- package/dist/modules/business_rules/api/sets/route.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/[id]/page.js +12 -1
- package/dist/modules/business_rules/backend/rules/[id]/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/[id]/page.js +12 -1
- package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
- package/dist/modules/catalog/api/product-media/route.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +12 -0
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +15 -0
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +12 -1
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +13 -3
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/lib/bulkDelete.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/[id]/page.js +15 -3
- package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +2 -1
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +12 -1
- package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +3 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles/[id].js +3 -3
- package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users/[id].js +3 -3
- package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +7 -12
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +5 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +2 -1
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection/company-users/widget.client.js +2 -1
- package/dist/modules/customer_accounts/widgets/injection/company-users/widget.client.js.map +2 -2
- package/dist/modules/customers/api/addresses/route.js +4 -2
- package/dist/modules/customers/api/addresses/route.js.map +2 -2
- package/dist/modules/customers/api/tags/route.js +8 -3
- package/dist/modules/customers/api/tags/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +13 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +24 -9
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +53 -23
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js +13 -3
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +19 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +13 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +5 -5
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/pipeline-stages.js +24 -2
- package/dist/modules/customers/commands/pipeline-stages.js.map +2 -2
- package/dist/modules/customers/commands/pipelines.js +24 -2
- package/dist/modules/customers/commands/pipelines.js.map +2 -2
- package/dist/modules/customers/components/detail/AddressesSection.js +46 -29
- package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +5 -1
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +76 -67
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +3 -3
- package/dist/modules/customers/components/detail/notesAdapter.js +25 -18
- package/dist/modules/customers/components/detail/notesAdapter.js.map +2 -2
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +4 -3
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/data_sync/api/runs.js +1 -0
- package/dist/modules/data_sync/api/runs.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/[id]/route.js +38 -19
- package/dist/modules/data_sync/api/schedules/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/route.js +1 -1
- package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +35 -16
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/data/validators.js +1 -0
- package/dist/modules/data_sync/data/validators.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-run-service.js +20 -0
- package/dist/modules/data_sync/lib/sync-run-service.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-schedule-service.js +19 -5
- package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +3 -3
- package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js +3 -3
- package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionariesManager.js +12 -1
- package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +12 -0
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +12 -0
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
- package/dist/modules/entities/api/entities.js +2 -2
- package/dist/modules/entities/api/entities.js.map +2 -2
- package/dist/modules/entities/api/records.js +18 -6
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +17 -10
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/feature_toggles/api/overrides/route.js +2 -2
- package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
- package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
- package/dist/modules/feature_toggles/data/entities.js +1 -1
- package/dist/modules/feature_toggles/data/entities.js.map +2 -2
- package/dist/modules/feature_toggles/data/validators.js +2 -1
- package/dist/modules/feature_toggles/data/validators.js.map +2 -2
- package/dist/modules/feature_toggles/lib/queries.js +2 -1
- package/dist/modules/feature_toggles/lib/queries.js.map +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
- package/dist/modules/messages/api/unread-count/route.js +32 -0
- package/dist/modules/messages/api/unread-count/route.js.map +2 -2
- package/dist/modules/query_index/components/QueryIndexesTable.js +13 -5
- package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +12 -1
- package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +12 -1
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/resources/components/detail/notesAdapter.js +25 -18
- package/dist/modules/resources/components/detail/notesAdapter.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +14 -1
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +11 -10
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +6 -1
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/commands/returns.js +3 -3
- package/dist/modules/sales/commands/returns.js.map +2 -2
- package/dist/modules/sales/commands/shared.js +3 -3
- package/dist/modules/sales/commands/shared.js.map +2 -2
- package/dist/modules/sales/commands/shipments.js +6 -1
- package/dist/modules/sales/commands/shipments.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentDialog.js +6 -3
- package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +7 -3
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +6 -3
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +7 -3
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/di.js +39 -3
- package/dist/modules/sales/di.js.map +2 -2
- package/dist/modules/sales/setup.js +2 -0
- package/dist/modules/sales/setup.js.map +2 -2
- package/dist/modules/shipping_carriers/i18n/en.js +11 -1
- package/dist/modules/shipping_carriers/i18n/en.js.map +2 -2
- package/dist/modules/shipping_carriers/i18n/pl.js +11 -1
- package/dist/modules/shipping_carriers/i18n/pl.js.map +2 -2
- package/dist/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.client.js +25 -0
- package/dist/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.client.js.map +7 -0
- package/dist/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.js +3 -17
- package/dist/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +12 -1
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +12 -1
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +12 -1
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +12 -1
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/commands/job-histories.js +3 -3
- package/dist/modules/staff/commands/job-histories.js.map +2 -2
- package/dist/modules/staff/components/detail/addressesAdapter.js +33 -24
- package/dist/modules/staff/components/detail/addressesAdapter.js.map +2 -2
- package/dist/modules/staff/components/detail/notesAdapter.js +25 -18
- package/dist/modules/staff/components/detail/notesAdapter.js.map +2 -2
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js +37 -0
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +7 -1
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/translations/widgets/injection/translation-manager/widget.client.js +19 -14
- package/dist/modules/translations/widgets/injection/translation-manager/widget.client.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/route.js +3 -3
- package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js +12 -1
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +11 -1
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +3 -0
- package/src/modules/auth/api/roles/acl/route.ts +2 -2
- package/src/modules/auth/api/users/acl/route.ts +2 -2
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +17 -0
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +17 -0
- package/src/modules/auth/data/entities.ts +2 -2
- package/src/modules/business_rules/api/rules/route.ts +3 -3
- package/src/modules/business_rules/api/sets/route.ts +3 -3
- package/src/modules/business_rules/backend/rules/[id]/page.tsx +17 -1
- package/src/modules/business_rules/backend/sets/[id]/page.tsx +18 -1
- package/src/modules/catalog/api/product-media/route.ts +4 -0
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +17 -0
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +21 -0
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +16 -1
- package/src/modules/catalog/components/PriceKindSettings.tsx +15 -7
- package/src/modules/catalog/lib/bulkDelete.ts +6 -0
- package/src/modules/currencies/backend/currencies/[id]/page.tsx +20 -3
- package/src/modules/currencies/backend/currencies/page.tsx +2 -1
- package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +17 -1
- package/src/modules/currencies/backend/exchange-rates/page.tsx +3 -2
- package/src/modules/customer_accounts/api/admin/roles/[id].ts +3 -3
- package/src/modules/customer_accounts/api/admin/users/[id].ts +3 -3
- package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +7 -10
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +6 -7
- package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +3 -2
- package/src/modules/customer_accounts/widgets/injection/company-users/widget.client.tsx +3 -2
- package/src/modules/customers/api/addresses/route.ts +2 -0
- package/src/modules/customers/api/tags/route.ts +6 -1
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +19 -2
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +29 -8
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +47 -20
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.ts +13 -3
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +21 -1
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +18 -2
- package/src/modules/customers/commands/interactions.ts +5 -5
- package/src/modules/customers/commands/pipeline-stages.ts +26 -2
- package/src/modules/customers/commands/pipelines.ts +26 -2
- package/src/modules/customers/components/detail/AddressesSection.tsx +50 -28
- package/src/modules/customers/components/detail/DealForm.tsx +12 -0
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +89 -71
- package/src/modules/customers/components/detail/notesAdapter.ts +29 -18
- package/src/modules/customers/i18n/de.json +2 -0
- package/src/modules/customers/i18n/en.json +2 -0
- package/src/modules/customers/i18n/es.json +2 -0
- package/src/modules/customers/i18n/pl.json +2 -0
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +6 -3
- package/src/modules/data_sync/api/runs.ts +1 -0
- package/src/modules/data_sync/api/schedules/[id]/route.ts +38 -20
- package/src/modules/data_sync/api/schedules/route.ts +1 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +35 -16
- package/src/modules/data_sync/data/validators.ts +1 -0
- package/src/modules/data_sync/i18n/de.json +1 -0
- package/src/modules/data_sync/i18n/en.json +1 -0
- package/src/modules/data_sync/i18n/es.json +1 -0
- package/src/modules/data_sync/i18n/pl.json +1 -0
- package/src/modules/data_sync/lib/sync-run-service.ts +23 -0
- package/src/modules/data_sync/lib/sync-schedule-service.ts +30 -5
- package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +3 -3
- package/src/modules/dictionaries/api/[dictionaryId]/route.ts +3 -3
- package/src/modules/dictionaries/components/DictionariesManager.tsx +21 -1
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +2 -0
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +17 -0
- package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +17 -0
- package/src/modules/entities/api/entities.ts +2 -2
- package/src/modules/entities/api/records.ts +24 -6
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +25 -12
- package/src/modules/feature_toggles/api/overrides/route.ts +2 -2
- package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +12 -0
- package/src/modules/feature_toggles/data/entities.ts +1 -1
- package/src/modules/feature_toggles/data/validators.ts +1 -0
- package/src/modules/feature_toggles/lib/queries.ts +1 -0
- package/src/modules/inbox_ops/api/settings/route.ts +2 -2
- package/src/modules/messages/api/unread-count/route.ts +40 -0
- package/src/modules/query_index/components/QueryIndexesTable.tsx +17 -15
- package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +17 -1
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +17 -1
- package/src/modules/resources/components/detail/notesAdapter.ts +29 -18
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +17 -1
- package/src/modules/sales/commands/documents.ts +11 -10
- package/src/modules/sales/commands/payments.ts +11 -0
- package/src/modules/sales/commands/returns.ts +3 -3
- package/src/modules/sales/commands/shared.ts +10 -4
- package/src/modules/sales/commands/shipments.ts +14 -0
- package/src/modules/sales/components/documents/PaymentDialog.tsx +7 -3
- package/src/modules/sales/components/documents/PaymentsSection.tsx +8 -3
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +7 -3
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +8 -3
- package/src/modules/sales/di.ts +68 -9
- package/src/modules/sales/setup.ts +2 -0
- package/src/modules/shipping_carriers/i18n/de.json +11 -1
- package/src/modules/shipping_carriers/i18n/en.json +11 -1
- package/src/modules/shipping_carriers/i18n/en.ts +10 -0
- package/src/modules/shipping_carriers/i18n/es.json +11 -1
- package/src/modules/shipping_carriers/i18n/pl.json +11 -1
- package/src/modules/shipping_carriers/i18n/pl.ts +10 -0
- package/src/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.client.tsx +35 -0
- package/src/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.tsx +3 -22
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +17 -1
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +17 -1
- package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +17 -1
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +17 -1
- package/src/modules/staff/commands/job-histories.ts +3 -3
- package/src/modules/staff/components/detail/addressesAdapter.ts +40 -23
- package/src/modules/staff/components/detail/notesAdapter.ts +28 -18
- package/src/modules/translations/api/[entityType]/[entityId]/route.ts +74 -0
- package/src/modules/translations/components/TranslationManager.tsx +14 -1
- package/src/modules/translations/widgets/injection/translation-manager/widget.client.tsx +30 -13
- package/src/modules/workflows/api/definitions/[id]/route.ts +3 -3
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +18 -1
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +19 -1
|
@@ -29,6 +29,8 @@ import {
|
|
|
29
29
|
ensureSameScope,
|
|
30
30
|
ensureTenantScope,
|
|
31
31
|
extractUndoPayload,
|
|
32
|
+
enforceSalesDocumentOptimisticLock,
|
|
33
|
+
SALES_RESOURCE_KIND_ORDER,
|
|
32
34
|
} from './shared'
|
|
33
35
|
import { resolveDictionaryEntryValue } from '../lib/dictionaries'
|
|
34
36
|
import { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'
|
|
@@ -442,6 +444,10 @@ const createShipmentCommand: CommandHandler<ShipmentCreateInput, { shipmentId: s
|
|
|
442
444
|
const shipment = await em.transactional(async (tx) => {
|
|
443
445
|
const order = await loadOrder(tx, input.orderId, { tenantId: input.tenantId, organizationId: input.organizationId })
|
|
444
446
|
ensureSameScope(order, input.organizationId, input.tenantId)
|
|
447
|
+
// Guard the parent order's aggregate version (Gap B): a shipment mutation
|
|
448
|
+
// recalculates the order's fulfilled quantities, so a stale parent must 409
|
|
449
|
+
// before we touch it.
|
|
450
|
+
await enforceSalesDocumentOptimisticLock(ctx, order, SALES_RESOURCE_KIND_ORDER)
|
|
445
451
|
const { items: normalizedItems, lineMap } = await validateShipmentItems({
|
|
446
452
|
em: tx,
|
|
447
453
|
order,
|
|
@@ -674,6 +680,10 @@ const updateShipmentCommand: CommandHandler<ShipmentUpdateInput, { shipmentId: s
|
|
|
674
680
|
if (input.orderId && input.orderId !== order.id) {
|
|
675
681
|
throw new CrudHttpError(400, { error: 'sales.shipments.invalid_order' })
|
|
676
682
|
}
|
|
683
|
+
// Guard the parent order's aggregate version (Gap B): updating a shipment
|
|
684
|
+
// recalculates the order's fulfilled quantities, so a stale parent must 409
|
|
685
|
+
// before we touch it.
|
|
686
|
+
await enforceSalesDocumentOptimisticLock(ctx, order, SALES_RESOURCE_KIND_ORDER)
|
|
677
687
|
|
|
678
688
|
// Check if order is financially closed - prevent modifications to shipments
|
|
679
689
|
const paidAmount = parseFloat(order.paidTotalAmount || '0')
|
|
@@ -976,6 +986,10 @@ const deleteShipmentCommand: CommandHandler<
|
|
|
976
986
|
if (order.id !== payload.orderId) {
|
|
977
987
|
throw new CrudHttpError(400, { error: translate('sales.shipments.invalid_order', 'Shipment does not belong to this order') })
|
|
978
988
|
}
|
|
989
|
+
// Guard the parent order's aggregate version (Gap B): deleting a shipment
|
|
990
|
+
// recalculates the order's fulfilled quantities, so a stale parent must 409
|
|
991
|
+
// before we touch it.
|
|
992
|
+
await enforceSalesDocumentOptimisticLock(ctx, order, SALES_RESOURCE_KIND_ORDER)
|
|
979
993
|
const scope = { tenantId: shipmentEntity.tenantId, organizationId: shipmentEntity.organizationId }
|
|
980
994
|
const items = await findWithDecryption(tx, SalesShipmentItem, { shipment: shipmentEntity }, {}, scope)
|
|
981
995
|
items.forEach((item) => tx.remove(item))
|
|
@@ -9,7 +9,7 @@ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimi
|
|
|
9
9
|
import { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'
|
|
10
10
|
import { createCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
11
11
|
import { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'
|
|
12
|
-
import { handleSectionMutationError
|
|
12
|
+
import { handleSectionMutationError } from './optimisticLock'
|
|
13
13
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'
|
|
14
14
|
import { useDialogKeyHandler } from '@open-mercato/ui/hooks/useDialogKeyHandler'
|
|
15
15
|
import { Input } from '@open-mercato/ui/primitives/input'
|
|
@@ -58,6 +58,7 @@ type PaymentDialogProps = {
|
|
|
58
58
|
orderId: string
|
|
59
59
|
organizationId: string | null
|
|
60
60
|
tenantId: string | null
|
|
61
|
+
documentUpdatedAt?: string | null
|
|
61
62
|
onOpenChange: (open: boolean) => void
|
|
62
63
|
onSaved?: (totals?: PaymentTotals | null) => void | Promise<void>
|
|
63
64
|
}
|
|
@@ -79,6 +80,7 @@ export function PaymentDialog({
|
|
|
79
80
|
orderId,
|
|
80
81
|
organizationId,
|
|
81
82
|
tenantId,
|
|
83
|
+
documentUpdatedAt,
|
|
82
84
|
onOpenChange,
|
|
83
85
|
onSaved,
|
|
84
86
|
}: PaymentDialogProps) {
|
|
@@ -539,7 +541,9 @@ export function PaymentDialog({
|
|
|
539
541
|
const action = payment?.id ? updateCrud : createCrud
|
|
540
542
|
try {
|
|
541
543
|
const result = await withScopedApiRequestHeaders(
|
|
542
|
-
|
|
544
|
+
// The server guards the PARENT order's aggregate version (Gap A) for
|
|
545
|
+
// both create and update, so send the order's `updated_at`.
|
|
546
|
+
buildOptimisticLockHeader(documentUpdatedAt ?? undefined),
|
|
543
547
|
() =>
|
|
544
548
|
action(
|
|
545
549
|
'sales/payments',
|
|
@@ -569,7 +573,7 @@ export function PaymentDialog({
|
|
|
569
573
|
throw err
|
|
570
574
|
}
|
|
571
575
|
},
|
|
572
|
-
[currencyCode, mode, onOpenChange, onSaved, orderId, organizationId, payment?.id,
|
|
576
|
+
[currencyCode, documentUpdatedAt, mode, onOpenChange, onSaved, orderId, organizationId, payment?.id, t, tenantId]
|
|
573
577
|
)
|
|
574
578
|
|
|
575
579
|
const handleSubmitForm = React.useCallback(
|
|
@@ -7,7 +7,7 @@ import { LoadingMessage, ErrorMessage, TabEmptyState } from '@open-mercato/ui/ba
|
|
|
7
7
|
import { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'
|
|
8
8
|
import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
|
|
9
9
|
import { deleteCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
10
|
-
import { handleSectionMutationError, readRowUpdatedAt
|
|
10
|
+
import { handleSectionMutationError, readRowUpdatedAt } from './optimisticLock'
|
|
11
11
|
import type { SectionAction } from '@open-mercato/ui/backend/detail'
|
|
12
12
|
import { RowActions } from '@open-mercato/ui/backend/RowActions'
|
|
13
13
|
import { Button } from '@open-mercato/ui/primitives/button'
|
|
@@ -41,6 +41,7 @@ type SalesDocumentPaymentsSectionProps = {
|
|
|
41
41
|
currencyCode: string | null | undefined
|
|
42
42
|
organizationId?: string | null
|
|
43
43
|
tenantId?: string | null
|
|
44
|
+
documentUpdatedAt?: string | null
|
|
44
45
|
onActionChange?: (action: SectionAction | null) => void
|
|
45
46
|
onTotalsChange?: () => void
|
|
46
47
|
onPaymentsChange?: (payments: PaymentRow[]) => void
|
|
@@ -69,6 +70,7 @@ export function SalesDocumentPaymentsSection({
|
|
|
69
70
|
currencyCode,
|
|
70
71
|
organizationId: orgFromProps,
|
|
71
72
|
tenantId: tenantFromProps,
|
|
73
|
+
documentUpdatedAt,
|
|
72
74
|
onActionChange,
|
|
73
75
|
onTotalsChange,
|
|
74
76
|
onPaymentsChange,
|
|
@@ -216,7 +218,9 @@ export function SalesDocumentPaymentsSection({
|
|
|
216
218
|
async (row: PaymentRow) => {
|
|
217
219
|
try {
|
|
218
220
|
const result = await withScopedApiRequestHeaders(
|
|
219
|
-
|
|
221
|
+
// The server guards the PARENT order's aggregate version (Gap A), so
|
|
222
|
+
// send the order's `updated_at`, not the payment row's.
|
|
223
|
+
buildOptimisticLockHeader(documentUpdatedAt ?? undefined),
|
|
220
224
|
() =>
|
|
221
225
|
deleteCrud<{ orderTotals?: PaymentTotals | null }>('sales/payments', {
|
|
222
226
|
body: {
|
|
@@ -242,7 +246,7 @@ export function SalesDocumentPaymentsSection({
|
|
|
242
246
|
flash(t('sales.documents.payments.errorDelete', 'Failed to delete payment.'), 'error')
|
|
243
247
|
}
|
|
244
248
|
},
|
|
245
|
-
[loadPayments, onTotalsChange, orderId, resolvedOrganizationId, resolvedTenantId, t]
|
|
249
|
+
[documentUpdatedAt, loadPayments, onTotalsChange, orderId, resolvedOrganizationId, resolvedTenantId, t]
|
|
246
250
|
)
|
|
247
251
|
|
|
248
252
|
React.useEffect(() => {
|
|
@@ -369,6 +373,7 @@ export function SalesDocumentPaymentsSection({
|
|
|
369
373
|
orderId={orderId}
|
|
370
374
|
organizationId={resolvedOrganizationId}
|
|
371
375
|
tenantId={resolvedTenantId}
|
|
376
|
+
documentUpdatedAt={documentUpdatedAt ?? null}
|
|
372
377
|
onSaved={handlePaymentSaved}
|
|
373
378
|
/>
|
|
374
379
|
</div>
|
|
@@ -15,7 +15,7 @@ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimi
|
|
|
15
15
|
import { createCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
16
16
|
import { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'
|
|
17
17
|
import { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'
|
|
18
|
-
import { handleSectionMutationError
|
|
18
|
+
import { handleSectionMutationError } from './optimisticLock'
|
|
19
19
|
import { flash } from '@open-mercato/ui/backend/FlashMessages'
|
|
20
20
|
import { cn } from '@open-mercato/shared/lib/utils'
|
|
21
21
|
import { E } from '#generated/entities.ids.generated'
|
|
@@ -46,6 +46,7 @@ type ShipmentDialogProps = {
|
|
|
46
46
|
currencyCode?: string | null
|
|
47
47
|
organizationId: string | null
|
|
48
48
|
tenantId: string | null
|
|
49
|
+
documentUpdatedAt?: string | null
|
|
49
50
|
computeAvailable: (lineId: string, excludeShipmentId?: string | null) => number
|
|
50
51
|
shippingAddressSnapshot?: NormalizedAddressSnapshot | Record<string, unknown> | null
|
|
51
52
|
onClose: () => void
|
|
@@ -278,6 +279,7 @@ export function ShipmentDialog({
|
|
|
278
279
|
currencyCode,
|
|
279
280
|
organizationId,
|
|
280
281
|
tenantId,
|
|
282
|
+
documentUpdatedAt,
|
|
281
283
|
computeAvailable,
|
|
282
284
|
shippingAddressSnapshot,
|
|
283
285
|
onClose,
|
|
@@ -1089,7 +1091,9 @@ export function ShipmentDialog({
|
|
|
1089
1091
|
let result
|
|
1090
1092
|
try {
|
|
1091
1093
|
result = await withScopedApiRequestHeaders(
|
|
1092
|
-
|
|
1094
|
+
// The server guards the PARENT order's aggregate version (Gap B) for
|
|
1095
|
+
// both create and update, so send the order's `updated_at`.
|
|
1096
|
+
buildOptimisticLockHeader(documentUpdatedAt ?? undefined),
|
|
1093
1097
|
() =>
|
|
1094
1098
|
action(
|
|
1095
1099
|
'sales/shipments',
|
|
@@ -1219,6 +1223,7 @@ export function ShipmentDialog({
|
|
|
1219
1223
|
},
|
|
1220
1224
|
[
|
|
1221
1225
|
currencyCode,
|
|
1226
|
+
documentUpdatedAt,
|
|
1222
1227
|
lines,
|
|
1223
1228
|
mode,
|
|
1224
1229
|
onAddComment,
|
|
@@ -1226,7 +1231,6 @@ export function ShipmentDialog({
|
|
|
1226
1231
|
orderId,
|
|
1227
1232
|
organizationId,
|
|
1228
1233
|
shipment?.id,
|
|
1229
|
-
shipment?.updatedAt,
|
|
1230
1234
|
addressOptions,
|
|
1231
1235
|
addressOptionsMap,
|
|
1232
1236
|
shippingMethods,
|
|
@@ -20,7 +20,7 @@ import type { SectionAction } from '@open-mercato/core/modules/customers/compone
|
|
|
20
20
|
import { generateTempId } from '@open-mercato/core/modules/customers/lib/detailHelpers'
|
|
21
21
|
import { formatAddressString, type AddressValue } from '@open-mercato/core/modules/customers/utils/addressFormat'
|
|
22
22
|
import { ShipmentDialog } from './ShipmentDialog'
|
|
23
|
-
import { handleSectionMutationError, readRowUpdatedAt
|
|
23
|
+
import { handleSectionMutationError, readRowUpdatedAt } from './optimisticLock'
|
|
24
24
|
import { extractCustomFieldValues } from './customFieldHelpers'
|
|
25
25
|
import type { OrderLine, ShipmentRow, ShipmentItem } from './shipmentTypes'
|
|
26
26
|
|
|
@@ -33,6 +33,7 @@ type SalesShipmentsSectionProps = {
|
|
|
33
33
|
shippingAddressSnapshot?: Record<string, unknown> | null
|
|
34
34
|
organizationId?: string | null
|
|
35
35
|
tenantId?: string | null
|
|
36
|
+
documentUpdatedAt?: string | null
|
|
36
37
|
onActionChange?: (action: SectionAction | null) => void
|
|
37
38
|
onAddComment?: (body: string) => Promise<void>
|
|
38
39
|
}
|
|
@@ -114,6 +115,7 @@ export function SalesShipmentsSection({
|
|
|
114
115
|
shippingAddressSnapshot,
|
|
115
116
|
organizationId: organizationIdProp,
|
|
116
117
|
tenantId: tenantIdProp,
|
|
118
|
+
documentUpdatedAt,
|
|
117
119
|
onActionChange,
|
|
118
120
|
onAddComment,
|
|
119
121
|
}: SalesShipmentsSectionProps) {
|
|
@@ -401,7 +403,9 @@ export function SalesShipmentsSection({
|
|
|
401
403
|
if (!confirmed) return
|
|
402
404
|
try {
|
|
403
405
|
const result = await withScopedApiRequestHeaders(
|
|
404
|
-
|
|
406
|
+
// The server guards the PARENT order's aggregate version (Gap B), so
|
|
407
|
+
// send the order's `updated_at`, not the shipment row's.
|
|
408
|
+
buildOptimisticLockHeader(documentUpdatedAt ?? undefined),
|
|
405
409
|
() =>
|
|
406
410
|
deleteCrud('sales/shipments', {
|
|
407
411
|
body: {
|
|
@@ -425,7 +429,7 @@ export function SalesShipmentsSection({
|
|
|
425
429
|
flash(t('sales.documents.shipments.errorDelete', 'Failed to delete shipment.'), 'error')
|
|
426
430
|
}
|
|
427
431
|
},
|
|
428
|
-
[confirm, loadShipments, orderId, resolvedOrganizationId, resolvedTenantId, t]
|
|
432
|
+
[confirm, documentUpdatedAt, loadShipments, orderId, resolvedOrganizationId, resolvedTenantId, t]
|
|
429
433
|
)
|
|
430
434
|
|
|
431
435
|
const renderItemList = (items: ShipmentItem[]) => (
|
|
@@ -573,6 +577,7 @@ export function SalesShipmentsSection({
|
|
|
573
577
|
currencyCode={currencyCode}
|
|
574
578
|
organizationId={resolvedOrganizationId}
|
|
575
579
|
tenantId={resolvedTenantId}
|
|
580
|
+
documentUpdatedAt={documentUpdatedAt ?? null}
|
|
576
581
|
computeAvailable={computeAvailable}
|
|
577
582
|
shippingAddressSnapshot={shippingAddressSnapshot}
|
|
578
583
|
onClose={() => setDialogState(null)}
|
package/src/modules/sales/di.ts
CHANGED
|
@@ -42,15 +42,20 @@ type AppCradle = AppContainer['cradle'] & {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const RESOURCE_KIND_ORDER = 'sales.order'
|
|
45
|
+
const RESOURCE_KIND_PAYMENT = 'sales.payment'
|
|
46
|
+
const RESOURCE_KIND_SHIPMENT = 'sales.shipment'
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
async function readOrderUpdatedAtById(
|
|
47
49
|
em: EntityManager,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
orderId: string | null | undefined,
|
|
51
|
+
tenantId: string,
|
|
52
|
+
organizationId: string | null | undefined,
|
|
53
|
+
): Promise<string | null> {
|
|
54
|
+
if (!orderId) return null
|
|
50
55
|
const row = await em.findOne(
|
|
51
56
|
SalesOrder,
|
|
52
57
|
{
|
|
53
|
-
id:
|
|
58
|
+
id: orderId,
|
|
54
59
|
tenantId,
|
|
55
60
|
...(organizationId ? { organizationId } : {}),
|
|
56
61
|
deletedAt: null,
|
|
@@ -60,13 +65,67 @@ const readSalesOrderUpdatedAt: OptimisticLockCurrentReader = async (
|
|
|
60
65
|
return row?.updatedAt instanceof Date ? row.updatedAt.toISOString() : null
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
const readSalesOrderUpdatedAt: OptimisticLockCurrentReader = async (
|
|
69
|
+
em: EntityManager,
|
|
70
|
+
{ resourceId, tenantId, organizationId },
|
|
71
|
+
) => readOrderUpdatedAtById(em, resourceId, tenantId, organizationId)
|
|
72
|
+
|
|
73
|
+
// Payments and shipments are guarded against the PARENT ORDER's aggregate
|
|
74
|
+
// version (their mutations recalc order totals / fulfilled quantities, so the
|
|
75
|
+
// order is the consistency boundary — same model as lines/adjustments/returns).
|
|
76
|
+
// The CRUD-layer guard therefore must compare against the order, not the
|
|
77
|
+
// payment/shipment row: resolve the parent order from the sub-resource id and
|
|
78
|
+
// return its `updated_at`. This keeps the single optimistic-lock header
|
|
79
|
+
// consistent across the makeCrudRoute guard and the command-level
|
|
80
|
+
// `enforceSalesDocumentOptimisticLock` guard (both read the order version).
|
|
81
|
+
const readPaymentParentOrderUpdatedAt: OptimisticLockCurrentReader = async (
|
|
82
|
+
em: EntityManager,
|
|
83
|
+
{ resourceId, tenantId, organizationId },
|
|
84
|
+
) => {
|
|
85
|
+
const payment = await em.findOne(
|
|
86
|
+
SalesPayment,
|
|
87
|
+
{
|
|
88
|
+
id: resourceId,
|
|
89
|
+
tenantId,
|
|
90
|
+
...(organizationId ? { organizationId } : {}),
|
|
91
|
+
deletedAt: null,
|
|
92
|
+
},
|
|
93
|
+
{ fields: ['order'] as const },
|
|
94
|
+
)
|
|
95
|
+
const orderId = (payment as { order?: { id?: string } | string | null } | null)?.order
|
|
96
|
+
const resolvedOrderId = typeof orderId === 'string' ? orderId : orderId?.id ?? null
|
|
97
|
+
return readOrderUpdatedAtById(em, resolvedOrderId, tenantId, organizationId)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const readShipmentParentOrderUpdatedAt: OptimisticLockCurrentReader = async (
|
|
101
|
+
em: EntityManager,
|
|
102
|
+
{ resourceId, tenantId, organizationId },
|
|
103
|
+
) => {
|
|
104
|
+
const shipment = await em.findOne(
|
|
105
|
+
SalesShipment,
|
|
106
|
+
{
|
|
107
|
+
id: resourceId,
|
|
108
|
+
tenantId,
|
|
109
|
+
...(organizationId ? { organizationId } : {}),
|
|
110
|
+
deletedAt: null,
|
|
111
|
+
},
|
|
112
|
+
{ fields: ['order'] as const },
|
|
113
|
+
)
|
|
114
|
+
const orderId = (shipment as { order?: { id?: string } | string | null } | null)?.order
|
|
115
|
+
const resolvedOrderId = typeof orderId === 'string' ? orderId : orderId?.id ?? null
|
|
116
|
+
return readOrderUpdatedAtById(em, resolvedOrderId, tenantId, organizationId)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Hand-wired sales readers registered at module-load time. `sales.order` mirrors
|
|
120
|
+
// the auto-registered generic reader (kept as the polymorphic-table override
|
|
121
|
+
// reference). `sales.payment`/`sales.shipment` redirect the CRUD-layer guard to
|
|
122
|
+
// the parent order so payments/shipments guard the aggregate (Phase 3 Gap A/B)
|
|
123
|
+
// instead of their own row. The guard's mode check short-circuits when
|
|
124
|
+
// `OM_OPTIMISTIC_LOCK=off`.
|
|
68
125
|
registerOptimisticLockReaders({
|
|
69
126
|
[RESOURCE_KIND_ORDER]: readSalesOrderUpdatedAt,
|
|
127
|
+
[RESOURCE_KIND_PAYMENT]: readPaymentParentOrderUpdatedAt,
|
|
128
|
+
[RESOURCE_KIND_SHIPMENT]: readShipmentParentOrderUpdatedAt,
|
|
70
129
|
})
|
|
71
130
|
|
|
72
131
|
export function register(container: AppContainer) {
|
|
@@ -51,7 +51,9 @@ export const setup: ModuleSetupConfig = {
|
|
|
51
51
|
admin: ['sales.*', 'sales.documents.number.edit'],
|
|
52
52
|
employee: [
|
|
53
53
|
'sales.channels.view',
|
|
54
|
+
'sales.channels.manage',
|
|
54
55
|
'sales.settings.view',
|
|
56
|
+
'sales.settings.manage',
|
|
55
57
|
'sales.orders.view',
|
|
56
58
|
'sales.orders.manage',
|
|
57
59
|
'sales.orders.approve',
|
|
@@ -70,5 +70,15 @@
|
|
|
70
70
|
"shipping_carriers.create.summary.to": "Nach",
|
|
71
71
|
"shipping_carriers.create.title": "Sendung beim Transporteur erstellen",
|
|
72
72
|
"shipping_carriers.feature.manage": "Versanddienstleister-Vorgaenge verwalten",
|
|
73
|
-
"shipping_carriers.feature.view": "Sendungen der Versanddienstleister anzeigen"
|
|
73
|
+
"shipping_carriers.feature.view": "Sendungen der Versanddienstleister anzeigen",
|
|
74
|
+
"shipping_carriers.status.cancelled": "Storniert",
|
|
75
|
+
"shipping_carriers.status.delivered": "Zugestellt",
|
|
76
|
+
"shipping_carriers.status.failed_delivery": "Zustellung fehlgeschlagen",
|
|
77
|
+
"shipping_carriers.status.in_transit": "Unterwegs",
|
|
78
|
+
"shipping_carriers.status.label_created": "Label erstellt",
|
|
79
|
+
"shipping_carriers.status.out_for_delivery": "In Zustellung",
|
|
80
|
+
"shipping_carriers.status.pending": "Ausstehend",
|
|
81
|
+
"shipping_carriers.status.picked_up": "Abgeholt",
|
|
82
|
+
"shipping_carriers.status.returned": "Zuruckgesendet",
|
|
83
|
+
"shipping_carriers.status.unknown": "Unbekannt"
|
|
74
84
|
}
|
|
@@ -70,5 +70,15 @@
|
|
|
70
70
|
"shipping_carriers.create.summary.to": "To",
|
|
71
71
|
"shipping_carriers.create.title": "Create carrier shipment",
|
|
72
72
|
"shipping_carriers.feature.manage": "Manage shipping carrier operations",
|
|
73
|
-
"shipping_carriers.feature.view": "View shipping carrier shipments"
|
|
73
|
+
"shipping_carriers.feature.view": "View shipping carrier shipments",
|
|
74
|
+
"shipping_carriers.status.cancelled": "Cancelled",
|
|
75
|
+
"shipping_carriers.status.delivered": "Delivered",
|
|
76
|
+
"shipping_carriers.status.failed_delivery": "Delivery failed",
|
|
77
|
+
"shipping_carriers.status.in_transit": "In transit",
|
|
78
|
+
"shipping_carriers.status.label_created": "Label created",
|
|
79
|
+
"shipping_carriers.status.out_for_delivery": "Out for delivery",
|
|
80
|
+
"shipping_carriers.status.pending": "Pending",
|
|
81
|
+
"shipping_carriers.status.picked_up": "Picked up",
|
|
82
|
+
"shipping_carriers.status.returned": "Returned",
|
|
83
|
+
"shipping_carriers.status.unknown": "Unknown"
|
|
74
84
|
}
|
|
@@ -4,4 +4,14 @@ export default {
|
|
|
4
4
|
'shipping_carriers.column.trackingStatus': 'Tracking status',
|
|
5
5
|
'shipping_carriers.column.shippingStatus': 'Shipping status',
|
|
6
6
|
'shipping_carriers.action.createShipment': 'Create shipment',
|
|
7
|
+
'shipping_carriers.status.cancelled': 'Cancelled',
|
|
8
|
+
'shipping_carriers.status.delivered': 'Delivered',
|
|
9
|
+
'shipping_carriers.status.failed_delivery': 'Delivery failed',
|
|
10
|
+
'shipping_carriers.status.in_transit': 'In transit',
|
|
11
|
+
'shipping_carriers.status.label_created': 'Label created',
|
|
12
|
+
'shipping_carriers.status.out_for_delivery': 'Out for delivery',
|
|
13
|
+
'shipping_carriers.status.pending': 'Pending',
|
|
14
|
+
'shipping_carriers.status.picked_up': 'Picked up',
|
|
15
|
+
'shipping_carriers.status.returned': 'Returned',
|
|
16
|
+
'shipping_carriers.status.unknown': 'Unknown',
|
|
7
17
|
}
|
|
@@ -70,5 +70,15 @@
|
|
|
70
70
|
"shipping_carriers.create.summary.to": "Hasta",
|
|
71
71
|
"shipping_carriers.create.title": "Crear envio con transportista",
|
|
72
72
|
"shipping_carriers.feature.manage": "Gestionar operaciones de transportistas",
|
|
73
|
-
"shipping_carriers.feature.view": "Ver envios de transportistas"
|
|
73
|
+
"shipping_carriers.feature.view": "Ver envios de transportistas",
|
|
74
|
+
"shipping_carriers.status.cancelled": "Cancelado",
|
|
75
|
+
"shipping_carriers.status.delivered": "Entregado",
|
|
76
|
+
"shipping_carriers.status.failed_delivery": "Entrega fallida",
|
|
77
|
+
"shipping_carriers.status.in_transit": "En transito",
|
|
78
|
+
"shipping_carriers.status.label_created": "Etiqueta creada",
|
|
79
|
+
"shipping_carriers.status.out_for_delivery": "En reparto",
|
|
80
|
+
"shipping_carriers.status.pending": "Pendiente",
|
|
81
|
+
"shipping_carriers.status.picked_up": "Recogido",
|
|
82
|
+
"shipping_carriers.status.returned": "Devuelto",
|
|
83
|
+
"shipping_carriers.status.unknown": "Desconocido"
|
|
74
84
|
}
|
|
@@ -70,5 +70,15 @@
|
|
|
70
70
|
"shipping_carriers.create.summary.to": "Odbiór",
|
|
71
71
|
"shipping_carriers.create.title": "Utwórz przesyłkę u przewoźnika",
|
|
72
72
|
"shipping_carriers.feature.manage": "Zarzadzanie operacjami przewoznikow",
|
|
73
|
-
"shipping_carriers.feature.view": "Podglad przesylek przewoznikow"
|
|
73
|
+
"shipping_carriers.feature.view": "Podglad przesylek przewoznikow",
|
|
74
|
+
"shipping_carriers.status.cancelled": "Anulowano",
|
|
75
|
+
"shipping_carriers.status.delivered": "Doreczono",
|
|
76
|
+
"shipping_carriers.status.failed_delivery": "Doreczenie nieudane",
|
|
77
|
+
"shipping_carriers.status.in_transit": "W transporcie",
|
|
78
|
+
"shipping_carriers.status.label_created": "Etykieta utworzona",
|
|
79
|
+
"shipping_carriers.status.out_for_delivery": "W doreczeniu",
|
|
80
|
+
"shipping_carriers.status.pending": "Oczekuje",
|
|
81
|
+
"shipping_carriers.status.picked_up": "Odebrano",
|
|
82
|
+
"shipping_carriers.status.returned": "Zwrocono",
|
|
83
|
+
"shipping_carriers.status.unknown": "Nieznany"
|
|
74
84
|
}
|
|
@@ -4,4 +4,14 @@ export default {
|
|
|
4
4
|
'shipping_carriers.column.trackingStatus': 'Status śledzenia',
|
|
5
5
|
'shipping_carriers.column.shippingStatus': 'Status wysyłki',
|
|
6
6
|
'shipping_carriers.action.createShipment': 'Utwórz przesyłkę',
|
|
7
|
+
'shipping_carriers.status.cancelled': 'Anulowano',
|
|
8
|
+
'shipping_carriers.status.delivered': 'Doręczono',
|
|
9
|
+
'shipping_carriers.status.failed_delivery': 'Doręczenie nieudane',
|
|
10
|
+
'shipping_carriers.status.in_transit': 'W transporcie',
|
|
11
|
+
'shipping_carriers.status.label_created': 'Etykieta utworzona',
|
|
12
|
+
'shipping_carriers.status.out_for_delivery': 'W doręczeniu',
|
|
13
|
+
'shipping_carriers.status.pending': 'Oczekuje',
|
|
14
|
+
'shipping_carriers.status.picked_up': 'Odebrano',
|
|
15
|
+
'shipping_carriers.status.returned': 'Zwrócono',
|
|
16
|
+
'shipping_carriers.status.unknown': 'Nieznany',
|
|
7
17
|
}
|
package/src/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.client.tsx
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
4
|
+
import { StatusBadge, type StatusMap } from '@open-mercato/ui/primitives/status-badge'
|
|
5
|
+
import type { UnifiedShipmentStatus } from '../../../lib/adapter'
|
|
6
|
+
|
|
7
|
+
type ShippingStatus = UnifiedShipmentStatus | 'pending'
|
|
8
|
+
|
|
9
|
+
const shippingStatusVariantMap: StatusMap<ShippingStatus> = {
|
|
10
|
+
pending: 'neutral',
|
|
11
|
+
label_created: 'info',
|
|
12
|
+
picked_up: 'info',
|
|
13
|
+
in_transit: 'info',
|
|
14
|
+
out_for_delivery: 'info',
|
|
15
|
+
delivered: 'success',
|
|
16
|
+
failed_delivery: 'error',
|
|
17
|
+
returned: 'warning',
|
|
18
|
+
cancelled: 'error',
|
|
19
|
+
unknown: 'neutral',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type ShippingStatusBadgeWidgetProps = {
|
|
23
|
+
status: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default function ShippingStatusBadgeWidget({ status }: ShippingStatusBadgeWidgetProps) {
|
|
27
|
+
const t = useT()
|
|
28
|
+
const variant = shippingStatusVariantMap[status as ShippingStatus] ?? 'neutral'
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<StatusBadge variant={variant} dot>
|
|
32
|
+
{t(`shipping_carriers.status.${status}`, status)}
|
|
33
|
+
</StatusBadge>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
@@ -1,20 +1,6 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
1
2
|
import type { InjectionColumnWidget } from '@open-mercato/shared/modules/widgets/injection'
|
|
2
|
-
|
|
3
|
-
const SHIPPING_STATUS_COLORS: Record<string, string> = {
|
|
4
|
-
pending: 'bg-gray-100 text-gray-700',
|
|
5
|
-
label_created: 'bg-slate-100 text-slate-700',
|
|
6
|
-
picked_up: 'bg-sky-100 text-sky-700',
|
|
7
|
-
in_transit: 'bg-blue-100 text-blue-700',
|
|
8
|
-
out_for_delivery: 'bg-indigo-100 text-indigo-700',
|
|
9
|
-
delivered: 'bg-green-100 text-green-700',
|
|
10
|
-
returned: 'bg-amber-100 text-amber-700',
|
|
11
|
-
cancelled: 'bg-red-100 text-red-700',
|
|
12
|
-
failed_delivery: 'bg-orange-100 text-orange-700',
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function formatShippingStatusLabel(value: string): string {
|
|
16
|
-
return value.replace(/_/g, ' ')
|
|
17
|
-
}
|
|
3
|
+
import ShippingStatusBadgeWidget from './widget.client'
|
|
18
4
|
|
|
19
5
|
const widget: InjectionColumnWidget = {
|
|
20
6
|
metadata: {
|
|
@@ -30,12 +16,7 @@ const widget: InjectionColumnWidget = {
|
|
|
30
16
|
cell: ({ getValue }) => {
|
|
31
17
|
const value = getValue()
|
|
32
18
|
if (typeof value !== 'string' || value.length === 0) return null
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<span className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${colors}`}>
|
|
36
|
-
{formatShippingStatusLabel(value)}
|
|
37
|
-
</span>
|
|
38
|
-
)
|
|
19
|
+
return React.createElement(ShippingStatusBadgeWidget, { status: value })
|
|
39
20
|
},
|
|
40
21
|
},
|
|
41
22
|
],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
|
-
import { useRouter } from 'next/navigation'
|
|
4
|
+
import { usePathname, useRouter } from 'next/navigation'
|
|
5
5
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
6
6
|
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
7
7
|
import { Button } from '@open-mercato/ui/primitives/button'
|
|
@@ -14,12 +14,14 @@ import { updateCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
|
14
14
|
import { flash } from '@open-mercato/ui/backend/FlashMessages'
|
|
15
15
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
16
16
|
import { LeaveRequestForm, buildLeaveRequestPayload, type LeaveRequestFormValues } from '@open-mercato/core/modules/staff/components/LeaveRequestForm'
|
|
17
|
+
import { buildRecordInjectionContext, useSetCurrentRecordInjectionContext } from '@open-mercato/ui/backend/injection/recordContext'
|
|
17
18
|
import { type LeaveRequestRecord, type LeaveRequestsResponse, type NormalizedLeaveRequest, normalizeLeaveRequest, resolveStatusVariant, formatDateLabel, formatDateRange } from '../../../../lib/leaveRequestHelpers'
|
|
18
19
|
|
|
19
20
|
export default function StaffLeaveRequestDetailPage({ params }: { params?: { id?: string } }) {
|
|
20
21
|
const id = params?.id
|
|
21
22
|
const t = useT()
|
|
22
23
|
const router = useRouter()
|
|
24
|
+
const pathname = usePathname()
|
|
23
25
|
const [isLoading, setIsLoading] = React.useState(true)
|
|
24
26
|
const [error, setError] = React.useState<string | null>(null)
|
|
25
27
|
const [isNotFound, setIsNotFound] = React.useState(false)
|
|
@@ -123,6 +125,20 @@ const handleSubmit = React.useCallback(async (values: LeaveRequestFormValues) =>
|
|
|
123
125
|
router.refresh()
|
|
124
126
|
}, [decisionComment, record?.id, record?.updatedAt, router, t])
|
|
125
127
|
|
|
128
|
+
// Publish page-load record context to the AppShell-owned `backend:record:current`
|
|
129
|
+
// mount so the enterprise record_locks widget resolves `staff.leaveRequest` + id
|
|
130
|
+
// explicitly. The resourceKind follows the module's camelCase version-history
|
|
131
|
+
// convention so the held lock matches the leave request's save-time conflict surface.
|
|
132
|
+
useSetCurrentRecordInjectionContext(
|
|
133
|
+
buildRecordInjectionContext({
|
|
134
|
+
resourceKind: 'staff.leaveRequest',
|
|
135
|
+
resourceId: id || null,
|
|
136
|
+
updatedAt: record?.updatedAt ?? null,
|
|
137
|
+
data: record as Record<string, unknown> | null,
|
|
138
|
+
path: pathname,
|
|
139
|
+
}),
|
|
140
|
+
)
|
|
141
|
+
|
|
126
142
|
if (isLoading) {
|
|
127
143
|
return (
|
|
128
144
|
<Page>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import Link from 'next/link'
|
|
5
|
-
import { useRouter, useSearchParams } from 'next/navigation'
|
|
5
|
+
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
|
6
6
|
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
7
7
|
import { Button } from '@open-mercato/ui/primitives/button'
|
|
8
8
|
import { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
|
|
@@ -15,6 +15,7 @@ import { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/tran
|
|
|
15
15
|
import { AvailabilityRulesEditor } from '@open-mercato/core/modules/planner/components/AvailabilityRulesEditor'
|
|
16
16
|
import { buildMemberScheduleItems } from '@open-mercato/core/modules/staff/lib/memberSchedule'
|
|
17
17
|
import { TeamMemberForm, buildTeamMemberPayload, type TeamMemberFormValues } from '@open-mercato/core/modules/staff/components/TeamMemberForm'
|
|
18
|
+
import { buildRecordInjectionContext, useSetCurrentRecordInjectionContext } from '@open-mercato/ui/backend/injection/recordContext'
|
|
18
19
|
import { NotesSection } from '@open-mercato/ui/backend/detail'
|
|
19
20
|
import { ActivitiesSection, type SectionAction } from '@open-mercato/ui/backend/detail'
|
|
20
21
|
import { AddressesSection as SharedAddressesSection } from '@open-mercato/ui/backend/detail'
|
|
@@ -71,6 +72,7 @@ export default function StaffTeamMemberDetailPage({ params }: { params?: { id?:
|
|
|
71
72
|
const t = useT()
|
|
72
73
|
const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])
|
|
73
74
|
const router = useRouter()
|
|
75
|
+
const pathname = usePathname()
|
|
74
76
|
const searchParams = useSearchParams()
|
|
75
77
|
const [initialValues, setInitialValues] = React.useState<TeamMemberFormValues | null>(null)
|
|
76
78
|
const [memberRecord, setMemberRecord] = React.useState<TeamMemberRecord | null>(null)
|
|
@@ -341,6 +343,20 @@ export default function StaffTeamMemberDetailPage({ params }: { params?: { id?:
|
|
|
341
343
|
: [t('staff.teamMembers.detail.roles.unassigned', 'No roles assigned')]
|
|
342
344
|
const userEmail = memberRecord?.user?.email ?? null
|
|
343
345
|
|
|
346
|
+
// Publish page-load record context to the AppShell-owned `backend:record:current`
|
|
347
|
+
// mount so the enterprise record_locks widget resolves `staff.teamMember` + id
|
|
348
|
+
// explicitly. The resourceKind mirrors the TeamMemberForm `versionHistory` so the held
|
|
349
|
+
// lock matches the save-time conflict surface for the same team member.
|
|
350
|
+
useSetCurrentRecordInjectionContext(
|
|
351
|
+
buildRecordInjectionContext({
|
|
352
|
+
resourceKind: 'staff.teamMember',
|
|
353
|
+
resourceId: memberId || null,
|
|
354
|
+
updatedAt: initialValues?.updatedAt ?? null,
|
|
355
|
+
data: initialValues as Record<string, unknown> | null,
|
|
356
|
+
path: pathname,
|
|
357
|
+
}),
|
|
358
|
+
)
|
|
359
|
+
|
|
344
360
|
if (isNotFound) {
|
|
345
361
|
return (
|
|
346
362
|
<Page>
|