@open-mercato/core 0.7.0 → 0.7.1-develop.7102.1.b41f7e3e51
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/helpers/integration/api.js +13 -1
- package/dist/helpers/integration/api.js.map +2 -2
- package/dist/helpers/integration/communicationChannelsFixtures.js +19 -0
- package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
- package/dist/modules/api_keys/api/keys/route.js +1 -1
- package/dist/modules/api_keys/api/keys/route.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +3 -1
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/api_keys/di.js +9 -0
- package/dist/modules/api_keys/di.js.map +7 -0
- package/dist/modules/api_keys/services/principalService.js +31 -0
- package/dist/modules/api_keys/services/principalService.js.map +7 -0
- package/dist/modules/attachments/api/route.js +2 -2
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentLibrary.js +2 -0
- package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
- package/dist/modules/attachments/di.js +11 -1
- package/dist/modules/attachments/di.js.map +2 -2
- package/dist/modules/attachments/index.js.map +1 -1
- package/dist/modules/attachments/lib/attachment-service.js +313 -0
- package/dist/modules/attachments/lib/attachment-service.js.map +7 -0
- package/dist/modules/attachments/lib/scoped-upload-service.js +15 -2
- package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
- package/dist/modules/attachments/lib/upload-limits.js +6 -2
- package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
- package/dist/modules/audit_logs/backend/audit-logs/page.js +6 -0
- package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
- package/dist/modules/audit_logs/lib/display-helpers.js +19 -11
- package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
- package/dist/modules/audit_logs/services/actionLogService.js +57 -12
- package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
- package/dist/modules/auth/acl.js +30 -5
- package/dist/modules/auth/acl.js.map +2 -2
- package/dist/modules/auth/api/feature-check.js +8 -2
- package/dist/modules/auth/api/feature-check.js.map +2 -2
- package/dist/modules/auth/api/login.js +4 -1
- package/dist/modules/auth/api/login.js.map +2 -2
- package/dist/modules/auth/api/reset/validate.js +55 -0
- package/dist/modules/auth/api/reset/validate.js.map +7 -0
- package/dist/modules/auth/api/roles/acl/route.js +28 -33
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/session/refresh.js +25 -1
- package/dist/modules/auth/api/session/refresh.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +96 -51
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +13 -5
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +5 -1
- package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +3 -1
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +5 -1
- package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +2 -1
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/commands/acl.js +254 -0
- package/dist/modules/auth/commands/acl.js.map +7 -0
- package/dist/modules/auth/components/AclEditor.js +39 -30
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/data/validators.js +5 -1
- package/dist/modules/auth/data/validators.js.map +2 -2
- package/dist/modules/auth/di.js +35 -9
- package/dist/modules/auth/di.js.map +2 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js +46 -0
- package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
- package/dist/modules/auth/lib/grantChecks.js.map +2 -2
- package/dist/modules/auth/lib/userIdFilter.js +16 -0
- package/dist/modules/auth/lib/userIdFilter.js.map +7 -0
- package/dist/modules/auth/services/authService.js +16 -2
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/auth/services/principalService.js +200 -0
- package/dist/modules/auth/services/principalService.js.map +7 -0
- package/dist/modules/auth/services/rbacService.js +67 -24
- package/dist/modules/auth/services/rbacService.js.map +3 -3
- package/dist/modules/auth/services/roleOrganizationScope.js +41 -0
- package/dist/modules/auth/services/roleOrganizationScope.js.map +7 -0
- package/dist/modules/business_rules/backend/logs/page.js +3 -1
- package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/page.js +3 -1
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +3 -1
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
- package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-evaluator.js +10 -9
- package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
- package/dist/modules/catalog/ai-agents.js +1 -1
- package/dist/modules/catalog/ai-agents.js.map +1 -1
- package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
- package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +5 -2
- package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -0
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +7 -1
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +2 -0
- package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +9 -1
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js +95 -10
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +3 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js +14 -1
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
- package/dist/modules/communication_channels/di.js +7 -1
- package/dist/modules/communication_channels/di.js.map +2 -2
- package/dist/modules/communication_channels/lib/email-capabilities.js +4 -1
- package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
- package/dist/modules/communication_channels/lib/outbound-recipient.js +33 -0
- package/dist/modules/communication_channels/lib/outbound-recipient.js.map +7 -0
- package/dist/modules/communication_channels/lib/resolve-channel-type.js +51 -0
- package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +7 -0
- package/dist/modules/communication_channels/lib/test-seed.js +41 -2
- package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
- package/dist/modules/configs/lib/system-status.js +9 -0
- package/dist/modules/configs/lib/system-status.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +3 -1
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +3 -1
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/currencies/services/rateFetchingService.js +6 -1
- package/dist/modules/currencies/services/rateFetchingService.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/domain-mappings.js +9 -0
- package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +3 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +3 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +2 -2
- package/dist/modules/customer_accounts/services/domainMappingService.js +10 -0
- package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
- package/dist/modules/customers/ai-tools/companies-pack.js +4 -1
- package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +13 -2
- package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/deals-pack.js +52 -6
- package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/people-pack.js +4 -1
- package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
- package/dist/modules/customers/api/activities/route.js +48 -6
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/people/route.js +20 -64
- package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +17 -94
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +8 -5
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
- package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
- package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/route.js +8 -25
- package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/stats/route.js +3 -22
- package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
- package/dist/modules/customers/api/deals/aggregate/route.js +11 -4
- package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
- package/dist/modules/customers/api/deals/map/route.js +2 -1
- package/dist/modules/customers/api/deals/map/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +38 -1
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/entity-roles-factory.js +4 -4
- package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +3 -1
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/tasks/route.js +27 -4
- package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +4 -3
- package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
- package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/route.js +11 -10
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/check-phone/route.js +51 -9
- package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
- package/dist/modules/customers/api/todos/route.js +30 -5
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +4 -2
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +6 -1
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +5 -2
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js +4 -13
- package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js +85 -14
- package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +18 -0
- package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +7 -0
- package/dist/modules/customers/backend/customers/people/page.js +4 -2
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +9 -3
- package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +21 -34
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js.map +1 -1
- package/dist/modules/customers/commands/personCompanyLinks.js +131 -2
- package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
- package/dist/modules/customers/components/CustomerTodosTable.js +1 -0
- package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
- package/dist/modules/customers/components/DealsKpiStrip.js +7 -6
- package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
- package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
- package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
- package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
- package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
- package/dist/modules/customers/components/calendar/EventPeekPopover.js +3 -2
- package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/PeopleField.js +40 -5
- package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/hooks.js +2 -1
- package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
- package/dist/modules/customers/components/calendar/types.js +1 -1
- package/dist/modules/customers/components/calendar/types.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyKpiBar.js +5 -4
- package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +3 -1
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +19 -7
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +6 -5
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +35 -11
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js +3 -1
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +19 -13
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -4
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +3 -3
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
- package/dist/modules/customers/components/detail/utils.js +5 -5
- package/dist/modules/customers/components/detail/utils.js.map +2 -2
- package/dist/modules/customers/data/entities.js.map +1 -1
- package/dist/modules/customers/data/validators.js +32 -3
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/events.js +5 -0
- package/dist/modules/customers/events.js.map +2 -2
- package/dist/modules/customers/lib/calendar/conflicts.js +8 -2
- package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
- package/dist/modules/customers/lib/calendar/editorPayload.js +3 -2
- package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
- package/dist/modules/customers/lib/calendar/mapItem.js +8 -3
- package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
- package/dist/modules/customers/lib/calendar/participantIdentity.js +9 -0
- package/dist/modules/customers/lib/calendar/participantIdentity.js.map +7 -0
- package/dist/modules/customers/lib/closureStage.js +45 -0
- package/dist/modules/customers/lib/closureStage.js.map +7 -0
- package/dist/modules/customers/lib/dealStatus.js +30 -0
- package/dist/modules/customers/lib/dealStatus.js.map +2 -2
- package/dist/modules/customers/lib/detailReadAccess.js +12 -0
- package/dist/modules/customers/lib/detailReadAccess.js.map +7 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js +1 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
- package/dist/modules/customers/lib/personCompanies.js +100 -2
- package/dist/modules/customers/lib/personCompanies.js.map +2 -2
- package/dist/modules/customers/lib/todoCompatibility.js +12 -0
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/dashboards/lib/widgetScope.js +6 -1
- package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +3 -1
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/lib/abandoned-run.js +19 -0
- package/dist/modules/data_sync/lib/abandoned-run.js.map +7 -0
- package/dist/modules/data_sync/lib/sync-engine.js +72 -6
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-export.js +5 -1
- package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-import.js +5 -1
- package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
- package/dist/modules/devices/acl.js +9 -1
- package/dist/modules/devices/acl.js.map +2 -2
- package/dist/modules/devices/api/admin/devices/[id]/route.js +5 -32
- package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
- package/dist/modules/devices/api/admin/devices/route.js +14 -1
- package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
- package/dist/modules/devices/api/deviceList.js +99 -12
- package/dist/modules/devices/api/deviceList.js.map +2 -2
- package/dist/modules/devices/api/deviceSerialization.js +46 -0
- package/dist/modules/devices/api/deviceSerialization.js.map +7 -0
- package/dist/modules/devices/api/openapi.js +3 -1
- package/dist/modules/devices/api/openapi.js.map +2 -2
- package/dist/modules/devices/api/route.js +9 -1
- package/dist/modules/devices/api/route.js.map +2 -2
- package/dist/modules/devices/backend/devices/[id]/page.js +10 -26
- package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/create/page.js +17 -1
- package/dist/modules/devices/backend/devices/create/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/page.js +28 -34
- package/dist/modules/devices/backend/devices/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/useDeviceUserLabels.js +34 -0
- package/dist/modules/devices/backend/devices/useDeviceUserLabels.js.map +7 -0
- package/dist/modules/devices/backend/devices/userOptions.js +52 -0
- package/dist/modules/devices/backend/devices/userOptions.js.map +7 -0
- package/dist/modules/devices/setup.js +6 -2
- package/dist/modules/devices/setup.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/directory/di.js +9 -0
- package/dist/modules/directory/di.js.map +2 -2
- package/dist/modules/directory/services/organizationHierarchyService.js +29 -0
- package/dist/modules/directory/services/organizationHierarchyService.js.map +7 -0
- package/dist/modules/directory/services/organizationScopeService.js +56 -0
- package/dist/modules/directory/services/organizationScopeService.js.map +7 -0
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/api/records.js +4 -2
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +3 -1
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/eudr/api/plots/route.js +5 -1
- package/dist/modules/eudr/api/plots/route.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/plots/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/product-mappings/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/statements/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
- package/dist/modules/eudr/commands/statements.js +0 -3
- package/dist/modules/eudr/commands/statements.js.map +2 -2
- package/dist/modules/eudr/data/validators.js +4 -1
- package/dist/modules/eudr/data/validators.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +1 -0
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/OverridesTable.js +1 -0
- package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
- package/dist/modules/feature_toggles/defaults.json +0 -8
- package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +3 -0
- package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js +3 -0
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
- package/dist/modules/inbox_ops/lib/htmlToPlainText.js +1 -12
- package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
- package/dist/modules/integrations/api/[id]/credentials/route.js +6 -1
- package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +38 -29
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +36 -9
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +55 -0
- package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +7 -0
- package/dist/modules/integrations/data/validators.js +11 -3
- package/dist/modules/integrations/data/validators.js.map +2 -2
- package/dist/modules/integrations/lib/credentials-masking.js +6 -2
- package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
- package/dist/modules/messages/api/[id]/route.js +29 -1
- package/dist/modules/messages/api/[id]/route.js.map +2 -2
- package/dist/modules/messages/api/openapi.js +17 -2
- package/dist/modules/messages/api/openapi.js.map +2 -2
- package/dist/modules/messages/api/route.js +17 -2
- package/dist/modules/messages/api/route.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +7 -14
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/inboxFilters.js +15 -0
- package/dist/modules/messages/components/inboxFilters.js.map +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +11 -1
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +3 -1
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js +2 -1
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
- package/dist/modules/messages/components/messageListLabels.js +14 -2
- package/dist/modules/messages/components/messageListLabels.js.map +2 -2
- package/dist/modules/messages/data/validators.js +18 -4
- package/dist/modules/messages/data/validators.js.map +2 -2
- package/dist/modules/messages/lib/channel-sender-identity.js +26 -0
- package/dist/modules/messages/lib/channel-sender-identity.js.map +7 -0
- package/dist/modules/messages/lib/composeSourceChannelType.js +41 -0
- package/dist/modules/messages/lib/composeSourceChannelType.js.map +7 -0
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +4 -6
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -1
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
- package/dist/modules/payment_gateways/lib/webhook-processor.js +7 -0
- package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +3 -0
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/push_notifications/backend/push_notifications/page.js +3 -1
- package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
- package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -1
- package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +150 -51
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/search-entity-policy.js +14 -0
- package/dist/modules/query_index/lib/search-entity-policy.js.map +7 -0
- package/dist/modules/query_index/lib/search-tokens.js +79 -3
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +3 -1
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +3 -1
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +3 -0
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +3 -0
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +10 -8
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +79 -1
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/components/PriceWithCurrency.js +7 -5
- package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +3 -0
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +8 -6
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +51 -22
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +83 -18
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +23 -9
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnsSection.js +8 -6
- package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +68 -14
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +6 -5
- package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +5 -4
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +8 -6
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/lineItemShipmentLock.js +54 -0
- package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +7 -0
- package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
- package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
- package/dist/modules/sales/data/entities.js +8 -2
- package/dist/modules/sales/data/entities.js.map +2 -2
- package/dist/modules/sales/extension-points.js +1 -0
- package/dist/modules/sales/extension-points.js.map +2 -2
- package/dist/modules/sales/lib/salesChannelsToggleSeed.js +33 -0
- package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +7 -0
- package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +32 -0
- package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +7 -0
- package/dist/modules/sales/setup.js +2 -0
- package/dist/modules/sales/setup.js.map +2 -2
- package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +10 -2
- package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
- package/dist/modules/sales/widgets/injection-table.js +4 -7
- package/dist/modules/sales/widgets/injection-table.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/page.js +3 -0
- package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/page.js +3 -0
- package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/page.js +3 -0
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +3 -0
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +3 -0
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +3 -0
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/page.js +29 -18
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +3 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/sync_excel/lib/adapters/customers.js +1 -0
- package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
- package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
- package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
- package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/claims/route.js +12 -9
- package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
- package/dist/modules/warranty_claims/backend/page.js +3 -0
- package/dist/modules/warranty_claims/backend/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
- package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +3 -0
- package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
- package/dist/modules/wms/api/warehouseSearch.js +21 -0
- package/dist/modules/wms/api/warehouseSearch.js.map +7 -0
- package/dist/modules/wms/api/warehouses/route.js +13 -9
- package/dist/modules/wms/api/warehouses/route.js.map +2 -2
- package/dist/modules/wms/api/zones/route.js +15 -2
- package/dist/modules/wms/api/zones/route.js.map +2 -2
- package/dist/modules/wms/commands/configuration.js +121 -9
- package/dist/modules/wms/commands/configuration.js.map +2 -2
- package/dist/modules/wms/commands/inventory-actions.js +3 -0
- package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
- package/dist/modules/wms/commands/shared.js +9 -1
- package/dist/modules/wms/commands/shared.js.map +2 -2
- package/dist/modules/wms/components/backend/WarehouseEditDialog.js +158 -0
- package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js +76 -111
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +1 -0
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotsListPage.js +1 -0
- package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +27 -20
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
- package/dist/modules/wms/components/backend/warehouseFormOptions.js +66 -0
- package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/page.js +3 -1
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/events/page.js +3 -1
- package/dist/modules/workflows/backend/events/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.js +3 -1
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +3 -1
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js +4 -0
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/package.json +9 -10
- package/src/helpers/integration/api.ts +33 -1
- package/src/helpers/integration/communicationChannelsFixtures.ts +69 -1
- package/src/modules/api_keys/api/keys/route.ts +3 -1
- package/src/modules/api_keys/backend/api-keys/page.tsx +4 -1
- package/src/modules/api_keys/di.ts +7 -0
- package/src/modules/api_keys/services/principalService.ts +33 -0
- package/src/modules/attachments/AGENTS.md +15 -0
- package/src/modules/attachments/api/route.ts +2 -2
- package/src/modules/attachments/components/AttachmentLibrary.tsx +3 -0
- package/src/modules/attachments/di.ts +16 -0
- package/src/modules/attachments/i18n/de.json +5 -0
- package/src/modules/attachments/i18n/en.json +5 -0
- package/src/modules/attachments/i18n/es.json +5 -0
- package/src/modules/attachments/i18n/ko.json +5 -0
- package/src/modules/attachments/i18n/pl.json +5 -0
- package/src/modules/attachments/index.ts +10 -0
- package/src/modules/attachments/lib/attachment-service.ts +468 -0
- package/src/modules/attachments/lib/scoped-upload-service.ts +46 -0
- package/src/modules/attachments/lib/upload-limits.ts +6 -2
- package/src/modules/audit_logs/backend/audit-logs/page.tsx +8 -0
- package/src/modules/audit_logs/lib/display-helpers.tsx +42 -32
- package/src/modules/audit_logs/services/actionLogService.ts +74 -11
- package/src/modules/auth/acl.ts +30 -6
- package/src/modules/auth/api/feature-check.ts +10 -3
- package/src/modules/auth/api/login.ts +9 -1
- package/src/modules/auth/api/reset/validate.ts +57 -0
- package/src/modules/auth/api/roles/acl/route.ts +42 -39
- package/src/modules/auth/api/session/refresh.ts +32 -1
- package/src/modules/auth/api/users/acl/route.ts +177 -53
- package/src/modules/auth/api/users/route.ts +18 -5
- package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +5 -2
- package/src/modules/auth/backend/roles/page.tsx +4 -2
- package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +5 -2
- package/src/modules/auth/backend/users/page.tsx +3 -2
- package/src/modules/auth/commands/acl.ts +495 -0
- package/src/modules/auth/components/AclEditor.tsx +63 -33
- package/src/modules/auth/data/entities.ts +4 -1
- package/src/modules/auth/data/validators.ts +5 -0
- package/src/modules/auth/di.ts +46 -16
- package/src/modules/auth/frontend/reset/[token]/page.tsx +74 -0
- package/src/modules/auth/i18n/de.json +389 -0
- package/src/modules/auth/i18n/en.json +389 -0
- package/src/modules/auth/i18n/es.json +389 -0
- package/src/modules/auth/i18n/ko.json +389 -0
- package/src/modules/auth/i18n/pl.json +391 -2
- package/src/modules/auth/lib/grantChecks.ts +6 -0
- package/src/modules/auth/lib/userIdFilter.ts +31 -0
- package/src/modules/auth/services/authService.ts +18 -2
- package/src/modules/auth/services/principalService.ts +266 -0
- package/src/modules/auth/services/rbacService.ts +110 -24
- package/src/modules/auth/services/roleOrganizationScope.ts +70 -0
- package/src/modules/business_rules/backend/logs/page.tsx +4 -1
- package/src/modules/business_rules/backend/rules/page.tsx +4 -1
- package/src/modules/business_rules/backend/sets/page.tsx +4 -1
- package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
- package/src/modules/business_rules/lib/rule-evaluator.ts +10 -9
- package/src/modules/catalog/ai-agents.ts +1 -1
- package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
- package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +12 -5
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +3 -0
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +7 -0
- package/src/modules/catalog/i18n/de.json +1 -0
- package/src/modules/catalog/i18n/en.json +1 -0
- package/src/modules/catalog/i18n/es.json +1 -0
- package/src/modules/catalog/i18n/ko.json +1 -0
- package/src/modules/catalog/i18n/pl.json +1 -0
- package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +4 -0
- package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +17 -1
- package/src/modules/communication_channels/api/post/test-seed/route.ts +155 -16
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +4 -0
- package/src/modules/communication_channels/commands/ingest-inbound-message.ts +38 -1
- package/src/modules/communication_channels/di.ts +7 -0
- package/src/modules/communication_channels/lib/adapter.ts +14 -0
- package/src/modules/communication_channels/lib/email-capabilities.ts +4 -0
- package/src/modules/communication_channels/lib/outbound-recipient.ts +71 -0
- package/src/modules/communication_channels/lib/resolve-channel-type.ts +99 -0
- package/src/modules/communication_channels/lib/test-seed.ts +64 -4
- package/src/modules/configs/i18n/de.json +2 -0
- package/src/modules/configs/i18n/en.json +2 -0
- package/src/modules/configs/i18n/es.json +2 -0
- package/src/modules/configs/i18n/ko.json +2 -0
- package/src/modules/configs/i18n/pl.json +2 -0
- package/src/modules/configs/lib/system-status.ts +9 -0
- package/src/modules/currencies/AGENTS.md +3 -0
- package/src/modules/currencies/backend/currencies/page.tsx +4 -1
- package/src/modules/currencies/backend/exchange-rates/page.tsx +4 -1
- package/src/modules/currencies/services/README.md +45 -0
- package/src/modules/currencies/services/rateFetchingService.ts +6 -1
- package/src/modules/customer_accounts/api/admin/domain-mappings.ts +7 -0
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +4 -1
- package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +4 -1
- package/src/modules/customer_accounts/services/domainMappingService.ts +10 -0
- package/src/modules/customers/ai-tools/companies-pack.ts +4 -1
- package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +17 -2
- package/src/modules/customers/ai-tools/deals-pack.ts +66 -1
- package/src/modules/customers/ai-tools/people-pack.ts +4 -1
- package/src/modules/customers/api/activities/route.ts +45 -0
- package/src/modules/customers/api/companies/[id]/people/route.ts +24 -73
- package/src/modules/customers/api/companies/[id]/route.ts +24 -107
- package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +16 -8
- package/src/modules/customers/api/deals/[id]/companies/route.ts +4 -1
- package/src/modules/customers/api/deals/[id]/people/route.ts +4 -1
- package/src/modules/customers/api/deals/[id]/route.ts +17 -28
- package/src/modules/customers/api/deals/[id]/stats/route.ts +10 -25
- package/src/modules/customers/api/deals/aggregate/route.ts +14 -4
- package/src/modules/customers/api/deals/map/route.ts +1 -0
- package/src/modules/customers/api/deals/route.ts +50 -1
- package/src/modules/customers/api/entity-roles-factory.ts +8 -4
- package/src/modules/customers/api/interactions/route.ts +8 -2
- package/src/modules/customers/api/interactions/tasks/route.ts +24 -1
- package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +12 -4
- package/src/modules/customers/api/people/[id]/companies/context.ts +4 -1
- package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +4 -1
- package/src/modules/customers/api/people/[id]/route.ts +16 -11
- package/src/modules/customers/api/people/check-phone/route.ts +75 -10
- package/src/modules/customers/api/todos/route.ts +27 -2
- package/src/modules/customers/backend/customers/companies/page.tsx +5 -2
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +7 -2
- package/src/modules/customers/backend/customers/deals/page.tsx +8 -2
- package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +5 -14
- package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +109 -27
- package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +21 -0
- package/src/modules/customers/backend/customers/people/page.tsx +5 -2
- package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +12 -4
- package/src/modules/customers/commands/deals.ts +34 -59
- package/src/modules/customers/commands/interactions.ts +1 -1
- package/src/modules/customers/commands/personCompanyLinks.ts +224 -8
- package/src/modules/customers/components/CustomerTodosTable.tsx +2 -0
- package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
- package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
- package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
- package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
- package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
- package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
- package/src/modules/customers/components/calendar/EventPeekPopover.tsx +4 -2
- package/src/modules/customers/components/calendar/editor/PeopleField.tsx +61 -5
- package/src/modules/customers/components/calendar/editor/hooks.ts +7 -1
- package/src/modules/customers/components/calendar/types.ts +2 -2
- package/src/modules/customers/components/detail/CompanyKpiBar.tsx +5 -4
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +8 -1
- package/src/modules/customers/components/detail/DealForm.tsx +22 -2
- package/src/modules/customers/components/detail/DealsSection.tsx +11 -5
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +58 -12
- package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +8 -1
- package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +23 -14
- package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
- package/src/modules/customers/components/detail/types.ts +1 -1
- package/src/modules/customers/components/detail/utils.ts +15 -5
- package/src/modules/customers/data/entities.ts +1 -1
- package/src/modules/customers/data/validators.ts +50 -9
- package/src/modules/customers/events.ts +5 -0
- package/src/modules/customers/i18n/de.json +9 -1
- package/src/modules/customers/i18n/en.json +9 -1
- package/src/modules/customers/i18n/es.json +9 -1
- package/src/modules/customers/i18n/ko.json +9 -1
- package/src/modules/customers/i18n/pl.json +9 -1
- package/src/modules/customers/lib/calendar/conflicts.ts +10 -2
- package/src/modules/customers/lib/calendar/editorPayload.ts +4 -3
- package/src/modules/customers/lib/calendar/mapItem.ts +8 -3
- package/src/modules/customers/lib/calendar/participantIdentity.ts +17 -0
- package/src/modules/customers/lib/closureStage.ts +76 -0
- package/src/modules/customers/lib/dealStatus.ts +42 -0
- package/src/modules/customers/lib/detailReadAccess.ts +35 -0
- package/src/modules/customers/lib/findPeopleByAddresses.ts +8 -6
- package/src/modules/customers/lib/personCompanies.ts +136 -1
- package/src/modules/customers/lib/todoCompatibility.ts +19 -1
- package/src/modules/dashboards/i18n/es.json +4 -4
- package/src/modules/dashboards/i18n/pl.json +7 -7
- package/src/modules/dashboards/lib/widgetScope.ts +6 -0
- package/src/modules/data_sync/AGENTS.md +1 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +4 -1
- package/src/modules/data_sync/lib/abandoned-run.ts +56 -0
- package/src/modules/data_sync/lib/adapter.ts +36 -0
- package/src/modules/data_sync/lib/sync-engine.ts +113 -5
- package/src/modules/data_sync/workers/sync-export.ts +4 -0
- package/src/modules/data_sync/workers/sync-import.ts +4 -0
- package/src/modules/devices/AGENTS.md +20 -1
- package/src/modules/devices/acl.ts +9 -1
- package/src/modules/devices/api/admin/devices/[id]/route.ts +5 -34
- package/src/modules/devices/api/admin/devices/route.ts +14 -1
- package/src/modules/devices/api/deviceList.ts +135 -11
- package/src/modules/devices/api/deviceSerialization.ts +50 -0
- package/src/modules/devices/api/openapi.ts +9 -1
- package/src/modules/devices/api/route.ts +9 -1
- package/src/modules/devices/backend/devices/[id]/page.tsx +18 -32
- package/src/modules/devices/backend/devices/create/page.tsx +17 -1
- package/src/modules/devices/backend/devices/page.tsx +44 -45
- package/src/modules/devices/backend/devices/useDeviceUserLabels.ts +45 -0
- package/src/modules/devices/backend/devices/userOptions.ts +99 -0
- package/src/modules/devices/i18n/de.json +3 -2
- package/src/modules/devices/i18n/en.json +3 -2
- package/src/modules/devices/i18n/es.json +3 -2
- package/src/modules/devices/i18n/ko.json +3 -2
- package/src/modules/devices/i18n/pl.json +3 -2
- package/src/modules/devices/setup.ts +6 -2
- package/src/modules/directory/backend/directory/organizations/page.tsx +3 -1
- package/src/modules/directory/backend/directory/tenants/page.tsx +3 -1
- package/src/modules/directory/di.ts +14 -2
- package/src/modules/directory/services/organizationHierarchyService.ts +34 -0
- package/src/modules/directory/services/organizationScopeService.ts +85 -0
- package/src/modules/directory/utils/organizationScope.ts +4 -15
- package/src/modules/entities/api/records.ts +2 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +4 -1
- package/src/modules/eudr/api/plots/route.ts +4 -0
- package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/plots/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/statements/page.tsx +4 -0
- package/src/modules/eudr/commands/statements.ts +0 -3
- package/src/modules/eudr/data/validators.ts +16 -1
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +2 -1
- package/src/modules/feature_toggles/components/OverridesTable.tsx +2 -1
- package/src/modules/feature_toggles/defaults.json +0 -8
- package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +4 -0
- package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +4 -0
- package/src/modules/inbox_ops/lib/htmlToPlainText.ts +1 -17
- package/src/modules/integrations/api/[id]/credentials/route.ts +6 -4
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +61 -31
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +44 -9
- package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +84 -0
- package/src/modules/integrations/data/validators.ts +12 -2
- package/src/modules/integrations/i18n/de.json +1 -0
- package/src/modules/integrations/i18n/en.json +1 -0
- package/src/modules/integrations/i18n/es.json +1 -0
- package/src/modules/integrations/i18n/ko.json +1 -0
- package/src/modules/integrations/i18n/pl.json +1 -0
- package/src/modules/integrations/lib/credentials-masking.ts +10 -6
- package/src/modules/messages/api/[id]/route.ts +55 -1
- package/src/modules/messages/api/openapi.ts +20 -0
- package/src/modules/messages/api/route.ts +31 -2
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +9 -16
- package/src/modules/messages/components/inboxFilters.ts +36 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +14 -1
- package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +3 -1
- package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +2 -1
- package/src/modules/messages/components/message-detail/types.ts +3 -0
- package/src/modules/messages/components/messageListLabels.ts +52 -3
- package/src/modules/messages/data/validators.ts +43 -4
- package/src/modules/messages/lib/channel-sender-identity.ts +55 -0
- package/src/modules/messages/lib/composeSourceChannelType.ts +95 -0
- package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +4 -6
- package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +4 -1
- package/src/modules/payment_gateways/lib/webhook-processor.ts +11 -0
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +4 -0
- package/src/modules/push_notifications/backend/push_notifications/page.tsx +4 -1
- package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
- package/src/modules/query_index/lib/engine.ts +249 -61
- package/src/modules/query_index/lib/search-entity-policy.ts +46 -0
- package/src/modules/query_index/lib/search-tokens.ts +135 -3
- package/src/modules/resources/backend/resources/resource-types/page.tsx +4 -1
- package/src/modules/resources/backend/resources/resources/page.tsx +4 -1
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +4 -0
- package/src/modules/sales/backend/sales/channels/page.tsx +4 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +14 -8
- package/src/modules/sales/commands/documents.ts +93 -0
- package/src/modules/sales/components/PriceWithCurrency.tsx +17 -5
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +4 -0
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +6 -5
- package/src/modules/sales/components/documents/ItemsSection.tsx +56 -18
- package/src/modules/sales/components/documents/LineItemDialog.tsx +137 -20
- package/src/modules/sales/components/documents/PaymentsSection.tsx +20 -9
- package/src/modules/sales/components/documents/ReturnsSection.tsx +6 -5
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +106 -14
- package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +6 -5
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +5 -4
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +6 -5
- package/src/modules/sales/components/documents/lineItemShipmentLock.ts +74 -0
- package/src/modules/sales/components/documents/lineItemUtils.ts +7 -2
- package/src/modules/sales/data/entities.ts +6 -0
- package/src/modules/sales/extension-points.ts +1 -0
- package/src/modules/sales/i18n/de.json +8 -0
- package/src/modules/sales/i18n/en.json +8 -0
- package/src/modules/sales/i18n/es.json +8 -0
- package/src/modules/sales/i18n/ko.json +8 -0
- package/src/modules/sales/i18n/pl.json +8 -0
- package/src/modules/sales/lib/salesChannelsToggleSeed.ts +42 -0
- package/src/modules/sales/migrations/.snapshot-open-mercato.json +60 -0
- package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +87 -0
- package/src/modules/sales/setup.ts +2 -0
- package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +9 -1
- package/src/modules/sales/widgets/injection-table.ts +4 -7
- package/src/modules/staff/backend/staff/leave-requests/page.tsx +4 -0
- package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +4 -0
- package/src/modules/staff/backend/staff/team-members/page.tsx +6 -0
- package/src/modules/staff/backend/staff/team-roles/page.tsx +4 -0
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +4 -0
- package/src/modules/staff/backend/staff/teams/page.tsx +4 -0
- package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +4 -0
- package/src/modules/sync_excel/lib/adapters/customers.ts +5 -0
- package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
- package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
- package/src/modules/warranty_claims/api/portal/claims/route.ts +12 -9
- package/src/modules/warranty_claims/backend/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +4 -0
- package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +4 -0
- package/src/modules/wms/api/warehouseSearch.ts +23 -0
- package/src/modules/wms/api/warehouses/route.ts +13 -9
- package/src/modules/wms/api/zones/route.ts +16 -0
- package/src/modules/wms/commands/configuration.ts +159 -10
- package/src/modules/wms/commands/inventory-actions.ts +3 -0
- package/src/modules/wms/commands/shared.ts +17 -0
- package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +216 -0
- package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +95 -141
- package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +2 -0
- package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -0
- package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +36 -20
- package/src/modules/wms/components/backend/warehouseFormOptions.ts +72 -0
- package/src/modules/wms/i18n/de.json +2 -0
- package/src/modules/wms/i18n/en.json +2 -0
- package/src/modules/wms/i18n/es.json +2 -0
- package/src/modules/wms/i18n/ko.json +2 -0
- package/src/modules/wms/i18n/pl.json +2 -0
- package/src/modules/workflows/backend/definitions/page.tsx +4 -1
- package/src/modules/workflows/backend/events/page.tsx +4 -1
- package/src/modules/workflows/backend/instances/page.tsx +4 -1
- package/src/modules/workflows/backend/tasks/page.tsx +4 -1
- package/src/modules/workflows/lib/activity-executor.ts +9 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { parseBooleanWithDefault } from '@open-mercato/shared/lib/boolean'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The canonical customer record. Every customer also has a person or company profile indexed under
|
|
5
|
+
* its own entity type, and it is the profile — not the base row — that carries the detail-page
|
|
6
|
+
* navigation.
|
|
7
|
+
*/
|
|
8
|
+
export const CUSTOMERS_BASE_ENTITY_TYPE = 'customers:customer_entity'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Whether base customer rows are offered as search results.
|
|
12
|
+
*
|
|
13
|
+
* Why the knob exists: `search_tokens` is written by the query index for **every** entity a CRUD
|
|
14
|
+
* route indexes, independently of any module's `search.ts` config. `customers:customer_entity` is
|
|
15
|
+
* indexed but no module registers it for search, so its rows only ever surface a second,
|
|
16
|
+
* navigation-less copy of a customer who is already represented by their person or company
|
|
17
|
+
* profile — the duplicate reported in #5046. Worse, the duplicate was visible to superadmins only:
|
|
18
|
+
* `resolveReadableEntityTypes` narrows every other caller to entity types a module registered for
|
|
19
|
+
* search, so the same query returned different shapes for different users.
|
|
20
|
+
*
|
|
21
|
+
* Default `false`: the token strategy never returns base customer rows, so a customer appears
|
|
22
|
+
* exactly once, as their profile. `OM_SEARCH_CUSTOMERS_INDEX_BASE_ENTITY=true` restores the
|
|
23
|
+
* previous behavior, where both rows are returned and the presenter enricher's linked-result merge
|
|
24
|
+
* collapses the pair into the canonical entity result.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately a **read-side** filter. `search_tokens` is not only the token-search index: the
|
|
27
|
+
* People and Companies list routes resolve their search box through
|
|
28
|
+
* `findEntityIdsBySearchTokens` on this exact entity type, and both query engines rewrite
|
|
29
|
+
* `like`/`ilike` on encrypted customer columns into the same table. Dropping the rows would
|
|
30
|
+
* silently break list search on `display_name`, `primary_email`, `description` and friends, so the
|
|
31
|
+
* rows stay and only the search strategy stops offering them.
|
|
32
|
+
*/
|
|
33
|
+
export function indexesCustomerBaseEntity(): boolean {
|
|
34
|
+
return parseBooleanWithDefault(process.env.OM_SEARCH_CUSTOMERS_INDEX_BASE_ENTITY, false)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Entity types the token search strategy must not return.
|
|
39
|
+
*
|
|
40
|
+
* Exposed as a list so the strategy can express the exclusion as a single `NOT IN` predicate
|
|
41
|
+
* instead of post-filtering rows it already paid to fetch — a post-filter would silently shrink
|
|
42
|
+
* the caller's `limit`.
|
|
43
|
+
*/
|
|
44
|
+
export function listSearchTokenExcludedEntityTypes(): string[] {
|
|
45
|
+
return indexesCustomerBaseEntity() ? [] : [CUSTOMERS_BASE_ENTITY_TYPE]
|
|
46
|
+
}
|
|
@@ -223,6 +223,49 @@ export async function deleteSearchTokensForRecord(
|
|
|
223
223
|
.execute()
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
// NUL, not a printable separator: a field name may itself contain a space, so `a b` + hash `c`
|
|
227
|
+
// would otherwise sign identically to field `a` + hash `b c`.
|
|
228
|
+
const SIGNATURE_SEPARATOR = String.fromCharCode(0)
|
|
229
|
+
|
|
230
|
+
// Identifies one token row for comparison. `token` is NULL unless `storeRawTokens` is on, and a
|
|
231
|
+
// stored NULL has to sign the same as the `null` a freshly built row carries — otherwise every
|
|
232
|
+
// record compares as changed and the skip never fires.
|
|
233
|
+
function tokenSignature(row: { field?: unknown; token_hash?: unknown; token?: unknown }): string {
|
|
234
|
+
return [
|
|
235
|
+
String(row.field ?? ''),
|
|
236
|
+
String(row.token_hash ?? ''),
|
|
237
|
+
row.token == null ? '' : String(row.token),
|
|
238
|
+
].join(SIGNATURE_SEPARATOR)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Multiplicities, not sets: #4681 reports token rows duplicated by the concurrent-replacement
|
|
242
|
+
// defect, and a set comparison reads such a record as already correct and preserves the duplicates
|
|
243
|
+
// forever. Counting sends it through a full rewrite, which collapses them.
|
|
244
|
+
function tallyEquals(a: Map<string, number> | undefined, b: Map<string, number> | undefined): boolean {
|
|
245
|
+
const left = a ?? new Map<string, number>()
|
|
246
|
+
const right = b ?? new Map<string, number>()
|
|
247
|
+
if (left.size !== right.size) return false
|
|
248
|
+
for (const [key, count] of left.entries()) {
|
|
249
|
+
if (right.get(key) !== count) return false
|
|
250
|
+
}
|
|
251
|
+
return true
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function tallyTokenRows<TRow extends { field?: unknown; token_hash?: unknown; token?: unknown }>(
|
|
255
|
+
rows: Iterable<TRow>,
|
|
256
|
+
keyOf: (row: TRow) => string
|
|
257
|
+
): Map<string, Map<string, number>> {
|
|
258
|
+
const tallies = new Map<string, Map<string, number>>()
|
|
259
|
+
for (const row of rows) {
|
|
260
|
+
const key = keyOf(row)
|
|
261
|
+
const tally = tallies.get(key) ?? new Map<string, number>()
|
|
262
|
+
const signature = tokenSignature(row)
|
|
263
|
+
tally.set(signature, (tally.get(signature) ?? 0) + 1)
|
|
264
|
+
tallies.set(key, tally)
|
|
265
|
+
}
|
|
266
|
+
return tallies
|
|
267
|
+
}
|
|
268
|
+
|
|
226
269
|
export async function replaceSearchTokensForBatch(
|
|
227
270
|
db: Kysely<any>,
|
|
228
271
|
payloads: Array<BuildTokenOptions & { doc: Record<string, unknown> }>
|
|
@@ -256,8 +299,95 @@ export async function replaceSearchTokensForBatch(
|
|
|
256
299
|
scopeBuckets.set(key, bucket)
|
|
257
300
|
}
|
|
258
301
|
|
|
302
|
+
const recordKeyOf = (row: SearchTokenRow) =>
|
|
303
|
+
`${scopeKey(row.organization_id ?? null, row.tenant_id ?? null)}|${String(row.entity_id)}`
|
|
304
|
+
const builtTally = tallyTokenRows(rows, recordKeyOf)
|
|
305
|
+
|
|
306
|
+
// Read outside the transaction, deliberately. The comparison decides only whether to skip a
|
|
307
|
+
// rewrite, so a concurrent writer costs us at most a rewrite we declined — declined because the
|
|
308
|
+
// table already held exactly the rows this call wanted to write. One ordering is worth naming
|
|
309
|
+
// though: if the read matches and a concurrent writer then commits tokens built from a *staler*
|
|
310
|
+
// doc, the unconditional rewrite this call used to perform would have overwritten them by
|
|
311
|
+
// accident. It no longer does, so those stale rows survive until the record's next write. That
|
|
312
|
+
// is a repair we lose, not a guarantee we break.
|
|
313
|
+
const changedIdsByBucket = new Map<string, Set<string>>()
|
|
314
|
+
for (const [key, bucket] of scopeBuckets.entries()) {
|
|
315
|
+
const ids = Array.from(bucket.ids)
|
|
316
|
+
const builtCountById = new Map<string, number>()
|
|
317
|
+
for (const id of ids) {
|
|
318
|
+
let total = 0
|
|
319
|
+
const tally = builtTally.get(`${key}|${id}`)
|
|
320
|
+
if (tally) for (const count of tally.values()) total += count
|
|
321
|
+
builtCountById.set(id, total)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Count probe first. Its result is one row per record in the batch, so it is bounded by the
|
|
325
|
+
// batch size — unlike a bare row read, which would be bounded only by how many token rows the
|
|
326
|
+
// table already holds for these ids, a quantity this function does not control and (per #4681)
|
|
327
|
+
// has no reason to trust.
|
|
328
|
+
const storedCounts = await db
|
|
329
|
+
.selectFrom('search_tokens' as any)
|
|
330
|
+
.select(['entity_id' as any, sql<number>`count(*)`.as('token_count') as any])
|
|
331
|
+
.where('entity_type' as any, '=', payloads[0].entityType)
|
|
332
|
+
.where(sql<boolean>`organization_id is not distinct from ${bucket.organizationId}`)
|
|
333
|
+
.where(sql<boolean>`tenant_id is not distinct from ${bucket.tenantId}`)
|
|
334
|
+
.where('entity_id' as any, 'in', ids)
|
|
335
|
+
.groupBy('entity_id' as any)
|
|
336
|
+
.execute()
|
|
337
|
+
const storedCountById = new Map<string, number>()
|
|
338
|
+
for (const row of storedCounts as any[]) {
|
|
339
|
+
storedCountById.set(String(row.entity_id), Number(row.token_count))
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const changed = new Set<string>()
|
|
343
|
+
// A record whose stored row count already differs is changed, whatever the rows say — the
|
|
344
|
+
// duplicate case from #4681 resolves here without ever materializing the duplicated rows.
|
|
345
|
+
const contentCandidates = ids.filter((id) => {
|
|
346
|
+
const builtCount = builtCountById.get(id) ?? 0
|
|
347
|
+
if ((storedCountById.get(id) ?? 0) !== builtCount) {
|
|
348
|
+
changed.add(id)
|
|
349
|
+
return false
|
|
350
|
+
}
|
|
351
|
+
return builtCount > 0
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
if (contentCandidates.length) {
|
|
355
|
+
const rowBudget = contentCandidates.reduce((sum, id) => sum + (builtCountById.get(id) ?? 0), 0)
|
|
356
|
+
const stored = await db
|
|
357
|
+
.selectFrom('search_tokens' as any)
|
|
358
|
+
.select(['entity_id' as any, 'field' as any, 'token_hash' as any, 'token' as any])
|
|
359
|
+
.where('entity_type' as any, '=', payloads[0].entityType)
|
|
360
|
+
.where(sql<boolean>`organization_id is not distinct from ${bucket.organizationId}`)
|
|
361
|
+
.where(sql<boolean>`tenant_id is not distinct from ${bucket.tenantId}`)
|
|
362
|
+
.where('entity_id' as any, 'in', contentCandidates)
|
|
363
|
+
// Counts already match, so this cannot truncate — it bounds the damage if a concurrent
|
|
364
|
+
// writer inserts between the probe and this read. A truncated read compares as changed,
|
|
365
|
+
// which costs a rewrite rather than a wrong skip.
|
|
366
|
+
.limit(rowBudget)
|
|
367
|
+
.execute()
|
|
368
|
+
const storedTally = tallyTokenRows(stored as any[], (row) => String(row.entity_id))
|
|
369
|
+
for (const id of contentCandidates) {
|
|
370
|
+
if (!tallyEquals(builtTally.get(`${key}|${id}`), storedTally.get(id))) changed.add(id)
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
changedIdsByBucket.set(key, changed)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const changedRecordKeys = new Set<string>()
|
|
377
|
+
for (const [key, changed] of changedIdsByBucket.entries()) {
|
|
378
|
+
for (const id of changed) changedRecordKeys.add(`${key}|${id}`)
|
|
379
|
+
}
|
|
380
|
+
debug('batch.skip', {
|
|
381
|
+
entityType: payloads[0].entityType,
|
|
382
|
+
recordCount: payloads.length,
|
|
383
|
+
changedCount: changedRecordKeys.size,
|
|
384
|
+
})
|
|
385
|
+
if (!changedRecordKeys.size) return
|
|
386
|
+
|
|
259
387
|
await db.transaction().execute(async (trx) => {
|
|
260
|
-
for (const [, bucket] of scopeBuckets.entries()) {
|
|
388
|
+
for (const [key, bucket] of scopeBuckets.entries()) {
|
|
389
|
+
const changed = changedIdsByBucket.get(key)
|
|
390
|
+
if (!changed?.size) continue
|
|
261
391
|
// Delete by entity_id: a batch replaces all of a record's tokens, and a per-field OR over the
|
|
262
392
|
// whole batch overflows the query compiler's call stack on large batches.
|
|
263
393
|
const deleteQuery = trx
|
|
@@ -265,10 +395,12 @@ export async function replaceSearchTokensForBatch(
|
|
|
265
395
|
.where('entity_type' as any, '=', payloads[0].entityType)
|
|
266
396
|
.where(sql<boolean>`organization_id is not distinct from ${bucket.organizationId}`)
|
|
267
397
|
.where(sql<boolean>`tenant_id is not distinct from ${bucket.tenantId}`)
|
|
268
|
-
.where('entity_id' as any, 'in', Array.from(
|
|
398
|
+
.where('entity_id' as any, 'in', Array.from(changed))
|
|
269
399
|
await deleteQuery.execute()
|
|
270
400
|
}
|
|
271
|
-
const payloadWithTimestamps = rows
|
|
401
|
+
const payloadWithTimestamps = rows
|
|
402
|
+
.filter((row) => changedRecordKeys.has(recordKeyOf(row)))
|
|
403
|
+
.map((row) => ({ ...row, created_at: sql`now()` }))
|
|
272
404
|
for (const batch of chunk(payloadWithTimestamps, INSERT_BATCH_SIZE)) {
|
|
273
405
|
await trx.insertInto('search_tokens' as any).values(batch as any).execute()
|
|
274
406
|
}
|
|
@@ -45,6 +45,7 @@ type ResourceTypesResponse = {
|
|
|
45
45
|
items?: Array<Record<string, unknown>>
|
|
46
46
|
total?: number
|
|
47
47
|
totalPages?: number
|
|
48
|
+
totalIsCapped?: boolean
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
type ResourceTypesMutationContext = {
|
|
@@ -63,6 +64,7 @@ export default function ResourcesResourceTypesPage() {
|
|
|
63
64
|
const [page, setPage] = React.useState(1)
|
|
64
65
|
const [total, setTotal] = React.useState(0)
|
|
65
66
|
const [totalPages, setTotalPages] = React.useState(1)
|
|
67
|
+
const [totalIsCapped, setTotalIsCapped] = React.useState(false)
|
|
66
68
|
const [sorting, setSorting] = React.useState<SortingState>([{ id: 'name', desc: false }])
|
|
67
69
|
const [search, setSearch] = React.useState('')
|
|
68
70
|
const [isLoading, setIsLoading] = React.useState(true)
|
|
@@ -232,6 +234,7 @@ export default function ResourcesResourceTypesPage() {
|
|
|
232
234
|
setRows(items.map(mapApiResourceType))
|
|
233
235
|
setTotal(typeof payload.total === 'number' ? payload.total : items.length)
|
|
234
236
|
setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))
|
|
237
|
+
setTotalIsCapped(payload?.totalIsCapped === true)
|
|
235
238
|
} catch (error) {
|
|
236
239
|
logger.error('Failed to list resource types', { err: error })
|
|
237
240
|
flash(translations.errors.load, 'error')
|
|
@@ -308,7 +311,7 @@ export default function ResourcesResourceTypesPage() {
|
|
|
308
311
|
sortable
|
|
309
312
|
sorting={sorting}
|
|
310
313
|
onSortingChange={setSorting}
|
|
311
|
-
pagination={{ page, pageSize: PAGE_SIZE, total, totalPages, onPageChange: setPage }}
|
|
314
|
+
pagination={{ page, pageSize: PAGE_SIZE, total, totalPages, totalIsCapped, onPageChange: setPage }}
|
|
312
315
|
rowActions={(row) => (
|
|
313
316
|
<RowActions
|
|
314
317
|
items={[
|
|
@@ -63,6 +63,7 @@ type ResourcesResponse = {
|
|
|
63
63
|
total: number
|
|
64
64
|
page: number
|
|
65
65
|
totalPages: number
|
|
66
|
+
totalIsCapped?: boolean
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
type ResourceTypesResponse = {
|
|
@@ -81,6 +82,7 @@ export default function ResourcesResourcesPage() {
|
|
|
81
82
|
const [page, setPage] = React.useState(1)
|
|
82
83
|
const [total, setTotal] = React.useState(0)
|
|
83
84
|
const [totalPages, setTotalPages] = React.useState(1)
|
|
85
|
+
const [totalIsCapped, setTotalIsCapped] = React.useState(false)
|
|
84
86
|
const [search, setSearch] = React.useState('')
|
|
85
87
|
const [filterValues, setFilterValues] = React.useState<FilterValues>({})
|
|
86
88
|
const [isLoading, setIsLoading] = React.useState(true)
|
|
@@ -360,6 +362,7 @@ export default function ResourcesResourcesPage() {
|
|
|
360
362
|
setRows(mapped)
|
|
361
363
|
setTotal(payload.total || 0)
|
|
362
364
|
setTotalPages(payload.totalPages || 1)
|
|
365
|
+
setTotalIsCapped(payload?.totalIsCapped === true)
|
|
363
366
|
}
|
|
364
367
|
} catch (error) {
|
|
365
368
|
if (!cancelled) {
|
|
@@ -546,7 +549,7 @@ export default function ResourcesResourcesPage() {
|
|
|
546
549
|
createLabel={t('resources.resources.list.actions.create', 'New resource')}
|
|
547
550
|
/>
|
|
548
551
|
)}
|
|
549
|
-
pagination={{ page, pageSize: PAGE_SIZE, total, totalPages, onPageChange: setPage }}
|
|
552
|
+
pagination={{ page, pageSize: PAGE_SIZE, total, totalPages, totalIsCapped, onPageChange: setPage }}
|
|
550
553
|
isLoading={isLoading}
|
|
551
554
|
/>
|
|
552
555
|
</PageBody>
|
|
@@ -29,6 +29,7 @@ type OffersResponse = {
|
|
|
29
29
|
items?: Array<Record<string, unknown>>
|
|
30
30
|
total?: number
|
|
31
31
|
totalPages?: number
|
|
32
|
+
totalIsCapped?: boolean
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
const PAGE_SIZE = 25
|
|
@@ -61,6 +62,7 @@ export default function SalesChannelOffersListPage() {
|
|
|
61
62
|
const [page, setPage] = React.useState(1)
|
|
62
63
|
const [total, setTotal] = React.useState(0)
|
|
63
64
|
const [totalPages, setTotalPages] = React.useState(1)
|
|
65
|
+
const [totalIsCapped, setTotalIsCapped] = React.useState(false)
|
|
64
66
|
const [sorting, setSorting] = React.useState<SortingState>([{ id: 'updatedAt', desc: true }])
|
|
65
67
|
const [search, setSearch] = React.useState('')
|
|
66
68
|
const [filterValues, setFilterValues] = React.useState<FilterValues>({})
|
|
@@ -271,6 +273,7 @@ export default function SalesChannelOffersListPage() {
|
|
|
271
273
|
setRows(mapped)
|
|
272
274
|
setTotal(typeof payload.total === 'number' ? payload.total : items.length)
|
|
273
275
|
setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))
|
|
276
|
+
setTotalIsCapped(payload?.totalIsCapped === true)
|
|
274
277
|
const ids = mapped
|
|
275
278
|
.map((row) => row.channelId)
|
|
276
279
|
.filter((value): value is string => typeof value === 'string' && value.length > 0)
|
|
@@ -362,6 +365,7 @@ export default function SalesChannelOffersListPage() {
|
|
|
362
365
|
pageSize: PAGE_SIZE,
|
|
363
366
|
total,
|
|
364
367
|
totalPages,
|
|
368
|
+
totalIsCapped,
|
|
365
369
|
onPageChange: setPage,
|
|
366
370
|
}}
|
|
367
371
|
refreshButton={{
|
|
@@ -37,6 +37,7 @@ type ChannelsResponse = {
|
|
|
37
37
|
items?: Array<Record<string, unknown>>
|
|
38
38
|
total?: number
|
|
39
39
|
totalPages?: number
|
|
40
|
+
totalIsCapped?: boolean
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
const PAGE_SIZE = 25
|
|
@@ -68,6 +69,7 @@ export default function SalesChannelsPage() {
|
|
|
68
69
|
const [page, setPage] = React.useState(1)
|
|
69
70
|
const [total, setTotal] = React.useState(0)
|
|
70
71
|
const [totalPages, setTotalPages] = React.useState(1)
|
|
72
|
+
const [totalIsCapped, setTotalIsCapped] = React.useState(false)
|
|
71
73
|
const [sorting, setSorting] = React.useState<SortingState>([])
|
|
72
74
|
const [search, setSearch] = React.useState('')
|
|
73
75
|
const [isLoading, setLoading] = React.useState(true)
|
|
@@ -142,6 +144,7 @@ export default function SalesChannelsPage() {
|
|
|
142
144
|
setRows(items.map(mapApiChannel))
|
|
143
145
|
setTotal(typeof payload.total === 'number' ? payload.total : items.length)
|
|
144
146
|
setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))
|
|
147
|
+
setTotalIsCapped(payload?.totalIsCapped === true)
|
|
145
148
|
} catch (err) {
|
|
146
149
|
logger.error('sales.channels.list', { err })
|
|
147
150
|
flash(t('sales.channels.table.errors.load', 'Failed to load channels.'), 'error')
|
|
@@ -230,6 +233,7 @@ export default function SalesChannelsPage() {
|
|
|
230
233
|
pageSize: PAGE_SIZE,
|
|
231
234
|
total,
|
|
232
235
|
totalPages,
|
|
236
|
+
totalIsCapped,
|
|
233
237
|
onPageChange: setPage,
|
|
234
238
|
}}
|
|
235
239
|
refreshButton={{
|
|
@@ -38,7 +38,7 @@ import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimi
|
|
|
38
38
|
import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
|
|
39
39
|
import { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'
|
|
40
40
|
import { mapCrudServerErrorToFormErrors } from '@open-mercato/ui/backend/utils/serverErrors'
|
|
41
|
-
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
41
|
+
import { useT, useLocale } from '@open-mercato/shared/lib/i18n/context'
|
|
42
42
|
import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
|
|
43
43
|
import { cn } from '@open-mercato/shared/lib/utils'
|
|
44
44
|
import { ContactEmailDisplay } from '@open-mercato/core/modules/sales/components/ContactEmailDisplay'
|
|
@@ -79,13 +79,17 @@ import { createLogger } from '@open-mercato/shared/lib/logger'
|
|
|
79
79
|
|
|
80
80
|
const logger = createLogger('sales')
|
|
81
81
|
|
|
82
|
-
function formatMessageAmount(
|
|
82
|
+
function formatMessageAmount(
|
|
83
|
+
amount: number | null | undefined,
|
|
84
|
+
currency: string | null | undefined,
|
|
85
|
+
locale?: string
|
|
86
|
+
): string | null {
|
|
83
87
|
if (typeof amount !== 'number' || !Number.isFinite(amount)) return null
|
|
84
|
-
if (!currency) return amount.toLocaleString()
|
|
88
|
+
if (!currency) return amount.toLocaleString(locale)
|
|
85
89
|
try {
|
|
86
|
-
return new Intl.NumberFormat(
|
|
90
|
+
return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amount)
|
|
87
91
|
} catch {
|
|
88
|
-
return `${amount.toLocaleString()} ${currency}`
|
|
92
|
+
return `${amount.toLocaleString(locale)} ${currency}`
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
95
|
|
|
@@ -1900,6 +1904,7 @@ export default function SalesDocumentDetailPage({
|
|
|
1900
1904
|
includeAmountInMessageMetadata?: boolean
|
|
1901
1905
|
}) {
|
|
1902
1906
|
const t = useT()
|
|
1907
|
+
const locale = useLocale()
|
|
1903
1908
|
const { enabled: channelsEnabled } = useSalesChannelsEnabled()
|
|
1904
1909
|
const router = useRouter()
|
|
1905
1910
|
const searchParams = useSearchParams()
|
|
@@ -2807,7 +2812,7 @@ export default function SalesDocumentDetailPage({
|
|
|
2807
2812
|
: null
|
|
2808
2813
|
const contactEmail = resolveCustomerEmail(customerSnapshot) ?? metadataEmail ?? record?.contactEmail ?? null
|
|
2809
2814
|
const statusDisplay = record?.status ? statusDictionaryMap[record.status] ?? null : null
|
|
2810
|
-
const previewAmount = formatMessageAmount(record?.grandTotalGrossAmount ?? null, record?.currencyCode ?? null)
|
|
2815
|
+
const previewAmount = formatMessageAmount(record?.grandTotalGrossAmount ?? null, record?.currencyCode ?? null, locale)
|
|
2811
2816
|
const messagePreviewMetadata: Record<string, string> = {}
|
|
2812
2817
|
if (includeAmountInMessageMetadata && previewAmount) {
|
|
2813
2818
|
messagePreviewMetadata[t('sales.documents.detail.totals.grandTotalGross')] = previewAmount
|
|
@@ -3867,7 +3872,7 @@ export default function SalesDocumentDetailPage({
|
|
|
3867
3872
|
renderDisplay: (params) => {
|
|
3868
3873
|
const { value, emptyLabel } = params
|
|
3869
3874
|
if (value && value.length) {
|
|
3870
|
-
return <span className="text-sm text-muted-foreground">{new Date(value).toLocaleDateString()}</span>
|
|
3875
|
+
return <span className="text-sm text-muted-foreground">{new Date(value).toLocaleDateString(locale)}</span>
|
|
3871
3876
|
}
|
|
3872
3877
|
return <span className="text-sm text-muted-foreground">{emptyLabel}</span>
|
|
3873
3878
|
},
|
|
@@ -3944,6 +3949,7 @@ export default function SalesDocumentDetailPage({
|
|
|
3944
3949
|
shippingMethodLoading,
|
|
3945
3950
|
shippingMethodOptions,
|
|
3946
3951
|
t,
|
|
3952
|
+
locale,
|
|
3947
3953
|
kind,
|
|
3948
3954
|
saveShortcutLabel,
|
|
3949
3955
|
])
|
|
@@ -4717,7 +4723,7 @@ export default function SalesDocumentDetailPage({
|
|
|
4717
4723
|
renderDisplay={({ value, emptyLabel }) =>
|
|
4718
4724
|
value && value.length ? (
|
|
4719
4725
|
<span className="text-sm text-muted-foreground">
|
|
4720
|
-
{new Date(value).toLocaleDateString()}
|
|
4726
|
+
{new Date(value).toLocaleDateString(locale)}
|
|
4721
4727
|
</span>
|
|
4722
4728
|
) : (
|
|
4723
4729
|
<span className="text-sm text-muted-foreground">{emptyLabel}</span>
|
|
@@ -584,6 +584,11 @@ const addressSnapshotSchema = z
|
|
|
584
584
|
.nullable()
|
|
585
585
|
.optional();
|
|
586
586
|
|
|
587
|
+
// Mirrors the create schema's `decimal({ min: 0 })` (data/validators.ts). `null`
|
|
588
|
+
// comes first in the union below because the coercion accepts it — `Number(null)`
|
|
589
|
+
// is 0 — and would turn a clear into a written zero.
|
|
590
|
+
const exchangeRateSchema = z.coerce.number().min(0);
|
|
591
|
+
|
|
587
592
|
export const documentUpdateSchema = z
|
|
588
593
|
.object({
|
|
589
594
|
id: z.string().uuid(),
|
|
@@ -602,6 +607,13 @@ export const documentUpdateSchema = z
|
|
|
602
607
|
orderNumber: z.string().trim().min(1).max(191).optional(),
|
|
603
608
|
quoteNumber: z.string().trim().min(1).max(191).optional(),
|
|
604
609
|
currencyCode: currencyCodeSchema.optional(),
|
|
610
|
+
// Order-only columns — SalesQuote declares none of them. Declared here
|
|
611
|
+
// because the create schema declares them and a caller reusing its create
|
|
612
|
+
// payload on an update otherwise lost them silently; `applyDocumentUpdate`
|
|
613
|
+
// rejects each with a 400 on a quote rather than dropping it.
|
|
614
|
+
exchangeRate: z.union([z.null(), exchangeRateSchema]).optional(),
|
|
615
|
+
paymentStatusEntryId: z.string().uuid().nullable().optional(),
|
|
616
|
+
fulfillmentStatusEntryId: z.string().uuid().nullable().optional(),
|
|
605
617
|
channelId: z.string().uuid().nullable().optional(),
|
|
606
618
|
statusEntryId: z.string().uuid().nullable().optional(),
|
|
607
619
|
placedAt: z.union([dateOnlySchema, z.null()]).optional(),
|
|
@@ -633,6 +645,9 @@ export const documentUpdateSchema = z
|
|
|
633
645
|
input.expectedDeliveryAt !== undefined ||
|
|
634
646
|
input.channelId !== undefined ||
|
|
635
647
|
input.statusEntryId !== undefined ||
|
|
648
|
+
input.exchangeRate !== undefined ||
|
|
649
|
+
input.paymentStatusEntryId !== undefined ||
|
|
650
|
+
input.fulfillmentStatusEntryId !== undefined ||
|
|
636
651
|
input.shippingAddressId !== undefined ||
|
|
637
652
|
input.billingAddressId !== undefined ||
|
|
638
653
|
input.customerEntityId !== undefined ||
|
|
@@ -1198,6 +1213,19 @@ async function applyDocumentUpdate({
|
|
|
1198
1213
|
if (typeof input.currencyCode === "string") {
|
|
1199
1214
|
entity.currencyCode = input.currencyCode;
|
|
1200
1215
|
}
|
|
1216
|
+
// Orders only — SalesQuote has no exchange_rate column, so the field is
|
|
1217
|
+
// rejected rather than ignored for the same reason as internalNotes above.
|
|
1218
|
+
if (kind === "quote" && input.exchangeRate !== undefined) {
|
|
1219
|
+
throw new CrudHttpError(400, {
|
|
1220
|
+
error: translate(
|
|
1221
|
+
"sales.quotes.exchange_rate_unsupported",
|
|
1222
|
+
"Exchange rate is not available on quotes.",
|
|
1223
|
+
),
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
if (kind === "order" && input.exchangeRate !== undefined) {
|
|
1227
|
+
(entity as SalesOrder).exchangeRate = toNumericString(input.exchangeRate);
|
|
1228
|
+
}
|
|
1201
1229
|
if (input.channelId !== undefined) {
|
|
1202
1230
|
if (input.channelId === null) {
|
|
1203
1231
|
entity.channelId = null;
|
|
@@ -1242,6 +1270,62 @@ async function applyDocumentUpdate({
|
|
|
1242
1270
|
(entity as any).statusEntryId = input.statusEntryId ?? null;
|
|
1243
1271
|
(entity as any).status = statusValue;
|
|
1244
1272
|
}
|
|
1273
|
+
// Orders only — SalesQuote has neither the entry-id nor the derived text
|
|
1274
|
+
// column for payment and fulfillment status, so both are rejected on a quote.
|
|
1275
|
+
if (kind === "quote" && input.paymentStatusEntryId !== undefined) {
|
|
1276
|
+
throw new CrudHttpError(400, {
|
|
1277
|
+
error: translate(
|
|
1278
|
+
"sales.quotes.payment_status_unsupported",
|
|
1279
|
+
"Payment status is not available on quotes.",
|
|
1280
|
+
),
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
if (kind === "order" && input.paymentStatusEntryId !== undefined) {
|
|
1284
|
+
const paymentStatusValue = await resolveDictionaryEntryValue(
|
|
1285
|
+
em,
|
|
1286
|
+
input.paymentStatusEntryId,
|
|
1287
|
+
{ tenantId },
|
|
1288
|
+
);
|
|
1289
|
+
if (input.paymentStatusEntryId && !paymentStatusValue) {
|
|
1290
|
+
throw new CrudHttpError(400, {
|
|
1291
|
+
error: translate(
|
|
1292
|
+
"sales.documents.detail.statusInvalid",
|
|
1293
|
+
"Selected status could not be found.",
|
|
1294
|
+
),
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
// Both columns, like the statusEntryId branch above and like order create:
|
|
1298
|
+
// moving the id without its derived text leaves a self-contradicting row.
|
|
1299
|
+
(entity as SalesOrder).paymentStatusEntryId =
|
|
1300
|
+
input.paymentStatusEntryId ?? null;
|
|
1301
|
+
(entity as SalesOrder).paymentStatus = paymentStatusValue;
|
|
1302
|
+
}
|
|
1303
|
+
if (kind === "quote" && input.fulfillmentStatusEntryId !== undefined) {
|
|
1304
|
+
throw new CrudHttpError(400, {
|
|
1305
|
+
error: translate(
|
|
1306
|
+
"sales.quotes.fulfillment_status_unsupported",
|
|
1307
|
+
"Fulfillment status is not available on quotes.",
|
|
1308
|
+
),
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
if (kind === "order" && input.fulfillmentStatusEntryId !== undefined) {
|
|
1312
|
+
const fulfillmentStatusValue = await resolveDictionaryEntryValue(
|
|
1313
|
+
em,
|
|
1314
|
+
input.fulfillmentStatusEntryId,
|
|
1315
|
+
{ tenantId },
|
|
1316
|
+
);
|
|
1317
|
+
if (input.fulfillmentStatusEntryId && !fulfillmentStatusValue) {
|
|
1318
|
+
throw new CrudHttpError(400, {
|
|
1319
|
+
error: translate(
|
|
1320
|
+
"sales.documents.detail.statusInvalid",
|
|
1321
|
+
"Selected status could not be found.",
|
|
1322
|
+
),
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
(entity as SalesOrder).fulfillmentStatusEntryId =
|
|
1326
|
+
input.fulfillmentStatusEntryId ?? null;
|
|
1327
|
+
(entity as SalesOrder).fulfillmentStatus = fulfillmentStatusValue;
|
|
1328
|
+
}
|
|
1245
1329
|
if (input.placedAt !== undefined) {
|
|
1246
1330
|
if (input.placedAt === null) {
|
|
1247
1331
|
entity.placedAt = null;
|
|
@@ -3732,6 +3816,15 @@ function buildDocumentUpdateChangeKeys(kind: SalesDocumentKind, input: DocumentU
|
|
|
3732
3816
|
if (input.internalNotes !== undefined) keys.add("internalNotes");
|
|
3733
3817
|
if (input.placedAt !== undefined) keys.add("placedAt");
|
|
3734
3818
|
if (input.expectedDeliveryAt !== undefined) keys.add("expectedDeliveryAt");
|
|
3819
|
+
if (input.exchangeRate !== undefined) keys.add("exchangeRate");
|
|
3820
|
+
if (input.paymentStatusEntryId !== undefined) {
|
|
3821
|
+
keys.add("paymentStatusEntryId");
|
|
3822
|
+
keys.add("paymentStatus");
|
|
3823
|
+
}
|
|
3824
|
+
if (input.fulfillmentStatusEntryId !== undefined) {
|
|
3825
|
+
keys.add("fulfillmentStatusEntryId");
|
|
3826
|
+
keys.add("fulfillmentStatus");
|
|
3827
|
+
}
|
|
3735
3828
|
}
|
|
3736
3829
|
if (
|
|
3737
3830
|
input.shippingAddressId !== undefined ||
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
|
+
import { useOptionalLocale } from '@open-mercato/shared/lib/i18n/context'
|
|
4
5
|
import { cn } from '@open-mercato/shared/lib/utils'
|
|
5
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Pass `locale` to format in the application locale (`useLocale()` in client components).
|
|
9
|
+
* Omitting it keeps the runtime default, which varies per machine and is therefore not
|
|
10
|
+
* assertable in tests.
|
|
11
|
+
*/
|
|
6
12
|
export function formatPriceWithCurrency(
|
|
7
13
|
amount: number | string | null | undefined,
|
|
8
14
|
currency: string | null | undefined,
|
|
9
|
-
fallback = '—'
|
|
15
|
+
fallback = '—',
|
|
16
|
+
locale?: string
|
|
10
17
|
): string {
|
|
11
18
|
if (amount === null || amount === undefined) return fallback
|
|
12
19
|
const parsed = typeof amount === 'string' ? Number(amount) : amount
|
|
13
20
|
if (Number.isNaN(parsed)) return fallback
|
|
14
21
|
if (currency) {
|
|
15
22
|
try {
|
|
16
|
-
return new Intl.NumberFormat(
|
|
23
|
+
return new Intl.NumberFormat(locale, {
|
|
17
24
|
style: 'currency',
|
|
18
25
|
currency,
|
|
19
26
|
minimumFractionDigits: 2,
|
|
@@ -23,7 +30,7 @@ export function formatPriceWithCurrency(
|
|
|
23
30
|
// fall through to plain number formatting
|
|
24
31
|
}
|
|
25
32
|
}
|
|
26
|
-
return parsed.toLocaleString(
|
|
33
|
+
return parsed.toLocaleString(locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
type PriceWithCurrencyProps = {
|
|
@@ -34,9 +41,14 @@ type PriceWithCurrencyProps = {
|
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
export function PriceWithCurrency({ amount, currency, fallback = '—', className }: PriceWithCurrencyProps) {
|
|
44
|
+
// `useOptionalLocale` rather than `useLocale`: this component is deep-importable and had no i18n
|
|
45
|
+
// dependency at all before it started formatting in the app locale, so making it throw outside
|
|
46
|
+
// `I18nProvider` would narrow its mounting contract. Without a provider it falls back to the
|
|
47
|
+
// runtime default, which is exactly the behaviour it had before.
|
|
48
|
+
const locale = useOptionalLocale()
|
|
37
49
|
const label = React.useMemo(
|
|
38
|
-
() => formatPriceWithCurrency(amount, currency, fallback),
|
|
39
|
-
[amount, currency, fallback]
|
|
50
|
+
() => formatPriceWithCurrency(amount, currency, fallback, locale),
|
|
51
|
+
[amount, currency, fallback, locale]
|
|
40
52
|
)
|
|
41
53
|
return <span className={cn('font-mono text-sm text-foreground', className)}>{label}</span>
|
|
42
54
|
}
|
|
@@ -25,6 +25,7 @@ type OffersResponse = {
|
|
|
25
25
|
items?: Array<Record<string, unknown>>
|
|
26
26
|
total?: number
|
|
27
27
|
totalPages?: number
|
|
28
|
+
totalIsCapped?: boolean
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
const PAGE_SIZE = 25
|
|
@@ -54,6 +55,7 @@ export function SalesChannelOffersPanel({ channelId, channelName }: { channelId:
|
|
|
54
55
|
const [page, setPage] = React.useState(1)
|
|
55
56
|
const [total, setTotal] = React.useState(0)
|
|
56
57
|
const [totalPages, setTotalPages] = React.useState(1)
|
|
58
|
+
const [totalIsCapped, setTotalIsCapped] = React.useState(false)
|
|
57
59
|
const [search, setSearch] = React.useState('')
|
|
58
60
|
const [isLoading, setLoading] = React.useState(true)
|
|
59
61
|
const [sorting, setSorting] = React.useState<SortingState>([])
|
|
@@ -134,6 +136,7 @@ export function SalesChannelOffersPanel({ channelId, channelName }: { channelId:
|
|
|
134
136
|
setRows(items.map(mapOfferRow))
|
|
135
137
|
setTotal(typeof payload.total === 'number' ? payload.total : items.length)
|
|
136
138
|
setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)))
|
|
139
|
+
setTotalIsCapped(payload?.totalIsCapped === true)
|
|
137
140
|
} catch (err) {
|
|
138
141
|
logger.error('sales.channels.offers', { err })
|
|
139
142
|
flash(t('sales.channels.offers.errors.load', 'Failed to load offers.'), 'error')
|
|
@@ -208,6 +211,7 @@ export function SalesChannelOffersPanel({ channelId, channelName }: { channelId:
|
|
|
208
211
|
pageSize: PAGE_SIZE,
|
|
209
212
|
total,
|
|
210
213
|
totalPages,
|
|
214
|
+
totalIsCapped,
|
|
211
215
|
onPageChange: setPage,
|
|
212
216
|
}}
|
|
213
217
|
refreshButton={{
|