@open-mercato/core 0.6.6-develop.6360.1.8504e06ff3 → 0.6.6-develop.6362.1.a3dd164018
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/auth/frontend/login.js +5 -4
- package/dist/modules/auth/frontend/login.js.map +3 -3
- package/dist/modules/sales/components/documents/AdjustmentDialog.js +11 -0
- package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +2 -2
- package/dist/modules/sales/data/validators.js +17 -2
- package/dist/modules/sales/data/validators.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/auth/frontend/login.tsx +3 -2
- package/src/modules/sales/components/documents/AdjustmentDialog.tsx +16 -0
- package/src/modules/sales/data/validators.ts +17 -2
- package/src/modules/sales/i18n/de.json +1 -0
- package/src/modules/sales/i18n/en.json +1 -0
- package/src/modules/sales/i18n/es.json +1 -0
- package/src/modules/sales/i18n/pl.json +1 -0
|
@@ -84,6 +84,7 @@ function LoginPage() {
|
|
|
84
84
|
const searchParams = useSearchParams();
|
|
85
85
|
const requireRole = (searchParams.get("requireRole") || searchParams.get("role") || "").trim();
|
|
86
86
|
const requireFeature = (searchParams.get("requireFeature") || "").trim();
|
|
87
|
+
const redirectParam = searchParams.get("redirect") || "";
|
|
87
88
|
const requiredRoles = requireRole ? requireRole.split(",").map((value) => value.trim()).filter(Boolean) : [];
|
|
88
89
|
const requiredFeatures = requireFeature ? requireFeature.split(",").map((value) => value.trim()).filter(Boolean) : [];
|
|
89
90
|
const translatedRoles = requiredRoles.map((role) => translate(`auth.roles.${role}`, role));
|
|
@@ -123,7 +124,7 @@ function LoginPage() {
|
|
|
123
124
|
if (!activeUserId) return;
|
|
124
125
|
setActiveAuthenticatedUser(true);
|
|
125
126
|
if (hasAclChallenge) return;
|
|
126
|
-
const rawRedirect =
|
|
127
|
+
const rawRedirect = redirectParam;
|
|
127
128
|
let destination = "/backend";
|
|
128
129
|
if (rawRedirect) {
|
|
129
130
|
try {
|
|
@@ -141,7 +142,7 @@ function LoginPage() {
|
|
|
141
142
|
return () => {
|
|
142
143
|
cancelled = true;
|
|
143
144
|
};
|
|
144
|
-
}, [router,
|
|
145
|
+
}, [router, redirectParam, requiredFeatures.length, requiredRoles.length]);
|
|
145
146
|
useEffect(() => {
|
|
146
147
|
const tenantParam = (searchParams.get("tenant") || "").trim();
|
|
147
148
|
if (tenantParam) {
|
|
@@ -218,8 +219,8 @@ function LoginPage() {
|
|
|
218
219
|
try {
|
|
219
220
|
const form = new FormData(e.currentTarget);
|
|
220
221
|
if (requiredRoles.length) form.set("requireRole", requiredRoles.join(","));
|
|
221
|
-
const
|
|
222
|
-
if (
|
|
222
|
+
const redirectParam2 = searchParams.get("redirect");
|
|
223
|
+
if (redirectParam2) form.set("redirect", redirectParam2);
|
|
223
224
|
const res = await fetch("/api/auth/login", { method: "POST", body: form });
|
|
224
225
|
if (res.redirected) {
|
|
225
226
|
clearAllOperations();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/auth/frontend/login.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Card, CardContent, CardHeader, CardDescription } from '@open-mercato/ui/primitives/card'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { EmailInput } from '@open-mercato/ui/primitives/email-input'\nimport { PasswordInput } from '@open-mercato/ui/primitives/password-input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { translateWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { clearAllOperations } from '@open-mercato/ui/backend/operations/store'\nimport { notifyAuthIdentityChange } from '@open-mercato/ui/backend/AuthSessionGuard'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { X } from 'lucide-react'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { useRegisteredComponent } from '@open-mercato/ui/backend/injection/useRegisteredComponent'\nimport type { AuthOverride, LoginFormWidgetContext } from './login-injection'\n\nconst loginTenantKey = 'om_login_tenant'\nconst loginTenantCookieMaxAge = 60 * 60 * 24 * 14\n\nfunction readTenantCookie() {\n if (typeof document === 'undefined') return null\n const entries = document.cookie.split(';')\n for (const entry of entries) {\n const [name, ...rest] = entry.trim().split('=')\n if (name === loginTenantKey) return decodeURIComponent(rest.join('='))\n }\n return null\n}\n\nfunction setTenantCookie(value: string) {\n if (typeof document === 'undefined') return\n document.cookie = `${loginTenantKey}=${encodeURIComponent(value)}; path=/; max-age=${loginTenantCookieMaxAge}; samesite=lax`\n}\n\nfunction clearTenantCookie() {\n if (typeof document === 'undefined') return\n document.cookie = `${loginTenantKey}=; path=/; max-age=0; samesite=lax`\n}\n\nfunction extractErrorMessage(payload: unknown): string | null {\n if (!payload) return null\n if (typeof payload === 'string') return payload\n if (Array.isArray(payload)) {\n for (const entry of payload) {\n const resolved = extractErrorMessage(entry)\n if (resolved) return resolved\n }\n return null\n }\n if (typeof payload === 'object') {\n const record = payload as Record<string, unknown>\n const candidates: unknown[] = [\n record.error,\n record.message,\n record.detail,\n record.details,\n record.description,\n ]\n for (const candidate of candidates) {\n const resolved = extractErrorMessage(candidate)\n if (resolved) return resolved\n }\n }\n return null\n}\n\nfunction looksLikeJsonString(value: string): boolean {\n const trimmed = value.trim()\n return trimmed.startsWith('{') || trimmed.startsWith('[')\n}\n\ntype LoginResponseEventDetail = Record<string, unknown> | null\n\ntype LoginFormSectionProps = {\n children: ReactNode\n}\n\nfunction LoginFormSectionDefault({ children }: LoginFormSectionProps) {\n return <>{children}</>\n}\n\nfunction emitLoginResponseEvent(detail: LoginResponseEventDetail) {\n if (typeof window === 'undefined') return\n window.dispatchEvent(new CustomEvent('om:auth:login-response', { detail }))\n}\n\nexport default function LoginPage() {\n const t = useT()\n const translate = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>) =>\n translateWithFallback(t, key, fallback, params),\n [t],\n )\n const router = useRouter()\n const searchParams = useSearchParams()\n const requireRole = (searchParams.get('requireRole') || searchParams.get('role') || '').trim()\n const requireFeature = (searchParams.get('requireFeature') || '').trim()\n const requiredRoles = requireRole ? requireRole.split(',').map((value) => value.trim()).filter(Boolean) : []\n const requiredFeatures = requireFeature ? requireFeature.split(',').map((value) => value.trim()).filter(Boolean) : []\n const translatedRoles = requiredRoles.map((role) => translate(`auth.roles.${role}`, role))\n const translatedFeatures = requiredFeatures.map((feature) => translate(`features.${feature}`, feature))\n const [error, setError] = useState<string | null>(null)\n const [submitting, setSubmitting] = useState(false)\n const [authOverride, setAuthOverride] = useState<AuthOverride | null>(null)\n const [authOverridePending, setAuthOverridePending] = useState(false)\n const [clientReady, setClientReady] = useState(false)\n const [activeAuthenticatedUser, setActiveAuthenticatedUser] = useState(false)\n const [email, setEmail] = useState('')\n const [tenantId, setTenantId] = useState<string | null>(null)\n const [tenantName, setTenantName] = useState<string | null>(null)\n const [tenantLoading, setTenantLoading] = useState(false)\n const [tenantInvalid, setTenantInvalid] = useState<string | null>(null)\n const showTenantInvalid = tenantId != null && tenantInvalid === tenantId\n const LoginFormSection = useRegisteredComponent<LoginFormSectionProps>(\n 'section:auth.login.form',\n LoginFormSectionDefault,\n )\n\n useEffect(() => {\n setClientReady(true)\n }, [])\n\n useEffect(() => {\n let cancelled = false\n const hasAclChallenge = requiredFeatures.length > 0 || requiredRoles.length > 0\n void (async () => {\n try {\n const res = await apiCall<{ userId?: string }>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: [] }),\n cache: 'no-store',\n })\n if (cancelled) return\n const activeUserId = typeof res.result?.userId === 'string' ? res.result.userId : ''\n if (!activeUserId) return\n setActiveAuthenticatedUser(true)\n // When a feature/role challenge is present in the URL, the user already\n // failed an ACL check while authenticated. Auto-redirecting back to\n // `redirect` would re-trigger the same 403 and re-bounce here,\n // producing an infinite loop (see GH #2070). Stay on the login page so\n // the access-denied banner is visible.\n if (hasAclChallenge) return\n const rawRedirect = searchParams.get('redirect') || ''\n let destination = '/backend'\n if (rawRedirect) {\n try {\n const resolved = new URL(rawRedirect, window.location.origin)\n if (\n resolved.origin === window.location.origin &&\n resolved.pathname.startsWith('/') &&\n !resolved.pathname.includes('//')\n ) {\n destination = resolved.pathname + resolved.search + resolved.hash\n }\n } catch {\n // fall back to /backend\n }\n }\n router.replace(destination)\n } catch {\n // ignore \u2014 leave login form usable on network failure\n }\n })()\n return () => { cancelled = true }\n }, [router, searchParams, requiredFeatures.length, requiredRoles.length])\n\n useEffect(() => {\n const tenantParam = (searchParams.get('tenant') || '').trim()\n if (tenantParam) {\n setTenantId(tenantParam)\n window.localStorage.setItem(loginTenantKey, tenantParam)\n setTenantCookie(tenantParam)\n return\n }\n const storedTenant = window.localStorage.getItem(loginTenantKey) || readTenantCookie()\n if (storedTenant) {\n setTenantId(storedTenant)\n }\n }, [searchParams])\n\n useEffect(() => {\n if (!tenantId) {\n setTenantName(null)\n setTenantInvalid(null)\n return\n }\n if (tenantInvalid === tenantId) {\n setTenantName(null)\n setTenantLoading(false)\n return\n }\n let active = true\n setTenantLoading(true)\n setTenantInvalid(null)\n apiCall<{ ok: boolean; tenant?: { id: string; name: string }; error?: string }>(\n `/api/directory/tenants/lookup?tenantId=${encodeURIComponent(tenantId)}`,\n )\n .then(({ result }) => {\n if (!active) return\n if (result?.ok && result.tenant) {\n setTenantName(result.tenant.name)\n return\n }\n setTenantName(null)\n setTenantInvalid(tenantId)\n setError(null)\n })\n .catch(() => {\n if (!active) return\n setTenantName(null)\n setTenantInvalid(tenantId)\n setError(null)\n })\n .finally(() => {\n if (active) setTenantLoading(false)\n })\n return () => {\n active = false\n }\n }, [tenantId, translate])\n\n function handleClearTenant() {\n window.localStorage.removeItem(loginTenantKey)\n clearTenantCookie()\n setTenantId(null)\n setTenantName(null)\n setTenantInvalid(null)\n const params = new URLSearchParams(searchParams)\n params.delete('tenant')\n setError(null)\n const query = params.toString()\n router.replace(query ? `/login?${query}` : '/login')\n }\n\n async function onSubmit(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault()\n if (!clientReady || authOverridePending) {\n return\n }\n setError(null)\n if (authOverride) {\n authOverride.onSubmit()\n return\n }\n setSubmitting(true)\n try {\n const form = new FormData(e.currentTarget)\n if (requiredRoles.length) form.set('requireRole', requiredRoles.join(','))\n const redirectParam = searchParams.get('redirect')\n if (redirectParam) form.set('redirect', redirectParam)\n const res = await fetch('/api/auth/login', { method: 'POST', body: form })\n if (res.redirected) {\n clearAllOperations()\n notifyAuthIdentityChange()\n // NextResponse.redirect from API\n router.replace(res.url)\n return\n }\n if (!res.ok) {\n const fallback = (() => {\n if (res.status === 403) {\n return translate(\n 'auth.login.errors.permissionDenied',\n 'You do not have permission to access this area. Please contact your administrator.',\n )\n }\n if (res.status === 401 || res.status === 400) {\n return translate('auth.login.errors.invalidCredentials', 'Invalid email or password')\n }\n return translate('auth.login.errors.generic', 'An error occurred. Please try again.')\n })()\n const cloned = res.clone()\n let errorMessage = ''\n const contentType = res.headers.get('content-type') || ''\n if (contentType.includes('application/json')) {\n try {\n const data = await res.json()\n errorMessage = extractErrorMessage(data) || ''\n } catch {\n try {\n const text = await cloned.text()\n const trimmed = text.trim()\n if (trimmed && !looksLikeJsonString(trimmed)) {\n errorMessage = trimmed\n }\n } catch {\n errorMessage = ''\n }\n }\n } else {\n try {\n const text = await res.text()\n const trimmed = text.trim()\n if (trimmed && !looksLikeJsonString(trimmed)) {\n errorMessage = trimmed\n }\n } catch {\n errorMessage = ''\n }\n }\n setError(errorMessage || fallback)\n return\n }\n // In case API returns 200 with JSON\n const data = await res.json().catch(() => null) as LoginResponseEventDetail\n emitLoginResponseEvent(data)\n clearAllOperations()\n notifyAuthIdentityChange()\n if (data && typeof data.redirect === 'string' && data.redirect.length > 0) {\n router.replace(data.redirect)\n }\n } catch (err: unknown) {\n // Handle any errors thrown (e.g., network errors or thrown exceptions)\n const message = err instanceof Error ? err.message : ''\n setError(message || translate('auth.login.errors.generic', 'An error occurred. Please try again.'))\n } finally {\n setSubmitting(false)\n }\n }\n\n const loginFormContext = useMemo<LoginFormWidgetContext>(() => ({\n email,\n tenantId,\n searchParams,\n setAuthOverride,\n setAuthOverridePending,\n setError,\n }), [email, tenantId, searchParams])\n\n const formReady = clientReady && !authOverridePending\n\n return (\n <div className=\"min-h-svh flex items-center justify-center p-4\">\n <Card className=\"w-full max-w-sm\">\n <CardHeader className=\"flex flex-col items-center gap-4 text-center p-10\">\n <Image alt={translate('auth.login.logoAlt', 'Open Mercato logo')} src=\"/open-mercato.svg\" width={150} height={150} priority />\n <h1 className=\"text-2xl font-semibold\">{translate('auth.login.brandName', 'Open Mercato')}</h1>\n <CardDescription>{translate('auth.login.subtitle', 'Access your workspace')}</CardDescription>\n </CardHeader>\n <CardContent>\n <LoginFormSection>\n <form className=\"grid gap-3\" onSubmit={onSubmit} noValidate data-auth-ready={formReady ? '1' : '0'}>\n {tenantId ? (\n <input type=\"hidden\" name=\"tenantId\" value={tenantId} />\n ) : null}\n {!!translatedRoles.length && (\n <Alert variant=\"info\" className=\"text-center\">\n <AlertDescription>\n {translate(\n translatedRoles.length > 1 ? 'auth.login.requireRolesMessage' : 'auth.login.requireRoleMessage',\n translatedRoles.length > 1\n ? 'Access requires one of the following roles: {roles}'\n : 'Access requires role: {roles}',\n { roles: translatedRoles.join(', ') },\n )}\n </AlertDescription>\n </Alert>\n )}\n {!!translatedFeatures.length && (\n <Alert variant=\"info\" className=\"text-center\">\n <AlertDescription>\n {translate('auth.login.featureDenied', \"You don't have access to this feature ({feature}). Please contact your administrator.\", {\n feature: translatedFeatures.join(', '),\n })}\n </AlertDescription>\n </Alert>\n )}\n {activeAuthenticatedUser && (translatedRoles.length || translatedFeatures.length) ? (\n <div className=\"flex justify-center\" data-testid=\"login-return-dashboard\">\n <Button asChild type=\"button\" variant=\"outline\" size=\"sm\">\n <Link href=\"/backend\">\n {translate('auth.accessDenied.dashboard', 'Go to Dashboard')}\n </Link>\n </Button>\n </div>\n ) : null}\n {showTenantInvalid ? (\n <div className=\"rounded-md border border-status-error-border bg-status-error-bg px-3 py-2 text-center text-xs text-status-error-text\">\n <div className=\"font-medium\">{translate('auth.login.errors.tenantInvalid', 'Tenant not found. Clear the tenant selection and try again.')}</div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"mt-2 border-status-error-border text-status-error-text hover:text-status-error-text\" onClick={handleClearTenant}>\n <X className=\"mr-2 size-4\" aria-hidden=\"true\" />\n {translate('auth.login.tenantClear', 'Clear')}\n </Button>\n </div>\n ) : tenantId ? (\n <div className=\"rounded-md border border-status-success-border bg-status-success-bg px-3 py-2 text-center text-xs text-status-success-text\">\n <div className=\"font-medium\">\n {tenantLoading\n ? translate('auth.login.tenantLoading', 'Loading tenant details...')\n : translate('auth.login.tenantBanner', \"You're logging in to {tenant}.\", {\n tenant: tenantName || tenantId,\n })}\n </div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"mt-2 border-status-success-border text-status-success-text hover:text-status-success-text\" onClick={handleClearTenant}>\n <X className=\"mr-2 size-4\" aria-hidden=\"true\" />\n {translate('auth.login.tenantClear', 'Clear')}\n </Button>\n </div>\n ) : null}\n {error && !showTenantInvalid && (\n <div className=\"rounded-md border border-status-error-border bg-status-error-bg px-3 py-2 text-center text-sm text-status-error-text\" role=\"alert\" aria-live=\"polite\">\n {error}\n </div>\n )}\n <div className=\"grid gap-1\">\n <Label htmlFor=\"email\">{t('auth.email')}</Label>\n <EmailInput\n id=\"email\"\n name=\"email\"\n required\n aria-invalid={!!error}\n onChange={(e) => setEmail(e.target.value)}\n onBlur={(e) => setEmail(e.target.value)}\n />\n </div>\n <InjectionSpot<LoginFormWidgetContext>\n spotId=\"auth.login:form\"\n context={loginFormContext}\n />\n {authOverride?.hidePassword ? null : (\n <div className=\"grid gap-1\">\n <Label htmlFor=\"password\">{t('auth.password')}</Label>\n <PasswordInput id=\"password\" name=\"password\" required={!authOverride} aria-invalid={!!error} autoComplete=\"current-password\" />\n </div>\n )}\n {!authOverride?.hideRememberMe && !authOverride?.hidePassword && (\n <label className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <input type=\"checkbox\" name=\"remember\" className=\"accent-foreground\" />\n <span>{translate('auth.login.rememberMe', 'Remember me')}</span>\n </label>\n )}\n <Button type=\"submit\" disabled={submitting || !formReady} className=\"h-10 mt-2\">\n {submitting\n ? translate('auth.login.loading', 'Loading...')\n : authOverride\n ? authOverride.providerLabel\n : translate('auth.signIn', 'Sign in')}\n </Button>\n {!authOverride?.hideForgotPassword && (\n <div className=\"text-xs text-muted-foreground mt-2\">\n <Link className=\"underline\" href=\"/reset\">\n {translate('auth.login.forgotPassword', 'Forgot password?')}\n </Link>\n </div>\n )}\n </form>\n </LoginFormSection>\n </CardContent>\n </Card>\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": ";AAqFS,
|
|
6
|
-
"names": ["data"]
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Card, CardContent, CardHeader, CardDescription } from '@open-mercato/ui/primitives/card'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { EmailInput } from '@open-mercato/ui/primitives/email-input'\nimport { PasswordInput } from '@open-mercato/ui/primitives/password-input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { translateWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { clearAllOperations } from '@open-mercato/ui/backend/operations/store'\nimport { notifyAuthIdentityChange } from '@open-mercato/ui/backend/AuthSessionGuard'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { X } from 'lucide-react'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { useRegisteredComponent } from '@open-mercato/ui/backend/injection/useRegisteredComponent'\nimport type { AuthOverride, LoginFormWidgetContext } from './login-injection'\n\nconst loginTenantKey = 'om_login_tenant'\nconst loginTenantCookieMaxAge = 60 * 60 * 24 * 14\n\nfunction readTenantCookie() {\n if (typeof document === 'undefined') return null\n const entries = document.cookie.split(';')\n for (const entry of entries) {\n const [name, ...rest] = entry.trim().split('=')\n if (name === loginTenantKey) return decodeURIComponent(rest.join('='))\n }\n return null\n}\n\nfunction setTenantCookie(value: string) {\n if (typeof document === 'undefined') return\n document.cookie = `${loginTenantKey}=${encodeURIComponent(value)}; path=/; max-age=${loginTenantCookieMaxAge}; samesite=lax`\n}\n\nfunction clearTenantCookie() {\n if (typeof document === 'undefined') return\n document.cookie = `${loginTenantKey}=; path=/; max-age=0; samesite=lax`\n}\n\nfunction extractErrorMessage(payload: unknown): string | null {\n if (!payload) return null\n if (typeof payload === 'string') return payload\n if (Array.isArray(payload)) {\n for (const entry of payload) {\n const resolved = extractErrorMessage(entry)\n if (resolved) return resolved\n }\n return null\n }\n if (typeof payload === 'object') {\n const record = payload as Record<string, unknown>\n const candidates: unknown[] = [\n record.error,\n record.message,\n record.detail,\n record.details,\n record.description,\n ]\n for (const candidate of candidates) {\n const resolved = extractErrorMessage(candidate)\n if (resolved) return resolved\n }\n }\n return null\n}\n\nfunction looksLikeJsonString(value: string): boolean {\n const trimmed = value.trim()\n return trimmed.startsWith('{') || trimmed.startsWith('[')\n}\n\ntype LoginResponseEventDetail = Record<string, unknown> | null\n\ntype LoginFormSectionProps = {\n children: ReactNode\n}\n\nfunction LoginFormSectionDefault({ children }: LoginFormSectionProps) {\n return <>{children}</>\n}\n\nfunction emitLoginResponseEvent(detail: LoginResponseEventDetail) {\n if (typeof window === 'undefined') return\n window.dispatchEvent(new CustomEvent('om:auth:login-response', { detail }))\n}\n\nexport default function LoginPage() {\n const t = useT()\n const translate = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>) =>\n translateWithFallback(t, key, fallback, params),\n [t],\n )\n const router = useRouter()\n const searchParams = useSearchParams()\n const requireRole = (searchParams.get('requireRole') || searchParams.get('role') || '').trim()\n const requireFeature = (searchParams.get('requireFeature') || '').trim()\n const redirectParam = searchParams.get('redirect') || ''\n const requiredRoles = requireRole ? requireRole.split(',').map((value) => value.trim()).filter(Boolean) : []\n const requiredFeatures = requireFeature ? requireFeature.split(',').map((value) => value.trim()).filter(Boolean) : []\n const translatedRoles = requiredRoles.map((role) => translate(`auth.roles.${role}`, role))\n const translatedFeatures = requiredFeatures.map((feature) => translate(`features.${feature}`, feature))\n const [error, setError] = useState<string | null>(null)\n const [submitting, setSubmitting] = useState(false)\n const [authOverride, setAuthOverride] = useState<AuthOverride | null>(null)\n const [authOverridePending, setAuthOverridePending] = useState(false)\n const [clientReady, setClientReady] = useState(false)\n const [activeAuthenticatedUser, setActiveAuthenticatedUser] = useState(false)\n const [email, setEmail] = useState('')\n const [tenantId, setTenantId] = useState<string | null>(null)\n const [tenantName, setTenantName] = useState<string | null>(null)\n const [tenantLoading, setTenantLoading] = useState(false)\n const [tenantInvalid, setTenantInvalid] = useState<string | null>(null)\n const showTenantInvalid = tenantId != null && tenantInvalid === tenantId\n const LoginFormSection = useRegisteredComponent<LoginFormSectionProps>(\n 'section:auth.login.form',\n LoginFormSectionDefault,\n )\n\n useEffect(() => {\n setClientReady(true)\n }, [])\n\n useEffect(() => {\n let cancelled = false\n const hasAclChallenge = requiredFeatures.length > 0 || requiredRoles.length > 0\n void (async () => {\n try {\n const res = await apiCall<{ userId?: string }>('/api/auth/feature-check', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ features: [] }),\n cache: 'no-store',\n })\n if (cancelled) return\n const activeUserId = typeof res.result?.userId === 'string' ? res.result.userId : ''\n if (!activeUserId) return\n setActiveAuthenticatedUser(true)\n // When a feature/role challenge is present in the URL, the user already\n // failed an ACL check while authenticated. Auto-redirecting back to\n // `redirect` would re-trigger the same 403 and re-bounce here,\n // producing an infinite loop (see GH #2070). Stay on the login page so\n // the access-denied banner is visible.\n if (hasAclChallenge) return\n const rawRedirect = redirectParam\n let destination = '/backend'\n if (rawRedirect) {\n try {\n const resolved = new URL(rawRedirect, window.location.origin)\n if (\n resolved.origin === window.location.origin &&\n resolved.pathname.startsWith('/') &&\n !resolved.pathname.includes('//')\n ) {\n destination = resolved.pathname + resolved.search + resolved.hash\n }\n } catch {\n // fall back to /backend\n }\n }\n router.replace(destination)\n } catch {\n // ignore \u2014 leave login form usable on network failure\n }\n })()\n return () => { cancelled = true }\n }, [router, redirectParam, requiredFeatures.length, requiredRoles.length])\n\n useEffect(() => {\n const tenantParam = (searchParams.get('tenant') || '').trim()\n if (tenantParam) {\n setTenantId(tenantParam)\n window.localStorage.setItem(loginTenantKey, tenantParam)\n setTenantCookie(tenantParam)\n return\n }\n const storedTenant = window.localStorage.getItem(loginTenantKey) || readTenantCookie()\n if (storedTenant) {\n setTenantId(storedTenant)\n }\n }, [searchParams])\n\n useEffect(() => {\n if (!tenantId) {\n setTenantName(null)\n setTenantInvalid(null)\n return\n }\n if (tenantInvalid === tenantId) {\n setTenantName(null)\n setTenantLoading(false)\n return\n }\n let active = true\n setTenantLoading(true)\n setTenantInvalid(null)\n apiCall<{ ok: boolean; tenant?: { id: string; name: string }; error?: string }>(\n `/api/directory/tenants/lookup?tenantId=${encodeURIComponent(tenantId)}`,\n )\n .then(({ result }) => {\n if (!active) return\n if (result?.ok && result.tenant) {\n setTenantName(result.tenant.name)\n return\n }\n setTenantName(null)\n setTenantInvalid(tenantId)\n setError(null)\n })\n .catch(() => {\n if (!active) return\n setTenantName(null)\n setTenantInvalid(tenantId)\n setError(null)\n })\n .finally(() => {\n if (active) setTenantLoading(false)\n })\n return () => {\n active = false\n }\n }, [tenantId, translate])\n\n function handleClearTenant() {\n window.localStorage.removeItem(loginTenantKey)\n clearTenantCookie()\n setTenantId(null)\n setTenantName(null)\n setTenantInvalid(null)\n const params = new URLSearchParams(searchParams)\n params.delete('tenant')\n setError(null)\n const query = params.toString()\n router.replace(query ? `/login?${query}` : '/login')\n }\n\n async function onSubmit(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault()\n if (!clientReady || authOverridePending) {\n return\n }\n setError(null)\n if (authOverride) {\n authOverride.onSubmit()\n return\n }\n setSubmitting(true)\n try {\n const form = new FormData(e.currentTarget)\n if (requiredRoles.length) form.set('requireRole', requiredRoles.join(','))\n const redirectParam = searchParams.get('redirect')\n if (redirectParam) form.set('redirect', redirectParam)\n const res = await fetch('/api/auth/login', { method: 'POST', body: form })\n if (res.redirected) {\n clearAllOperations()\n notifyAuthIdentityChange()\n // NextResponse.redirect from API\n router.replace(res.url)\n return\n }\n if (!res.ok) {\n const fallback = (() => {\n if (res.status === 403) {\n return translate(\n 'auth.login.errors.permissionDenied',\n 'You do not have permission to access this area. Please contact your administrator.',\n )\n }\n if (res.status === 401 || res.status === 400) {\n return translate('auth.login.errors.invalidCredentials', 'Invalid email or password')\n }\n return translate('auth.login.errors.generic', 'An error occurred. Please try again.')\n })()\n const cloned = res.clone()\n let errorMessage = ''\n const contentType = res.headers.get('content-type') || ''\n if (contentType.includes('application/json')) {\n try {\n const data = await res.json()\n errorMessage = extractErrorMessage(data) || ''\n } catch {\n try {\n const text = await cloned.text()\n const trimmed = text.trim()\n if (trimmed && !looksLikeJsonString(trimmed)) {\n errorMessage = trimmed\n }\n } catch {\n errorMessage = ''\n }\n }\n } else {\n try {\n const text = await res.text()\n const trimmed = text.trim()\n if (trimmed && !looksLikeJsonString(trimmed)) {\n errorMessage = trimmed\n }\n } catch {\n errorMessage = ''\n }\n }\n setError(errorMessage || fallback)\n return\n }\n // In case API returns 200 with JSON\n const data = await res.json().catch(() => null) as LoginResponseEventDetail\n emitLoginResponseEvent(data)\n clearAllOperations()\n notifyAuthIdentityChange()\n if (data && typeof data.redirect === 'string' && data.redirect.length > 0) {\n router.replace(data.redirect)\n }\n } catch (err: unknown) {\n // Handle any errors thrown (e.g., network errors or thrown exceptions)\n const message = err instanceof Error ? err.message : ''\n setError(message || translate('auth.login.errors.generic', 'An error occurred. Please try again.'))\n } finally {\n setSubmitting(false)\n }\n }\n\n const loginFormContext = useMemo<LoginFormWidgetContext>(() => ({\n email,\n tenantId,\n searchParams,\n setAuthOverride,\n setAuthOverridePending,\n setError,\n }), [email, tenantId, searchParams])\n\n const formReady = clientReady && !authOverridePending\n\n return (\n <div className=\"min-h-svh flex items-center justify-center p-4\">\n <Card className=\"w-full max-w-sm\">\n <CardHeader className=\"flex flex-col items-center gap-4 text-center p-10\">\n <Image alt={translate('auth.login.logoAlt', 'Open Mercato logo')} src=\"/open-mercato.svg\" width={150} height={150} priority />\n <h1 className=\"text-2xl font-semibold\">{translate('auth.login.brandName', 'Open Mercato')}</h1>\n <CardDescription>{translate('auth.login.subtitle', 'Access your workspace')}</CardDescription>\n </CardHeader>\n <CardContent>\n <LoginFormSection>\n <form className=\"grid gap-3\" onSubmit={onSubmit} noValidate data-auth-ready={formReady ? '1' : '0'}>\n {tenantId ? (\n <input type=\"hidden\" name=\"tenantId\" value={tenantId} />\n ) : null}\n {!!translatedRoles.length && (\n <Alert variant=\"info\" className=\"text-center\">\n <AlertDescription>\n {translate(\n translatedRoles.length > 1 ? 'auth.login.requireRolesMessage' : 'auth.login.requireRoleMessage',\n translatedRoles.length > 1\n ? 'Access requires one of the following roles: {roles}'\n : 'Access requires role: {roles}',\n { roles: translatedRoles.join(', ') },\n )}\n </AlertDescription>\n </Alert>\n )}\n {!!translatedFeatures.length && (\n <Alert variant=\"info\" className=\"text-center\">\n <AlertDescription>\n {translate('auth.login.featureDenied', \"You don't have access to this feature ({feature}). Please contact your administrator.\", {\n feature: translatedFeatures.join(', '),\n })}\n </AlertDescription>\n </Alert>\n )}\n {activeAuthenticatedUser && (translatedRoles.length || translatedFeatures.length) ? (\n <div className=\"flex justify-center\" data-testid=\"login-return-dashboard\">\n <Button asChild type=\"button\" variant=\"outline\" size=\"sm\">\n <Link href=\"/backend\">\n {translate('auth.accessDenied.dashboard', 'Go to Dashboard')}\n </Link>\n </Button>\n </div>\n ) : null}\n {showTenantInvalid ? (\n <div className=\"rounded-md border border-status-error-border bg-status-error-bg px-3 py-2 text-center text-xs text-status-error-text\">\n <div className=\"font-medium\">{translate('auth.login.errors.tenantInvalid', 'Tenant not found. Clear the tenant selection and try again.')}</div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"mt-2 border-status-error-border text-status-error-text hover:text-status-error-text\" onClick={handleClearTenant}>\n <X className=\"mr-2 size-4\" aria-hidden=\"true\" />\n {translate('auth.login.tenantClear', 'Clear')}\n </Button>\n </div>\n ) : tenantId ? (\n <div className=\"rounded-md border border-status-success-border bg-status-success-bg px-3 py-2 text-center text-xs text-status-success-text\">\n <div className=\"font-medium\">\n {tenantLoading\n ? translate('auth.login.tenantLoading', 'Loading tenant details...')\n : translate('auth.login.tenantBanner', \"You're logging in to {tenant}.\", {\n tenant: tenantName || tenantId,\n })}\n </div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"mt-2 border-status-success-border text-status-success-text hover:text-status-success-text\" onClick={handleClearTenant}>\n <X className=\"mr-2 size-4\" aria-hidden=\"true\" />\n {translate('auth.login.tenantClear', 'Clear')}\n </Button>\n </div>\n ) : null}\n {error && !showTenantInvalid && (\n <div className=\"rounded-md border border-status-error-border bg-status-error-bg px-3 py-2 text-center text-sm text-status-error-text\" role=\"alert\" aria-live=\"polite\">\n {error}\n </div>\n )}\n <div className=\"grid gap-1\">\n <Label htmlFor=\"email\">{t('auth.email')}</Label>\n <EmailInput\n id=\"email\"\n name=\"email\"\n required\n aria-invalid={!!error}\n onChange={(e) => setEmail(e.target.value)}\n onBlur={(e) => setEmail(e.target.value)}\n />\n </div>\n <InjectionSpot<LoginFormWidgetContext>\n spotId=\"auth.login:form\"\n context={loginFormContext}\n />\n {authOverride?.hidePassword ? null : (\n <div className=\"grid gap-1\">\n <Label htmlFor=\"password\">{t('auth.password')}</Label>\n <PasswordInput id=\"password\" name=\"password\" required={!authOverride} aria-invalid={!!error} autoComplete=\"current-password\" />\n </div>\n )}\n {!authOverride?.hideRememberMe && !authOverride?.hidePassword && (\n <label className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <input type=\"checkbox\" name=\"remember\" className=\"accent-foreground\" />\n <span>{translate('auth.login.rememberMe', 'Remember me')}</span>\n </label>\n )}\n <Button type=\"submit\" disabled={submitting || !formReady} className=\"h-10 mt-2\">\n {submitting\n ? translate('auth.login.loading', 'Loading...')\n : authOverride\n ? authOverride.providerLabel\n : translate('auth.signIn', 'Sign in')}\n </Button>\n {!authOverride?.hideForgotPassword && (\n <div className=\"text-xs text-muted-foreground mt-2\">\n <Link className=\"underline\" href=\"/reset\">\n {translate('auth.login.forgotPassword', 'Forgot password?')}\n </Link>\n </div>\n )}\n </form>\n </LoginFormSection>\n </CardContent>\n </Card>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["redirectParam", "data"]
|
|
7
7
|
}
|
|
@@ -537,6 +537,17 @@ function AdjustmentDialog({
|
|
|
537
537
|
);
|
|
538
538
|
}
|
|
539
539
|
}
|
|
540
|
+
const resolvedKind = typeof values.kind === "string" && values.kind.trim().length ? values.kind.trim() : "custom";
|
|
541
|
+
if (resolvedKind === "return") {
|
|
542
|
+
const hasNonZeroValue = calculationMode === "rate" ? Number.isFinite(percentageRate) && percentageRate !== 0 : Number.isFinite(amountNet) && amountNet !== 0 || Number.isFinite(amountGross) && amountGross !== 0;
|
|
543
|
+
if (!hasNonZeroValue) {
|
|
544
|
+
const message = t(
|
|
545
|
+
"sales.documents.adjustments.errorReturnZero",
|
|
546
|
+
"Return adjustments must use a non-zero amount. Create the return through the Returns tab instead."
|
|
547
|
+
);
|
|
548
|
+
throw createCrudFormError(message, { amountNet: message });
|
|
549
|
+
}
|
|
550
|
+
}
|
|
540
551
|
const customFields = collectCustomFieldValues(values, {
|
|
541
552
|
transform: (value) => normalizeCustomFieldSubmitValue(value)
|
|
542
553
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/sales/components/documents/AdjustmentDialog.tsx"],
|
|
4
|
-
"sourcesContent": ["// @ts-nocheck\n\n\"use client\"\n\nimport * as React from 'react'\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { useDialogKeyHandler } from '@open-mercato/ui/hooks/useDialogKeyHandler'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { normalizeCustomFieldResponse, normalizeCustomFieldValues } from '@open-mercato/shared/lib/custom-fields/normalize'\nimport { DictionaryEntrySelect, type DictionaryOption } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { SalesAdjustmentKind } from '../../data/entities'\nimport { E } from '#generated/entities.ids.generated'\nimport { Settings } from 'lucide-react'\nimport { extractCustomFieldValues, normalizeCustomFieldSubmitValue } from './customFieldHelpers'\n\ntype TaxRateOption = {\n id: string\n name: string\n code: string | null\n rate: number | null\n isDefault: boolean\n}\n\ntype AdjustmentFormState = {\n id?: string\n label: string\n code: string\n kind: SalesAdjustmentKind\n mode?: 'rate' | 'amount'\n calculatorKey: string\n rate: string\n amountNet: string\n amountGross: string\n position: string\n customFieldSetId?: string | null\n taxRateId?: string | null\n taxRateValue?: number | null\n}\n\nexport type AdjustmentRowData = {\n id: string\n label: string | null\n code: string | null\n kind: SalesAdjustmentKind\n calculatorKey: string | null\n rate: number | null\n amountNet: number | null\n amountGross: number | null\n currencyCode: string | null\n position: number\n customFields?: Record<string, unknown> | null\n customFieldSetId?: string | null\n metadata?: Record<string, unknown> | null\n}\n\nexport type AdjustmentSubmitPayload = {\n id?: string\n label: string | null\n code: string | null\n kind: SalesAdjustmentKind\n calculatorKey: string | null\n rate?: number | null\n amountNet?: number | null\n amountGross?: number | null\n position?: number | null\n currencyCode: string\n customFields?: Record<string, unknown> | null\n metadata?: Record<string, unknown> | null\n}\n\ntype AdjustmentDialogProps = {\n open: boolean\n onOpenChange: (open: boolean) => void\n kind: 'order' | 'quote'\n currencyCode: string | null | undefined\n kindOptions: DictionaryOption[]\n loadKindOptions: () => Promise<DictionaryOption[]>\n labels: {\n addTitle: string\n editTitle: string\n submitCreate: string\n submitUpdate: string\n }\n initialAdjustment?: AdjustmentRowData | null\n onSubmit: (payload: AdjustmentSubmitPayload) => Promise<void>\n}\n\nconst normalizeNumber = (value: unknown): number | null => {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return null\n}\n\nconst formatTaxRateLabel = (rate: TaxRateOption): string => {\n const extras: string[] = []\n if (typeof rate.rate === 'number' && Number.isFinite(rate.rate)) {\n extras.push(`${rate.rate}%`)\n }\n if (rate.code) {\n extras.push(rate.code.toUpperCase())\n }\n if (!extras.length) return rate.name\n return `${rate.name} \u2022 ${extras.join(' \u00B7 ')}`\n}\n\nconst mapTaxRateOption = (item: Record<string, unknown>): TaxRateOption | null => {\n const id = typeof item.id === 'string' ? item.id : null\n const name =\n typeof item.name === 'string' && item.name.trim().length\n ? item.name.trim()\n : typeof item.code === 'string'\n ? item.code\n : null\n if (!id || !name) return null\n const rate = normalizeNumber((item as any).rate)\n const code =\n typeof (item as any).code === 'string' && (item as any).code.trim().length\n ? (item as any).code.trim()\n : null\n const isDefault = Boolean((item as any).isDefault ?? (item as any).is_default)\n return { id, name, code, rate: Number.isFinite(rate) ? rate : null, isDefault }\n}\n\nconst mergeTaxRateOptions = (\n options: TaxRateOption[],\n selected: TaxRateOption | null,\n): TaxRateOption[] => {\n if (!selected) return options\n if (options.some((option) => option.id === selected.id)) return options\n return [selected, ...options]\n}\n\nconst roundAmount = (value: number): number => Math.round((value + Number.EPSILON) * 100) / 100\n\nconst resolveModeFromAdjustment = (adjustment?: AdjustmentRowData | null): 'rate' | 'amount' => {\n if (!adjustment) return 'amount'\n const metadataMode =\n typeof adjustment.metadata === 'object' && adjustment.metadata\n ? (adjustment.metadata as any).calculationMode\n : null\n if (metadataMode === 'rate' || metadataMode === 'amount') return metadataMode\n const rateValue = normalizeNumber(adjustment.rate)\n const amountNetValue = normalizeNumber(adjustment.amountNet)\n const amountGrossValue = normalizeNumber(adjustment.amountGross)\n const hasAmounts = Number.isFinite(amountNetValue) || Number.isFinite(amountGrossValue)\n if (Number.isFinite(rateValue) && (rateValue !== 0 || !hasAmounts)) return 'rate'\n if (hasAmounts) return 'amount'\n return 'amount'\n}\n\nconst PROVIDER_CALCULATOR_PREFIXES = ['shipping-provider:', 'payment-provider:']\n\nexport function AdjustmentDialog({\n open,\n onOpenChange,\n kind,\n currencyCode,\n kindOptions,\n loadKindOptions,\n labels,\n initialAdjustment,\n onSubmit,\n}: AdjustmentDialogProps) {\n const t = useT()\n const dialogContentRef = React.useRef<HTMLDivElement | null>(null)\n const entityId = kind === 'order' ? E.sales.sales_order_adjustment : E.sales.sales_quote_adjustment\n const initialMode: 'rate' | 'amount' = resolveModeFromAdjustment(initialAdjustment)\n const [mode, setMode] = React.useState<'rate' | 'amount'>(initialMode)\n const [formResetKey, setFormResetKey] = React.useState(0)\n const [taxRates, setTaxRates] = React.useState<TaxRateOption[]>([])\n const taxRatesRef = React.useRef<TaxRateOption[]>([])\n const taxRatesLoadedRef = React.useRef(false)\n const lastAmountChangedRef = React.useRef<'net' | 'gross' | null>(null)\n const [initialValues, setInitialValues] = React.useState<AdjustmentFormState>(() => ({\n id: undefined,\n label: '',\n code: '',\n kind: (kindOptions[0]?.value as SalesAdjustmentKind) ?? 'custom',\n mode: initialMode,\n calculatorKey: '',\n rate: '',\n amountNet: '',\n amountGross: '',\n position: '',\n customFieldSetId: null,\n taxRateId: null,\n taxRateValue: null,\n }))\n\n const taxRateMap = React.useMemo(\n () =>\n taxRates.reduce<Map<string, TaxRateOption>>((acc, rate) => {\n acc.set(rate.id, rate)\n return acc\n }, new Map()),\n [taxRates]\n )\n\n const resolveTaxRateValue = React.useCallback(\n (values: Record<string, unknown>): number | null => {\n const fallback = normalizeNumber((values as any)?.taxRateValue)\n if (Number.isFinite(fallback)) return fallback\n const rateId =\n typeof (values as any)?.taxRateId === 'string' && (values as any)?.taxRateId.trim().length\n ? (values as any)?.taxRateId.trim()\n : null\n if (rateId) {\n const option = taxRateMap.get(rateId)\n const parsed = normalizeNumber(option?.rate)\n if (Number.isFinite(parsed)) return parsed\n }\n return null\n },\n [taxRateMap]\n )\n\n const loadTaxRates = React.useCallback(async (): Promise<TaxRateOption[]> => {\n if (taxRatesLoadedRef.current && taxRatesRef.current.length) return taxRatesRef.current\n try {\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n '/api/sales/tax-rates?pageSize=200',\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const parsed = items\n .map<TaxRateOption | null>((item) => mapTaxRateOption(item))\n .filter((entry): entry is TaxRateOption => Boolean(entry))\n taxRatesRef.current = parsed\n taxRatesLoadedRef.current = true\n setTaxRates(parsed)\n return parsed\n } catch (err) {\n console.error('sales.tax-rates.fetch', err)\n taxRatesRef.current = []\n setTaxRates([])\n taxRatesLoadedRef.current = true\n return []\n }\n }, [])\n\n const loadTaxRateById = React.useCallback(async (taxRateId: string): Promise<TaxRateOption | null> => {\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/tax-rates?id=${encodeURIComponent(taxRateId)}&pageSize=1`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n return (\n items\n .map<TaxRateOption | null>((item) => mapTaxRateOption(item))\n .find((entry): entry is TaxRateOption => entry?.id === taxRateId) ?? null\n )\n }, [])\n\n React.useEffect(() => {\n const selectedId =\n typeof initialValues.taxRateId === 'string' && initialValues.taxRateId.trim().length\n ? initialValues.taxRateId.trim()\n : null\n if (!selectedId || taxRates.some((rate) => rate.id === selectedId)) return\n loadTaxRateById(selectedId)\n .then((selected) => {\n taxRatesRef.current = mergeTaxRateOptions(taxRatesRef.current, selected)\n setTaxRates((current) => mergeTaxRateOptions(current, selected))\n })\n .catch(() => {})\n }, [initialValues.taxRateId, loadTaxRateById, taxRates])\n\n const applyOppositeAmount = React.useCallback(\n (\n source: 'net' | 'gross',\n rawValue: string,\n values: Record<string, unknown>,\n setFormValue?: (key: string, value: unknown) => void\n ) => {\n if (mode !== 'amount') return\n if (!rawValue || rawValue.trim() === '') {\n if (!setFormValue) return\n setFormValue(source === 'net' ? 'amountGross' : 'amountNet', '')\n return\n }\n const rateValue = resolveTaxRateValue(values)\n if (!Number.isFinite(rateValue)) return\n const numeric = normalizeNumber(rawValue)\n if (!Number.isFinite(numeric)) return\n if (!setFormValue) return\n if (source === 'net') {\n const gross = roundAmount(numeric * (1 + rateValue / 100))\n setFormValue('amountGross', Number.isFinite(gross) ? gross.toFixed(2) : '')\n } else {\n const net = roundAmount(numeric / (1 + rateValue / 100))\n setFormValue('amountNet', Number.isFinite(net) ? net.toFixed(2) : '')\n }\n },\n [mode, resolveTaxRateValue]\n )\n\n React.useEffect(() => {\n if (!open) return\n let mounted = true\n if (!kindOptions.length) {\n void loadKindOptions()\n }\n const prepare = async () => {\n const rates = await loadTaxRates()\n if (!mounted) return\n const metaTaxRateId =\n typeof initialAdjustment?.metadata === 'object' &&\n initialAdjustment?.metadata &&\n typeof (initialAdjustment.metadata as any).taxRateId === 'string'\n ? (initialAdjustment.metadata as any).taxRateId\n : null\n const metaTaxRateValue =\n typeof initialAdjustment?.metadata === 'object' &&\n initialAdjustment?.metadata &&\n Number.isFinite(normalizeNumber((initialAdjustment.metadata as any).taxRate))\n ? Number(normalizeNumber((initialAdjustment.metadata as any).taxRate))\n : null\n const defaultRate = rates.find((rate) => rate.isDefault) ?? null\n const resolvedMode = resolveModeFromAdjustment(initialAdjustment)\n const next: AdjustmentFormState = {\n id: initialAdjustment?.id,\n label: initialAdjustment?.label ?? '',\n code: initialAdjustment?.code ?? '',\n kind: initialAdjustment?.kind ?? (kindOptions[0]?.value as SalesAdjustmentKind) ?? 'custom',\n mode: resolvedMode,\n calculatorKey: initialAdjustment?.calculatorKey ?? '',\n rate: initialAdjustment?.rate ?? '',\n amountNet: initialAdjustment?.amountNet ?? '',\n amountGross: initialAdjustment?.amountGross ?? '',\n position: initialAdjustment?.position ?? '',\n customFieldSetId: initialAdjustment?.customFieldSetId ?? null,\n taxRateId: metaTaxRateId ?? defaultRate?.id ?? null,\n taxRateValue:\n metaTaxRateValue ??\n (Number.isFinite(defaultRate?.rate ?? null) ? (defaultRate?.rate as number) : null),\n }\n const customValues = extractCustomFieldValues(initialAdjustment as Record<string, unknown> | null)\n setInitialValues({ ...next, ...customValues })\n setMode(resolvedMode)\n setFormResetKey((prev) => prev + 1)\n }\n prepare().catch(() => {})\n return () => {\n mounted = false\n }\n }, [initialAdjustment, kindOptions, loadKindOptions, loadTaxRates, open])\n\n const fields = React.useMemo<CrudField<AdjustmentFormState>[]>(() => {\n const percentSuffix = (\n <div className=\"flex h-9 items-center rounded-r-md border border-l-0 bg-muted px-3 text-sm font-semibold text-muted-foreground\">\n %\n </div>\n )\n return [\n {\n id: 'label',\n label: t('sales.documents.adjustments.label', 'Label'),\n type: 'text',\n placeholder: t('sales.documents.adjustments.labelPlaceholder', 'e.g. Shipping fee'),\n required: true,\n },\n {\n id: 'code',\n label: t('sales.documents.adjustments.code', 'Code'),\n type: 'text',\n placeholder: t('sales.documents.adjustments.codePlaceholder', 'PROMO10'),\n },\n {\n id: 'kind',\n label: t('sales.documents.adjustments.kindLabel', 'Kind'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <DictionaryEntrySelect\n value={typeof value === 'string' ? value : undefined}\n onChange={(next) => setValue(next ?? 'custom')}\n fetchOptions={loadKindOptions}\n allowInlineCreate={false}\n manageHref=\"/backend/config/sales#adjustment-kinds\"\n selectClassName=\"w-full\"\n sortOptions=\"none\"\n labels={{\n placeholder: t('sales.documents.adjustments.kindSelect.placeholder', 'Select adjustment kind\u2026'),\n addLabel: t('sales.config.adjustmentKinds.actions.add', 'Add adjustment kind'),\n addPrompt: t(\n 'sales.config.adjustmentKinds.dialog.createDescription',\n 'Define a reusable adjustment kind shown in document adjustment dialogs.'\n ),\n dialogTitle: t('sales.config.adjustmentKinds.dialog.createTitle', 'Create adjustment kind'),\n valueLabel: t('sales.config.adjustmentKinds.form.codeLabel', 'Code'),\n valuePlaceholder: t('sales.config.adjustmentKinds.form.codePlaceholder', 'e.g. discount'),\n labelLabel: t('sales.config.adjustmentKinds.form.labelLabel', 'Label'),\n labelPlaceholder: t('sales.config.adjustmentKinds.form.labelPlaceholder', 'e.g. Discount'),\n emptyError: t('sales.config.adjustmentKinds.errors.required', 'Code is required.'),\n cancelLabel: t('ui.actions.cancel', 'Cancel'),\n saveLabel: t('ui.actions.save', 'Save'),\n saveShortcutHint: t('ui.actions.saveShortcut', 'Cmd/Ctrl + Enter'),\n successCreateLabel: t('sales.config.adjustmentKinds.messages.created', 'Adjustment kind created.'),\n errorLoad: t('sales.config.adjustmentKinds.errors.load', 'Failed to load adjustment kinds.'),\n errorSave: t('sales.config.adjustmentKinds.errors.save', 'Failed to save adjustment kind.'),\n loadingLabel: t('sales.config.adjustmentKinds.loading', 'Loading adjustment kinds\u2026'),\n manageTitle: t('sales.config.adjustmentKinds.title', 'Adjustment kinds'),\n }}\n showLabelInput={false}\n />\n ),\n },\n {\n id: 'calculatorKey',\n label: t('sales.documents.adjustments.calculatorKey', 'Calculator key'),\n type: 'text',\n placeholder: 'optional',\n },\n {\n id: 'mode',\n label: t('sales.documents.adjustments.amountMode', 'Calculation mode'),\n type: 'custom',\n component: ({ value, setValue }) => {\n const currentMode = value === 'rate' || value === 'amount' ? value : mode\n return (\n <div className=\"inline-flex rounded-md border bg-muted/50 p-1 text-sm font-medium\">\n {(['rate', 'amount'] as const).map((option) => (\n <button\n key={option}\n type=\"button\"\n className={`rounded px-3 py-1 transition-colors ${\n currentMode === option ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground'\n }`}\n onClick={() => {\n setMode(option)\n setValue?.(option)\n if (option === 'rate') {\n const form = dialogContentRef.current?.querySelector('form')\n const rateInput = form?.querySelector<HTMLInputElement>('input[name=\"rate\"]')\n rateInput?.focus()\n }\n }}\n >\n {option === 'rate'\n ? t('sales.documents.adjustments.mode.rate', 'Percentage')\n : t('sales.documents.adjustments.mode.amount', 'Fixed amount')}\n </button>\n ))}\n </div>\n )\n },\n },\n {\n id: 'rate',\n label: t('sales.documents.adjustments.rate', 'Rate'),\n type: 'custom',\n placeholder: '0.00',\n required: mode === 'rate',\n component: ({ value, setValue }) => (\n <div className=\"flex items-center\">\n <Input\n value={typeof value === 'string' ? value : value == null ? '' : String(value)}\n onChange={(event) => setValue(event.target.value)}\n placeholder=\"0.00\"\n disabled={mode !== 'rate'}\n className=\"rounded-r-none\"\n />\n {percentSuffix}\n </div>\n ),\n },\n {\n id: 'amountNet',\n label: t('sales.documents.adjustments.amountNet', 'Net amount'),\n type: 'custom',\n placeholder: '0.00',\n required: mode === 'amount',\n disabled: mode !== 'amount',\n layout: 'half',\n component: ({ value, setValue, setFormValue, values }) => (\n <Input\n value={typeof value === 'string' ? value : value == null ? '' : String(value)}\n onChange={(event) => {\n setValue(event.target.value)\n lastAmountChangedRef.current = 'net'\n applyOppositeAmount('net', event.target.value, values ?? {}, setFormValue)\n }}\n placeholder=\"0.00\"\n disabled={mode !== 'amount'}\n />\n ),\n },\n {\n id: 'amountGross',\n label: t('sales.documents.adjustments.amountGross', 'Gross amount'),\n type: 'custom',\n placeholder: '0.00',\n disabled: mode !== 'amount',\n layout: 'half',\n component: ({ value, setValue, setFormValue, values }) => (\n <Input\n value={typeof value === 'string' ? value : value == null ? '' : String(value)}\n onChange={(event) => {\n setValue(event.target.value)\n lastAmountChangedRef.current = 'gross'\n applyOppositeAmount('gross', event.target.value, values ?? {}, setFormValue)\n }}\n placeholder=\"0.00\"\n disabled={mode !== 'amount'}\n />\n ),\n },\n {\n id: 'taxRateId',\n label: t('sales.documents.adjustments.taxRate', 'Tax class'),\n type: 'custom',\n layout: 'half',\n component: ({ value, setValue, setFormValue, values }) => {\n const resolvedValue =\n typeof value === 'string' && value.trim().length\n ? value\n : null\n const rateId =\n resolvedValue ??\n (() => {\n const rateValue = normalizeNumber(\n (values as any)?.taxRateValue ?? (values as any)?.taxRate\n )\n if (!Number.isFinite(rateValue)) return null\n const match = taxRatesRef.current.find(\n (rate) => Number.isFinite(rate.rate) && rate.rate === rateValue\n )\n return match?.id ?? null\n })()\n const selectedTaxRate = rateId ? taxRateMap.get(rateId) ?? null : null\n const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {\n const nextId = event.target.value || null\n const option = nextId ? taxRateMap.get(nextId) ?? null : null\n setValue(nextId)\n const normalizedRate = normalizeNumber(option?.rate)\n setFormValue?.('taxRateValue', Number.isFinite(normalizedRate) ? normalizedRate : null)\n const rateNumeric = Number.isFinite(normalizedRate) ? normalizedRate : null\n if (rateNumeric === null) return\n const lastChanged = lastAmountChangedRef.current\n if (mode !== 'amount') return\n if (lastChanged === 'gross') {\n const gross = normalizeNumber((values as any)?.amountGross)\n if (Number.isFinite(gross)) {\n const net = roundAmount(gross / (1 + rateNumeric / 100))\n setFormValue?.('amountNet', net.toFixed(2))\n }\n return\n }\n const net = normalizeNumber((values as any)?.amountNet)\n if (Number.isFinite(net)) {\n const gross = roundAmount(net * (1 + rateNumeric / 100))\n setFormValue?.('amountGross', gross.toFixed(2))\n }\n }\n return (\n <div className=\"flex items-center gap-2\">\n <Select\n value={rateId || undefined}\n onValueChange={(value) => handleChange({ target: { value } } as React.ChangeEvent<HTMLSelectElement>)}\n disabled={!taxRates.length}\n >\n <SelectTrigger>\n <SelectValue\n placeholder={\n taxRates.length\n ? t('sales.documents.adjustments.taxRate.placeholder', 'No tax class selected')\n : t('sales.documents.adjustments.taxRate.empty', 'No tax classes available')\n }\n >\n {selectedTaxRate ? formatTaxRateLabel(selectedTaxRate) : undefined}\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {taxRates.map((rate) => (\n <SelectItem key={rate.id} value={rate.id}>\n {formatTaxRateLabel(rate)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if (typeof window !== 'undefined') {\n window.open('/backend/config/sales?section=tax-rates', '_blank', 'noopener,noreferrer')\n }\n }}\n title={t('sales.documents.adjustments.taxRate.manage', 'Manage tax classes')}\n >\n <Settings className=\"h-4 w-4\" />\n <span className=\"sr-only\">\n {t('sales.documents.adjustments.taxRate.manage', 'Manage tax classes')}\n </span>\n </Button>\n </div>\n )\n },\n },\n {\n id: 'taxRateValue',\n label: '',\n type: 'custom',\n component: () => null,\n },\n {\n id: 'position',\n label: t('sales.documents.adjustments.position', 'Position'),\n type: 'number',\n placeholder: '0',\n },\n {\n id: 'currencyDisplay',\n label: t('sales.documents.adjustments.currency', 'Currency'),\n type: 'custom',\n component: () => (\n <Badge variant=\"outline\" className=\"px-3 py-2 text-sm font-semibold\">\n {currencyCode ? currencyCode.toUpperCase() : t('sales.documents.adjustments.currencyPlaceholder', 'e.g. USD')}\n </Badge>\n ),\n },\n ]\n }, [applyOppositeAmount, currencyCode, loadKindOptions, mode, t, taxRates.length, taxRateMap])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => {\n return [\n { id: 'adjustment-core', fields },\n {\n id: 'adjustment-custom',\n column: 2,\n title: t('entities.customFields.title', 'Custom fields'),\n kind: 'customFields',\n },\n ]\n }, [fields, t])\n\n const resolveFormMode = React.useCallback(\n (values: Record<string, unknown>): 'rate' | 'amount' => {\n const raw = values.mode\n if (raw === 'rate' || raw === 'amount') return raw\n return mode\n },\n [mode]\n )\n\n const handleSubmit = React.useCallback(\n async (values: Record<string, unknown>) => {\n const calculationMode = resolveFormMode(values)\n const resolvedCurrency = currencyCode ? currencyCode.toUpperCase() : ''\n if (!resolvedCurrency || resolvedCurrency.length !== 3) {\n throw createCrudFormError(\n t('sales.documents.adjustments.errorCurrency', 'Currency is required.'),\n { currencyCode: t('sales.documents.adjustments.errorCurrency', 'Currency is required.') }\n )\n }\n const label = typeof values.label === 'string' ? values.label.trim() : ''\n if (!label.length) {\n throw createCrudFormError(\n t('sales.documents.adjustments.labelRequired', 'Label is required.'),\n { label: t('sales.documents.adjustments.labelRequired', 'Label is required.') }\n )\n }\n const percentageRate = normalizeNumber(values.rate)\n const amountNet = normalizeNumber(values.amountNet)\n const amountGross = normalizeNumber(values.amountGross)\n if (calculationMode === 'rate') {\n if (!Number.isFinite(percentageRate)) {\n throw createCrudFormError(\n t('sales.documents.adjustments.errorRate', 'Enter a percentage rate.'),\n { rate: t('sales.documents.adjustments.errorRate', 'Enter a percentage rate.') }\n )\n }\n } else {\n if (!Number.isFinite(amountNet) && !Number.isFinite(amountGross)) {\n throw createCrudFormError(\n t('sales.documents.adjustments.errorAmount', 'Provide at least one amount.'),\n { amountNet: t('sales.documents.adjustments.errorAmount', 'Provide at least one amount.') }\n )\n }\n }\n const customFields = collectCustomFieldValues(values, {\n transform: (value) => normalizeCustomFieldSubmitValue(value),\n })\n const rateValue = resolveTaxRateValue(values)\n const selectedRateId =\n typeof values.taxRateId === 'string' && values.taxRateId.trim().length\n ? values.taxRateId\n : null\n const metadata: Record<string, unknown> = {\n ...(typeof initialAdjustment?.metadata === 'object' && initialAdjustment?.metadata\n ? initialAdjustment.metadata\n : {}),\n }\n const isEditingProviderAdjustment =\n typeof initialAdjustment?.calculatorKey === 'string' &&\n PROVIDER_CALCULATOR_PREFIXES.some((prefix) =>\n (initialAdjustment?.calculatorKey ?? '').startsWith(prefix)\n )\n if (selectedRateId) metadata.taxRateId = selectedRateId\n if (Number.isFinite(rateValue)) metadata.taxRate = rateValue\n if (isEditingProviderAdjustment) {\n metadata.manualOverride = true\n }\n metadata.calculationMode = calculationMode\n\n const payload: AdjustmentSubmitPayload = {\n id: typeof values.id === 'string' ? values.id : initialAdjustment?.id,\n label,\n code:\n typeof values.code === 'string' && values.code.trim().length ? values.code.trim() : null,\n kind:\n typeof values.kind === 'string' && values.kind.trim().length\n ? (values.kind as SalesAdjustmentKind)\n : 'custom',\n calculatorKey:\n typeof values.calculatorKey === 'string' && values.calculatorKey.trim().length\n ? values.calculatorKey.trim()\n : null,\n rate: calculationMode === 'rate' && Number.isFinite(percentageRate) ? percentageRate : null,\n amountNet: calculationMode === 'amount' && Number.isFinite(amountNet) ? amountNet : null,\n amountGross: calculationMode === 'amount' && Number.isFinite(amountGross) ? amountGross : null,\n position: Number.isFinite(normalizeNumber(values.position)) ? Number(normalizeNumber(values.position)) : null,\n currencyCode: resolvedCurrency,\n customFields: Object.keys(customFields).length ? normalizeCustomFieldValues(customFields) : null,\n metadata: Object.keys(metadata).length ? metadata : null,\n }\n await onSubmit(payload)\n onOpenChange(false)\n },\n [\n currencyCode,\n initialAdjustment?.calculatorKey,\n initialAdjustment?.id,\n initialAdjustment?.metadata,\n onOpenChange,\n onSubmit,\n resolveFormMode,\n resolveTaxRateValue,\n t,\n ]\n )\n\n const handleSubmitForm = React.useCallback(\n () => dialogContentRef.current?.querySelector('form')?.requestSubmit(),\n [],\n )\n const handleKeyDown = useDialogKeyHandler({\n onConfirm: handleSubmitForm,\n onCancel: () => onOpenChange(false),\n })\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n className=\"sm:max-w-5xl\"\n onKeyDown={handleKeyDown}\n ref={dialogContentRef}\n >\n <DialogHeader>\n <DialogTitle>{initialAdjustment ? labels.editTitle : labels.addTitle}</DialogTitle>\n </DialogHeader>\n <CrudForm<AdjustmentFormState>\n key={formResetKey}\n embedded\n fields={fields}\n groups={groups}\n entityId={entityId}\n initialValues={initialValues}\n submitLabel={initialAdjustment ? labels.submitUpdate : labels.submitCreate}\n onSubmit={handleSubmit}\n loadingMessage={t('sales.documents.adjustments.loading', 'Loading adjustments\u2026')}\n customFieldsLoadingMessage={t('ui.forms.loading', 'Loading data...')}\n />\n </DialogContent>\n </Dialog>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["// @ts-nocheck\n\n\"use client\"\n\nimport * as React from 'react'\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { useDialogKeyHandler } from '@open-mercato/ui/hooks/useDialogKeyHandler'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { normalizeCustomFieldResponse, normalizeCustomFieldValues } from '@open-mercato/shared/lib/custom-fields/normalize'\nimport { DictionaryEntrySelect, type DictionaryOption } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { SalesAdjustmentKind } from '../../data/entities'\nimport { E } from '#generated/entities.ids.generated'\nimport { Settings } from 'lucide-react'\nimport { extractCustomFieldValues, normalizeCustomFieldSubmitValue } from './customFieldHelpers'\n\ntype TaxRateOption = {\n id: string\n name: string\n code: string | null\n rate: number | null\n isDefault: boolean\n}\n\ntype AdjustmentFormState = {\n id?: string\n label: string\n code: string\n kind: SalesAdjustmentKind\n mode?: 'rate' | 'amount'\n calculatorKey: string\n rate: string\n amountNet: string\n amountGross: string\n position: string\n customFieldSetId?: string | null\n taxRateId?: string | null\n taxRateValue?: number | null\n}\n\nexport type AdjustmentRowData = {\n id: string\n label: string | null\n code: string | null\n kind: SalesAdjustmentKind\n calculatorKey: string | null\n rate: number | null\n amountNet: number | null\n amountGross: number | null\n currencyCode: string | null\n position: number\n customFields?: Record<string, unknown> | null\n customFieldSetId?: string | null\n metadata?: Record<string, unknown> | null\n}\n\nexport type AdjustmentSubmitPayload = {\n id?: string\n label: string | null\n code: string | null\n kind: SalesAdjustmentKind\n calculatorKey: string | null\n rate?: number | null\n amountNet?: number | null\n amountGross?: number | null\n position?: number | null\n currencyCode: string\n customFields?: Record<string, unknown> | null\n metadata?: Record<string, unknown> | null\n}\n\ntype AdjustmentDialogProps = {\n open: boolean\n onOpenChange: (open: boolean) => void\n kind: 'order' | 'quote'\n currencyCode: string | null | undefined\n kindOptions: DictionaryOption[]\n loadKindOptions: () => Promise<DictionaryOption[]>\n labels: {\n addTitle: string\n editTitle: string\n submitCreate: string\n submitUpdate: string\n }\n initialAdjustment?: AdjustmentRowData | null\n onSubmit: (payload: AdjustmentSubmitPayload) => Promise<void>\n}\n\nconst normalizeNumber = (value: unknown): number | null => {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return null\n}\n\nconst formatTaxRateLabel = (rate: TaxRateOption): string => {\n const extras: string[] = []\n if (typeof rate.rate === 'number' && Number.isFinite(rate.rate)) {\n extras.push(`${rate.rate}%`)\n }\n if (rate.code) {\n extras.push(rate.code.toUpperCase())\n }\n if (!extras.length) return rate.name\n return `${rate.name} \u2022 ${extras.join(' \u00B7 ')}`\n}\n\nconst mapTaxRateOption = (item: Record<string, unknown>): TaxRateOption | null => {\n const id = typeof item.id === 'string' ? item.id : null\n const name =\n typeof item.name === 'string' && item.name.trim().length\n ? item.name.trim()\n : typeof item.code === 'string'\n ? item.code\n : null\n if (!id || !name) return null\n const rate = normalizeNumber((item as any).rate)\n const code =\n typeof (item as any).code === 'string' && (item as any).code.trim().length\n ? (item as any).code.trim()\n : null\n const isDefault = Boolean((item as any).isDefault ?? (item as any).is_default)\n return { id, name, code, rate: Number.isFinite(rate) ? rate : null, isDefault }\n}\n\nconst mergeTaxRateOptions = (\n options: TaxRateOption[],\n selected: TaxRateOption | null,\n): TaxRateOption[] => {\n if (!selected) return options\n if (options.some((option) => option.id === selected.id)) return options\n return [selected, ...options]\n}\n\nconst roundAmount = (value: number): number => Math.round((value + Number.EPSILON) * 100) / 100\n\nconst resolveModeFromAdjustment = (adjustment?: AdjustmentRowData | null): 'rate' | 'amount' => {\n if (!adjustment) return 'amount'\n const metadataMode =\n typeof adjustment.metadata === 'object' && adjustment.metadata\n ? (adjustment.metadata as any).calculationMode\n : null\n if (metadataMode === 'rate' || metadataMode === 'amount') return metadataMode\n const rateValue = normalizeNumber(adjustment.rate)\n const amountNetValue = normalizeNumber(adjustment.amountNet)\n const amountGrossValue = normalizeNumber(adjustment.amountGross)\n const hasAmounts = Number.isFinite(amountNetValue) || Number.isFinite(amountGrossValue)\n if (Number.isFinite(rateValue) && (rateValue !== 0 || !hasAmounts)) return 'rate'\n if (hasAmounts) return 'amount'\n return 'amount'\n}\n\nconst PROVIDER_CALCULATOR_PREFIXES = ['shipping-provider:', 'payment-provider:']\n\nexport function AdjustmentDialog({\n open,\n onOpenChange,\n kind,\n currencyCode,\n kindOptions,\n loadKindOptions,\n labels,\n initialAdjustment,\n onSubmit,\n}: AdjustmentDialogProps) {\n const t = useT()\n const dialogContentRef = React.useRef<HTMLDivElement | null>(null)\n const entityId = kind === 'order' ? E.sales.sales_order_adjustment : E.sales.sales_quote_adjustment\n const initialMode: 'rate' | 'amount' = resolveModeFromAdjustment(initialAdjustment)\n const [mode, setMode] = React.useState<'rate' | 'amount'>(initialMode)\n const [formResetKey, setFormResetKey] = React.useState(0)\n const [taxRates, setTaxRates] = React.useState<TaxRateOption[]>([])\n const taxRatesRef = React.useRef<TaxRateOption[]>([])\n const taxRatesLoadedRef = React.useRef(false)\n const lastAmountChangedRef = React.useRef<'net' | 'gross' | null>(null)\n const [initialValues, setInitialValues] = React.useState<AdjustmentFormState>(() => ({\n id: undefined,\n label: '',\n code: '',\n kind: (kindOptions[0]?.value as SalesAdjustmentKind) ?? 'custom',\n mode: initialMode,\n calculatorKey: '',\n rate: '',\n amountNet: '',\n amountGross: '',\n position: '',\n customFieldSetId: null,\n taxRateId: null,\n taxRateValue: null,\n }))\n\n const taxRateMap = React.useMemo(\n () =>\n taxRates.reduce<Map<string, TaxRateOption>>((acc, rate) => {\n acc.set(rate.id, rate)\n return acc\n }, new Map()),\n [taxRates]\n )\n\n const resolveTaxRateValue = React.useCallback(\n (values: Record<string, unknown>): number | null => {\n const fallback = normalizeNumber((values as any)?.taxRateValue)\n if (Number.isFinite(fallback)) return fallback\n const rateId =\n typeof (values as any)?.taxRateId === 'string' && (values as any)?.taxRateId.trim().length\n ? (values as any)?.taxRateId.trim()\n : null\n if (rateId) {\n const option = taxRateMap.get(rateId)\n const parsed = normalizeNumber(option?.rate)\n if (Number.isFinite(parsed)) return parsed\n }\n return null\n },\n [taxRateMap]\n )\n\n const loadTaxRates = React.useCallback(async (): Promise<TaxRateOption[]> => {\n if (taxRatesLoadedRef.current && taxRatesRef.current.length) return taxRatesRef.current\n try {\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n '/api/sales/tax-rates?pageSize=200',\n undefined,\n { fallback: { items: [] } }\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n const parsed = items\n .map<TaxRateOption | null>((item) => mapTaxRateOption(item))\n .filter((entry): entry is TaxRateOption => Boolean(entry))\n taxRatesRef.current = parsed\n taxRatesLoadedRef.current = true\n setTaxRates(parsed)\n return parsed\n } catch (err) {\n console.error('sales.tax-rates.fetch', err)\n taxRatesRef.current = []\n setTaxRates([])\n taxRatesLoadedRef.current = true\n return []\n }\n }, [])\n\n const loadTaxRateById = React.useCallback(async (taxRateId: string): Promise<TaxRateOption | null> => {\n const response = await apiCall<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/tax-rates?id=${encodeURIComponent(taxRateId)}&pageSize=1`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(response.result?.items) ? response.result.items : []\n return (\n items\n .map<TaxRateOption | null>((item) => mapTaxRateOption(item))\n .find((entry): entry is TaxRateOption => entry?.id === taxRateId) ?? null\n )\n }, [])\n\n React.useEffect(() => {\n const selectedId =\n typeof initialValues.taxRateId === 'string' && initialValues.taxRateId.trim().length\n ? initialValues.taxRateId.trim()\n : null\n if (!selectedId || taxRates.some((rate) => rate.id === selectedId)) return\n loadTaxRateById(selectedId)\n .then((selected) => {\n taxRatesRef.current = mergeTaxRateOptions(taxRatesRef.current, selected)\n setTaxRates((current) => mergeTaxRateOptions(current, selected))\n })\n .catch(() => {})\n }, [initialValues.taxRateId, loadTaxRateById, taxRates])\n\n const applyOppositeAmount = React.useCallback(\n (\n source: 'net' | 'gross',\n rawValue: string,\n values: Record<string, unknown>,\n setFormValue?: (key: string, value: unknown) => void\n ) => {\n if (mode !== 'amount') return\n if (!rawValue || rawValue.trim() === '') {\n if (!setFormValue) return\n setFormValue(source === 'net' ? 'amountGross' : 'amountNet', '')\n return\n }\n const rateValue = resolveTaxRateValue(values)\n if (!Number.isFinite(rateValue)) return\n const numeric = normalizeNumber(rawValue)\n if (!Number.isFinite(numeric)) return\n if (!setFormValue) return\n if (source === 'net') {\n const gross = roundAmount(numeric * (1 + rateValue / 100))\n setFormValue('amountGross', Number.isFinite(gross) ? gross.toFixed(2) : '')\n } else {\n const net = roundAmount(numeric / (1 + rateValue / 100))\n setFormValue('amountNet', Number.isFinite(net) ? net.toFixed(2) : '')\n }\n },\n [mode, resolveTaxRateValue]\n )\n\n React.useEffect(() => {\n if (!open) return\n let mounted = true\n if (!kindOptions.length) {\n void loadKindOptions()\n }\n const prepare = async () => {\n const rates = await loadTaxRates()\n if (!mounted) return\n const metaTaxRateId =\n typeof initialAdjustment?.metadata === 'object' &&\n initialAdjustment?.metadata &&\n typeof (initialAdjustment.metadata as any).taxRateId === 'string'\n ? (initialAdjustment.metadata as any).taxRateId\n : null\n const metaTaxRateValue =\n typeof initialAdjustment?.metadata === 'object' &&\n initialAdjustment?.metadata &&\n Number.isFinite(normalizeNumber((initialAdjustment.metadata as any).taxRate))\n ? Number(normalizeNumber((initialAdjustment.metadata as any).taxRate))\n : null\n const defaultRate = rates.find((rate) => rate.isDefault) ?? null\n const resolvedMode = resolveModeFromAdjustment(initialAdjustment)\n const next: AdjustmentFormState = {\n id: initialAdjustment?.id,\n label: initialAdjustment?.label ?? '',\n code: initialAdjustment?.code ?? '',\n kind: initialAdjustment?.kind ?? (kindOptions[0]?.value as SalesAdjustmentKind) ?? 'custom',\n mode: resolvedMode,\n calculatorKey: initialAdjustment?.calculatorKey ?? '',\n rate: initialAdjustment?.rate ?? '',\n amountNet: initialAdjustment?.amountNet ?? '',\n amountGross: initialAdjustment?.amountGross ?? '',\n position: initialAdjustment?.position ?? '',\n customFieldSetId: initialAdjustment?.customFieldSetId ?? null,\n taxRateId: metaTaxRateId ?? defaultRate?.id ?? null,\n taxRateValue:\n metaTaxRateValue ??\n (Number.isFinite(defaultRate?.rate ?? null) ? (defaultRate?.rate as number) : null),\n }\n const customValues = extractCustomFieldValues(initialAdjustment as Record<string, unknown> | null)\n setInitialValues({ ...next, ...customValues })\n setMode(resolvedMode)\n setFormResetKey((prev) => prev + 1)\n }\n prepare().catch(() => {})\n return () => {\n mounted = false\n }\n }, [initialAdjustment, kindOptions, loadKindOptions, loadTaxRates, open])\n\n const fields = React.useMemo<CrudField<AdjustmentFormState>[]>(() => {\n const percentSuffix = (\n <div className=\"flex h-9 items-center rounded-r-md border border-l-0 bg-muted px-3 text-sm font-semibold text-muted-foreground\">\n %\n </div>\n )\n return [\n {\n id: 'label',\n label: t('sales.documents.adjustments.label', 'Label'),\n type: 'text',\n placeholder: t('sales.documents.adjustments.labelPlaceholder', 'e.g. Shipping fee'),\n required: true,\n },\n {\n id: 'code',\n label: t('sales.documents.adjustments.code', 'Code'),\n type: 'text',\n placeholder: t('sales.documents.adjustments.codePlaceholder', 'PROMO10'),\n },\n {\n id: 'kind',\n label: t('sales.documents.adjustments.kindLabel', 'Kind'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <DictionaryEntrySelect\n value={typeof value === 'string' ? value : undefined}\n onChange={(next) => setValue(next ?? 'custom')}\n fetchOptions={loadKindOptions}\n allowInlineCreate={false}\n manageHref=\"/backend/config/sales#adjustment-kinds\"\n selectClassName=\"w-full\"\n sortOptions=\"none\"\n labels={{\n placeholder: t('sales.documents.adjustments.kindSelect.placeholder', 'Select adjustment kind\u2026'),\n addLabel: t('sales.config.adjustmentKinds.actions.add', 'Add adjustment kind'),\n addPrompt: t(\n 'sales.config.adjustmentKinds.dialog.createDescription',\n 'Define a reusable adjustment kind shown in document adjustment dialogs.'\n ),\n dialogTitle: t('sales.config.adjustmentKinds.dialog.createTitle', 'Create adjustment kind'),\n valueLabel: t('sales.config.adjustmentKinds.form.codeLabel', 'Code'),\n valuePlaceholder: t('sales.config.adjustmentKinds.form.codePlaceholder', 'e.g. discount'),\n labelLabel: t('sales.config.adjustmentKinds.form.labelLabel', 'Label'),\n labelPlaceholder: t('sales.config.adjustmentKinds.form.labelPlaceholder', 'e.g. Discount'),\n emptyError: t('sales.config.adjustmentKinds.errors.required', 'Code is required.'),\n cancelLabel: t('ui.actions.cancel', 'Cancel'),\n saveLabel: t('ui.actions.save', 'Save'),\n saveShortcutHint: t('ui.actions.saveShortcut', 'Cmd/Ctrl + Enter'),\n successCreateLabel: t('sales.config.adjustmentKinds.messages.created', 'Adjustment kind created.'),\n errorLoad: t('sales.config.adjustmentKinds.errors.load', 'Failed to load adjustment kinds.'),\n errorSave: t('sales.config.adjustmentKinds.errors.save', 'Failed to save adjustment kind.'),\n loadingLabel: t('sales.config.adjustmentKinds.loading', 'Loading adjustment kinds\u2026'),\n manageTitle: t('sales.config.adjustmentKinds.title', 'Adjustment kinds'),\n }}\n showLabelInput={false}\n />\n ),\n },\n {\n id: 'calculatorKey',\n label: t('sales.documents.adjustments.calculatorKey', 'Calculator key'),\n type: 'text',\n placeholder: 'optional',\n },\n {\n id: 'mode',\n label: t('sales.documents.adjustments.amountMode', 'Calculation mode'),\n type: 'custom',\n component: ({ value, setValue }) => {\n const currentMode = value === 'rate' || value === 'amount' ? value : mode\n return (\n <div className=\"inline-flex rounded-md border bg-muted/50 p-1 text-sm font-medium\">\n {(['rate', 'amount'] as const).map((option) => (\n <button\n key={option}\n type=\"button\"\n className={`rounded px-3 py-1 transition-colors ${\n currentMode === option ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground'\n }`}\n onClick={() => {\n setMode(option)\n setValue?.(option)\n if (option === 'rate') {\n const form = dialogContentRef.current?.querySelector('form')\n const rateInput = form?.querySelector<HTMLInputElement>('input[name=\"rate\"]')\n rateInput?.focus()\n }\n }}\n >\n {option === 'rate'\n ? t('sales.documents.adjustments.mode.rate', 'Percentage')\n : t('sales.documents.adjustments.mode.amount', 'Fixed amount')}\n </button>\n ))}\n </div>\n )\n },\n },\n {\n id: 'rate',\n label: t('sales.documents.adjustments.rate', 'Rate'),\n type: 'custom',\n placeholder: '0.00',\n required: mode === 'rate',\n component: ({ value, setValue }) => (\n <div className=\"flex items-center\">\n <Input\n value={typeof value === 'string' ? value : value == null ? '' : String(value)}\n onChange={(event) => setValue(event.target.value)}\n placeholder=\"0.00\"\n disabled={mode !== 'rate'}\n className=\"rounded-r-none\"\n />\n {percentSuffix}\n </div>\n ),\n },\n {\n id: 'amountNet',\n label: t('sales.documents.adjustments.amountNet', 'Net amount'),\n type: 'custom',\n placeholder: '0.00',\n required: mode === 'amount',\n disabled: mode !== 'amount',\n layout: 'half',\n component: ({ value, setValue, setFormValue, values }) => (\n <Input\n value={typeof value === 'string' ? value : value == null ? '' : String(value)}\n onChange={(event) => {\n setValue(event.target.value)\n lastAmountChangedRef.current = 'net'\n applyOppositeAmount('net', event.target.value, values ?? {}, setFormValue)\n }}\n placeholder=\"0.00\"\n disabled={mode !== 'amount'}\n />\n ),\n },\n {\n id: 'amountGross',\n label: t('sales.documents.adjustments.amountGross', 'Gross amount'),\n type: 'custom',\n placeholder: '0.00',\n disabled: mode !== 'amount',\n layout: 'half',\n component: ({ value, setValue, setFormValue, values }) => (\n <Input\n value={typeof value === 'string' ? value : value == null ? '' : String(value)}\n onChange={(event) => {\n setValue(event.target.value)\n lastAmountChangedRef.current = 'gross'\n applyOppositeAmount('gross', event.target.value, values ?? {}, setFormValue)\n }}\n placeholder=\"0.00\"\n disabled={mode !== 'amount'}\n />\n ),\n },\n {\n id: 'taxRateId',\n label: t('sales.documents.adjustments.taxRate', 'Tax class'),\n type: 'custom',\n layout: 'half',\n component: ({ value, setValue, setFormValue, values }) => {\n const resolvedValue =\n typeof value === 'string' && value.trim().length\n ? value\n : null\n const rateId =\n resolvedValue ??\n (() => {\n const rateValue = normalizeNumber(\n (values as any)?.taxRateValue ?? (values as any)?.taxRate\n )\n if (!Number.isFinite(rateValue)) return null\n const match = taxRatesRef.current.find(\n (rate) => Number.isFinite(rate.rate) && rate.rate === rateValue\n )\n return match?.id ?? null\n })()\n const selectedTaxRate = rateId ? taxRateMap.get(rateId) ?? null : null\n const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {\n const nextId = event.target.value || null\n const option = nextId ? taxRateMap.get(nextId) ?? null : null\n setValue(nextId)\n const normalizedRate = normalizeNumber(option?.rate)\n setFormValue?.('taxRateValue', Number.isFinite(normalizedRate) ? normalizedRate : null)\n const rateNumeric = Number.isFinite(normalizedRate) ? normalizedRate : null\n if (rateNumeric === null) return\n const lastChanged = lastAmountChangedRef.current\n if (mode !== 'amount') return\n if (lastChanged === 'gross') {\n const gross = normalizeNumber((values as any)?.amountGross)\n if (Number.isFinite(gross)) {\n const net = roundAmount(gross / (1 + rateNumeric / 100))\n setFormValue?.('amountNet', net.toFixed(2))\n }\n return\n }\n const net = normalizeNumber((values as any)?.amountNet)\n if (Number.isFinite(net)) {\n const gross = roundAmount(net * (1 + rateNumeric / 100))\n setFormValue?.('amountGross', gross.toFixed(2))\n }\n }\n return (\n <div className=\"flex items-center gap-2\">\n <Select\n value={rateId || undefined}\n onValueChange={(value) => handleChange({ target: { value } } as React.ChangeEvent<HTMLSelectElement>)}\n disabled={!taxRates.length}\n >\n <SelectTrigger>\n <SelectValue\n placeholder={\n taxRates.length\n ? t('sales.documents.adjustments.taxRate.placeholder', 'No tax class selected')\n : t('sales.documents.adjustments.taxRate.empty', 'No tax classes available')\n }\n >\n {selectedTaxRate ? formatTaxRateLabel(selectedTaxRate) : undefined}\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {taxRates.map((rate) => (\n <SelectItem key={rate.id} value={rate.id}>\n {formatTaxRateLabel(rate)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if (typeof window !== 'undefined') {\n window.open('/backend/config/sales?section=tax-rates', '_blank', 'noopener,noreferrer')\n }\n }}\n title={t('sales.documents.adjustments.taxRate.manage', 'Manage tax classes')}\n >\n <Settings className=\"h-4 w-4\" />\n <span className=\"sr-only\">\n {t('sales.documents.adjustments.taxRate.manage', 'Manage tax classes')}\n </span>\n </Button>\n </div>\n )\n },\n },\n {\n id: 'taxRateValue',\n label: '',\n type: 'custom',\n component: () => null,\n },\n {\n id: 'position',\n label: t('sales.documents.adjustments.position', 'Position'),\n type: 'number',\n placeholder: '0',\n },\n {\n id: 'currencyDisplay',\n label: t('sales.documents.adjustments.currency', 'Currency'),\n type: 'custom',\n component: () => (\n <Badge variant=\"outline\" className=\"px-3 py-2 text-sm font-semibold\">\n {currencyCode ? currencyCode.toUpperCase() : t('sales.documents.adjustments.currencyPlaceholder', 'e.g. USD')}\n </Badge>\n ),\n },\n ]\n }, [applyOppositeAmount, currencyCode, loadKindOptions, mode, t, taxRates.length, taxRateMap])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => {\n return [\n { id: 'adjustment-core', fields },\n {\n id: 'adjustment-custom',\n column: 2,\n title: t('entities.customFields.title', 'Custom fields'),\n kind: 'customFields',\n },\n ]\n }, [fields, t])\n\n const resolveFormMode = React.useCallback(\n (values: Record<string, unknown>): 'rate' | 'amount' => {\n const raw = values.mode\n if (raw === 'rate' || raw === 'amount') return raw\n return mode\n },\n [mode]\n )\n\n const handleSubmit = React.useCallback(\n async (values: Record<string, unknown>) => {\n const calculationMode = resolveFormMode(values)\n const resolvedCurrency = currencyCode ? currencyCode.toUpperCase() : ''\n if (!resolvedCurrency || resolvedCurrency.length !== 3) {\n throw createCrudFormError(\n t('sales.documents.adjustments.errorCurrency', 'Currency is required.'),\n { currencyCode: t('sales.documents.adjustments.errorCurrency', 'Currency is required.') }\n )\n }\n const label = typeof values.label === 'string' ? values.label.trim() : ''\n if (!label.length) {\n throw createCrudFormError(\n t('sales.documents.adjustments.labelRequired', 'Label is required.'),\n { label: t('sales.documents.adjustments.labelRequired', 'Label is required.') }\n )\n }\n const percentageRate = normalizeNumber(values.rate)\n const amountNet = normalizeNumber(values.amountNet)\n const amountGross = normalizeNumber(values.amountGross)\n if (calculationMode === 'rate') {\n if (!Number.isFinite(percentageRate)) {\n throw createCrudFormError(\n t('sales.documents.adjustments.errorRate', 'Enter a percentage rate.'),\n { rate: t('sales.documents.adjustments.errorRate', 'Enter a percentage rate.') }\n )\n }\n } else {\n if (!Number.isFinite(amountNet) && !Number.isFinite(amountGross)) {\n throw createCrudFormError(\n t('sales.documents.adjustments.errorAmount', 'Provide at least one amount.'),\n { amountNet: t('sales.documents.adjustments.errorAmount', 'Provide at least one amount.') }\n )\n }\n }\n const resolvedKind =\n typeof values.kind === 'string' && values.kind.trim().length ? values.kind.trim() : 'custom'\n if (resolvedKind === 'return') {\n const hasNonZeroValue =\n calculationMode === 'rate'\n ? Number.isFinite(percentageRate) && percentageRate !== 0\n : (Number.isFinite(amountNet) && amountNet !== 0) ||\n (Number.isFinite(amountGross) && amountGross !== 0)\n if (!hasNonZeroValue) {\n const message = t(\n 'sales.documents.adjustments.errorReturnZero',\n 'Return adjustments must use a non-zero amount. Create the return through the Returns tab instead.'\n )\n throw createCrudFormError(message, { amountNet: message })\n }\n }\n const customFields = collectCustomFieldValues(values, {\n transform: (value) => normalizeCustomFieldSubmitValue(value),\n })\n const rateValue = resolveTaxRateValue(values)\n const selectedRateId =\n typeof values.taxRateId === 'string' && values.taxRateId.trim().length\n ? values.taxRateId\n : null\n const metadata: Record<string, unknown> = {\n ...(typeof initialAdjustment?.metadata === 'object' && initialAdjustment?.metadata\n ? initialAdjustment.metadata\n : {}),\n }\n const isEditingProviderAdjustment =\n typeof initialAdjustment?.calculatorKey === 'string' &&\n PROVIDER_CALCULATOR_PREFIXES.some((prefix) =>\n (initialAdjustment?.calculatorKey ?? '').startsWith(prefix)\n )\n if (selectedRateId) metadata.taxRateId = selectedRateId\n if (Number.isFinite(rateValue)) metadata.taxRate = rateValue\n if (isEditingProviderAdjustment) {\n metadata.manualOverride = true\n }\n metadata.calculationMode = calculationMode\n\n const payload: AdjustmentSubmitPayload = {\n id: typeof values.id === 'string' ? values.id : initialAdjustment?.id,\n label,\n code:\n typeof values.code === 'string' && values.code.trim().length ? values.code.trim() : null,\n kind:\n typeof values.kind === 'string' && values.kind.trim().length\n ? (values.kind as SalesAdjustmentKind)\n : 'custom',\n calculatorKey:\n typeof values.calculatorKey === 'string' && values.calculatorKey.trim().length\n ? values.calculatorKey.trim()\n : null,\n rate: calculationMode === 'rate' && Number.isFinite(percentageRate) ? percentageRate : null,\n amountNet: calculationMode === 'amount' && Number.isFinite(amountNet) ? amountNet : null,\n amountGross: calculationMode === 'amount' && Number.isFinite(amountGross) ? amountGross : null,\n position: Number.isFinite(normalizeNumber(values.position)) ? Number(normalizeNumber(values.position)) : null,\n currencyCode: resolvedCurrency,\n customFields: Object.keys(customFields).length ? normalizeCustomFieldValues(customFields) : null,\n metadata: Object.keys(metadata).length ? metadata : null,\n }\n await onSubmit(payload)\n onOpenChange(false)\n },\n [\n currencyCode,\n initialAdjustment?.calculatorKey,\n initialAdjustment?.id,\n initialAdjustment?.metadata,\n onOpenChange,\n onSubmit,\n resolveFormMode,\n resolveTaxRateValue,\n t,\n ]\n )\n\n const handleSubmitForm = React.useCallback(\n () => dialogContentRef.current?.querySelector('form')?.requestSubmit(),\n [],\n )\n const handleKeyDown = useDialogKeyHandler({\n onConfirm: handleSubmitForm,\n onCancel: () => onOpenChange(false),\n })\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent\n className=\"sm:max-w-5xl\"\n onKeyDown={handleKeyDown}\n ref={dialogContentRef}\n >\n <DialogHeader>\n <DialogTitle>{initialAdjustment ? labels.editTitle : labels.addTitle}</DialogTitle>\n </DialogHeader>\n <CrudForm<AdjustmentFormState>\n key={formResetKey}\n embedded\n fields={fields}\n groups={groups}\n entityId={entityId}\n initialValues={initialValues}\n submitLabel={initialAdjustment ? labels.submitUpdate : labels.submitCreate}\n onSubmit={handleSubmit}\n loadingMessage={t('sales.documents.adjustments.loading', 'Loading adjustments\u2026')}\n customFieldsLoadingMessage={t('ui.forms.loading', 'Loading data...')}\n />\n </DialogContent>\n </Dialog>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["net", "value"]
|
|
7
7
|
}
|
|
@@ -286,6 +286,7 @@ const quoteLineUpdateSchema = z.object({
|
|
|
286
286
|
}).merge(quoteLineCreateSchema.partial());
|
|
287
287
|
const RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE = "Return adjustments must use a non-positive amountNet (returns reduce the total).";
|
|
288
288
|
const RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE = "Return adjustments must use a non-positive amountGross (returns reduce the total).";
|
|
289
|
+
const RETURN_ADJUSTMENT_ZERO_MESSAGE = "Return adjustments must use a non-zero amount. Create the return through the Returns tab instead of recording a zero-value Return adjustment.";
|
|
289
290
|
const DISCOUNT_ADJUSTMENT_NEGATIVE_NET_MESSAGE = "Discount adjustments must use a non-negative amountNet (discounts reduce the total).";
|
|
290
291
|
const DISCOUNT_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE = "Discount adjustments must use a non-negative amountGross (discounts reduce the total).";
|
|
291
292
|
const SURCHARGE_ADJUSTMENT_NEGATIVE_NET_MESSAGE = "Surcharge adjustments must use a non-negative amountNet (surcharges add to the total).";
|
|
@@ -315,20 +316,33 @@ const NON_NEGATIVE_SIGN_MESSAGES = {
|
|
|
315
316
|
const enforceAdjustmentSign = (value, ctx) => {
|
|
316
317
|
if (!value.kind) return;
|
|
317
318
|
if (value.kind === "return") {
|
|
318
|
-
|
|
319
|
+
const netIsPositive = typeof value.amountNet === "number" && value.amountNet > 0;
|
|
320
|
+
const grossIsPositive = typeof value.amountGross === "number" && value.amountGross > 0;
|
|
321
|
+
if (netIsPositive) {
|
|
319
322
|
ctx.addIssue({
|
|
320
323
|
code: z.ZodIssueCode.custom,
|
|
321
324
|
message: RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE,
|
|
322
325
|
path: ["amountNet"]
|
|
323
326
|
});
|
|
324
327
|
}
|
|
325
|
-
if (
|
|
328
|
+
if (grossIsPositive) {
|
|
326
329
|
ctx.addIssue({
|
|
327
330
|
code: z.ZodIssueCode.custom,
|
|
328
331
|
message: RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE,
|
|
329
332
|
path: ["amountGross"]
|
|
330
333
|
});
|
|
331
334
|
}
|
|
335
|
+
if (!netIsPositive && !grossIsPositive) {
|
|
336
|
+
const netIsNegative = typeof value.amountNet === "number" && value.amountNet < 0;
|
|
337
|
+
const grossIsNegative = typeof value.amountGross === "number" && value.amountGross < 0;
|
|
338
|
+
if (!netIsNegative && !grossIsNegative) {
|
|
339
|
+
ctx.addIssue({
|
|
340
|
+
code: z.ZodIssueCode.custom,
|
|
341
|
+
message: RETURN_ADJUSTMENT_ZERO_MESSAGE,
|
|
342
|
+
path: ["amountNet"]
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
}
|
|
332
346
|
return;
|
|
333
347
|
}
|
|
334
348
|
const messages = NON_NEGATIVE_SIGN_MESSAGES[value.kind];
|
|
@@ -751,6 +765,7 @@ export {
|
|
|
751
765
|
RETURN_ADJUSTMENT_EXCEEDS_REMAINING_NET_MESSAGE,
|
|
752
766
|
RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE,
|
|
753
767
|
RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE,
|
|
768
|
+
RETURN_ADJUSTMENT_ZERO_MESSAGE,
|
|
754
769
|
RETURN_DATE_IN_FUTURE_MESSAGE,
|
|
755
770
|
SALES_PHONE_INVALID_MESSAGE_KEY,
|
|
756
771
|
SHIPPING_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/sales/data/validators.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod'\nimport {\n createDictionaryEntrySchema,\n updateDictionaryEntrySchema,\n} from '@open-mercato/core/modules/dictionaries/data/validators'\nimport { getPaymentProvider, getShippingProvider } from '../lib/providers'\nimport { REFERENCE_UNIT_CODES } from '@open-mercato/shared/lib/units/unitCodes'\nimport { isValidPhoneNumber } from '@open-mercato/shared/lib/phone'\n\nexport const SALES_PHONE_INVALID_MESSAGE_KEY = 'customers.people.form.primaryPhone.invalid'\n\nconst optionalPhoneField = (max = 50) =>\n z\n .string()\n .trim()\n .max(max)\n .refine((val) => isValidPhoneNumber(val), { message: SALES_PHONE_INVALID_MESSAGE_KEY })\n .optional()\n\nconst optionalNullablePhoneField = (max = 50) =>\n z\n .union([\n z\n .string()\n .trim()\n .max(max)\n .refine((val) => isValidPhoneNumber(val), { message: SALES_PHONE_INVALID_MESSAGE_KEY }),\n z.literal(''),\n z.null(),\n ])\n .optional()\n\nexport const customerSnapshotSchema = z\n .object({\n customer: z\n .object({\n primaryPhone: optionalNullablePhoneField(),\n })\n .passthrough()\n .nullable()\n .optional(),\n contact: z.unknown().optional(),\n })\n .passthrough()\n\nconst uuid = () => z.string().uuid()\n\nconst scoped = z.object({\n organizationId: uuid(),\n tenantId: uuid(),\n})\n\nconst currencyCode = z\n .string()\n .trim()\n .regex(/^[A-Z]{3}$/, 'currency code must be a three-letter ISO code')\n\nconst decimal = (opts?: { min?: number; max?: number; message?: string }) => {\n let schema = z.coerce.number()\n if (typeof opts?.min === 'number') schema = schema.min(opts.min)\n if (typeof opts?.max === 'number') schema = schema.max(opts.max, opts.message)\n return schema\n}\n\nconst MAX_QUANTITY = 999_999_999\n\nconst percentage = () => decimal({ min: 0, max: 100 })\n\nconst jsonRecord = z.record(z.string(), z.unknown())\n\nconst metadata = jsonRecord.optional()\nconst providerSettings = jsonRecord.optional()\n\nconst channelCodeSchema = z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120)\n\nconst numberFormatSchema = z.string().trim().min(1).max(191)\nconst statusListSchema = z\n .array(z.string().trim().min(1).max(120))\n .max(200)\n .optional()\n .nullable()\n\nexport const salesSettingsUpsertSchema = scoped.extend({\n orderNumberFormat: numberFormatSchema,\n quoteNumberFormat: numberFormatSchema,\n orderNextNumber: z.coerce.number().int().min(1).max(1_000_000_000).optional(),\n quoteNextNumber: z.coerce.number().int().min(1).max(1_000_000_000).optional(),\n orderCustomerEditableStatuses: statusListSchema,\n orderAddressEditableStatuses: statusListSchema,\n})\n\nexport type SalesSettingsUpsertInput = z.infer<typeof salesSettingsUpsertSchema>\n\nexport const salesEditingSettingsSchema = scoped.extend({\n orderNumberFormat: numberFormatSchema.optional(),\n quoteNumberFormat: numberFormatSchema.optional(),\n orderCustomerEditableStatuses: statusListSchema,\n orderAddressEditableStatuses: statusListSchema,\n})\n\nexport type SalesEditingSettingsInput = z.infer<typeof salesEditingSettingsSchema>\n\nexport const channelCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: channelCodeSchema,\n description: z.string().trim().max(2000).optional(),\n statusEntryId: uuid().optional(),\n websiteUrl: z.string().trim().url().max(300).optional(),\n contactEmail: z.string().trim().email().max(320).optional(),\n contactPhone: optionalPhoneField(),\n addressLine1: z.string().trim().max(255).optional(),\n addressLine2: z.string().trim().max(255).optional(),\n city: z.string().trim().max(120).optional(),\n region: z.string().trim().max(120).optional(),\n postalCode: z.string().trim().max(30).optional(),\n country: z.string().trim().max(2).optional(),\n latitude: decimal().optional(),\n longitude: decimal().optional(),\n isActive: z.boolean().optional(),\n metadata,\n})\n\nexport const channelUpdateSchema = z\n .object({\n id: uuid(),\n code: channelCodeSchema,\n })\n .merge(channelCreateSchema.omit({ code: true }).partial())\n\n// Base schema without refinements (used for .partial() in update schema)\nconst shippingMethodBaseSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120),\n description: z.string().trim().max(2000).optional(),\n carrierCode: z.string().trim().max(120).optional(),\n providerKey: z.string().trim().max(120).optional(),\n serviceLevel: z.string().trim().max(120).optional(),\n estimatedTransitDays: z.coerce.number().int().min(0).max(365).optional(),\n baseRateNet: decimal({ min: 0 }).optional(),\n baseRateGross: decimal({ min: 0 }).optional(),\n currencyCode: currencyCode.optional(),\n isActive: z.boolean().optional(),\n providerSettings,\n metadata,\n})\n\n// Refinement for provider settings validation\nconst shippingMethodRefine = (value: { providerKey?: string; providerSettings?: Record<string, unknown> }, ctx: z.RefinementCtx) => {\n if (value.providerKey) {\n const provider = getShippingProvider(value.providerKey)\n const schema = provider?.settings?.schema\n if (schema) {\n const parsed = schema.safeParse(value.providerSettings ?? {})\n if (!parsed.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: parsed.error.issues?.[0]?.message ?? 'Invalid provider configuration',\n path: ['providerSettings'],\n })\n }\n }\n }\n}\n\nexport const shippingMethodCreateSchema = shippingMethodBaseSchema.superRefine(shippingMethodRefine)\n\nexport const shippingMethodUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(shippingMethodBaseSchema.partial())\n .superRefine(shippingMethodRefine)\n\nexport const deliveryWindowCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120),\n description: z.string().trim().max(2000).optional(),\n leadTimeDays: z.coerce.number().int().min(0).max(365).optional(),\n cutoffTime: z.string().trim().regex(/^\\d{2}:\\d{2}$/).optional(),\n timezone: z.string().trim().max(120).optional(),\n isActive: z.boolean().optional(),\n metadata,\n})\n\nexport const deliveryWindowUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(deliveryWindowCreateSchema.partial())\n\n// Base schema without refinements (used for .partial() in update schema)\nconst paymentMethodBaseSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120),\n description: z.string().trim().max(2000).optional(),\n providerKey: z.string().trim().max(120).optional(),\n terms: z.string().trim().max(4000).optional(),\n isActive: z.boolean().optional(),\n providerSettings,\n metadata,\n})\n\n// Refinement for provider settings validation\nconst paymentMethodRefine = (value: { providerKey?: string; providerSettings?: Record<string, unknown> }, ctx: z.RefinementCtx) => {\n if (value.providerKey) {\n const provider = getPaymentProvider(value.providerKey)\n const schema = provider?.settings?.schema\n if (schema) {\n const parsed = schema.safeParse(value.providerSettings ?? {})\n if (!parsed.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: parsed.error.issues?.[0]?.message ?? 'Invalid provider configuration',\n path: ['providerSettings'],\n })\n }\n }\n }\n}\n\nexport const paymentMethodCreateSchema = paymentMethodBaseSchema.superRefine(paymentMethodRefine)\n\nexport const paymentMethodUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(paymentMethodBaseSchema.partial())\n .superRefine(paymentMethodRefine)\n\nexport const salesTagCreateSchema = scoped.extend({\n slug: z\n .string()\n .trim()\n .min(1)\n .max(80)\n .regex(/^[a-z0-9_-]+$/, 'Slug must be lowercase and may contain dashes or underscores'),\n label: z.string().trim().min(1).max(120),\n color: z.string().trim().max(30).optional(),\n description: z.string().trim().max(400).optional(),\n})\n\nexport const salesTagUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(salesTagCreateSchema.partial())\n\nexport const taxRateCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120),\n rate: percentage(),\n countryCode: z.string().trim().length(2).optional(),\n regionCode: z.string().trim().max(6).optional(),\n postalCode: z.string().trim().max(30).optional(),\n city: z.string().trim().max(120).optional(),\n customerGroupId: uuid().optional(),\n productCategoryId: uuid().optional(),\n channelId: uuid().optional(),\n priority: z.coerce.number().int().min(0).max(10).optional(),\n isCompound: z.boolean().optional(),\n isDefault: z.boolean().optional(),\n metadata,\n startsAt: z.coerce.date().optional(),\n endsAt: z.coerce.date().optional(),\n})\n\nexport const taxRateUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(taxRateCreateSchema.partial())\n\nconst statusDictionaryEntryCreateSchema = z.object({\n value: createDictionaryEntrySchema.shape.value,\n label: z.string().trim().min(1).max(150).optional(),\n color: createDictionaryEntrySchema.shape.color,\n icon: createDictionaryEntrySchema.shape.icon,\n})\n\nconst statusDictionaryEntryUpdateFieldsSchema = z.object({\n value: updateDictionaryEntrySchema.shape.value,\n label: z.string().trim().min(1).max(150).optional(),\n color: updateDictionaryEntrySchema.shape.color,\n icon: updateDictionaryEntrySchema.shape.icon,\n})\n\nconst validateStatusDictionaryUpdate = (\n payload: z.infer<typeof statusDictionaryEntryUpdateFieldsSchema>,\n) => Object.values(payload).some((value) => value !== undefined)\n\nconst statusDictionaryEntryUpdateSchema = statusDictionaryEntryUpdateFieldsSchema.refine(\n validateStatusDictionaryUpdate,\n { message: 'Provide at least one field to update.' },\n)\n\nexport const statusDictionaryCreateSchema = scoped.merge(statusDictionaryEntryCreateSchema)\n\nexport const statusDictionaryUpdateSchema = scoped\n .merge(statusDictionaryEntryUpdateFieldsSchema)\n .safeExtend({ id: uuid() })\n .refine(validateStatusDictionaryUpdate, { message: 'Provide at least one field to update.' })\n\nconst lineKindSchema = z.enum(['product', 'service', 'shipping', 'discount', 'adjustment'])\n\nconst adjustmentKindSchema = z.string().trim().min(1).max(150)\n\nconst linePricingSchema = z.object({\n quantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }),\n quantityUnit: z.string().trim().max(25).optional(),\n normalizedQuantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }).optional(),\n normalizedUnit: z.string().trim().max(25).nullable().optional(),\n unitPriceNet: decimal({ min: 0 }).optional(),\n unitPriceGross: decimal({ min: 0 }).optional(),\n priceId: uuid().optional(),\n priceMode: z.enum(['net', 'gross']).optional(),\n taxRateId: uuid().optional(),\n discountAmount: decimal({ min: 0 }).optional(),\n discountPercent: percentage().optional(),\n taxRate: percentage().optional(),\n taxAmount: decimal({ min: 0 }).optional(),\n totalNetAmount: decimal({ min: 0 }).optional(),\n totalGrossAmount: decimal({ min: 0 }).optional(),\n})\n\nconst uomSnapshotSchema = z.object({\n version: z.literal(1),\n productId: z.string().nullable(),\n productVariantId: z.string().nullable(),\n baseUnitCode: z.string().nullable(),\n enteredUnitCode: z.string().nullable(),\n enteredQuantity: z.string(),\n toBaseFactor: z.string(),\n normalizedQuantity: z.string(),\n rounding: z.object({\n mode: z.enum(['half_up', 'down', 'up']),\n scale: z.number().int(),\n }),\n source: z.object({\n conversionId: z.string().nullable(),\n resolvedAt: z.string(),\n }),\n unitPriceReference: z.object({\n enabled: z.boolean(),\n referenceUnitCode: z.enum(REFERENCE_UNIT_CODES).nullable(),\n baseQuantity: z.string().nullable(),\n grossPerReference: z.string().nullable().optional(),\n netPerReference: z.string().nullable().optional(),\n }).optional(),\n}).nullable().optional()\n\nconst lineSharedSchema = z.object({\n kind: lineKindSchema.optional(),\n statusEntryId: uuid().optional(),\n productId: uuid().optional(),\n productVariantId: uuid().optional(),\n name: z.string().trim().max(255).optional(),\n description: z.string().trim().max(4000).optional(),\n comment: z.string().trim().max(2000).optional(),\n currencyCode,\n configuration: z.record(z.string(), z.unknown()).optional(),\n promotionCode: z.string().trim().max(120).optional(),\n promotionSnapshot: z.record(z.string(), z.unknown()).optional(),\n uomSnapshot: uomSnapshotSchema,\n metadata,\n customFieldSetId: uuid().optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const orderLineCreateSchema = scoped.extend({\n orderId: uuid(),\n lineNumber: z.coerce.number().int().min(0).optional(),\n ...lineSharedSchema.shape,\n ...linePricingSchema.shape,\n catalogSnapshot: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const orderLineUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(orderLineCreateSchema.partial())\n\nexport const quoteLineCreateSchema = scoped.extend({\n quoteId: uuid(),\n lineNumber: z.coerce.number().int().min(0).optional(),\n ...lineSharedSchema.shape,\n ...linePricingSchema.shape,\n catalogSnapshot: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const quoteLineUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(quoteLineCreateSchema.partial())\n\n// Each adjustment kind has an intrinsic sign convention so the grand total\n// stays semantically correct regardless of operator input. The calculation\n// engine normalizes signs defensively, but the API edge rejects values that\n// would invert the kind's meaning so bad data never reaches storage.\n//\n// - `return`: non-positive \u2014 returns reduce the total (see #1705).\n// - `discount`: non-negative \u2014 discounts reduce the total.\n// - `surcharge`/`shipping`/`tax`: non-negative \u2014 they add to the total.\n// - `custom` and unknown kinds: unconstrained (operator-controlled).\n//\n// See #1905.\nexport const RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE =\n 'Return adjustments must use a non-positive amountNet (returns reduce the total).'\nexport const RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE =\n 'Return adjustments must use a non-positive amountGross (returns reduce the total).'\nexport const DISCOUNT_ADJUSTMENT_NEGATIVE_NET_MESSAGE =\n 'Discount adjustments must use a non-negative amountNet (discounts reduce the total).'\nexport const DISCOUNT_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =\n 'Discount adjustments must use a non-negative amountGross (discounts reduce the total).'\nexport const SURCHARGE_ADJUSTMENT_NEGATIVE_NET_MESSAGE =\n 'Surcharge adjustments must use a non-negative amountNet (surcharges add to the total).'\nexport const SURCHARGE_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =\n 'Surcharge adjustments must use a non-negative amountGross (surcharges add to the total).'\nexport const SHIPPING_ADJUSTMENT_NEGATIVE_NET_MESSAGE =\n 'Shipping adjustments must use a non-negative amountNet (shipping adds to the total).'\nexport const SHIPPING_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =\n 'Shipping adjustments must use a non-negative amountGross (shipping adds to the total).'\nexport const TAX_ADJUSTMENT_NEGATIVE_NET_MESSAGE =\n 'Tax adjustments must use a non-negative amountNet (taxes add to the total).'\nexport const TAX_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =\n 'Tax adjustments must use a non-negative amountGross (taxes add to the total).'\n\ntype AdjustmentSignInput = {\n kind?: string\n amountNet?: number\n amountGross?: number\n}\n\nconst NON_NEGATIVE_SIGN_MESSAGES: Record<string, { net: string; gross: string }> = {\n discount: {\n net: DISCOUNT_ADJUSTMENT_NEGATIVE_NET_MESSAGE,\n gross: DISCOUNT_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,\n },\n surcharge: {\n net: SURCHARGE_ADJUSTMENT_NEGATIVE_NET_MESSAGE,\n gross: SURCHARGE_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,\n },\n shipping: {\n net: SHIPPING_ADJUSTMENT_NEGATIVE_NET_MESSAGE,\n gross: SHIPPING_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,\n },\n tax: {\n net: TAX_ADJUSTMENT_NEGATIVE_NET_MESSAGE,\n gross: TAX_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,\n },\n}\n\nexport const enforceAdjustmentSign = (\n value: AdjustmentSignInput,\n ctx: z.RefinementCtx\n) => {\n if (!value.kind) return\n if (value.kind === 'return') {\n if (typeof value.amountNet === 'number' && value.amountNet > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE,\n path: ['amountNet'],\n })\n }\n if (typeof value.amountGross === 'number' && value.amountGross > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE,\n path: ['amountGross'],\n })\n }\n return\n }\n const messages = NON_NEGATIVE_SIGN_MESSAGES[value.kind]\n if (!messages) return\n if (typeof value.amountNet === 'number' && value.amountNet < 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: messages.net,\n path: ['amountNet'],\n })\n }\n if (typeof value.amountGross === 'number' && value.amountGross < 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: messages.gross,\n path: ['amountGross'],\n })\n }\n}\n\n/**\n * @deprecated Use `enforceAdjustmentSign` \u2014 it enforces the sign convention\n * for every adjustment kind, not just `return`. Kept for backward compatibility\n * with third-party code that imported the original helper.\n */\nexport const enforceReturnAdjustmentSign = enforceAdjustmentSign\n\nexport const RETURN_ADJUSTMENT_EXCEEDS_REMAINING_NET_MESSAGE =\n 'Return adjustment amountNet exceeds the remaining grand total. Reduce the amount or remove existing returns first.'\nexport const RETURN_ADJUSTMENT_EXCEEDS_REMAINING_GROSS_MESSAGE =\n 'Return adjustment amountGross exceeds the remaining grand total. Reduce the amount or remove existing returns first.'\n\nexport type ReturnAdjustmentRemainingCheck = {\n kind?: string | null\n amountNet?: number | null\n amountGross?: number | null\n remainingNet: number\n remainingGross: number\n}\n\nexport type ReturnAdjustmentRemainingIssue = {\n path: 'amountNet' | 'amountGross'\n message: string\n}\n\n// Inclusive: abs(amount) === remaining is allowed. Tiny epsilon absorbs\n// floating-point rounding from upstream tax/rate adjustments.\nconst RETURN_REMAINING_EPSILON = 0.005\n\nexport const validateReturnAdjustmentWithinRemaining = (\n value: ReturnAdjustmentRemainingCheck\n): ReturnAdjustmentRemainingIssue[] => {\n if (value.kind !== 'return') return []\n const absNet = typeof value.amountNet === 'number' ? Math.abs(value.amountNet) : 0\n const absGross = typeof value.amountGross === 'number' ? Math.abs(value.amountGross) : 0\n const issues: ReturnAdjustmentRemainingIssue[] = []\n if (absGross > value.remainingGross + RETURN_REMAINING_EPSILON) {\n issues.push({ path: 'amountGross', message: RETURN_ADJUSTMENT_EXCEEDS_REMAINING_GROSS_MESSAGE })\n }\n if (absNet > value.remainingNet + RETURN_REMAINING_EPSILON) {\n issues.push({ path: 'amountNet', message: RETURN_ADJUSTMENT_EXCEEDS_REMAINING_NET_MESSAGE })\n }\n return issues\n}\n\nexport const orderAdjustmentCreateSchema = scoped.extend({\n orderId: uuid(),\n orderLineId: uuid().optional(),\n scope: z.enum(['order', 'line']).optional(),\n kind: adjustmentKindSchema.optional(),\n code: z.string().trim().max(120).optional(),\n label: z.string().trim().max(255).optional(),\n calculatorKey: z.string().trim().max(120).optional(),\n promotionId: uuid().optional(),\n rate: percentage().optional(),\n amountNet: decimal().optional(),\n amountGross: decimal().optional(),\n currencyCode: currencyCode.optional(),\n metadata,\n customFields: z.record(z.string(), z.unknown()).optional(),\n position: z.coerce.number().int().min(0).optional(),\n})\n\nexport const orderAdjustmentUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(orderAdjustmentCreateSchema.partial())\n\nexport const quoteAdjustmentCreateSchema = scoped.extend({\n quoteId: uuid(),\n quoteLineId: uuid().optional(),\n scope: z.enum(['order', 'line']).optional(),\n kind: adjustmentKindSchema.optional(),\n code: z.string().trim().max(120).optional(),\n label: z.string().trim().max(255).optional(),\n calculatorKey: z.string().trim().max(120).optional(),\n promotionId: uuid().optional(),\n rate: percentage().optional(),\n amountNet: decimal().optional(),\n amountGross: decimal().optional(),\n currencyCode: currencyCode.optional(),\n metadata,\n customFields: z.record(z.string(), z.unknown()).optional(),\n position: z.coerce.number().int().min(0).optional(),\n})\n\nexport const quoteAdjustmentUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(quoteAdjustmentCreateSchema.partial())\n\nconst orderTotalsSchema = z.object({\n subtotalNetAmount: decimal({ min: 0 }).optional(),\n subtotalGrossAmount: decimal({ min: 0 }).optional(),\n discountTotalAmount: decimal({ min: 0 }).optional(),\n taxTotalAmount: decimal({ min: 0 }).optional(),\n shippingNetAmount: decimal({ min: 0 }).optional(),\n shippingGrossAmount: decimal({ min: 0 }).optional(),\n surchargeTotalAmount: decimal({ min: 0 }).optional(),\n grandTotalNetAmount: decimal({ min: 0 }).optional(),\n grandTotalGrossAmount: decimal({ min: 0 }).optional(),\n paidTotalAmount: decimal({ min: 0 }).optional(),\n refundedTotalAmount: decimal({ min: 0 }).optional(),\n outstandingAmount: decimal().optional(),\n lineItemCount: z.coerce.number().int().min(0).optional(),\n})\n\nconst quoteTotalsSchema = z.object({\n subtotalNetAmount: decimal({ min: 0 }).optional(),\n subtotalGrossAmount: decimal({ min: 0 }).optional(),\n discountTotalAmount: decimal({ min: 0 }).optional(),\n taxTotalAmount: decimal({ min: 0 }).optional(),\n grandTotalNetAmount: decimal({ min: 0 }).optional(),\n grandTotalGrossAmount: decimal({ min: 0 }).optional(),\n lineItemCount: z.coerce.number().int().min(0).optional(),\n})\n\nexport const orderCreateSchema = scoped.extend({\n orderNumber: z.string().trim().min(1).max(191).optional(),\n externalReference: z.string().trim().max(191).optional(),\n customerReference: z.string().trim().max(191).optional(),\n customerEntityId: uuid().optional(),\n customerContactId: uuid().optional(),\n customerSnapshot: customerSnapshotSchema.optional(),\n billingAddressId: uuid().optional(),\n shippingAddressId: uuid().optional(),\n billingAddressSnapshot: jsonRecord.optional(),\n shippingAddressSnapshot: jsonRecord.optional(),\n currencyCode,\n exchangeRate: decimal({ min: 0 }).optional(),\n statusEntryId: uuid().optional(),\n fulfillmentStatusEntryId: uuid().optional(),\n paymentStatusEntryId: uuid().optional(),\n taxStrategyKey: z.string().trim().max(120).optional(),\n discountStrategyKey: z.string().trim().max(120).optional(),\n taxInfo: jsonRecord.optional(),\n shippingMethodId: uuid().optional(),\n shippingMethodCode: z.string().trim().max(120).optional(),\n deliveryWindowId: uuid().optional(),\n deliveryWindowCode: z.string().trim().max(120).optional(),\n paymentMethodId: uuid().optional(),\n paymentMethodCode: z.string().trim().max(120).optional(),\n channelId: uuid().optional(),\n placedAt: z.coerce.date().optional(),\n expectedDeliveryAt: z.coerce.date().optional(),\n dueAt: z.coerce.date().optional(),\n comments: z.string().trim().max(4000).optional(),\n internalNotes: z.string().trim().max(4000).optional(),\n shippingMethodSnapshot: jsonRecord.optional(),\n deliveryWindowSnapshot: jsonRecord.optional(),\n paymentMethodSnapshot: jsonRecord.optional(),\n metadata,\n customFieldSetId: uuid().optional(),\n lines: z.array(orderLineCreateSchema.omit({ organizationId: true, tenantId: true, orderId: true })).optional(),\n adjustments: z.array(orderAdjustmentCreateSchema.omit({ organizationId: true, tenantId: true, orderId: true })).optional(),\n tags: z.array(uuid()).optional(),\n ...orderTotalsSchema.shape,\n})\n\nexport const orderUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(orderCreateSchema.partial())\n\nexport const quoteCreateSchema = scoped.extend({\n quoteNumber: z.string().trim().min(1).max(191).optional(),\n statusEntryId: uuid().optional(),\n customerEntityId: uuid().optional(),\n customerContactId: uuid().optional(),\n channelId: uuid().optional(),\n customerSnapshot: customerSnapshotSchema.optional(),\n billingAddressId: uuid().optional(),\n shippingAddressId: uuid().optional(),\n billingAddressSnapshot: jsonRecord.optional(),\n shippingAddressSnapshot: jsonRecord.optional(),\n currencyCode,\n validFrom: z.coerce.date().optional(),\n validUntil: z.coerce.date().optional(),\n comments: z.string().trim().max(4000).optional(),\n taxInfo: jsonRecord.optional(),\n shippingMethodId: uuid().optional(),\n shippingMethodCode: z.string().trim().max(120).optional(),\n deliveryWindowId: uuid().optional(),\n deliveryWindowCode: z.string().trim().max(120).optional(),\n paymentMethodId: uuid().optional(),\n paymentMethodCode: z.string().trim().max(120).optional(),\n shippingMethodSnapshot: jsonRecord.optional(),\n deliveryWindowSnapshot: jsonRecord.optional(),\n paymentMethodSnapshot: jsonRecord.optional(),\n metadata,\n customFieldSetId: uuid().optional(),\n lines: z\n .array(quoteLineCreateSchema.omit({ organizationId: true, tenantId: true, quoteId: true }))\n .optional(),\n adjustments: z\n .array(quoteAdjustmentCreateSchema.omit({ organizationId: true, tenantId: true, quoteId: true }))\n .optional(),\n tags: z.array(uuid()).optional(),\n ...quoteTotalsSchema.shape,\n})\n\nexport const quoteUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(quoteCreateSchema.partial())\n\nconst documentKind = z.enum(['order', 'quote'])\n\nconst documentAddressFields = {\n documentId: uuid(),\n documentKind,\n customerAddressId: uuid().optional(),\n name: z.string().trim().max(255).nullable().optional(),\n purpose: z.string().trim().max(120).nullable().optional(),\n companyName: z.string().trim().max(255).nullable().optional(),\n addressLine1: z.string().trim().min(1).max(255),\n addressLine2: z.string().trim().max(255).nullable().optional(),\n city: z.string().trim().max(120).nullable().optional(),\n region: z.string().trim().max(120).nullable().optional(),\n postalCode: z.string().trim().max(60).nullable().optional(),\n country: z.string().trim().max(2).nullable().optional(),\n buildingNumber: z.string().trim().max(60).nullable().optional(),\n flatNumber: z.string().trim().max(60).nullable().optional(),\n latitude: z.coerce.number().optional().nullable(),\n longitude: z.coerce.number().optional().nullable(),\n}\n\nexport const documentAddressCreateSchema = scoped.extend(documentAddressFields)\n\nexport const documentAddressUpdateSchema = scoped.extend({\n id: uuid(),\n ...documentAddressFields,\n})\n\nexport const documentAddressDeleteSchema = scoped.extend({\n id: uuid(),\n documentId: uuid(),\n documentKind,\n})\n\nexport const shipmentCreateSchema = scoped.extend({\n orderId: uuid(),\n shipmentNumber: z.string().trim().max(191).optional(),\n shippingMethodId: uuid().optional(),\n statusEntryId: uuid().optional(),\n documentStatusEntryId: uuid().optional(),\n lineStatusEntryId: uuid().optional(),\n carrierName: z.string().trim().max(191).optional(),\n trackingNumbers: z.array(z.string().trim().max(191)).optional(),\n shippedAt: z.coerce.date().optional(),\n deliveredAt: z.coerce.date().optional(),\n weightValue: decimal({ min: 0 }).optional(),\n weightUnit: z.string().trim().max(25).optional(),\n declaredValueNet: decimal({ min: 0 }).optional(),\n declaredValueGross: decimal({ min: 0 }).optional(),\n currencyCode: currencyCode.optional(),\n notes: z.string().trim().max(4000).optional(),\n metadata,\n shipmentAddressSnapshot: jsonRecord.optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n items: z\n .array(\n z.object({\n orderLineId: uuid(),\n quantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }).int('Quantity must be a whole number.'),\n metadata,\n })\n )\n .optional(),\n})\n\nexport const shipmentUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(shipmentCreateSchema.partial())\n\nconst returnLineQuantitySchema = z.coerce\n .number()\n .int('Return quantity must be a whole number.')\n .min(1, 'Return quantity must be at least 1.')\n .max(MAX_QUANTITY, 'Quantity is too large.')\n\nexport const RETURN_DATE_IN_FUTURE_MESSAGE = 'Return date cannot be in the future.'\n\n// A return records when goods physically came back to the seller, so a future\n// date is not yet a fact. Evaluate \"now\" at parse time (not module-load time)\n// so a long-running server never rejects legitimate same-day returns.\nconst returnedAtSchema = z.coerce\n .date()\n .refine((value) => value.getTime() <= Date.now(), {\n message: RETURN_DATE_IN_FUTURE_MESSAGE,\n })\n .optional()\n\nexport const returnCreateSchema = scoped.extend({\n orderId: uuid(),\n reason: z.string().trim().max(4000).optional(),\n notes: z.string().trim().max(4000).optional(),\n returnedAt: returnedAtSchema,\n lines: z\n .array(\n z.object({\n orderLineId: uuid(),\n quantity: returnLineQuantitySchema,\n })\n )\n .min(1),\n})\n\nexport const returnUpdateSchema = scoped.extend({\n id: uuid(),\n orderId: uuid(),\n reason: z.string().trim().max(4000).optional(),\n notes: z.string().trim().max(4000).optional(),\n returnedAt: returnedAtSchema,\n})\n\nexport const returnDeleteSchema = scoped.extend({\n id: uuid(),\n orderId: uuid(),\n})\n\nexport const invoiceCreateSchema = scoped.extend({\n orderId: uuid().optional(),\n invoiceNumber: z.string().trim().min(1).max(191).optional(),\n statusEntryId: uuid().optional(),\n issueDate: z.coerce.date().optional(),\n dueDate: z.coerce.date().optional(),\n currencyCode,\n metadata,\n customFieldSetId: uuid().optional(),\n lines: z\n .array(\n z.object({\n orderLineId: uuid().optional(),\n lineNumber: z.coerce.number().int().min(0).optional(),\n kind: lineKindSchema.optional(),\n name: z.string().trim().max(500).optional(),\n sku: z.string().trim().max(191).optional(),\n description: z.string().trim().max(4000).optional(),\n quantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }),\n quantityUnit: z.string().trim().max(25).optional(),\n normalizedQuantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }).optional(),\n normalizedUnit: z.string().trim().max(25).nullable().optional(),\n uomSnapshot: uomSnapshotSchema,\n currencyCode,\n unitPriceNet: decimal({ min: 0 }).optional(),\n unitPriceGross: decimal({ min: 0 }).optional(),\n discountAmount: decimal({ min: 0 }).optional(),\n discountPercent: percentage().optional(),\n taxRate: percentage().optional(),\n taxAmount: decimal({ min: 0 }).optional(),\n totalNetAmount: decimal({ min: 0 }).optional(),\n totalGrossAmount: decimal({ min: 0 }).optional(),\n metadata,\n })\n )\n .optional(),\n subtotalNetAmount: decimal({ min: 0 }).optional(),\n subtotalGrossAmount: decimal({ min: 0 }).optional(),\n discountTotalAmount: decimal({ min: 0 }).optional(),\n taxTotalAmount: decimal({ min: 0 }).optional(),\n grandTotalNetAmount: decimal({ min: 0 }).optional(),\n grandTotalGrossAmount: decimal({ min: 0 }).optional(),\n paidTotalAmount: decimal({ min: 0 }).optional(),\n outstandingAmount: decimal().optional(),\n})\n\nexport const invoiceUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(invoiceCreateSchema.partial())\n\nexport const creditMemoCreateSchema = scoped.extend({\n orderId: uuid().optional(),\n invoiceId: uuid().optional(),\n creditMemoNumber: z.string().trim().min(1).max(191).optional(),\n statusEntryId: uuid().optional(),\n issueDate: z.coerce.date().optional(),\n reason: z.string().trim().max(4000).optional(),\n currencyCode,\n metadata,\n customFieldSetId: uuid().optional(),\n lines: z\n .array(\n z.object({\n orderLineId: uuid().optional(),\n lineNumber: z.coerce.number().int().min(0).optional(),\n name: z.string().trim().max(500).optional(),\n sku: z.string().trim().max(191).optional(),\n description: z.string().trim().max(4000).optional(),\n quantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }),\n quantityUnit: z.string().trim().max(25).optional(),\n normalizedQuantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }).optional(),\n normalizedUnit: z.string().trim().max(25).nullable().optional(),\n uomSnapshot: uomSnapshotSchema,\n currencyCode,\n unitPriceNet: decimal({ min: 0 }).optional(),\n unitPriceGross: decimal({ min: 0 }).optional(),\n taxRate: percentage().optional(),\n taxAmount: decimal({ min: 0 }).optional(),\n totalNetAmount: decimal({ min: 0 }).optional(),\n totalGrossAmount: decimal({ min: 0 }).optional(),\n metadata,\n })\n )\n .optional(),\n subtotalNetAmount: decimal({ min: 0 }).optional(),\n subtotalGrossAmount: decimal({ min: 0 }).optional(),\n taxTotalAmount: decimal({ min: 0 }).optional(),\n grandTotalNetAmount: decimal({ min: 0 }).optional(),\n grandTotalGrossAmount: decimal({ min: 0 }).optional(),\n})\n\nexport const creditMemoUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(creditMemoCreateSchema.partial())\n\nexport const paymentCreateSchema = scoped.extend({\n orderId: uuid().optional(),\n paymentMethodId: uuid().optional(),\n paymentReference: z.string().trim().max(191).optional(),\n statusEntryId: uuid().optional(),\n documentStatusEntryId: uuid().optional(),\n lineStatusEntryId: uuid().optional(),\n amount: decimal({ min: 0 }),\n currencyCode,\n capturedAmount: decimal({ min: 0 }).optional(),\n refundedAmount: decimal({ min: 0 }).optional(),\n receivedAt: z.coerce.date().optional(),\n capturedAt: z.coerce.date().optional(),\n metadata,\n customFieldSetId: uuid().optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n allocations: z\n .array(\n z.object({\n orderId: uuid().optional(),\n invoiceId: uuid().optional(),\n amount: decimal({ min: 0 }),\n currencyCode,\n metadata,\n })\n )\n .optional(),\n})\n\nexport const paymentUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(paymentCreateSchema.partial())\n\nexport const noteCreateSchema = scoped.extend({\n contextType: z.enum(['order', 'quote', 'invoice', 'credit_memo']),\n contextId: uuid(),\n orderId: uuid().optional(),\n quoteId: uuid().optional(),\n authorUserId: uuid().optional(),\n body: z.string().trim().min(1).max(8000),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const noteUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(\n z\n .object({\n body: z.string().trim().min(1).max(8000).optional(),\n })\n .extend({\n authorUserId: uuid().optional(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n })\n )\n\nexport const documentNumberRequestSchema = scoped.extend({\n kind: z.enum(['order', 'quote', 'invoice', 'credit_memo']),\n format: numberFormatSchema.optional(),\n})\n\nexport type DocumentNumberRequestInput = z.infer<typeof documentNumberRequestSchema>\n\nexport type ChannelCreateInput = z.infer<typeof channelCreateSchema>\nexport type ChannelUpdateInput = z.infer<typeof channelUpdateSchema>\nexport type ShippingMethodCreateInput = z.infer<typeof shippingMethodCreateSchema>\nexport type ShippingMethodUpdateInput = z.infer<typeof shippingMethodUpdateSchema>\nexport type DeliveryWindowCreateInput = z.infer<typeof deliveryWindowCreateSchema>\nexport type DeliveryWindowUpdateInput = z.infer<typeof deliveryWindowUpdateSchema>\nexport type PaymentMethodCreateInput = z.infer<typeof paymentMethodCreateSchema>\nexport type PaymentMethodUpdateInput = z.infer<typeof paymentMethodUpdateSchema>\nexport type TaxRateCreateInput = z.infer<typeof taxRateCreateSchema>\nexport type TaxRateUpdateInput = z.infer<typeof taxRateUpdateSchema>\nexport type OrderCreateInput = z.infer<typeof orderCreateSchema>\nexport type OrderUpdateInput = z.infer<typeof orderUpdateSchema>\nexport type OrderLineCreateInput = z.infer<typeof orderLineCreateSchema>\nexport type OrderLineUpdateInput = z.infer<typeof orderLineUpdateSchema>\nexport type OrderAdjustmentCreateInput = z.infer<typeof orderAdjustmentCreateSchema>\nexport type OrderAdjustmentUpdateInput = z.infer<typeof orderAdjustmentUpdateSchema>\nexport type QuoteCreateInput = z.infer<typeof quoteCreateSchema>\nexport type QuoteUpdateInput = z.infer<typeof quoteUpdateSchema>\nexport type QuoteLineCreateInput = z.infer<typeof quoteLineCreateSchema>\nexport type QuoteLineUpdateInput = z.infer<typeof quoteLineUpdateSchema>\nexport type QuoteAdjustmentCreateInput = z.infer<typeof quoteAdjustmentCreateSchema>\nexport type QuoteAdjustmentUpdateInput = z.infer<typeof quoteAdjustmentUpdateSchema>\nexport type ShipmentCreateInput = z.infer<typeof shipmentCreateSchema>\nexport type ShipmentUpdateInput = z.infer<typeof shipmentUpdateSchema>\nexport type ReturnCreateInput = z.infer<typeof returnCreateSchema>\nexport type ReturnUpdateInput = z.infer<typeof returnUpdateSchema>\nexport type ReturnDeleteInput = z.infer<typeof returnDeleteSchema>\nexport type InvoiceCreateInput = z.infer<typeof invoiceCreateSchema>\nexport type InvoiceUpdateInput = z.infer<typeof invoiceUpdateSchema>\nexport type CreditMemoCreateInput = z.infer<typeof creditMemoCreateSchema>\nexport type CreditMemoUpdateInput = z.infer<typeof creditMemoUpdateSchema>\nexport const quoteSendSchema = z.object({\n quoteId: z.string().uuid(),\n validForDays: z.coerce.number().int().min(1).max(365).default(14),\n})\n\nexport const quoteAcceptSchema = z.object({\n token: z.string().uuid(),\n})\n\nexport type PaymentCreateInput = z.infer<typeof paymentCreateSchema>\nexport type PaymentUpdateInput = z.infer<typeof paymentUpdateSchema>\nexport type NoteCreateInput = z.infer<typeof noteCreateSchema>\nexport type NoteUpdateInput = z.infer<typeof noteUpdateSchema>\nexport type SalesTagCreateInput = z.infer<typeof salesTagCreateSchema>\nexport type SalesTagUpdateInput = z.infer<typeof salesTagUpdateSchema>\nexport type DocumentAddressCreateInput = z.infer<typeof documentAddressCreateSchema>\nexport type DocumentAddressUpdateInput = z.infer<typeof documentAddressUpdateSchema>\nexport type DocumentAddressDeleteInput = z.infer<typeof documentAddressDeleteSchema>\nexport type QuoteSendInput = z.infer<typeof quoteSendSchema>\nexport type QuoteAcceptInput = z.infer<typeof quoteAcceptSchema>\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport {\n createDictionaryEntrySchema,\n updateDictionaryEntrySchema,\n} from '@open-mercato/core/modules/dictionaries/data/validators'\nimport { getPaymentProvider, getShippingProvider } from '../lib/providers'\nimport { REFERENCE_UNIT_CODES } from '@open-mercato/shared/lib/units/unitCodes'\nimport { isValidPhoneNumber } from '@open-mercato/shared/lib/phone'\n\nexport const SALES_PHONE_INVALID_MESSAGE_KEY = 'customers.people.form.primaryPhone.invalid'\n\nconst optionalPhoneField = (max = 50) =>\n z\n .string()\n .trim()\n .max(max)\n .refine((val) => isValidPhoneNumber(val), { message: SALES_PHONE_INVALID_MESSAGE_KEY })\n .optional()\n\nconst optionalNullablePhoneField = (max = 50) =>\n z\n .union([\n z\n .string()\n .trim()\n .max(max)\n .refine((val) => isValidPhoneNumber(val), { message: SALES_PHONE_INVALID_MESSAGE_KEY }),\n z.literal(''),\n z.null(),\n ])\n .optional()\n\nexport const customerSnapshotSchema = z\n .object({\n customer: z\n .object({\n primaryPhone: optionalNullablePhoneField(),\n })\n .passthrough()\n .nullable()\n .optional(),\n contact: z.unknown().optional(),\n })\n .passthrough()\n\nconst uuid = () => z.string().uuid()\n\nconst scoped = z.object({\n organizationId: uuid(),\n tenantId: uuid(),\n})\n\nconst currencyCode = z\n .string()\n .trim()\n .regex(/^[A-Z]{3}$/, 'currency code must be a three-letter ISO code')\n\nconst decimal = (opts?: { min?: number; max?: number; message?: string }) => {\n let schema = z.coerce.number()\n if (typeof opts?.min === 'number') schema = schema.min(opts.min)\n if (typeof opts?.max === 'number') schema = schema.max(opts.max, opts.message)\n return schema\n}\n\nconst MAX_QUANTITY = 999_999_999\n\nconst percentage = () => decimal({ min: 0, max: 100 })\n\nconst jsonRecord = z.record(z.string(), z.unknown())\n\nconst metadata = jsonRecord.optional()\nconst providerSettings = jsonRecord.optional()\n\nconst channelCodeSchema = z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120)\n\nconst numberFormatSchema = z.string().trim().min(1).max(191)\nconst statusListSchema = z\n .array(z.string().trim().min(1).max(120))\n .max(200)\n .optional()\n .nullable()\n\nexport const salesSettingsUpsertSchema = scoped.extend({\n orderNumberFormat: numberFormatSchema,\n quoteNumberFormat: numberFormatSchema,\n orderNextNumber: z.coerce.number().int().min(1).max(1_000_000_000).optional(),\n quoteNextNumber: z.coerce.number().int().min(1).max(1_000_000_000).optional(),\n orderCustomerEditableStatuses: statusListSchema,\n orderAddressEditableStatuses: statusListSchema,\n})\n\nexport type SalesSettingsUpsertInput = z.infer<typeof salesSettingsUpsertSchema>\n\nexport const salesEditingSettingsSchema = scoped.extend({\n orderNumberFormat: numberFormatSchema.optional(),\n quoteNumberFormat: numberFormatSchema.optional(),\n orderCustomerEditableStatuses: statusListSchema,\n orderAddressEditableStatuses: statusListSchema,\n})\n\nexport type SalesEditingSettingsInput = z.infer<typeof salesEditingSettingsSchema>\n\nexport const channelCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: channelCodeSchema,\n description: z.string().trim().max(2000).optional(),\n statusEntryId: uuid().optional(),\n websiteUrl: z.string().trim().url().max(300).optional(),\n contactEmail: z.string().trim().email().max(320).optional(),\n contactPhone: optionalPhoneField(),\n addressLine1: z.string().trim().max(255).optional(),\n addressLine2: z.string().trim().max(255).optional(),\n city: z.string().trim().max(120).optional(),\n region: z.string().trim().max(120).optional(),\n postalCode: z.string().trim().max(30).optional(),\n country: z.string().trim().max(2).optional(),\n latitude: decimal().optional(),\n longitude: decimal().optional(),\n isActive: z.boolean().optional(),\n metadata,\n})\n\nexport const channelUpdateSchema = z\n .object({\n id: uuid(),\n code: channelCodeSchema,\n })\n .merge(channelCreateSchema.omit({ code: true }).partial())\n\n// Base schema without refinements (used for .partial() in update schema)\nconst shippingMethodBaseSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120),\n description: z.string().trim().max(2000).optional(),\n carrierCode: z.string().trim().max(120).optional(),\n providerKey: z.string().trim().max(120).optional(),\n serviceLevel: z.string().trim().max(120).optional(),\n estimatedTransitDays: z.coerce.number().int().min(0).max(365).optional(),\n baseRateNet: decimal({ min: 0 }).optional(),\n baseRateGross: decimal({ min: 0 }).optional(),\n currencyCode: currencyCode.optional(),\n isActive: z.boolean().optional(),\n providerSettings,\n metadata,\n})\n\n// Refinement for provider settings validation\nconst shippingMethodRefine = (value: { providerKey?: string; providerSettings?: Record<string, unknown> }, ctx: z.RefinementCtx) => {\n if (value.providerKey) {\n const provider = getShippingProvider(value.providerKey)\n const schema = provider?.settings?.schema\n if (schema) {\n const parsed = schema.safeParse(value.providerSettings ?? {})\n if (!parsed.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: parsed.error.issues?.[0]?.message ?? 'Invalid provider configuration',\n path: ['providerSettings'],\n })\n }\n }\n }\n}\n\nexport const shippingMethodCreateSchema = shippingMethodBaseSchema.superRefine(shippingMethodRefine)\n\nexport const shippingMethodUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(shippingMethodBaseSchema.partial())\n .superRefine(shippingMethodRefine)\n\nexport const deliveryWindowCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120),\n description: z.string().trim().max(2000).optional(),\n leadTimeDays: z.coerce.number().int().min(0).max(365).optional(),\n cutoffTime: z.string().trim().regex(/^\\d{2}:\\d{2}$/).optional(),\n timezone: z.string().trim().max(120).optional(),\n isActive: z.boolean().optional(),\n metadata,\n})\n\nexport const deliveryWindowUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(deliveryWindowCreateSchema.partial())\n\n// Base schema without refinements (used for .partial() in update schema)\nconst paymentMethodBaseSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120),\n description: z.string().trim().max(2000).optional(),\n providerKey: z.string().trim().max(120).optional(),\n terms: z.string().trim().max(4000).optional(),\n isActive: z.boolean().optional(),\n providerSettings,\n metadata,\n})\n\n// Refinement for provider settings validation\nconst paymentMethodRefine = (value: { providerKey?: string; providerSettings?: Record<string, unknown> }, ctx: z.RefinementCtx) => {\n if (value.providerKey) {\n const provider = getPaymentProvider(value.providerKey)\n const schema = provider?.settings?.schema\n if (schema) {\n const parsed = schema.safeParse(value.providerSettings ?? {})\n if (!parsed.success) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: parsed.error.issues?.[0]?.message ?? 'Invalid provider configuration',\n path: ['providerSettings'],\n })\n }\n }\n }\n}\n\nexport const paymentMethodCreateSchema = paymentMethodBaseSchema.superRefine(paymentMethodRefine)\n\nexport const paymentMethodUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(paymentMethodBaseSchema.partial())\n .superRefine(paymentMethodRefine)\n\nexport const salesTagCreateSchema = scoped.extend({\n slug: z\n .string()\n .trim()\n .min(1)\n .max(80)\n .regex(/^[a-z0-9_-]+$/, 'Slug must be lowercase and may contain dashes or underscores'),\n label: z.string().trim().min(1).max(120),\n color: z.string().trim().max(30).optional(),\n description: z.string().trim().max(400).optional(),\n})\n\nexport const salesTagUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(salesTagCreateSchema.partial())\n\nexport const taxRateCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/)\n .max(120),\n rate: percentage(),\n countryCode: z.string().trim().length(2).optional(),\n regionCode: z.string().trim().max(6).optional(),\n postalCode: z.string().trim().max(30).optional(),\n city: z.string().trim().max(120).optional(),\n customerGroupId: uuid().optional(),\n productCategoryId: uuid().optional(),\n channelId: uuid().optional(),\n priority: z.coerce.number().int().min(0).max(10).optional(),\n isCompound: z.boolean().optional(),\n isDefault: z.boolean().optional(),\n metadata,\n startsAt: z.coerce.date().optional(),\n endsAt: z.coerce.date().optional(),\n})\n\nexport const taxRateUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(taxRateCreateSchema.partial())\n\nconst statusDictionaryEntryCreateSchema = z.object({\n value: createDictionaryEntrySchema.shape.value,\n label: z.string().trim().min(1).max(150).optional(),\n color: createDictionaryEntrySchema.shape.color,\n icon: createDictionaryEntrySchema.shape.icon,\n})\n\nconst statusDictionaryEntryUpdateFieldsSchema = z.object({\n value: updateDictionaryEntrySchema.shape.value,\n label: z.string().trim().min(1).max(150).optional(),\n color: updateDictionaryEntrySchema.shape.color,\n icon: updateDictionaryEntrySchema.shape.icon,\n})\n\nconst validateStatusDictionaryUpdate = (\n payload: z.infer<typeof statusDictionaryEntryUpdateFieldsSchema>,\n) => Object.values(payload).some((value) => value !== undefined)\n\nconst statusDictionaryEntryUpdateSchema = statusDictionaryEntryUpdateFieldsSchema.refine(\n validateStatusDictionaryUpdate,\n { message: 'Provide at least one field to update.' },\n)\n\nexport const statusDictionaryCreateSchema = scoped.merge(statusDictionaryEntryCreateSchema)\n\nexport const statusDictionaryUpdateSchema = scoped\n .merge(statusDictionaryEntryUpdateFieldsSchema)\n .safeExtend({ id: uuid() })\n .refine(validateStatusDictionaryUpdate, { message: 'Provide at least one field to update.' })\n\nconst lineKindSchema = z.enum(['product', 'service', 'shipping', 'discount', 'adjustment'])\n\nconst adjustmentKindSchema = z.string().trim().min(1).max(150)\n\nconst linePricingSchema = z.object({\n quantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }),\n quantityUnit: z.string().trim().max(25).optional(),\n normalizedQuantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }).optional(),\n normalizedUnit: z.string().trim().max(25).nullable().optional(),\n unitPriceNet: decimal({ min: 0 }).optional(),\n unitPriceGross: decimal({ min: 0 }).optional(),\n priceId: uuid().optional(),\n priceMode: z.enum(['net', 'gross']).optional(),\n taxRateId: uuid().optional(),\n discountAmount: decimal({ min: 0 }).optional(),\n discountPercent: percentage().optional(),\n taxRate: percentage().optional(),\n taxAmount: decimal({ min: 0 }).optional(),\n totalNetAmount: decimal({ min: 0 }).optional(),\n totalGrossAmount: decimal({ min: 0 }).optional(),\n})\n\nconst uomSnapshotSchema = z.object({\n version: z.literal(1),\n productId: z.string().nullable(),\n productVariantId: z.string().nullable(),\n baseUnitCode: z.string().nullable(),\n enteredUnitCode: z.string().nullable(),\n enteredQuantity: z.string(),\n toBaseFactor: z.string(),\n normalizedQuantity: z.string(),\n rounding: z.object({\n mode: z.enum(['half_up', 'down', 'up']),\n scale: z.number().int(),\n }),\n source: z.object({\n conversionId: z.string().nullable(),\n resolvedAt: z.string(),\n }),\n unitPriceReference: z.object({\n enabled: z.boolean(),\n referenceUnitCode: z.enum(REFERENCE_UNIT_CODES).nullable(),\n baseQuantity: z.string().nullable(),\n grossPerReference: z.string().nullable().optional(),\n netPerReference: z.string().nullable().optional(),\n }).optional(),\n}).nullable().optional()\n\nconst lineSharedSchema = z.object({\n kind: lineKindSchema.optional(),\n statusEntryId: uuid().optional(),\n productId: uuid().optional(),\n productVariantId: uuid().optional(),\n name: z.string().trim().max(255).optional(),\n description: z.string().trim().max(4000).optional(),\n comment: z.string().trim().max(2000).optional(),\n currencyCode,\n configuration: z.record(z.string(), z.unknown()).optional(),\n promotionCode: z.string().trim().max(120).optional(),\n promotionSnapshot: z.record(z.string(), z.unknown()).optional(),\n uomSnapshot: uomSnapshotSchema,\n metadata,\n customFieldSetId: uuid().optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const orderLineCreateSchema = scoped.extend({\n orderId: uuid(),\n lineNumber: z.coerce.number().int().min(0).optional(),\n ...lineSharedSchema.shape,\n ...linePricingSchema.shape,\n catalogSnapshot: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const orderLineUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(orderLineCreateSchema.partial())\n\nexport const quoteLineCreateSchema = scoped.extend({\n quoteId: uuid(),\n lineNumber: z.coerce.number().int().min(0).optional(),\n ...lineSharedSchema.shape,\n ...linePricingSchema.shape,\n catalogSnapshot: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const quoteLineUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(quoteLineCreateSchema.partial())\n\n// Each adjustment kind has an intrinsic sign convention so the grand total\n// stays semantically correct regardless of operator input. The calculation\n// engine normalizes signs defensively, but the API edge rejects values that\n// would invert the kind's meaning so bad data never reaches storage.\n//\n// - `return`: non-positive \u2014 returns reduce the total (see #1705).\n// - `discount`: non-negative \u2014 discounts reduce the total.\n// - `surcharge`/`shipping`/`tax`: non-negative \u2014 they add to the total.\n// - `custom` and unknown kinds: unconstrained (operator-controlled).\n//\n// See #1905.\nexport const RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE =\n 'Return adjustments must use a non-positive amountNet (returns reduce the total).'\nexport const RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE =\n 'Return adjustments must use a non-positive amountGross (returns reduce the total).'\nexport const RETURN_ADJUSTMENT_ZERO_MESSAGE =\n 'Return adjustments must use a non-zero amount. Create the return through the Returns tab instead of recording a zero-value Return adjustment.'\nexport const DISCOUNT_ADJUSTMENT_NEGATIVE_NET_MESSAGE =\n 'Discount adjustments must use a non-negative amountNet (discounts reduce the total).'\nexport const DISCOUNT_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =\n 'Discount adjustments must use a non-negative amountGross (discounts reduce the total).'\nexport const SURCHARGE_ADJUSTMENT_NEGATIVE_NET_MESSAGE =\n 'Surcharge adjustments must use a non-negative amountNet (surcharges add to the total).'\nexport const SURCHARGE_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =\n 'Surcharge adjustments must use a non-negative amountGross (surcharges add to the total).'\nexport const SHIPPING_ADJUSTMENT_NEGATIVE_NET_MESSAGE =\n 'Shipping adjustments must use a non-negative amountNet (shipping adds to the total).'\nexport const SHIPPING_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =\n 'Shipping adjustments must use a non-negative amountGross (shipping adds to the total).'\nexport const TAX_ADJUSTMENT_NEGATIVE_NET_MESSAGE =\n 'Tax adjustments must use a non-negative amountNet (taxes add to the total).'\nexport const TAX_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =\n 'Tax adjustments must use a non-negative amountGross (taxes add to the total).'\n\ntype AdjustmentSignInput = {\n kind?: string\n amountNet?: number\n amountGross?: number\n}\n\nconst NON_NEGATIVE_SIGN_MESSAGES: Record<string, { net: string; gross: string }> = {\n discount: {\n net: DISCOUNT_ADJUSTMENT_NEGATIVE_NET_MESSAGE,\n gross: DISCOUNT_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,\n },\n surcharge: {\n net: SURCHARGE_ADJUSTMENT_NEGATIVE_NET_MESSAGE,\n gross: SURCHARGE_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,\n },\n shipping: {\n net: SHIPPING_ADJUSTMENT_NEGATIVE_NET_MESSAGE,\n gross: SHIPPING_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,\n },\n tax: {\n net: TAX_ADJUSTMENT_NEGATIVE_NET_MESSAGE,\n gross: TAX_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE,\n },\n}\n\nexport const enforceAdjustmentSign = (\n value: AdjustmentSignInput,\n ctx: z.RefinementCtx\n) => {\n if (!value.kind) return\n if (value.kind === 'return') {\n const netIsPositive = typeof value.amountNet === 'number' && value.amountNet > 0\n const grossIsPositive = typeof value.amountGross === 'number' && value.amountGross > 0\n if (netIsPositive) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE,\n path: ['amountNet'],\n })\n }\n if (grossIsPositive) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE,\n path: ['amountGross'],\n })\n }\n if (!netIsPositive && !grossIsPositive) {\n const netIsNegative = typeof value.amountNet === 'number' && value.amountNet < 0\n const grossIsNegative = typeof value.amountGross === 'number' && value.amountGross < 0\n if (!netIsNegative && !grossIsNegative) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: RETURN_ADJUSTMENT_ZERO_MESSAGE,\n path: ['amountNet'],\n })\n }\n }\n return\n }\n const messages = NON_NEGATIVE_SIGN_MESSAGES[value.kind]\n if (!messages) return\n if (typeof value.amountNet === 'number' && value.amountNet < 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: messages.net,\n path: ['amountNet'],\n })\n }\n if (typeof value.amountGross === 'number' && value.amountGross < 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: messages.gross,\n path: ['amountGross'],\n })\n }\n}\n\n/**\n * @deprecated Use `enforceAdjustmentSign` \u2014 it enforces the sign convention\n * for every adjustment kind, not just `return`. Kept for backward compatibility\n * with third-party code that imported the original helper.\n */\nexport const enforceReturnAdjustmentSign = enforceAdjustmentSign\n\nexport const RETURN_ADJUSTMENT_EXCEEDS_REMAINING_NET_MESSAGE =\n 'Return adjustment amountNet exceeds the remaining grand total. Reduce the amount or remove existing returns first.'\nexport const RETURN_ADJUSTMENT_EXCEEDS_REMAINING_GROSS_MESSAGE =\n 'Return adjustment amountGross exceeds the remaining grand total. Reduce the amount or remove existing returns first.'\n\nexport type ReturnAdjustmentRemainingCheck = {\n kind?: string | null\n amountNet?: number | null\n amountGross?: number | null\n remainingNet: number\n remainingGross: number\n}\n\nexport type ReturnAdjustmentRemainingIssue = {\n path: 'amountNet' | 'amountGross'\n message: string\n}\n\n// Inclusive: abs(amount) === remaining is allowed. Tiny epsilon absorbs\n// floating-point rounding from upstream tax/rate adjustments.\nconst RETURN_REMAINING_EPSILON = 0.005\n\nexport const validateReturnAdjustmentWithinRemaining = (\n value: ReturnAdjustmentRemainingCheck\n): ReturnAdjustmentRemainingIssue[] => {\n if (value.kind !== 'return') return []\n const absNet = typeof value.amountNet === 'number' ? Math.abs(value.amountNet) : 0\n const absGross = typeof value.amountGross === 'number' ? Math.abs(value.amountGross) : 0\n const issues: ReturnAdjustmentRemainingIssue[] = []\n if (absGross > value.remainingGross + RETURN_REMAINING_EPSILON) {\n issues.push({ path: 'amountGross', message: RETURN_ADJUSTMENT_EXCEEDS_REMAINING_GROSS_MESSAGE })\n }\n if (absNet > value.remainingNet + RETURN_REMAINING_EPSILON) {\n issues.push({ path: 'amountNet', message: RETURN_ADJUSTMENT_EXCEEDS_REMAINING_NET_MESSAGE })\n }\n return issues\n}\n\nexport const orderAdjustmentCreateSchema = scoped.extend({\n orderId: uuid(),\n orderLineId: uuid().optional(),\n scope: z.enum(['order', 'line']).optional(),\n kind: adjustmentKindSchema.optional(),\n code: z.string().trim().max(120).optional(),\n label: z.string().trim().max(255).optional(),\n calculatorKey: z.string().trim().max(120).optional(),\n promotionId: uuid().optional(),\n rate: percentage().optional(),\n amountNet: decimal().optional(),\n amountGross: decimal().optional(),\n currencyCode: currencyCode.optional(),\n metadata,\n customFields: z.record(z.string(), z.unknown()).optional(),\n position: z.coerce.number().int().min(0).optional(),\n})\n\nexport const orderAdjustmentUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(orderAdjustmentCreateSchema.partial())\n\nexport const quoteAdjustmentCreateSchema = scoped.extend({\n quoteId: uuid(),\n quoteLineId: uuid().optional(),\n scope: z.enum(['order', 'line']).optional(),\n kind: adjustmentKindSchema.optional(),\n code: z.string().trim().max(120).optional(),\n label: z.string().trim().max(255).optional(),\n calculatorKey: z.string().trim().max(120).optional(),\n promotionId: uuid().optional(),\n rate: percentage().optional(),\n amountNet: decimal().optional(),\n amountGross: decimal().optional(),\n currencyCode: currencyCode.optional(),\n metadata,\n customFields: z.record(z.string(), z.unknown()).optional(),\n position: z.coerce.number().int().min(0).optional(),\n})\n\nexport const quoteAdjustmentUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(quoteAdjustmentCreateSchema.partial())\n\nconst orderTotalsSchema = z.object({\n subtotalNetAmount: decimal({ min: 0 }).optional(),\n subtotalGrossAmount: decimal({ min: 0 }).optional(),\n discountTotalAmount: decimal({ min: 0 }).optional(),\n taxTotalAmount: decimal({ min: 0 }).optional(),\n shippingNetAmount: decimal({ min: 0 }).optional(),\n shippingGrossAmount: decimal({ min: 0 }).optional(),\n surchargeTotalAmount: decimal({ min: 0 }).optional(),\n grandTotalNetAmount: decimal({ min: 0 }).optional(),\n grandTotalGrossAmount: decimal({ min: 0 }).optional(),\n paidTotalAmount: decimal({ min: 0 }).optional(),\n refundedTotalAmount: decimal({ min: 0 }).optional(),\n outstandingAmount: decimal().optional(),\n lineItemCount: z.coerce.number().int().min(0).optional(),\n})\n\nconst quoteTotalsSchema = z.object({\n subtotalNetAmount: decimal({ min: 0 }).optional(),\n subtotalGrossAmount: decimal({ min: 0 }).optional(),\n discountTotalAmount: decimal({ min: 0 }).optional(),\n taxTotalAmount: decimal({ min: 0 }).optional(),\n grandTotalNetAmount: decimal({ min: 0 }).optional(),\n grandTotalGrossAmount: decimal({ min: 0 }).optional(),\n lineItemCount: z.coerce.number().int().min(0).optional(),\n})\n\nexport const orderCreateSchema = scoped.extend({\n orderNumber: z.string().trim().min(1).max(191).optional(),\n externalReference: z.string().trim().max(191).optional(),\n customerReference: z.string().trim().max(191).optional(),\n customerEntityId: uuid().optional(),\n customerContactId: uuid().optional(),\n customerSnapshot: customerSnapshotSchema.optional(),\n billingAddressId: uuid().optional(),\n shippingAddressId: uuid().optional(),\n billingAddressSnapshot: jsonRecord.optional(),\n shippingAddressSnapshot: jsonRecord.optional(),\n currencyCode,\n exchangeRate: decimal({ min: 0 }).optional(),\n statusEntryId: uuid().optional(),\n fulfillmentStatusEntryId: uuid().optional(),\n paymentStatusEntryId: uuid().optional(),\n taxStrategyKey: z.string().trim().max(120).optional(),\n discountStrategyKey: z.string().trim().max(120).optional(),\n taxInfo: jsonRecord.optional(),\n shippingMethodId: uuid().optional(),\n shippingMethodCode: z.string().trim().max(120).optional(),\n deliveryWindowId: uuid().optional(),\n deliveryWindowCode: z.string().trim().max(120).optional(),\n paymentMethodId: uuid().optional(),\n paymentMethodCode: z.string().trim().max(120).optional(),\n channelId: uuid().optional(),\n placedAt: z.coerce.date().optional(),\n expectedDeliveryAt: z.coerce.date().optional(),\n dueAt: z.coerce.date().optional(),\n comments: z.string().trim().max(4000).optional(),\n internalNotes: z.string().trim().max(4000).optional(),\n shippingMethodSnapshot: jsonRecord.optional(),\n deliveryWindowSnapshot: jsonRecord.optional(),\n paymentMethodSnapshot: jsonRecord.optional(),\n metadata,\n customFieldSetId: uuid().optional(),\n lines: z.array(orderLineCreateSchema.omit({ organizationId: true, tenantId: true, orderId: true })).optional(),\n adjustments: z.array(orderAdjustmentCreateSchema.omit({ organizationId: true, tenantId: true, orderId: true })).optional(),\n tags: z.array(uuid()).optional(),\n ...orderTotalsSchema.shape,\n})\n\nexport const orderUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(orderCreateSchema.partial())\n\nexport const quoteCreateSchema = scoped.extend({\n quoteNumber: z.string().trim().min(1).max(191).optional(),\n statusEntryId: uuid().optional(),\n customerEntityId: uuid().optional(),\n customerContactId: uuid().optional(),\n channelId: uuid().optional(),\n customerSnapshot: customerSnapshotSchema.optional(),\n billingAddressId: uuid().optional(),\n shippingAddressId: uuid().optional(),\n billingAddressSnapshot: jsonRecord.optional(),\n shippingAddressSnapshot: jsonRecord.optional(),\n currencyCode,\n validFrom: z.coerce.date().optional(),\n validUntil: z.coerce.date().optional(),\n comments: z.string().trim().max(4000).optional(),\n taxInfo: jsonRecord.optional(),\n shippingMethodId: uuid().optional(),\n shippingMethodCode: z.string().trim().max(120).optional(),\n deliveryWindowId: uuid().optional(),\n deliveryWindowCode: z.string().trim().max(120).optional(),\n paymentMethodId: uuid().optional(),\n paymentMethodCode: z.string().trim().max(120).optional(),\n shippingMethodSnapshot: jsonRecord.optional(),\n deliveryWindowSnapshot: jsonRecord.optional(),\n paymentMethodSnapshot: jsonRecord.optional(),\n metadata,\n customFieldSetId: uuid().optional(),\n lines: z\n .array(quoteLineCreateSchema.omit({ organizationId: true, tenantId: true, quoteId: true }))\n .optional(),\n adjustments: z\n .array(quoteAdjustmentCreateSchema.omit({ organizationId: true, tenantId: true, quoteId: true }))\n .optional(),\n tags: z.array(uuid()).optional(),\n ...quoteTotalsSchema.shape,\n})\n\nexport const quoteUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(quoteCreateSchema.partial())\n\nconst documentKind = z.enum(['order', 'quote'])\n\nconst documentAddressFields = {\n documentId: uuid(),\n documentKind,\n customerAddressId: uuid().optional(),\n name: z.string().trim().max(255).nullable().optional(),\n purpose: z.string().trim().max(120).nullable().optional(),\n companyName: z.string().trim().max(255).nullable().optional(),\n addressLine1: z.string().trim().min(1).max(255),\n addressLine2: z.string().trim().max(255).nullable().optional(),\n city: z.string().trim().max(120).nullable().optional(),\n region: z.string().trim().max(120).nullable().optional(),\n postalCode: z.string().trim().max(60).nullable().optional(),\n country: z.string().trim().max(2).nullable().optional(),\n buildingNumber: z.string().trim().max(60).nullable().optional(),\n flatNumber: z.string().trim().max(60).nullable().optional(),\n latitude: z.coerce.number().optional().nullable(),\n longitude: z.coerce.number().optional().nullable(),\n}\n\nexport const documentAddressCreateSchema = scoped.extend(documentAddressFields)\n\nexport const documentAddressUpdateSchema = scoped.extend({\n id: uuid(),\n ...documentAddressFields,\n})\n\nexport const documentAddressDeleteSchema = scoped.extend({\n id: uuid(),\n documentId: uuid(),\n documentKind,\n})\n\nexport const shipmentCreateSchema = scoped.extend({\n orderId: uuid(),\n shipmentNumber: z.string().trim().max(191).optional(),\n shippingMethodId: uuid().optional(),\n statusEntryId: uuid().optional(),\n documentStatusEntryId: uuid().optional(),\n lineStatusEntryId: uuid().optional(),\n carrierName: z.string().trim().max(191).optional(),\n trackingNumbers: z.array(z.string().trim().max(191)).optional(),\n shippedAt: z.coerce.date().optional(),\n deliveredAt: z.coerce.date().optional(),\n weightValue: decimal({ min: 0 }).optional(),\n weightUnit: z.string().trim().max(25).optional(),\n declaredValueNet: decimal({ min: 0 }).optional(),\n declaredValueGross: decimal({ min: 0 }).optional(),\n currencyCode: currencyCode.optional(),\n notes: z.string().trim().max(4000).optional(),\n metadata,\n shipmentAddressSnapshot: jsonRecord.optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n items: z\n .array(\n z.object({\n orderLineId: uuid(),\n quantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }).int('Quantity must be a whole number.'),\n metadata,\n })\n )\n .optional(),\n})\n\nexport const shipmentUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(shipmentCreateSchema.partial())\n\nconst returnLineQuantitySchema = z.coerce\n .number()\n .int('Return quantity must be a whole number.')\n .min(1, 'Return quantity must be at least 1.')\n .max(MAX_QUANTITY, 'Quantity is too large.')\n\nexport const RETURN_DATE_IN_FUTURE_MESSAGE = 'Return date cannot be in the future.'\n\n// A return records when goods physically came back to the seller, so a future\n// date is not yet a fact. Evaluate \"now\" at parse time (not module-load time)\n// so a long-running server never rejects legitimate same-day returns.\nconst returnedAtSchema = z.coerce\n .date()\n .refine((value) => value.getTime() <= Date.now(), {\n message: RETURN_DATE_IN_FUTURE_MESSAGE,\n })\n .optional()\n\nexport const returnCreateSchema = scoped.extend({\n orderId: uuid(),\n reason: z.string().trim().max(4000).optional(),\n notes: z.string().trim().max(4000).optional(),\n returnedAt: returnedAtSchema,\n lines: z\n .array(\n z.object({\n orderLineId: uuid(),\n quantity: returnLineQuantitySchema,\n })\n )\n .min(1),\n})\n\nexport const returnUpdateSchema = scoped.extend({\n id: uuid(),\n orderId: uuid(),\n reason: z.string().trim().max(4000).optional(),\n notes: z.string().trim().max(4000).optional(),\n returnedAt: returnedAtSchema,\n})\n\nexport const returnDeleteSchema = scoped.extend({\n id: uuid(),\n orderId: uuid(),\n})\n\nexport const invoiceCreateSchema = scoped.extend({\n orderId: uuid().optional(),\n invoiceNumber: z.string().trim().min(1).max(191).optional(),\n statusEntryId: uuid().optional(),\n issueDate: z.coerce.date().optional(),\n dueDate: z.coerce.date().optional(),\n currencyCode,\n metadata,\n customFieldSetId: uuid().optional(),\n lines: z\n .array(\n z.object({\n orderLineId: uuid().optional(),\n lineNumber: z.coerce.number().int().min(0).optional(),\n kind: lineKindSchema.optional(),\n name: z.string().trim().max(500).optional(),\n sku: z.string().trim().max(191).optional(),\n description: z.string().trim().max(4000).optional(),\n quantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }),\n quantityUnit: z.string().trim().max(25).optional(),\n normalizedQuantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }).optional(),\n normalizedUnit: z.string().trim().max(25).nullable().optional(),\n uomSnapshot: uomSnapshotSchema,\n currencyCode,\n unitPriceNet: decimal({ min: 0 }).optional(),\n unitPriceGross: decimal({ min: 0 }).optional(),\n discountAmount: decimal({ min: 0 }).optional(),\n discountPercent: percentage().optional(),\n taxRate: percentage().optional(),\n taxAmount: decimal({ min: 0 }).optional(),\n totalNetAmount: decimal({ min: 0 }).optional(),\n totalGrossAmount: decimal({ min: 0 }).optional(),\n metadata,\n })\n )\n .optional(),\n subtotalNetAmount: decimal({ min: 0 }).optional(),\n subtotalGrossAmount: decimal({ min: 0 }).optional(),\n discountTotalAmount: decimal({ min: 0 }).optional(),\n taxTotalAmount: decimal({ min: 0 }).optional(),\n grandTotalNetAmount: decimal({ min: 0 }).optional(),\n grandTotalGrossAmount: decimal({ min: 0 }).optional(),\n paidTotalAmount: decimal({ min: 0 }).optional(),\n outstandingAmount: decimal().optional(),\n})\n\nexport const invoiceUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(invoiceCreateSchema.partial())\n\nexport const creditMemoCreateSchema = scoped.extend({\n orderId: uuid().optional(),\n invoiceId: uuid().optional(),\n creditMemoNumber: z.string().trim().min(1).max(191).optional(),\n statusEntryId: uuid().optional(),\n issueDate: z.coerce.date().optional(),\n reason: z.string().trim().max(4000).optional(),\n currencyCode,\n metadata,\n customFieldSetId: uuid().optional(),\n lines: z\n .array(\n z.object({\n orderLineId: uuid().optional(),\n lineNumber: z.coerce.number().int().min(0).optional(),\n name: z.string().trim().max(500).optional(),\n sku: z.string().trim().max(191).optional(),\n description: z.string().trim().max(4000).optional(),\n quantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }),\n quantityUnit: z.string().trim().max(25).optional(),\n normalizedQuantity: decimal({ min: 0, max: MAX_QUANTITY, message: 'Quantity is too large.' }).optional(),\n normalizedUnit: z.string().trim().max(25).nullable().optional(),\n uomSnapshot: uomSnapshotSchema,\n currencyCode,\n unitPriceNet: decimal({ min: 0 }).optional(),\n unitPriceGross: decimal({ min: 0 }).optional(),\n taxRate: percentage().optional(),\n taxAmount: decimal({ min: 0 }).optional(),\n totalNetAmount: decimal({ min: 0 }).optional(),\n totalGrossAmount: decimal({ min: 0 }).optional(),\n metadata,\n })\n )\n .optional(),\n subtotalNetAmount: decimal({ min: 0 }).optional(),\n subtotalGrossAmount: decimal({ min: 0 }).optional(),\n taxTotalAmount: decimal({ min: 0 }).optional(),\n grandTotalNetAmount: decimal({ min: 0 }).optional(),\n grandTotalGrossAmount: decimal({ min: 0 }).optional(),\n})\n\nexport const creditMemoUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(creditMemoCreateSchema.partial())\n\nexport const paymentCreateSchema = scoped.extend({\n orderId: uuid().optional(),\n paymentMethodId: uuid().optional(),\n paymentReference: z.string().trim().max(191).optional(),\n statusEntryId: uuid().optional(),\n documentStatusEntryId: uuid().optional(),\n lineStatusEntryId: uuid().optional(),\n amount: decimal({ min: 0 }),\n currencyCode,\n capturedAmount: decimal({ min: 0 }).optional(),\n refundedAmount: decimal({ min: 0 }).optional(),\n receivedAt: z.coerce.date().optional(),\n capturedAt: z.coerce.date().optional(),\n metadata,\n customFieldSetId: uuid().optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n allocations: z\n .array(\n z.object({\n orderId: uuid().optional(),\n invoiceId: uuid().optional(),\n amount: decimal({ min: 0 }),\n currencyCode,\n metadata,\n })\n )\n .optional(),\n})\n\nexport const paymentUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(paymentCreateSchema.partial())\n\nexport const noteCreateSchema = scoped.extend({\n contextType: z.enum(['order', 'quote', 'invoice', 'credit_memo']),\n contextId: uuid(),\n orderId: uuid().optional(),\n quoteId: uuid().optional(),\n authorUserId: uuid().optional(),\n body: z.string().trim().min(1).max(8000),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n})\n\nexport const noteUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(\n z\n .object({\n body: z.string().trim().min(1).max(8000).optional(),\n })\n .extend({\n authorUserId: uuid().optional(),\n appearanceIcon: z.string().trim().max(100).optional().nullable(),\n appearanceColor: z\n .string()\n .trim()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .optional()\n .nullable(),\n })\n )\n\nexport const documentNumberRequestSchema = scoped.extend({\n kind: z.enum(['order', 'quote', 'invoice', 'credit_memo']),\n format: numberFormatSchema.optional(),\n})\n\nexport type DocumentNumberRequestInput = z.infer<typeof documentNumberRequestSchema>\n\nexport type ChannelCreateInput = z.infer<typeof channelCreateSchema>\nexport type ChannelUpdateInput = z.infer<typeof channelUpdateSchema>\nexport type ShippingMethodCreateInput = z.infer<typeof shippingMethodCreateSchema>\nexport type ShippingMethodUpdateInput = z.infer<typeof shippingMethodUpdateSchema>\nexport type DeliveryWindowCreateInput = z.infer<typeof deliveryWindowCreateSchema>\nexport type DeliveryWindowUpdateInput = z.infer<typeof deliveryWindowUpdateSchema>\nexport type PaymentMethodCreateInput = z.infer<typeof paymentMethodCreateSchema>\nexport type PaymentMethodUpdateInput = z.infer<typeof paymentMethodUpdateSchema>\nexport type TaxRateCreateInput = z.infer<typeof taxRateCreateSchema>\nexport type TaxRateUpdateInput = z.infer<typeof taxRateUpdateSchema>\nexport type OrderCreateInput = z.infer<typeof orderCreateSchema>\nexport type OrderUpdateInput = z.infer<typeof orderUpdateSchema>\nexport type OrderLineCreateInput = z.infer<typeof orderLineCreateSchema>\nexport type OrderLineUpdateInput = z.infer<typeof orderLineUpdateSchema>\nexport type OrderAdjustmentCreateInput = z.infer<typeof orderAdjustmentCreateSchema>\nexport type OrderAdjustmentUpdateInput = z.infer<typeof orderAdjustmentUpdateSchema>\nexport type QuoteCreateInput = z.infer<typeof quoteCreateSchema>\nexport type QuoteUpdateInput = z.infer<typeof quoteUpdateSchema>\nexport type QuoteLineCreateInput = z.infer<typeof quoteLineCreateSchema>\nexport type QuoteLineUpdateInput = z.infer<typeof quoteLineUpdateSchema>\nexport type QuoteAdjustmentCreateInput = z.infer<typeof quoteAdjustmentCreateSchema>\nexport type QuoteAdjustmentUpdateInput = z.infer<typeof quoteAdjustmentUpdateSchema>\nexport type ShipmentCreateInput = z.infer<typeof shipmentCreateSchema>\nexport type ShipmentUpdateInput = z.infer<typeof shipmentUpdateSchema>\nexport type ReturnCreateInput = z.infer<typeof returnCreateSchema>\nexport type ReturnUpdateInput = z.infer<typeof returnUpdateSchema>\nexport type ReturnDeleteInput = z.infer<typeof returnDeleteSchema>\nexport type InvoiceCreateInput = z.infer<typeof invoiceCreateSchema>\nexport type InvoiceUpdateInput = z.infer<typeof invoiceUpdateSchema>\nexport type CreditMemoCreateInput = z.infer<typeof creditMemoCreateSchema>\nexport type CreditMemoUpdateInput = z.infer<typeof creditMemoUpdateSchema>\nexport const quoteSendSchema = z.object({\n quoteId: z.string().uuid(),\n validForDays: z.coerce.number().int().min(1).max(365).default(14),\n})\n\nexport const quoteAcceptSchema = z.object({\n token: z.string().uuid(),\n})\n\nexport type PaymentCreateInput = z.infer<typeof paymentCreateSchema>\nexport type PaymentUpdateInput = z.infer<typeof paymentUpdateSchema>\nexport type NoteCreateInput = z.infer<typeof noteCreateSchema>\nexport type NoteUpdateInput = z.infer<typeof noteUpdateSchema>\nexport type SalesTagCreateInput = z.infer<typeof salesTagCreateSchema>\nexport type SalesTagUpdateInput = z.infer<typeof salesTagUpdateSchema>\nexport type DocumentAddressCreateInput = z.infer<typeof documentAddressCreateSchema>\nexport type DocumentAddressUpdateInput = z.infer<typeof documentAddressUpdateSchema>\nexport type DocumentAddressDeleteInput = z.infer<typeof documentAddressDeleteSchema>\nexport type QuoteSendInput = z.infer<typeof quoteSendSchema>\nexport type QuoteAcceptInput = z.infer<typeof quoteAcceptSchema>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.6.6-develop.
|
|
3
|
+
"version": "0.6.6-develop.6362.1.a3dd164018",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -246,16 +246,16 @@
|
|
|
246
246
|
"zod": "^4.4.3"
|
|
247
247
|
},
|
|
248
248
|
"peerDependencies": {
|
|
249
|
-
"@open-mercato/ai-assistant": "0.6.6-develop.
|
|
250
|
-
"@open-mercato/shared": "0.6.6-develop.
|
|
251
|
-
"@open-mercato/ui": "0.6.6-develop.
|
|
249
|
+
"@open-mercato/ai-assistant": "0.6.6-develop.6362.1.a3dd164018",
|
|
250
|
+
"@open-mercato/shared": "0.6.6-develop.6362.1.a3dd164018",
|
|
251
|
+
"@open-mercato/ui": "0.6.6-develop.6362.1.a3dd164018",
|
|
252
252
|
"react": "^19.0.0",
|
|
253
253
|
"react-dom": "^19.0.0"
|
|
254
254
|
},
|
|
255
255
|
"devDependencies": {
|
|
256
|
-
"@open-mercato/ai-assistant": "0.6.6-develop.
|
|
257
|
-
"@open-mercato/shared": "0.6.6-develop.
|
|
258
|
-
"@open-mercato/ui": "0.6.6-develop.
|
|
256
|
+
"@open-mercato/ai-assistant": "0.6.6-develop.6362.1.a3dd164018",
|
|
257
|
+
"@open-mercato/shared": "0.6.6-develop.6362.1.a3dd164018",
|
|
258
|
+
"@open-mercato/ui": "0.6.6-develop.6362.1.a3dd164018",
|
|
259
259
|
"@testing-library/dom": "^10.4.1",
|
|
260
260
|
"@testing-library/jest-dom": "^6.9.1",
|
|
261
261
|
"@testing-library/react": "^16.3.1",
|
|
@@ -102,6 +102,7 @@ export default function LoginPage() {
|
|
|
102
102
|
const searchParams = useSearchParams()
|
|
103
103
|
const requireRole = (searchParams.get('requireRole') || searchParams.get('role') || '').trim()
|
|
104
104
|
const requireFeature = (searchParams.get('requireFeature') || '').trim()
|
|
105
|
+
const redirectParam = searchParams.get('redirect') || ''
|
|
105
106
|
const requiredRoles = requireRole ? requireRole.split(',').map((value) => value.trim()).filter(Boolean) : []
|
|
106
107
|
const requiredFeatures = requireFeature ? requireFeature.split(',').map((value) => value.trim()).filter(Boolean) : []
|
|
107
108
|
const translatedRoles = requiredRoles.map((role) => translate(`auth.roles.${role}`, role))
|
|
@@ -148,7 +149,7 @@ export default function LoginPage() {
|
|
|
148
149
|
// producing an infinite loop (see GH #2070). Stay on the login page so
|
|
149
150
|
// the access-denied banner is visible.
|
|
150
151
|
if (hasAclChallenge) return
|
|
151
|
-
const rawRedirect =
|
|
152
|
+
const rawRedirect = redirectParam
|
|
152
153
|
let destination = '/backend'
|
|
153
154
|
if (rawRedirect) {
|
|
154
155
|
try {
|
|
@@ -170,7 +171,7 @@ export default function LoginPage() {
|
|
|
170
171
|
}
|
|
171
172
|
})()
|
|
172
173
|
return () => { cancelled = true }
|
|
173
|
-
}, [router,
|
|
174
|
+
}, [router, redirectParam, requiredFeatures.length, requiredRoles.length])
|
|
174
175
|
|
|
175
176
|
useEffect(() => {
|
|
176
177
|
const tenantParam = (searchParams.get('tenant') || '').trim()
|
|
@@ -698,6 +698,22 @@ export function AdjustmentDialog({
|
|
|
698
698
|
)
|
|
699
699
|
}
|
|
700
700
|
}
|
|
701
|
+
const resolvedKind =
|
|
702
|
+
typeof values.kind === 'string' && values.kind.trim().length ? values.kind.trim() : 'custom'
|
|
703
|
+
if (resolvedKind === 'return') {
|
|
704
|
+
const hasNonZeroValue =
|
|
705
|
+
calculationMode === 'rate'
|
|
706
|
+
? Number.isFinite(percentageRate) && percentageRate !== 0
|
|
707
|
+
: (Number.isFinite(amountNet) && amountNet !== 0) ||
|
|
708
|
+
(Number.isFinite(amountGross) && amountGross !== 0)
|
|
709
|
+
if (!hasNonZeroValue) {
|
|
710
|
+
const message = t(
|
|
711
|
+
'sales.documents.adjustments.errorReturnZero',
|
|
712
|
+
'Return adjustments must use a non-zero amount. Create the return through the Returns tab instead.'
|
|
713
|
+
)
|
|
714
|
+
throw createCrudFormError(message, { amountNet: message })
|
|
715
|
+
}
|
|
716
|
+
}
|
|
701
717
|
const customFields = collectCustomFieldValues(values, {
|
|
702
718
|
transform: (value) => normalizeCustomFieldSubmitValue(value),
|
|
703
719
|
})
|
|
@@ -434,6 +434,8 @@ export const RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE =
|
|
|
434
434
|
'Return adjustments must use a non-positive amountNet (returns reduce the total).'
|
|
435
435
|
export const RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE =
|
|
436
436
|
'Return adjustments must use a non-positive amountGross (returns reduce the total).'
|
|
437
|
+
export const RETURN_ADJUSTMENT_ZERO_MESSAGE =
|
|
438
|
+
'Return adjustments must use a non-zero amount. Create the return through the Returns tab instead of recording a zero-value Return adjustment.'
|
|
437
439
|
export const DISCOUNT_ADJUSTMENT_NEGATIVE_NET_MESSAGE =
|
|
438
440
|
'Discount adjustments must use a non-negative amountNet (discounts reduce the total).'
|
|
439
441
|
export const DISCOUNT_ADJUSTMENT_NEGATIVE_GROSS_MESSAGE =
|
|
@@ -482,20 +484,33 @@ export const enforceAdjustmentSign = (
|
|
|
482
484
|
) => {
|
|
483
485
|
if (!value.kind) return
|
|
484
486
|
if (value.kind === 'return') {
|
|
485
|
-
|
|
487
|
+
const netIsPositive = typeof value.amountNet === 'number' && value.amountNet > 0
|
|
488
|
+
const grossIsPositive = typeof value.amountGross === 'number' && value.amountGross > 0
|
|
489
|
+
if (netIsPositive) {
|
|
486
490
|
ctx.addIssue({
|
|
487
491
|
code: z.ZodIssueCode.custom,
|
|
488
492
|
message: RETURN_ADJUSTMENT_POSITIVE_NET_MESSAGE,
|
|
489
493
|
path: ['amountNet'],
|
|
490
494
|
})
|
|
491
495
|
}
|
|
492
|
-
if (
|
|
496
|
+
if (grossIsPositive) {
|
|
493
497
|
ctx.addIssue({
|
|
494
498
|
code: z.ZodIssueCode.custom,
|
|
495
499
|
message: RETURN_ADJUSTMENT_POSITIVE_GROSS_MESSAGE,
|
|
496
500
|
path: ['amountGross'],
|
|
497
501
|
})
|
|
498
502
|
}
|
|
503
|
+
if (!netIsPositive && !grossIsPositive) {
|
|
504
|
+
const netIsNegative = typeof value.amountNet === 'number' && value.amountNet < 0
|
|
505
|
+
const grossIsNegative = typeof value.amountGross === 'number' && value.amountGross < 0
|
|
506
|
+
if (!netIsNegative && !grossIsNegative) {
|
|
507
|
+
ctx.addIssue({
|
|
508
|
+
code: z.ZodIssueCode.custom,
|
|
509
|
+
message: RETURN_ADJUSTMENT_ZERO_MESSAGE,
|
|
510
|
+
path: ['amountNet'],
|
|
511
|
+
})
|
|
512
|
+
}
|
|
513
|
+
}
|
|
499
514
|
return
|
|
500
515
|
}
|
|
501
516
|
const messages = NON_NEGATIVE_SIGN_MESSAGES[value.kind]
|
|
@@ -463,6 +463,7 @@
|
|
|
463
463
|
"sales.documents.adjustments.errorDelete": "Anpassung konnte nicht gelöscht werden.",
|
|
464
464
|
"sales.documents.adjustments.errorLoad": "Anpassungen konnten nicht geladen werden.",
|
|
465
465
|
"sales.documents.adjustments.errorRate": "Geben Sie einen Prozentsatz ein.",
|
|
466
|
+
"sales.documents.adjustments.errorReturnZero": "Rückgabe-Anpassungen müssen einen Betrag ungleich null verwenden. Erstellen Sie die Rückgabe über den Tab „Rückgaben“, anstatt eine Rückgabe-Anpassung mit dem Wert null zu erfassen.",
|
|
466
467
|
"sales.documents.adjustments.errorSave": "Anpassung konnte nicht gespeichert werden.",
|
|
467
468
|
"sales.documents.adjustments.errorScope": "Organisation und Mandant sind erforderlich.",
|
|
468
469
|
"sales.documents.adjustments.kind": "Typ",
|
|
@@ -463,6 +463,7 @@
|
|
|
463
463
|
"sales.documents.adjustments.errorDelete": "Failed to delete adjustment.",
|
|
464
464
|
"sales.documents.adjustments.errorLoad": "Failed to load adjustments.",
|
|
465
465
|
"sales.documents.adjustments.errorRate": "Enter a percentage rate.",
|
|
466
|
+
"sales.documents.adjustments.errorReturnZero": "Return adjustments must use a non-zero amount. Create the return through the Returns tab instead.",
|
|
466
467
|
"sales.documents.adjustments.errorSave": "Failed to save adjustment.",
|
|
467
468
|
"sales.documents.adjustments.errorScope": "Organization and tenant are required.",
|
|
468
469
|
"sales.documents.adjustments.kind": "Kind",
|
|
@@ -463,6 +463,7 @@
|
|
|
463
463
|
"sales.documents.adjustments.errorDelete": "No se pudo eliminar el ajuste.",
|
|
464
464
|
"sales.documents.adjustments.errorLoad": "No se pudieron cargar los ajustes.",
|
|
465
465
|
"sales.documents.adjustments.errorRate": "Introduce un porcentaje.",
|
|
466
|
+
"sales.documents.adjustments.errorReturnZero": "Los ajustes de devolución deben usar un importe distinto de cero. Crea la devolución desde la pestaña Devoluciones en lugar de registrar un ajuste de devolución con valor cero.",
|
|
466
467
|
"sales.documents.adjustments.errorSave": "No se pudo guardar el ajuste.",
|
|
467
468
|
"sales.documents.adjustments.errorScope": "Se requieren organización y arrendatario.",
|
|
468
469
|
"sales.documents.adjustments.kind": "Tipo",
|
|
@@ -463,6 +463,7 @@
|
|
|
463
463
|
"sales.documents.adjustments.errorDelete": "Nie udało się usunąć korekty.",
|
|
464
464
|
"sales.documents.adjustments.errorLoad": "Nie udało się wczytać korekt.",
|
|
465
465
|
"sales.documents.adjustments.errorRate": "Wprowadź stawkę procentową.",
|
|
466
|
+
"sales.documents.adjustments.errorReturnZero": "Korekty zwrotu muszą mieć kwotę różną od zera. Utwórz zwrot na karcie Zwroty zamiast dodawać korektę zwrotu o wartości zero.",
|
|
466
467
|
"sales.documents.adjustments.errorSave": "Nie udało się zapisać korekty.",
|
|
467
468
|
"sales.documents.adjustments.errorScope": "Wymagane są identyfikatory organizacji i dzierżawcy.",
|
|
468
469
|
"sales.documents.adjustments.kind": "Typ",
|