@lambda-development/erp-core 0.1.29 → 0.1.31
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/i18n/locales/de.json.d.ts +1 -0
- package/dist/i18n/locales/en.json.d.ts +1 -0
- package/dist/i18n/locales/fr.json.d.ts +1 -0
- package/dist/index.js +706 -683
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsx as e, jsxs as r, Fragment as Se } from "react/jsx-runtime";
|
|
2
|
-
import { useState as v, useEffect as
|
|
3
|
-
import { createRoot as
|
|
4
|
-
import { useQueryClient as We, useQuery as le, useMutation as oe, QueryClientProvider as
|
|
5
|
-
import { NavLink as Et, useLocation as Ct, useNavigate as Oe, Outlet as
|
|
6
|
-
import { useTranslation as ae, initReactI18next as
|
|
7
|
-
import { BookOpen as
|
|
2
|
+
import { useState as v, useEffect as se, useCallback as Te, useContext as $n, createContext as Un, useRef as X, useMemo as Ie, useLayoutEffect as cn, StrictMode as ba } from "react";
|
|
3
|
+
import { createRoot as xa } from "react-dom/client";
|
|
4
|
+
import { useQueryClient as We, useQuery as le, useMutation as oe, QueryClientProvider as va, QueryClient as Na } from "@tanstack/react-query";
|
|
5
|
+
import { NavLink as Et, useLocation as Ct, useNavigate as Oe, Outlet as wa, Navigate as ka, Link as Ne, useSearchParams as Ot, useParams as ft, createBrowserRouter as Sa, RouterProvider as Ca } from "react-router-dom";
|
|
6
|
+
import { useTranslation as ae, initReactI18next as Da } from "react-i18next";
|
|
7
|
+
import { BookOpen as _a, ShoppingCart as Vn, CreditCard as Pa, FileText as Zt, Package as jn, BarChart3 as Ta, Database as Aa, Settings as Ra, MessageCircle as Ia, ChevronDown as Xt, ChevronRight as en, Plus as Gn, Trash2 as Kn, LineChart as La, TrendingUp as Ba, ArrowDownRight as Ea, ArrowUpRight as Oa, Wallet as qa, Receipt as dn, Info as Fa } from "lucide-react";
|
|
8
8
|
import { createColumnHelper as Wn, useReactTable as Hn, getCoreRowModel as Qn, flexRender as Rt } from "@tanstack/react-table";
|
|
9
|
-
import { createPortal as
|
|
9
|
+
import { createPortal as Jn } from "react-dom";
|
|
10
10
|
import { ResponsiveContainer as Ma, LineChart as za, CartesianGrid as un, XAxis as mn, YAxis as pn, Tooltip as zt, Line as $a, PieChart as Ua, Pie as Va, Cell as ja, BarChart as Ga, Bar as Ka } from "recharts";
|
|
11
|
-
import
|
|
11
|
+
import Yn from "i18next";
|
|
12
12
|
import { default as wo } from "i18next";
|
|
13
13
|
let yt = "/api";
|
|
14
14
|
function uo(t) {
|
|
@@ -202,17 +202,17 @@ const L = {
|
|
|
202
202
|
getSettings: () => O("/auth/settings"),
|
|
203
203
|
updateSettings: (t) => O("/auth/settings", { method: "PUT", body: JSON.stringify(t) }),
|
|
204
204
|
getDemoSpend: () => O("/admin/demo-spend")
|
|
205
|
-
},
|
|
205
|
+
}, Zn = Un(null);
|
|
206
206
|
function Ha({ children: t }) {
|
|
207
207
|
const [n, a] = v(null), [s, o] = v(!0);
|
|
208
|
-
|
|
209
|
-
L.authMe().then((
|
|
208
|
+
se(() => {
|
|
209
|
+
L.authMe().then((y) => a(y)).catch(() => a(null)).finally(() => o(!1));
|
|
210
210
|
}, []);
|
|
211
|
-
const i = Te(async (
|
|
212
|
-
const p = await L.authLogin(
|
|
211
|
+
const i = Te(async (y, d) => {
|
|
212
|
+
const p = await L.authLogin(y, d);
|
|
213
213
|
return a(p), p;
|
|
214
|
-
}, []), c = Te(async (
|
|
215
|
-
const f = await L.authRegister({ email:
|
|
214
|
+
}, []), c = Te(async (y, d, p, m) => {
|
|
215
|
+
const f = await L.authRegister({ email: y, full_name: d, password: p, invite_token: m });
|
|
216
216
|
return a(f), f;
|
|
217
217
|
}, []), l = Te(async () => {
|
|
218
218
|
try {
|
|
@@ -221,14 +221,14 @@ function Ha({ children: t }) {
|
|
|
221
221
|
}
|
|
222
222
|
a(null);
|
|
223
223
|
}, []);
|
|
224
|
-
return /* @__PURE__ */ e(
|
|
224
|
+
return /* @__PURE__ */ e(Zn.Provider, { value: { user: n, loading: s, login: i, register: c, logout: l }, children: t });
|
|
225
225
|
}
|
|
226
226
|
function bt() {
|
|
227
|
-
const t = $n(
|
|
227
|
+
const t = $n(Zn);
|
|
228
228
|
if (!t) throw new Error("useAuth must be used within AuthProvider");
|
|
229
229
|
return t;
|
|
230
230
|
}
|
|
231
|
-
const
|
|
231
|
+
const Xn = Un(null), hn = {
|
|
232
232
|
quotation: { group: "Selling", item: "Quotation" },
|
|
233
233
|
"sales-order": { group: "Selling", item: "Sales Order" },
|
|
234
234
|
"sales-invoice": { group: "Selling", item: "Sales Invoice" },
|
|
@@ -277,11 +277,11 @@ function yn(t) {
|
|
|
277
277
|
attachments: t.attachments
|
|
278
278
|
};
|
|
279
279
|
}
|
|
280
|
-
const
|
|
280
|
+
const ea = "lambda-erp:known-chat-sessions";
|
|
281
281
|
function tn() {
|
|
282
282
|
if (typeof localStorage > "u") return /* @__PURE__ */ new Set();
|
|
283
283
|
try {
|
|
284
|
-
const t = localStorage.getItem(
|
|
284
|
+
const t = localStorage.getItem(ea);
|
|
285
285
|
if (!t) return /* @__PURE__ */ new Set();
|
|
286
286
|
const n = JSON.parse(t);
|
|
287
287
|
return new Set(Array.isArray(n) ? n.filter((a) => typeof a == "string") : []);
|
|
@@ -289,20 +289,20 @@ function tn() {
|
|
|
289
289
|
return /* @__PURE__ */ new Set();
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
|
-
function
|
|
292
|
+
function ta(t) {
|
|
293
293
|
if (!(typeof localStorage > "u"))
|
|
294
294
|
try {
|
|
295
|
-
localStorage.setItem(
|
|
295
|
+
localStorage.setItem(ea, JSON.stringify([...t]));
|
|
296
296
|
} catch {
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
|
-
function
|
|
299
|
+
function na(t) {
|
|
300
300
|
const n = tn();
|
|
301
|
-
n.has(t) || (n.add(t),
|
|
301
|
+
n.has(t) || (n.add(t), ta(n));
|
|
302
302
|
}
|
|
303
303
|
function fn(t) {
|
|
304
304
|
const n = tn();
|
|
305
|
-
n.delete(t) &&
|
|
305
|
+
n.delete(t) && ta(n);
|
|
306
306
|
}
|
|
307
307
|
function Ja() {
|
|
308
308
|
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `req-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
@@ -313,7 +313,7 @@ function et(t) {
|
|
|
313
313
|
return Number.isNaN(a) ? 0 : a;
|
|
314
314
|
}
|
|
315
315
|
function Ya({ children: t }) {
|
|
316
|
-
const n = We(), [a, s] = v([]), [o, i] = v({}), [c, l] = v({}), [
|
|
316
|
+
const n = We(), [a, s] = v([]), [o, i] = v({}), [c, l] = v({}), [y, d] = v({}), [p, m] = v({}), [f, w] = v({}), [b, g] = v({}), [P, D] = v({}), [T, u] = v(null), [h, A] = v("connecting"), [R, S] = v(0), H = X(null), $ = X(null), z = X(/* @__PURE__ */ new Map()), k = X(null), K = X({}), N = X({}), B = X(null);
|
|
317
317
|
function C(_) {
|
|
318
318
|
for (const V of z.current.values())
|
|
319
319
|
V.reject(new Error(_));
|
|
@@ -326,10 +326,10 @@ function Ya({ children: t }) {
|
|
|
326
326
|
}));
|
|
327
327
|
}
|
|
328
328
|
function Z(_, V) {
|
|
329
|
-
|
|
329
|
+
w((W) => ({ ...W, [_]: V }));
|
|
330
330
|
}
|
|
331
331
|
function re(_, V) {
|
|
332
|
-
|
|
332
|
+
g((W) => ({ ...W, [_]: V }));
|
|
333
333
|
}
|
|
334
334
|
function he(_, V) {
|
|
335
335
|
D((W) => ({ ...W, [_]: V }));
|
|
@@ -382,7 +382,7 @@ function Ya({ children: t }) {
|
|
|
382
382
|
}
|
|
383
383
|
});
|
|
384
384
|
}
|
|
385
|
-
|
|
385
|
+
se(() => {
|
|
386
386
|
let _ = !1;
|
|
387
387
|
function V() {
|
|
388
388
|
if (_) return;
|
|
@@ -393,7 +393,7 @@ function Ya({ children: t }) {
|
|
|
393
393
|
xe.close();
|
|
394
394
|
return;
|
|
395
395
|
}
|
|
396
|
-
A("connected"),
|
|
396
|
+
A("connected"), S((De) => De + 1);
|
|
397
397
|
}, xe.onmessage = (De) => {
|
|
398
398
|
var it;
|
|
399
399
|
try {
|
|
@@ -413,16 +413,16 @@ function Ya({ children: t }) {
|
|
|
413
413
|
Ee.length > 0 && Promise.all(
|
|
414
414
|
Ee.map(async (ve) => {
|
|
415
415
|
try {
|
|
416
|
-
const
|
|
417
|
-
return !
|
|
416
|
+
const ie = await L.getChatSession(ve);
|
|
417
|
+
return !ie || ie.detail || !ie.id ? (fn(ve), null) : ie;
|
|
418
418
|
} catch {
|
|
419
419
|
return null;
|
|
420
420
|
}
|
|
421
421
|
})
|
|
422
422
|
).then((ve) => {
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
...
|
|
423
|
+
const ie = ve.filter((de) => !!de);
|
|
424
|
+
ie.length && (ze(ie), me((de) => [
|
|
425
|
+
...ie.filter((pt) => !de.some((vt) => vt.id === pt.id)),
|
|
426
426
|
...de
|
|
427
427
|
]));
|
|
428
428
|
});
|
|
@@ -431,17 +431,17 @@ function Ya({ children: t }) {
|
|
|
431
431
|
if (ue === "session_created") {
|
|
432
432
|
const q = j.session;
|
|
433
433
|
if (!q) return;
|
|
434
|
-
|
|
434
|
+
na(q.id), ze([q]), me((G) => [q, ...G.filter((Q) => Q.id !== q.id)]);
|
|
435
435
|
return;
|
|
436
436
|
}
|
|
437
437
|
if (ue === "session_deleted" && E) {
|
|
438
438
|
fn(E), me((G) => G.filter((Q) => Q.id !== E)), i((G) => {
|
|
439
439
|
const Q = { ...G };
|
|
440
440
|
return delete Q[E], Q;
|
|
441
|
-
}),
|
|
441
|
+
}), w((G) => {
|
|
442
442
|
const Q = { ...G };
|
|
443
443
|
return delete Q[E], Q;
|
|
444
|
-
}),
|
|
444
|
+
}), g((G) => {
|
|
445
445
|
const Q = { ...G };
|
|
446
446
|
return delete Q[E], Q;
|
|
447
447
|
}), D((G) => {
|
|
@@ -463,23 +463,23 @@ function Ya({ children: t }) {
|
|
|
463
463
|
}
|
|
464
464
|
if (ue === "history_loaded" && E) {
|
|
465
465
|
const q = Array.isArray(j.messages) ? j.messages.map(yn) : [], G = j.before_id != null, Q = !!j.has_more, Ee = typeof j.oldest_id == "number" ? j.oldest_id : null;
|
|
466
|
-
i((
|
|
466
|
+
i((ie) => {
|
|
467
467
|
if (G) {
|
|
468
|
-
const de =
|
|
468
|
+
const de = ie[E] ?? [], pt = new Set(
|
|
469
469
|
de.map((Ze) => Ze.id).filter((Ze) => typeof Ze == "number")
|
|
470
470
|
), vt = q.filter(
|
|
471
471
|
(Ze) => Ze.id === void 0 || !pt.has(Ze.id)
|
|
472
472
|
);
|
|
473
|
-
return { ...
|
|
473
|
+
return { ...ie, [E]: [...vt, ...de] };
|
|
474
474
|
}
|
|
475
|
-
return { ...
|
|
476
|
-
}), l((
|
|
475
|
+
return { ...ie, [E]: q };
|
|
476
|
+
}), l((ie) => ({ ...ie, [E]: Q })), d((ie) => ({ ...ie, [E]: Ee })), m((ie) => ({ ...ie, [E]: !1 }));
|
|
477
477
|
const ve = typeof j.title == "string" ? j.title : null;
|
|
478
478
|
if (ve && me(
|
|
479
|
-
(
|
|
479
|
+
(ie) => ie.map((de) => de.id === E ? { ...de, title: ve } : de)
|
|
480
480
|
), !G) {
|
|
481
|
-
const
|
|
482
|
-
|
|
481
|
+
const ie = q[q.length - 1];
|
|
482
|
+
ie != null && ie.timestamp && (ye(E, ie.timestamp), me((de) => de));
|
|
483
483
|
}
|
|
484
484
|
return;
|
|
485
485
|
}
|
|
@@ -633,12 +633,12 @@ function Ya({ children: t }) {
|
|
|
633
633
|
};
|
|
634
634
|
}, []);
|
|
635
635
|
async function Ae() {
|
|
636
|
-
if (
|
|
637
|
-
return
|
|
636
|
+
if (k.current)
|
|
637
|
+
return k.current;
|
|
638
638
|
const _ = te("create_session", {}, "session_created").then((V) => V.session).finally(() => {
|
|
639
|
-
|
|
639
|
+
k.current === _ && (k.current = null);
|
|
640
640
|
});
|
|
641
|
-
return
|
|
641
|
+
return k.current = _, _;
|
|
642
642
|
}
|
|
643
643
|
async function Ce(_) {
|
|
644
644
|
re(_, "running"), he(_, null);
|
|
@@ -662,7 +662,7 @@ function Ya({ children: t }) {
|
|
|
662
662
|
}
|
|
663
663
|
async function dt(_) {
|
|
664
664
|
if (p[_]) return;
|
|
665
|
-
const V =
|
|
665
|
+
const V = y[_];
|
|
666
666
|
if (V != null && c[_]) {
|
|
667
667
|
m((W) => ({ ...W, [_]: !0 }));
|
|
668
668
|
try {
|
|
@@ -717,13 +717,13 @@ function Ya({ children: t }) {
|
|
|
717
717
|
return _ ? !!p[_] : !1;
|
|
718
718
|
}
|
|
719
719
|
function st(_) {
|
|
720
|
-
return _ ?
|
|
720
|
+
return _ ? b[_] ?? "idle" : "idle";
|
|
721
721
|
}
|
|
722
722
|
function mt(_) {
|
|
723
723
|
return _ ? P[_] ?? null : null;
|
|
724
724
|
}
|
|
725
725
|
return /* @__PURE__ */ e(
|
|
726
|
-
|
|
726
|
+
Xn.Provider,
|
|
727
727
|
{
|
|
728
728
|
value: {
|
|
729
729
|
sessions: a,
|
|
@@ -751,7 +751,7 @@ function Ya({ children: t }) {
|
|
|
751
751
|
);
|
|
752
752
|
}
|
|
753
753
|
function ct() {
|
|
754
|
-
const t = $n(
|
|
754
|
+
const t = $n(Xn);
|
|
755
755
|
if (!t)
|
|
756
756
|
throw new Error("useChat must be used within ChatProvider.");
|
|
757
757
|
return t;
|
|
@@ -759,7 +759,7 @@ function ct() {
|
|
|
759
759
|
const lt = [
|
|
760
760
|
{
|
|
761
761
|
label: "Introduction",
|
|
762
|
-
icon: /* @__PURE__ */ e(
|
|
762
|
+
icon: /* @__PURE__ */ e(_a, { className: "h-4 w-4" }),
|
|
763
763
|
items: [
|
|
764
764
|
{ label: "Getting Started", path: "/tutorial" },
|
|
765
765
|
{ label: "Company Setup", path: "/setup" },
|
|
@@ -779,7 +779,7 @@ const lt = [
|
|
|
779
779
|
},
|
|
780
780
|
{
|
|
781
781
|
label: "Buying",
|
|
782
|
-
icon: /* @__PURE__ */ e(
|
|
782
|
+
icon: /* @__PURE__ */ e(Pa, { className: "h-4 w-4" }),
|
|
783
783
|
items: [
|
|
784
784
|
{ label: "Purchase Order", path: "/app/purchase-order" },
|
|
785
785
|
{ label: "Purchase Invoice", path: "/app/purchase-invoice" }
|
|
@@ -807,7 +807,7 @@ const lt = [
|
|
|
807
807
|
},
|
|
808
808
|
{
|
|
809
809
|
label: "Reports",
|
|
810
|
-
icon: /* @__PURE__ */ e(
|
|
810
|
+
icon: /* @__PURE__ */ e(Ta, { className: "h-4 w-4" }),
|
|
811
811
|
items: [
|
|
812
812
|
{ label: "Trial Balance", path: "/reports/trial-balance" },
|
|
813
813
|
{ label: "Profit & Loss", path: "/reports/profit-and-loss" },
|
|
@@ -821,7 +821,7 @@ const lt = [
|
|
|
821
821
|
},
|
|
822
822
|
{
|
|
823
823
|
label: "Masters",
|
|
824
|
-
icon: /* @__PURE__ */ e(
|
|
824
|
+
icon: /* @__PURE__ */ e(Aa, { className: "h-4 w-4" }),
|
|
825
825
|
items: [
|
|
826
826
|
{ label: "Company", path: "/masters/company" },
|
|
827
827
|
{ label: "Customer", path: "/masters/customer" },
|
|
@@ -832,7 +832,7 @@ const lt = [
|
|
|
832
832
|
},
|
|
833
833
|
{
|
|
834
834
|
label: "Settings",
|
|
835
|
-
icon: /* @__PURE__ */ e(
|
|
835
|
+
icon: /* @__PURE__ */ e(Ra, { className: "h-4 w-4" }),
|
|
836
836
|
items: [
|
|
837
837
|
{ label: "General", path: "/admin/settings" },
|
|
838
838
|
{ label: "Pricing Rule", path: "/app/pricing-rule" },
|
|
@@ -893,17 +893,17 @@ function Me(t, n) {
|
|
|
893
893
|
const a = parseFloat(String(t ?? 0)) || 0;
|
|
894
894
|
return n !== void 0 ? parseFloat(a.toFixed(n)) : a;
|
|
895
895
|
}
|
|
896
|
-
const
|
|
896
|
+
const aa = "sidebar-collapsed";
|
|
897
897
|
function Ut() {
|
|
898
898
|
try {
|
|
899
|
-
const t = localStorage.getItem(
|
|
899
|
+
const t = localStorage.getItem(aa);
|
|
900
900
|
return t ? new Set(JSON.parse(t)) : /* @__PURE__ */ new Set();
|
|
901
901
|
} catch {
|
|
902
902
|
return /* @__PURE__ */ new Set();
|
|
903
903
|
}
|
|
904
904
|
}
|
|
905
905
|
function bn(t) {
|
|
906
|
-
localStorage.setItem(
|
|
906
|
+
localStorage.setItem(aa, JSON.stringify([...t]));
|
|
907
907
|
}
|
|
908
908
|
function nn(t) {
|
|
909
909
|
const [n, a] = v(() => !Ut().has(t)), s = Te(() => {
|
|
@@ -932,7 +932,7 @@ const an = {
|
|
|
932
932
|
"Custom Analytics": "bg-indigo-300 text-indigo-950 ring-2 ring-inset ring-indigo-100"
|
|
933
933
|
};
|
|
934
934
|
function er() {
|
|
935
|
-
const [t, n] = nn("chats"), a = Ct(), s = Oe(), { t: o } = ae(), { sessions: i, createSession: c, deleteSession: l } = ct(),
|
|
935
|
+
const [t, n] = nn("chats"), a = Ct(), s = Oe(), { t: o } = ae(), { sessions: i, createSession: c, deleteSession: l } = ct(), y = async () => {
|
|
936
936
|
try {
|
|
937
937
|
const p = await c();
|
|
938
938
|
s(`/chat/${p.id}`);
|
|
@@ -953,7 +953,7 @@ function er() {
|
|
|
953
953
|
onClick: n,
|
|
954
954
|
className: "flex w-full items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-fg-muted transition-colors hover:text-fg",
|
|
955
955
|
children: [
|
|
956
|
-
/* @__PURE__ */ e(
|
|
956
|
+
/* @__PURE__ */ e(Ia, { className: "h-4 w-4" }),
|
|
957
957
|
/* @__PURE__ */ e("span", { className: "flex-1 text-left", children: o("nav.chats") }),
|
|
958
958
|
t ? /* @__PURE__ */ e(Xt, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ e(en, { className: "h-3.5 w-3.5" })
|
|
959
959
|
]
|
|
@@ -963,7 +963,7 @@ function er() {
|
|
|
963
963
|
/* @__PURE__ */ e("li", { children: /* @__PURE__ */ r(
|
|
964
964
|
"button",
|
|
965
965
|
{
|
|
966
|
-
onClick:
|
|
966
|
+
onClick: y,
|
|
967
967
|
className: "flex w-full items-center gap-2 px-4 py-1.5 pl-10 text-sm text-brand transition-colors hover:bg-brand/5",
|
|
968
968
|
children: [
|
|
969
969
|
/* @__PURE__ */ e(Gn, { className: "h-3.5 w-3.5" }),
|
|
@@ -1010,25 +1010,25 @@ function rn() {
|
|
|
1010
1010
|
);
|
|
1011
1011
|
}
|
|
1012
1012
|
function tr() {
|
|
1013
|
-
const [t, n, a] = nn("custom-analytics"), s = Ct(), o = Oe(), i = We(), { t: c } = ae(), { navigationFlash: l, sessions:
|
|
1013
|
+
const [t, n, a] = nn("custom-analytics"), s = Ct(), o = Oe(), i = We(), { t: c } = ae(), { navigationFlash: l, sessions: y, createSession: d } = ct(), p = (l == null ? void 0 : l.group) === "Custom Analytics", m = an["Custom Analytics"], { data: f } = le({
|
|
1014
1014
|
queryKey: ["runtime-drafts"],
|
|
1015
1015
|
queryFn: () => L.listRuntimeDrafts(),
|
|
1016
1016
|
staleTime: 3e4
|
|
1017
|
-
}),
|
|
1018
|
-
|
|
1017
|
+
}), w = (f == null ? void 0 : f.drafts) ?? [];
|
|
1018
|
+
se(() => {
|
|
1019
1019
|
(l == null ? void 0 : l.group) === "Custom Analytics" && (a(), i.invalidateQueries({ queryKey: ["runtime-drafts"] }));
|
|
1020
1020
|
}, [l == null ? void 0 : l.key, i, a]);
|
|
1021
|
-
const
|
|
1021
|
+
const b = oe({
|
|
1022
1022
|
mutationFn: (D) => L.deleteRuntimeDraft(D),
|
|
1023
1023
|
onSuccess: (D, T) => {
|
|
1024
1024
|
i.invalidateQueries({ queryKey: ["runtime-drafts"] }), s.search.includes(`report_id=${T}`) && o("/reports/analytics");
|
|
1025
1025
|
}
|
|
1026
|
-
}),
|
|
1027
|
-
D.preventDefault(), D.stopPropagation(),
|
|
1026
|
+
}), g = async (D, T) => {
|
|
1027
|
+
D.preventDefault(), D.stopPropagation(), b.mutate(T);
|
|
1028
1028
|
}, P = async () => {
|
|
1029
1029
|
var u;
|
|
1030
1030
|
const D = "Build me a custom analytics report: <describe what you want — e.g. top 10 customers by revenue for the last quarter, or monthly purchases trend by supplier>";
|
|
1031
|
-
let T = ((u =
|
|
1031
|
+
let T = ((u = y[0]) == null ? void 0 : u.id) || "";
|
|
1032
1032
|
if (!T)
|
|
1033
1033
|
try {
|
|
1034
1034
|
T = (await d()).id;
|
|
@@ -1049,7 +1049,7 @@ function tr() {
|
|
|
1049
1049
|
p && m
|
|
1050
1050
|
),
|
|
1051
1051
|
children: [
|
|
1052
|
-
/* @__PURE__ */ e(
|
|
1052
|
+
/* @__PURE__ */ e(La, { className: "h-4 w-4" }),
|
|
1053
1053
|
/* @__PURE__ */ e("span", { className: "flex-1 text-left", children: c("nav.customAnalytics") }),
|
|
1054
1054
|
t ? /* @__PURE__ */ e(Xt, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ e(en, { className: "h-3.5 w-3.5" })
|
|
1055
1055
|
]
|
|
@@ -1067,7 +1067,7 @@ function tr() {
|
|
|
1067
1067
|
]
|
|
1068
1068
|
}
|
|
1069
1069
|
) }),
|
|
1070
|
-
|
|
1070
|
+
w.map((D) => {
|
|
1071
1071
|
const T = `/reports/analytics?report_id=${D.id}`, u = s.pathname === "/reports/analytics" && s.search.includes(`report_id=${D.id}`), h = (l == null ? void 0 : l.group) === "Custom Analytics" && (l == null ? void 0 : l.item) === D.id;
|
|
1072
1072
|
return /* @__PURE__ */ r("li", { className: "group relative", children: [
|
|
1073
1073
|
/* @__PURE__ */ e(
|
|
@@ -1088,7 +1088,7 @@ function tr() {
|
|
|
1088
1088
|
/* @__PURE__ */ e(
|
|
1089
1089
|
"button",
|
|
1090
1090
|
{
|
|
1091
|
-
onClick: (A) =>
|
|
1091
|
+
onClick: (A) => g(A, D.id),
|
|
1092
1092
|
className: "absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-fg-muted opacity-0 transition-opacity hover:text-red-500 group-hover:opacity-100",
|
|
1093
1093
|
title: c("nav.deleteReport"),
|
|
1094
1094
|
children: /* @__PURE__ */ e(Kn, { className: "h-3.5 w-3.5" })
|
|
@@ -1119,14 +1119,14 @@ function nr({ group: t }) {
|
|
|
1119
1119
|
}
|
|
1120
1120
|
),
|
|
1121
1121
|
n && /* @__PURE__ */ e("ul", { className: "mb-1", children: t.items.map((l) => {
|
|
1122
|
-
const
|
|
1122
|
+
const y = t.items.some(
|
|
1123
1123
|
(d) => d.path !== l.path && d.path.startsWith(l.path + "/")
|
|
1124
1124
|
);
|
|
1125
1125
|
return /* @__PURE__ */ e("li", { className: "relative", children: /* @__PURE__ */ e(
|
|
1126
1126
|
Et,
|
|
1127
1127
|
{
|
|
1128
1128
|
to: l.path,
|
|
1129
|
-
end:
|
|
1129
|
+
end: y,
|
|
1130
1130
|
className: ({ isActive: d }) => Le(
|
|
1131
1131
|
"relative block px-4 py-1.5 pl-10 text-sm transition-all duration-300",
|
|
1132
1132
|
!d && "text-fg-muted hover:bg-surface-subtle hover:text-fg",
|
|
@@ -1208,7 +1208,7 @@ function rr({ isMobileOpen: t = !1, onClose: n }) {
|
|
|
1208
1208
|
/* @__PURE__ */ r("nav", { className: "flex-1 overflow-y-auto py-3", children: [
|
|
1209
1209
|
/* @__PURE__ */ e(er, {}),
|
|
1210
1210
|
/* @__PURE__ */ e(tr, {}),
|
|
1211
|
-
c.map((
|
|
1211
|
+
c.map((y) => /* @__PURE__ */ e(nr, { group: y }, y.label))
|
|
1212
1212
|
] })
|
|
1213
1213
|
]
|
|
1214
1214
|
}
|
|
@@ -1239,10 +1239,10 @@ function ir() {
|
|
|
1239
1239
|
}
|
|
1240
1240
|
function or() {
|
|
1241
1241
|
const { pathname: t } = Ct(), { user: n, logout: a } = bt(), { navigationFlash: s } = ct(), { t: o } = ae(), i = sr(t, o), [c, l] = v(!1);
|
|
1242
|
-
|
|
1242
|
+
se(() => {
|
|
1243
1243
|
l(!1);
|
|
1244
1244
|
}, [t]);
|
|
1245
|
-
const
|
|
1245
|
+
const y = s ? an[s.group] : null;
|
|
1246
1246
|
return /* @__PURE__ */ r("div", { className: "flex h-dvh bg-surface-muted", children: [
|
|
1247
1247
|
/* @__PURE__ */ e(rr, { isMobileOpen: c, onClose: () => l(!1) }),
|
|
1248
1248
|
c && /* @__PURE__ */ e(
|
|
@@ -1262,7 +1262,7 @@ function or() {
|
|
|
1262
1262
|
onClick: () => l(!0),
|
|
1263
1263
|
className: Le(
|
|
1264
1264
|
"rounded p-1 text-gray-500 transition-all duration-300 hover:bg-gray-100 hover:text-gray-900 md:hidden",
|
|
1265
|
-
|
|
1265
|
+
y
|
|
1266
1266
|
),
|
|
1267
1267
|
"aria-label": o("header.openMenu"),
|
|
1268
1268
|
children: /* @__PURE__ */ e("svg", { viewBox: "0 0 20 20", fill: "currentColor", width: "22", height: "22", children: /* @__PURE__ */ e("path", { d: "M6.835 4c-.451.004-.82.012-1.137.038-.386.032-.659.085-.876.162l-.2.086c-.44.224-.807.564-1.063.982l-.103.184c-.126.247-.206.562-.248 1.076-.043.523-.043 1.19-.043 2.135v2.664c0 .944 0 1.612.043 2.135.042.515.122.829.248 1.076l.103.184c.256.418.624.758 1.063.982l.2.086c.217.077.49.13.876.162.316.026.685.034 1.136.038zm11.33 7.327c0 .922 0 1.654-.048 2.243-.043.522-.125.977-.305 1.395l-.082.177a4 4 0 0 1-1.473 1.593l-.276.155c-.465.237-.974.338-1.57.387-.59.048-1.322.048-2.244.048H7.833c-.922 0-1.654 0-2.243-.048-.522-.042-.977-.126-1.395-.305l-.176-.082a4 4 0 0 1-1.594-1.473l-.154-.275c-.238-.466-.34-.975-.388-1.572-.048-.589-.048-1.32-.048-2.243V8.663c0-.922 0-1.654.048-2.243.049-.597.15-1.106.388-1.571l.154-.276a4 4 0 0 1 1.594-1.472l.176-.083c.418-.18.873-.263 1.395-.305.589-.048 1.32-.048 2.243-.048h4.334c.922 0 1.654 0 2.243.048.597.049 1.106.15 1.571.388l.276.154a4 4 0 0 1 1.473 1.594l.082.176c.18.418.262.873.305 1.395.048.589.048 1.32.048 2.243zm-10 4.668h4.002c.944 0 1.612 0 2.135-.043.514-.042.829-.122 1.076-.248l.184-.103c.418-.256.758-.624.982-1.063l.086-.2c.077-.217.13-.49.162-.876.043-.523.043-1.19.043-2.135V8.663c0-.944 0-1.612-.043-2.135-.032-.386-.085-.659-.162-.876l-.086-.2a2.67 2.67 0 0 0-.982-1.063l-.184-.103c-.247-.126-.562-.206-1.076-.248-.523-.043-1.19-.043-2.135-.043H8.164L8.165 4z" }) })
|
|
@@ -1285,13 +1285,13 @@ function or() {
|
|
|
1285
1285
|
)
|
|
1286
1286
|
] })
|
|
1287
1287
|
] }),
|
|
1288
|
-
/* @__PURE__ */ e("main", { className: "flex-1 overflow-auto p-4 md:p-6", children: /* @__PURE__ */ e(
|
|
1288
|
+
/* @__PURE__ */ e("main", { className: "flex-1 overflow-auto p-4 md:p-6", children: /* @__PURE__ */ e(wa, {}) })
|
|
1289
1289
|
] })
|
|
1290
1290
|
] });
|
|
1291
1291
|
}
|
|
1292
1292
|
function lr({ children: t }) {
|
|
1293
1293
|
const { user: n, loading: a } = bt();
|
|
1294
|
-
return a ? /* @__PURE__ */ e("div", { className: "flex h-dvh items-center justify-center", children: /* @__PURE__ */ e("div", { className: "text-gray-400", children: "Loading..." }) }) : n ? /* @__PURE__ */ e(Se, { children: t }) : /* @__PURE__ */ e(
|
|
1294
|
+
return a ? /* @__PURE__ */ e("div", { className: "flex h-dvh items-center justify-center", children: /* @__PURE__ */ e("div", { className: "text-gray-400", children: "Loading..." }) }) : n ? /* @__PURE__ */ e(Se, { children: t }) : /* @__PURE__ */ e(ka, { to: "/login", replace: !0 });
|
|
1295
1295
|
}
|
|
1296
1296
|
function U({ title: t, children: n, className: a, interactive: s }) {
|
|
1297
1297
|
return /* @__PURE__ */ r(
|
|
@@ -1392,7 +1392,7 @@ function Pt() {
|
|
|
1392
1392
|
const mr = {
|
|
1393
1393
|
"Sales Invoice": dn,
|
|
1394
1394
|
"Purchase Invoice": dn,
|
|
1395
|
-
"Payment Entry":
|
|
1395
|
+
"Payment Entry": qa,
|
|
1396
1396
|
"Sales Order": Vn,
|
|
1397
1397
|
Quotation: Zt
|
|
1398
1398
|
};
|
|
@@ -1443,7 +1443,7 @@ function hr() {
|
|
|
1443
1443
|
{
|
|
1444
1444
|
title: t("dashboard.totalRevenue"),
|
|
1445
1445
|
value: n == null ? void 0 : n.total_revenue,
|
|
1446
|
-
icon:
|
|
1446
|
+
icon: Ba,
|
|
1447
1447
|
tone: "text-emerald-600 bg-emerald-500/10"
|
|
1448
1448
|
}
|
|
1449
1449
|
),
|
|
@@ -1452,7 +1452,7 @@ function hr() {
|
|
|
1452
1452
|
{
|
|
1453
1453
|
title: t("dashboard.outstandingReceivable"),
|
|
1454
1454
|
value: n == null ? void 0 : n.outstanding_receivable,
|
|
1455
|
-
icon:
|
|
1455
|
+
icon: Ea,
|
|
1456
1456
|
tone: "text-sky-600 bg-sky-500/10"
|
|
1457
1457
|
}
|
|
1458
1458
|
),
|
|
@@ -1461,7 +1461,7 @@ function hr() {
|
|
|
1461
1461
|
{
|
|
1462
1462
|
title: t("dashboard.outstandingPayable"),
|
|
1463
1463
|
value: n == null ? void 0 : n.outstanding_payable,
|
|
1464
|
-
icon:
|
|
1464
|
+
icon: Oa,
|
|
1465
1465
|
tone: "text-amber-600 bg-amber-500/10"
|
|
1466
1466
|
}
|
|
1467
1467
|
),
|
|
@@ -1522,8 +1522,8 @@ function ne(t, n) {
|
|
|
1522
1522
|
const c = Te(
|
|
1523
1523
|
(l) => {
|
|
1524
1524
|
s(
|
|
1525
|
-
(
|
|
1526
|
-
const d = new URLSearchParams(
|
|
1525
|
+
(y) => {
|
|
1526
|
+
const d = new URLSearchParams(y);
|
|
1527
1527
|
return l === n || l === "" || l == null ? d.delete(t) : d.set(t, String(l)), d;
|
|
1528
1528
|
},
|
|
1529
1529
|
{ replace: !0 }
|
|
@@ -2177,7 +2177,7 @@ const at = [
|
|
|
2177
2177
|
conversions: []
|
|
2178
2178
|
}
|
|
2179
2179
|
};
|
|
2180
|
-
function
|
|
2180
|
+
function ra(t) {
|
|
2181
2181
|
return on[t];
|
|
2182
2182
|
}
|
|
2183
2183
|
function go(t) {
|
|
@@ -2230,7 +2230,7 @@ function J({
|
|
|
2230
2230
|
}
|
|
2231
2231
|
);
|
|
2232
2232
|
}
|
|
2233
|
-
function
|
|
2233
|
+
function ee({ label: t, hint: n, error: a, className: s, id: o, ...i }) {
|
|
2234
2234
|
const c = o || (t ? t.toLowerCase().replace(/\s+/g, "-") : void 0);
|
|
2235
2235
|
return /* @__PURE__ */ r("div", { children: [
|
|
2236
2236
|
t && /* @__PURE__ */ e(
|
|
@@ -2309,8 +2309,8 @@ function rt({ label: t, options: n, value: a, onChange: s, className: o, require
|
|
|
2309
2309
|
),
|
|
2310
2310
|
children: [
|
|
2311
2311
|
/* @__PURE__ */ e("option", { value: "", children: "Select..." }),
|
|
2312
|
-
n.map((
|
|
2313
|
-
const { value: d, label: p } = xr(
|
|
2312
|
+
n.map((y) => {
|
|
2313
|
+
const { value: d, label: p } = xr(y);
|
|
2314
2314
|
return /* @__PURE__ */ e("option", { value: d, children: p }, d);
|
|
2315
2315
|
})
|
|
2316
2316
|
]
|
|
@@ -2342,6 +2342,7 @@ function Nr() {
|
|
|
2342
2342
|
const { t } = ae(), [n, a] = v(!1), s = [
|
|
2343
2343
|
["# Heading", t("notesMarkup.heading", { defaultValue: "bold heading" })],
|
|
2344
2344
|
["*italic* **bold**", t("notesMarkup.emphasis", { defaultValue: "italic / bold" })],
|
|
2345
|
+
["---", t("notesMarkup.rule", { defaultValue: "horizontal divider line" })],
|
|
2345
2346
|
[
|
|
2346
2347
|
">> Period | Amount",
|
|
2347
2348
|
t("notesMarkup.price", {
|
|
@@ -2363,7 +2364,7 @@ function Nr() {
|
|
|
2363
2364
|
className: "inline-flex h-4 w-4 items-center justify-center rounded-full text-fg-muted hover:text-fg",
|
|
2364
2365
|
onClick: () => a((o) => !o),
|
|
2365
2366
|
"aria-label": t("notesMarkup.title", { defaultValue: "Formatting help" }),
|
|
2366
|
-
children: /* @__PURE__ */ e(
|
|
2367
|
+
children: /* @__PURE__ */ e(Fa, { className: "h-3.5 w-3.5" })
|
|
2367
2368
|
}
|
|
2368
2369
|
),
|
|
2369
2370
|
n && /* @__PURE__ */ r("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-80 rounded-md bg-gray-900 px-3 py-2.5 text-xs leading-relaxed text-white shadow-lg", children: [
|
|
@@ -2412,40 +2413,62 @@ function Sr({
|
|
|
2412
2413
|
disabled: s,
|
|
2413
2414
|
hideLabel: o
|
|
2414
2415
|
}) {
|
|
2415
|
-
const [i, c] = v(n ?? ""), [l,
|
|
2416
|
+
const [i, c] = v(n ?? ""), [l, y] = v(!1), d = X(null), [p, m] = v(null), { data: f } = le({
|
|
2416
2417
|
queryKey: ["link-search", t.linkDoctype, i],
|
|
2417
2418
|
queryFn: () => L.searchLink(t.linkDoctype, i),
|
|
2418
2419
|
enabled: !!t.linkDoctype && l
|
|
2419
2420
|
});
|
|
2420
|
-
return
|
|
2421
|
+
return se(() => {
|
|
2421
2422
|
c(n ?? "");
|
|
2422
|
-
}, [n]),
|
|
2423
|
+
}, [n]), se(() => {
|
|
2424
|
+
if (!l) return;
|
|
2425
|
+
const w = () => {
|
|
2426
|
+
const b = d.current;
|
|
2427
|
+
if (b) {
|
|
2428
|
+
const g = b.getBoundingClientRect();
|
|
2429
|
+
m({ top: g.bottom, left: g.left, width: g.width });
|
|
2430
|
+
}
|
|
2431
|
+
};
|
|
2432
|
+
return w(), window.addEventListener("scroll", w, !0), window.addEventListener("resize", w), () => {
|
|
2433
|
+
window.removeEventListener("scroll", w, !0), window.removeEventListener("resize", w);
|
|
2434
|
+
};
|
|
2435
|
+
}, [l]), s ? /* @__PURE__ */ r("div", { children: [
|
|
2423
2436
|
!o && /* @__PURE__ */ e("label", { className: "mb-1.5 block text-sm font-medium text-fg", children: t.label }),
|
|
2424
2437
|
/* @__PURE__ */ e("p", { className: "py-2 text-sm text-fg", children: n || "-" })
|
|
2425
|
-
] }) : /* @__PURE__ */ r("div", { className: "relative", children: [
|
|
2438
|
+
] }) : /* @__PURE__ */ r("div", { className: "relative", ref: d, children: [
|
|
2426
2439
|
/* @__PURE__ */ e(
|
|
2427
|
-
|
|
2440
|
+
ee,
|
|
2428
2441
|
{
|
|
2429
2442
|
label: o ? void 0 : t.label,
|
|
2430
2443
|
value: i,
|
|
2431
|
-
onChange: (
|
|
2432
|
-
c(
|
|
2444
|
+
onChange: (w) => {
|
|
2445
|
+
c(w.target.value), y(!0);
|
|
2433
2446
|
},
|
|
2434
|
-
onFocus: () =>
|
|
2435
|
-
onBlur: () => setTimeout(() =>
|
|
2447
|
+
onFocus: () => y(!0),
|
|
2448
|
+
onBlur: () => setTimeout(() => y(!1), 200)
|
|
2436
2449
|
}
|
|
2437
2450
|
),
|
|
2438
|
-
l &&
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2451
|
+
l && f && f.length > 0 && p && Jn(
|
|
2452
|
+
/* @__PURE__ */ e(
|
|
2453
|
+
"ul",
|
|
2454
|
+
{
|
|
2455
|
+
className: "fixed z-50 mt-1 max-h-40 overflow-auto rounded-lg bg-surface ring-1 ring-line shadow-card-hover",
|
|
2456
|
+
style: { top: p.top, left: p.left, width: p.width },
|
|
2457
|
+
children: f.map((w) => /* @__PURE__ */ e(
|
|
2458
|
+
"li",
|
|
2459
|
+
{
|
|
2460
|
+
className: "cursor-pointer px-3 py-2 text-sm text-fg transition-colors hover:bg-surface-subtle",
|
|
2461
|
+
onMouseDown: () => {
|
|
2462
|
+
a(w.name), c(w.name), y(!1);
|
|
2463
|
+
},
|
|
2464
|
+
children: w.name
|
|
2465
|
+
},
|
|
2466
|
+
w.name
|
|
2467
|
+
))
|
|
2468
|
+
}
|
|
2469
|
+
),
|
|
2470
|
+
document.body
|
|
2471
|
+
)
|
|
2449
2472
|
] });
|
|
2450
2473
|
}
|
|
2451
2474
|
function At({
|
|
@@ -2457,11 +2480,11 @@ function At({
|
|
|
2457
2480
|
hideLabel: i,
|
|
2458
2481
|
currency: c = "USD"
|
|
2459
2482
|
}) {
|
|
2460
|
-
var
|
|
2461
|
-
const { t: l } = ae(),
|
|
2462
|
-
if (
|
|
2483
|
+
var w;
|
|
2484
|
+
const { t: l } = ae(), y = s || !!t.readOnly, d = () => i ? null : /* @__PURE__ */ e(vn, { label: l(`fields.${t.label}`, { defaultValue: t.label }), hint: t.hint }), p = t.type === "select" && t.optionsSource === "currency", m = wr(void 0, p);
|
|
2485
|
+
if (y) {
|
|
2463
2486
|
if (t.type === "link" && n) {
|
|
2464
|
-
const
|
|
2487
|
+
const g = t.linkDoctypeField && o ? String(o[t.linkDoctypeField] ?? "").toLowerCase().replace(/\s+/g, "-") : t.linkDoctype, P = Qt(g, String(n));
|
|
2465
2488
|
if (P)
|
|
2466
2489
|
return /* @__PURE__ */ r("div", { children: [
|
|
2467
2490
|
/* @__PURE__ */ e(d, {}),
|
|
@@ -2475,51 +2498,51 @@ function At({
|
|
|
2475
2498
|
) })
|
|
2476
2499
|
] });
|
|
2477
2500
|
}
|
|
2478
|
-
let
|
|
2479
|
-
return t.type === "currency" && typeof n == "number" && (
|
|
2501
|
+
let b = n ?? "-";
|
|
2502
|
+
return t.type === "currency" && typeof n == "number" && (b = qe(n, c)), /* @__PURE__ */ r("div", { children: [
|
|
2480
2503
|
/* @__PURE__ */ e(d, {}),
|
|
2481
|
-
/* @__PURE__ */ e("p", { className: i ? "text-sm text-fg" : "py-2 text-sm text-fg", children:
|
|
2504
|
+
/* @__PURE__ */ e("p", { className: i ? "text-sm text-fg" : "py-2 text-sm text-fg", children: b })
|
|
2482
2505
|
] });
|
|
2483
2506
|
}
|
|
2484
2507
|
if (t.type === "link") {
|
|
2485
|
-
const
|
|
2508
|
+
const b = t.linkDoctypeField && o ? { ...t, linkDoctype: (w = o[t.linkDoctypeField]) == null ? void 0 : w.toLowerCase().replace(/\s+/g, "-") } : t;
|
|
2486
2509
|
return /* @__PURE__ */ r("div", { children: [
|
|
2487
2510
|
/* @__PURE__ */ e(d, {}),
|
|
2488
2511
|
/* @__PURE__ */ e(
|
|
2489
2512
|
Sr,
|
|
2490
2513
|
{
|
|
2491
|
-
field:
|
|
2514
|
+
field: b,
|
|
2492
2515
|
value: n ?? "",
|
|
2493
2516
|
onChange: a,
|
|
2494
|
-
disabled:
|
|
2517
|
+
disabled: y,
|
|
2495
2518
|
hideLabel: !0
|
|
2496
2519
|
}
|
|
2497
2520
|
)
|
|
2498
2521
|
] });
|
|
2499
2522
|
}
|
|
2500
2523
|
if (t.type === "select" && (t.options || p)) {
|
|
2501
|
-
const
|
|
2524
|
+
const b = p ? n && !m.includes(n) ? [n, ...m] : m : t.options;
|
|
2502
2525
|
return /* @__PURE__ */ r("div", { children: [
|
|
2503
2526
|
/* @__PURE__ */ e(d, {}),
|
|
2504
2527
|
/* @__PURE__ */ e(
|
|
2505
2528
|
rt,
|
|
2506
2529
|
{
|
|
2507
|
-
options:
|
|
2530
|
+
options: b,
|
|
2508
2531
|
value: n ?? "",
|
|
2509
|
-
onChange: (
|
|
2532
|
+
onChange: (g) => a(g.target.value)
|
|
2510
2533
|
}
|
|
2511
2534
|
)
|
|
2512
2535
|
] });
|
|
2513
2536
|
}
|
|
2514
2537
|
if (t.type === "textarea") {
|
|
2515
|
-
const
|
|
2538
|
+
const b = t.name === "remarks";
|
|
2516
2539
|
return /* @__PURE__ */ r("div", { children: [
|
|
2517
2540
|
!i && /* @__PURE__ */ e(
|
|
2518
2541
|
vn,
|
|
2519
2542
|
{
|
|
2520
2543
|
label: l(`fields.${t.label}`, { defaultValue: t.label }),
|
|
2521
2544
|
hint: t.hint,
|
|
2522
|
-
extra:
|
|
2545
|
+
extra: b ? /* @__PURE__ */ e(Nr, {}) : void 0
|
|
2523
2546
|
}
|
|
2524
2547
|
),
|
|
2525
2548
|
/* @__PURE__ */ e(
|
|
@@ -2528,7 +2551,7 @@ function At({
|
|
|
2528
2551
|
className: "block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30",
|
|
2529
2552
|
rows: i ? 3 : 7,
|
|
2530
2553
|
value: n ?? "",
|
|
2531
|
-
onChange: (
|
|
2554
|
+
onChange: (g) => a(g.target.value)
|
|
2532
2555
|
}
|
|
2533
2556
|
)
|
|
2534
2557
|
] });
|
|
@@ -2537,13 +2560,13 @@ function At({
|
|
|
2537
2560
|
return /* @__PURE__ */ r("div", { children: [
|
|
2538
2561
|
/* @__PURE__ */ e(d, {}),
|
|
2539
2562
|
/* @__PURE__ */ e(
|
|
2540
|
-
|
|
2563
|
+
ee,
|
|
2541
2564
|
{
|
|
2542
2565
|
type: f,
|
|
2543
2566
|
step: t.type === "currency" ? "0.01" : void 0,
|
|
2544
2567
|
value: n ?? "",
|
|
2545
|
-
onChange: (
|
|
2546
|
-
f === "number" ? parseFloat(
|
|
2568
|
+
onChange: (b) => a(
|
|
2569
|
+
f === "number" ? parseFloat(b.target.value) || 0 : b.target.value
|
|
2547
2570
|
)
|
|
2548
2571
|
}
|
|
2549
2572
|
)
|
|
@@ -2558,7 +2581,7 @@ function Cr({
|
|
|
2558
2581
|
}) {
|
|
2559
2582
|
const { t: i } = ae(), c = (d, p, m) => {
|
|
2560
2583
|
const f = n.map(
|
|
2561
|
-
(
|
|
2584
|
+
(w, b) => b === d ? { ...w, [p]: m } : w
|
|
2562
2585
|
);
|
|
2563
2586
|
a(f);
|
|
2564
2587
|
}, l = () => {
|
|
@@ -2566,7 +2589,7 @@ function Cr({
|
|
|
2566
2589
|
t.fields.forEach((p) => {
|
|
2567
2590
|
d[p.name] = p.default ?? (p.type === "number" || p.type === "currency" ? 0 : "");
|
|
2568
2591
|
}), a([...n, d]);
|
|
2569
|
-
},
|
|
2592
|
+
}, y = (d) => {
|
|
2570
2593
|
a(n.filter((p, m) => m !== d));
|
|
2571
2594
|
};
|
|
2572
2595
|
return /* @__PURE__ */ r(U, { title: i(`tables.${t.key}`, { defaultValue: t.label }), children: [
|
|
@@ -2602,7 +2625,7 @@ function Cr({
|
|
|
2602
2625
|
{
|
|
2603
2626
|
variant: "ghost",
|
|
2604
2627
|
size: "sm",
|
|
2605
|
-
onClick: () =>
|
|
2628
|
+
onClick: () => y(p),
|
|
2606
2629
|
children: "Remove"
|
|
2607
2630
|
}
|
|
2608
2631
|
) })
|
|
@@ -2620,19 +2643,19 @@ function Dr({
|
|
|
2620
2643
|
saving: i,
|
|
2621
2644
|
config: c,
|
|
2622
2645
|
onSave: l,
|
|
2623
|
-
onSubmit:
|
|
2646
|
+
onSubmit: y,
|
|
2624
2647
|
onCancel: d,
|
|
2625
2648
|
onConvert: p,
|
|
2626
2649
|
onDiscard: m
|
|
2627
2650
|
}) {
|
|
2628
|
-
const { t: f } = ae(), [
|
|
2651
|
+
const { t: f } = ae(), [w, b] = v(!1), [g, P] = v(!1);
|
|
2629
2652
|
if (!c) return null;
|
|
2630
2653
|
const D = !t && n && a ? `/api/documents/${n}/${encodeURIComponent(a)}/pdf` : null, T = !t && c.canCancel && s === 1;
|
|
2631
2654
|
return /* @__PURE__ */ r("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2632
2655
|
D && /* @__PURE__ */ e(J, { variant: "secondary", onClick: () => window.open(D, "_blank"), children: f("common.pdf") }),
|
|
2633
2656
|
s < 1 && !o && /* @__PURE__ */ e(J, { onClick: l, disabled: i, children: f(i ? "common.saving" : "common.save") }),
|
|
2634
|
-
!t && c.canSubmit && s === 0 && !o && /* @__PURE__ */ e(J, { variant: "secondary", onClick:
|
|
2635
|
-
!t && c.canSubmit && s === 0 && !o && (
|
|
2657
|
+
!t && c.canSubmit && s === 0 && !o && /* @__PURE__ */ e(J, { variant: "secondary", onClick: y, children: f("common.submit") }),
|
|
2658
|
+
!t && c.canSubmit && s === 0 && !o && (g ? /* @__PURE__ */ r(Se, { children: [
|
|
2636
2659
|
/* @__PURE__ */ e(J, { variant: "secondary", onClick: () => P(!1), children: f("common.keepDraft") }),
|
|
2637
2660
|
/* @__PURE__ */ e(
|
|
2638
2661
|
J,
|
|
@@ -2645,8 +2668,8 @@ function Dr({
|
|
|
2645
2668
|
}
|
|
2646
2669
|
)
|
|
2647
2670
|
] }) : /* @__PURE__ */ e(J, { variant: "ghost", onClick: () => P(!0), children: f("common.discardDraft") })),
|
|
2648
|
-
T && (
|
|
2649
|
-
!t && s === 1 && !
|
|
2671
|
+
T && (w ? /* @__PURE__ */ e(J, { variant: "secondary", onClick: () => b(!1), children: f("common.cancelDocAbort") }) : /* @__PURE__ */ e(J, { variant: "danger", onClick: () => b(!0), children: f("common.cancelDoc") })),
|
|
2672
|
+
!t && s === 1 && !w && c.conversions.map((u) => /* @__PURE__ */ e(
|
|
2650
2673
|
J,
|
|
2651
2674
|
{
|
|
2652
2675
|
variant: "secondary",
|
|
@@ -2655,13 +2678,13 @@ function Dr({
|
|
|
2655
2678
|
},
|
|
2656
2679
|
u.targetDoctype
|
|
2657
2680
|
)),
|
|
2658
|
-
T &&
|
|
2681
|
+
T && w && /* @__PURE__ */ e(
|
|
2659
2682
|
J,
|
|
2660
2683
|
{
|
|
2661
2684
|
variant: "danger",
|
|
2662
2685
|
className: "ml-auto",
|
|
2663
2686
|
onClick: () => {
|
|
2664
|
-
|
|
2687
|
+
b(!1), d();
|
|
2665
2688
|
},
|
|
2666
2689
|
children: f("common.cancelDocConfirmBtn")
|
|
2667
2690
|
}
|
|
@@ -2692,45 +2715,45 @@ function Nn(t, n) {
|
|
|
2692
2715
|
}
|
|
2693
2716
|
function wn() {
|
|
2694
2717
|
var ze;
|
|
2695
|
-
const { doctype: t, name: n } = ft(), a = Oe(), s = We(), { t: o } = ae(), i =
|
|
2718
|
+
const { doctype: t, name: n } = ft(), a = Oe(), s = We(), { t: o } = ae(), i = ra(t ?? ""), c = !n, [l, y] = v({}), [d, p] = v(!1), { data: m, isLoading: f } = le({
|
|
2696
2719
|
queryKey: ["document", t, n],
|
|
2697
2720
|
queryFn: () => L.getDocument(t, n),
|
|
2698
2721
|
enabled: !!t && !!n && !c
|
|
2699
|
-
}),
|
|
2722
|
+
}), w = Ie(
|
|
2700
2723
|
() => !!(i != null && i.fields.some((I) => I.name === "currency")),
|
|
2701
2724
|
[i]
|
|
2702
|
-
),
|
|
2703
|
-
queryKey: ["master",
|
|
2704
|
-
queryFn: () => L.getMaster(
|
|
2705
|
-
enabled: c &&
|
|
2725
|
+
), b = i == null ? void 0 : i.partyField, g = b ? l[b] : void 0, P = He(l.company), { data: D } = le({
|
|
2726
|
+
queryKey: ["master", b, g],
|
|
2727
|
+
queryFn: () => L.getMaster(b, g),
|
|
2728
|
+
enabled: c && w && !!b && !!g,
|
|
2706
2729
|
staleTime: 300 * 1e3
|
|
2707
2730
|
});
|
|
2708
|
-
|
|
2709
|
-
if (!c || !
|
|
2731
|
+
se(() => {
|
|
2732
|
+
if (!c || !w || d) return;
|
|
2710
2733
|
let I;
|
|
2711
|
-
if (
|
|
2734
|
+
if (g) {
|
|
2712
2735
|
if (!D) return;
|
|
2713
2736
|
I = D.default_currency || P;
|
|
2714
2737
|
} else
|
|
2715
2738
|
I = P;
|
|
2716
|
-
I && I !== l.currency &&
|
|
2739
|
+
I && I !== l.currency && y((te) => ({ ...te, currency: I }));
|
|
2717
2740
|
}, [
|
|
2718
2741
|
c,
|
|
2719
|
-
|
|
2742
|
+
w,
|
|
2720
2743
|
d,
|
|
2721
|
-
|
|
2744
|
+
g,
|
|
2722
2745
|
D,
|
|
2723
2746
|
P,
|
|
2724
2747
|
l.currency
|
|
2725
|
-
]),
|
|
2748
|
+
]), se(() => {
|
|
2726
2749
|
if (c && i) {
|
|
2727
2750
|
const I = {};
|
|
2728
2751
|
i.fields.forEach((te) => {
|
|
2729
2752
|
te.type === "date" ? I[te.name] = (/* @__PURE__ */ new Date()).toISOString().split("T")[0] : I[te.name] = te.default ?? "";
|
|
2730
2753
|
}), i.childTables.forEach((te) => {
|
|
2731
2754
|
I[te.key] = [];
|
|
2732
|
-
}), I.docstatus = 0,
|
|
2733
|
-
} else m &&
|
|
2755
|
+
}), I.docstatus = 0, y(I);
|
|
2756
|
+
} else m && y(m);
|
|
2734
2757
|
}, [c, m, i]);
|
|
2735
2758
|
const T = oe({
|
|
2736
2759
|
mutationFn: (I) => L.createDocument(t, I),
|
|
@@ -2740,24 +2763,24 @@ function wn() {
|
|
|
2740
2763
|
}), u = oe({
|
|
2741
2764
|
mutationFn: (I) => L.updateDocument(t, n, I),
|
|
2742
2765
|
onSuccess: (I) => {
|
|
2743
|
-
s.invalidateQueries({ queryKey: ["document", t, n] }), s.invalidateQueries({ queryKey: ["documents", t] }),
|
|
2766
|
+
s.invalidateQueries({ queryKey: ["document", t, n] }), s.invalidateQueries({ queryKey: ["documents", t] }), y(I);
|
|
2744
2767
|
}
|
|
2745
2768
|
}), h = oe({
|
|
2746
2769
|
mutationFn: () => L.submitDocument(t, n),
|
|
2747
2770
|
onSuccess: (I) => {
|
|
2748
|
-
|
|
2771
|
+
y(I), s.invalidateQueries({ queryKey: ["document", t, n] }), s.invalidateQueries({ queryKey: ["documents", t] });
|
|
2749
2772
|
}
|
|
2750
2773
|
}), A = oe({
|
|
2751
2774
|
mutationFn: () => L.cancelDocument(t, n),
|
|
2752
2775
|
onSuccess: (I) => {
|
|
2753
|
-
|
|
2776
|
+
y(I), s.invalidateQueries({ queryKey: ["document", t, n] }), s.invalidateQueries({ queryKey: ["documents", t] });
|
|
2754
2777
|
}
|
|
2755
2778
|
}), R = oe({
|
|
2756
2779
|
mutationFn: () => L.discardDocument(t, n),
|
|
2757
2780
|
onSuccess: () => {
|
|
2758
2781
|
s.invalidateQueries({ queryKey: ["documents", t] }), a(`/app/${t}`, { replace: !0 });
|
|
2759
2782
|
}
|
|
2760
|
-
}),
|
|
2783
|
+
}), S = oe({
|
|
2761
2784
|
mutationFn: (I) => L.convertDocument(t, n, I),
|
|
2762
2785
|
onSuccess: (I, te) => {
|
|
2763
2786
|
const Ae = te.toLowerCase().replace(/\s+/g, "-");
|
|
@@ -2765,7 +2788,7 @@ function wn() {
|
|
|
2765
2788
|
}
|
|
2766
2789
|
}), H = Te(
|
|
2767
2790
|
(I, te) => {
|
|
2768
|
-
I === "currency" && p(!0),
|
|
2791
|
+
I === "currency" && p(!0), y((Ae) => {
|
|
2769
2792
|
const Ce = { ...Ae, [I]: te };
|
|
2770
2793
|
return I === "currency" && (Ce.conversion_rate = 0), Nn(Ce, i);
|
|
2771
2794
|
});
|
|
@@ -2773,7 +2796,7 @@ function wn() {
|
|
|
2773
2796
|
[i]
|
|
2774
2797
|
), $ = Te(
|
|
2775
2798
|
(I, te) => {
|
|
2776
|
-
|
|
2799
|
+
y((Ae) => {
|
|
2777
2800
|
const Ce = { ...Ae, [I]: te };
|
|
2778
2801
|
return Nn(Ce, i);
|
|
2779
2802
|
});
|
|
@@ -2781,12 +2804,12 @@ function wn() {
|
|
|
2781
2804
|
[i]
|
|
2782
2805
|
), z = () => {
|
|
2783
2806
|
c ? T.mutate(l) : u.mutate(l);
|
|
2784
|
-
},
|
|
2807
|
+
}, k = () => {
|
|
2785
2808
|
h.mutate();
|
|
2786
2809
|
}, K = () => {
|
|
2787
2810
|
A.mutate();
|
|
2788
2811
|
}, N = (I) => {
|
|
2789
|
-
|
|
2812
|
+
S.mutate(I);
|
|
2790
2813
|
}, B = () => {
|
|
2791
2814
|
R.mutate();
|
|
2792
2815
|
};
|
|
@@ -2828,7 +2851,7 @@ function wn() {
|
|
|
2828
2851
|
config: i,
|
|
2829
2852
|
discarded: F,
|
|
2830
2853
|
onSave: z,
|
|
2831
|
-
onSubmit:
|
|
2854
|
+
onSubmit: k,
|
|
2832
2855
|
onCancel: K,
|
|
2833
2856
|
onConvert: N,
|
|
2834
2857
|
onDiscard: B
|
|
@@ -2890,12 +2913,12 @@ function wn() {
|
|
|
2890
2913
|
function fe(t) {
|
|
2891
2914
|
return t.toISOString().split("T")[0];
|
|
2892
2915
|
}
|
|
2893
|
-
function
|
|
2916
|
+
function sa(t) {
|
|
2894
2917
|
const n = new Date(t), a = n.getDay(), s = a === 0 ? 6 : a - 1;
|
|
2895
2918
|
return n.setDate(n.getDate() - s), n;
|
|
2896
2919
|
}
|
|
2897
2920
|
function _r(t) {
|
|
2898
|
-
const n =
|
|
2921
|
+
const n = sa(t);
|
|
2899
2922
|
return n.setDate(n.getDate() + 6), n;
|
|
2900
2923
|
}
|
|
2901
2924
|
function kn(t) {
|
|
@@ -2928,7 +2951,7 @@ const Pr = [
|
|
|
2928
2951
|
},
|
|
2929
2952
|
{
|
|
2930
2953
|
label: "This Week",
|
|
2931
|
-
range: () => [fe(
|
|
2954
|
+
range: () => [fe(sa(/* @__PURE__ */ new Date())), fe(_r(/* @__PURE__ */ new Date()))]
|
|
2932
2955
|
},
|
|
2933
2956
|
{
|
|
2934
2957
|
label: "This Month",
|
|
@@ -3032,18 +3055,18 @@ function Ir(t) {
|
|
|
3032
3055
|
}
|
|
3033
3056
|
const Lr = ["25", "50", "100", "200"];
|
|
3034
3057
|
function Br() {
|
|
3035
|
-
const { t } = ae(), { doctype: n } = ft(), a =
|
|
3036
|
-
const
|
|
3037
|
-
return s !== "All" && (
|
|
3038
|
-
}, [s, o, i, c, l, d]), { data: T, isLoading: u } = gr(n ?? "", D), h = (T == null ? void 0 : T.rows) ?? [], A = (T == null ? void 0 : T.total) ?? 0, R = Math.max(1, Math.ceil(A / l)),
|
|
3058
|
+
const { t } = ae(), { doctype: n } = ft(), a = ra(n ?? ""), [s] = ne("status", "All"), [o] = ne("from", ""), [i] = ne("to", ""), [c] = ne("discarded", ""), [l] = ne("per_page", 50), [y] = ne("page", 1), d = y - 1, p = Qe(), m = (k) => p({ page: k === 0 ? null : k + 1 }), f = (k) => p({ status: k === "All" ? null : k, page: null }), w = (k) => p({ from: k || null, page: null }), b = (k) => p({ to: k || null, page: null }), g = (k) => p({ discarded: k ? "1" : null, page: null }), P = (k) => p({ per_page: k, page: null }), D = Ie(() => {
|
|
3059
|
+
const k = {};
|
|
3060
|
+
return s !== "All" && (k.status = s), o && (k.from_date = o), i && (k.to_date = i), c && (k.include_discarded = "true"), k.limit = l, k.offset = d * l, k;
|
|
3061
|
+
}, [s, o, i, c, l, d]), { data: T, isLoading: u } = gr(n ?? "", D), h = (T == null ? void 0 : T.rows) ?? [], A = (T == null ? void 0 : T.total) ?? 0, R = Math.max(1, Math.ceil(A / l)), S = A === 0 ? 0 : d * l + 1, H = Math.min(A, (d + 1) * l), $ = Ie(() => {
|
|
3039
3062
|
if (!a) return [];
|
|
3040
|
-
const
|
|
3063
|
+
const k = Wn(), K = (N) => {
|
|
3041
3064
|
const B = N.split("_").map((C) => C.charAt(0).toUpperCase() + C.slice(1)).join(" ");
|
|
3042
3065
|
return t(`fields.${B}`, { defaultValue: B });
|
|
3043
3066
|
};
|
|
3044
3067
|
return a.listColumns.map((N) => {
|
|
3045
3068
|
if (N === "name")
|
|
3046
|
-
return
|
|
3069
|
+
return k.accessor("name", {
|
|
3047
3070
|
header: t("fields.Name", { defaultValue: "Name" }),
|
|
3048
3071
|
cell: (B) => /* @__PURE__ */ e(
|
|
3049
3072
|
Ne,
|
|
@@ -3055,12 +3078,12 @@ function Br() {
|
|
|
3055
3078
|
)
|
|
3056
3079
|
});
|
|
3057
3080
|
if (N === "status")
|
|
3058
|
-
return
|
|
3081
|
+
return k.accessor("status", {
|
|
3059
3082
|
header: t("fields.Status", { defaultValue: "Status" }),
|
|
3060
3083
|
cell: (B) => /* @__PURE__ */ e(sn, { status: B.getValue() })
|
|
3061
3084
|
});
|
|
3062
3085
|
if (Ar.has(N))
|
|
3063
|
-
return
|
|
3086
|
+
return k.accessor(N, {
|
|
3064
3087
|
header: K(N),
|
|
3065
3088
|
cell: (B) => {
|
|
3066
3089
|
var C;
|
|
@@ -3068,7 +3091,7 @@ function Br() {
|
|
|
3068
3091
|
}
|
|
3069
3092
|
});
|
|
3070
3093
|
if (N === "party")
|
|
3071
|
-
return
|
|
3094
|
+
return k.accessor("party", {
|
|
3072
3095
|
header: t("fields.Party", { defaultValue: "Party" }),
|
|
3073
3096
|
cell: (B) => {
|
|
3074
3097
|
const C = B.getValue();
|
|
@@ -3087,7 +3110,7 @@ function Br() {
|
|
|
3087
3110
|
});
|
|
3088
3111
|
if (Cn[N]) {
|
|
3089
3112
|
const B = Cn[N];
|
|
3090
|
-
return
|
|
3113
|
+
return k.accessor(N, {
|
|
3091
3114
|
header: K(N),
|
|
3092
3115
|
cell: (C) => {
|
|
3093
3116
|
const F = C.getValue();
|
|
@@ -3105,10 +3128,10 @@ function Br() {
|
|
|
3105
3128
|
}
|
|
3106
3129
|
});
|
|
3107
3130
|
}
|
|
3108
|
-
return Rr.has(N) ?
|
|
3131
|
+
return Rr.has(N) ? k.accessor(N, {
|
|
3109
3132
|
header: K(N),
|
|
3110
3133
|
cell: (B) => qt(B.getValue())
|
|
3111
|
-
}) :
|
|
3134
|
+
}) : k.accessor(N, {
|
|
3112
3135
|
header: K(N)
|
|
3113
3136
|
});
|
|
3114
3137
|
});
|
|
@@ -3124,30 +3147,30 @@ function Br() {
|
|
|
3124
3147
|
rt,
|
|
3125
3148
|
{
|
|
3126
3149
|
label: t("fields.Status", { defaultValue: "Status" }),
|
|
3127
|
-
options: Tr.map((
|
|
3128
|
-
value:
|
|
3129
|
-
label:
|
|
3150
|
+
options: Tr.map((k) => ({
|
|
3151
|
+
value: k,
|
|
3152
|
+
label: k === "All" ? t("common.all") : t(`status.${k}`, { defaultValue: k })
|
|
3130
3153
|
})),
|
|
3131
3154
|
value: s,
|
|
3132
|
-
onChange: (
|
|
3155
|
+
onChange: (k) => f(k.target.value)
|
|
3133
3156
|
}
|
|
3134
3157
|
),
|
|
3135
3158
|
/* @__PURE__ */ e(
|
|
3136
|
-
|
|
3159
|
+
ee,
|
|
3137
3160
|
{
|
|
3138
3161
|
label: t("fields.From Date", { defaultValue: "From Date" }),
|
|
3139
3162
|
type: "date",
|
|
3140
3163
|
value: o,
|
|
3141
|
-
onChange: (
|
|
3164
|
+
onChange: (k) => w(k.target.value)
|
|
3142
3165
|
}
|
|
3143
3166
|
),
|
|
3144
3167
|
/* @__PURE__ */ e(
|
|
3145
|
-
|
|
3168
|
+
ee,
|
|
3146
3169
|
{
|
|
3147
3170
|
label: t("fields.To Date", { defaultValue: "To Date" }),
|
|
3148
3171
|
type: "date",
|
|
3149
3172
|
value: i,
|
|
3150
|
-
onChange: (
|
|
3173
|
+
onChange: (k) => b(k.target.value)
|
|
3151
3174
|
}
|
|
3152
3175
|
),
|
|
3153
3176
|
/* @__PURE__ */ r("label", { className: "flex h-10 items-center gap-2 text-sm text-fg-muted", children: [
|
|
@@ -3157,16 +3180,16 @@ function Br() {
|
|
|
3157
3180
|
type: "checkbox",
|
|
3158
3181
|
className: "h-4 w-4 rounded border-line text-brand focus:ring-brand/30",
|
|
3159
3182
|
checked: !!c,
|
|
3160
|
-
onChange: (
|
|
3183
|
+
onChange: (k) => g(k.target.checked)
|
|
3161
3184
|
}
|
|
3162
3185
|
),
|
|
3163
3186
|
t("common.showDiscarded")
|
|
3164
3187
|
] })
|
|
3165
3188
|
] }),
|
|
3166
|
-
/* @__PURE__ */ e(Ft, { onSelect: (
|
|
3189
|
+
/* @__PURE__ */ e(Ft, { onSelect: (k, K) => p({ from: k, to: K, page: null }) }),
|
|
3167
3190
|
u ? /* @__PURE__ */ e("p", { className: "text-fg-muted", children: t("common.loading") }) : h.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-fg-muted", children: t("reports.noDocuments") }) : /* @__PURE__ */ r(Se, { children: [
|
|
3168
3191
|
/* @__PURE__ */ e("div", { className: "overflow-x-auto rounded-xl bg-surface ring-1 ring-line shadow-card", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-line text-sm", children: [
|
|
3169
|
-
/* @__PURE__ */ e("thead", { className: "bg-surface-subtle", children: z.getHeaderGroups().map((
|
|
3192
|
+
/* @__PURE__ */ e("thead", { className: "bg-surface-subtle", children: z.getHeaderGroups().map((k) => /* @__PURE__ */ e("tr", { children: k.headers.map((K) => /* @__PURE__ */ e(
|
|
3170
3193
|
"th",
|
|
3171
3194
|
{
|
|
3172
3195
|
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted",
|
|
@@ -3176,18 +3199,18 @@ function Br() {
|
|
|
3176
3199
|
)
|
|
3177
3200
|
},
|
|
3178
3201
|
K.id
|
|
3179
|
-
)) },
|
|
3180
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-line", children: z.getRowModel().rows.map((
|
|
3202
|
+
)) }, k.id)) }),
|
|
3203
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-line", children: z.getRowModel().rows.map((k) => /* @__PURE__ */ e("tr", { className: "transition-colors hover:bg-surface-subtle", children: k.getVisibleCells().map((K) => /* @__PURE__ */ e("td", { className: "px-4 py-2.5 text-fg", children: Rt(
|
|
3181
3204
|
K.column.columnDef.cell,
|
|
3182
3205
|
K.getContext()
|
|
3183
|
-
) }, K.id)) },
|
|
3206
|
+
) }, K.id)) }, k.id)) })
|
|
3184
3207
|
] }) }),
|
|
3185
3208
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-center justify-between gap-3 text-sm text-fg-muted", children: [
|
|
3186
3209
|
/* @__PURE__ */ r("div", { children: [
|
|
3187
3210
|
t("common.showing"),
|
|
3188
3211
|
" ",
|
|
3189
3212
|
/* @__PURE__ */ r("span", { className: "font-medium text-fg", children: [
|
|
3190
|
-
|
|
3213
|
+
S,
|
|
3191
3214
|
"–",
|
|
3192
3215
|
H
|
|
3193
3216
|
] }),
|
|
@@ -3203,9 +3226,9 @@ function Br() {
|
|
|
3203
3226
|
"select",
|
|
3204
3227
|
{
|
|
3205
3228
|
value: l,
|
|
3206
|
-
onChange: (
|
|
3229
|
+
onChange: (k) => P(Number(k.target.value)),
|
|
3207
3230
|
className: "h-8 rounded-md bg-surface px-2 text-sm text-fg ring-1 ring-line transition-all focus:outline-none focus:ring-2 focus:ring-brand/30",
|
|
3208
|
-
children: Lr.map((
|
|
3231
|
+
children: Lr.map((k) => /* @__PURE__ */ e("option", { value: k, children: k }, k))
|
|
3209
3232
|
}
|
|
3210
3233
|
)
|
|
3211
3234
|
] }),
|
|
@@ -3251,14 +3274,14 @@ function ke({
|
|
|
3251
3274
|
linkDoctype: s,
|
|
3252
3275
|
readOnly: o
|
|
3253
3276
|
}) {
|
|
3254
|
-
const [i, c] = v(n ?? ""), [l,
|
|
3255
|
-
|
|
3277
|
+
const [i, c] = v(n ?? ""), [l, y] = v([]), [d, p] = v(!1), [m, f] = v(!1), [w, b] = v({}), g = X(null), P = X(null), D = X(null), T = X(null), u = X(!1);
|
|
3278
|
+
se(() => {
|
|
3256
3279
|
c(n ?? "");
|
|
3257
3280
|
}, [n]);
|
|
3258
3281
|
const h = Te(() => {
|
|
3259
3282
|
if (T.current) {
|
|
3260
3283
|
const $ = T.current.getBoundingClientRect();
|
|
3261
|
-
|
|
3284
|
+
b({
|
|
3262
3285
|
position: "fixed",
|
|
3263
3286
|
top: $.bottom + 4,
|
|
3264
3287
|
left: $.left,
|
|
@@ -3268,13 +3291,13 @@ function ke({
|
|
|
3268
3291
|
}
|
|
3269
3292
|
}, []), A = Te(
|
|
3270
3293
|
($) => {
|
|
3271
|
-
|
|
3294
|
+
g.current && clearTimeout(g.current), g.current = setTimeout(async () => {
|
|
3272
3295
|
f(!0);
|
|
3273
3296
|
try {
|
|
3274
3297
|
const z = await L.searchLink(s, $);
|
|
3275
|
-
|
|
3298
|
+
y(z), p(!0);
|
|
3276
3299
|
} catch {
|
|
3277
|
-
|
|
3300
|
+
y([]);
|
|
3278
3301
|
} finally {
|
|
3279
3302
|
f(!1);
|
|
3280
3303
|
}
|
|
@@ -3284,9 +3307,9 @@ function ke({
|
|
|
3284
3307
|
), R = ($) => {
|
|
3285
3308
|
const z = $.target.value;
|
|
3286
3309
|
c(z), A(z);
|
|
3287
|
-
},
|
|
3310
|
+
}, S = ($) => {
|
|
3288
3311
|
const z = $.name ?? $.id ?? String($);
|
|
3289
|
-
c(z), a(z), p(!1),
|
|
3312
|
+
c(z), a(z), p(!1), y([]);
|
|
3290
3313
|
}, H = () => {
|
|
3291
3314
|
setTimeout(() => {
|
|
3292
3315
|
if (u.current) {
|
|
@@ -3296,11 +3319,11 @@ function ke({
|
|
|
3296
3319
|
p(!1), i !== n && a(i);
|
|
3297
3320
|
}, 150);
|
|
3298
3321
|
};
|
|
3299
|
-
return
|
|
3322
|
+
return se(() => {
|
|
3300
3323
|
const $ = (z) => {
|
|
3301
3324
|
var K, N;
|
|
3302
|
-
const
|
|
3303
|
-
(K = P.current) != null && K.contains(
|
|
3325
|
+
const k = z.target;
|
|
3326
|
+
(K = P.current) != null && K.contains(k) || (N = D.current) != null && N.contains(k) || p(!1);
|
|
3304
3327
|
};
|
|
3305
3328
|
return document.addEventListener("mousedown", $), () => document.removeEventListener("mousedown", $);
|
|
3306
3329
|
}, []), o ? /* @__PURE__ */ r("div", { children: [
|
|
@@ -3326,9 +3349,9 @@ function ke({
|
|
|
3326
3349
|
)
|
|
3327
3350
|
}
|
|
3328
3351
|
),
|
|
3329
|
-
d && l.length > 0 &&
|
|
3330
|
-
/* @__PURE__ */ e("div", { ref: D, style:
|
|
3331
|
-
const
|
|
3352
|
+
d && l.length > 0 && Jn(
|
|
3353
|
+
/* @__PURE__ */ e("div", { ref: D, style: w, className: "max-h-48 overflow-y-auto rounded-lg bg-surface ring-1 ring-line shadow-card-hover", children: l.map(($, z) => {
|
|
3354
|
+
const k = $.name ?? $.id ?? String($);
|
|
3332
3355
|
return /* @__PURE__ */ e(
|
|
3333
3356
|
"button",
|
|
3334
3357
|
{
|
|
@@ -3336,9 +3359,9 @@ function ke({
|
|
|
3336
3359
|
onMouseDown: () => {
|
|
3337
3360
|
u.current = !0;
|
|
3338
3361
|
},
|
|
3339
|
-
onClick: () =>
|
|
3362
|
+
onClick: () => S($),
|
|
3340
3363
|
className: "block w-full px-3 py-1.5 text-left text-sm text-fg transition-colors hover:bg-surface-subtle",
|
|
3341
|
-
children:
|
|
3364
|
+
children: k
|
|
3342
3365
|
},
|
|
3343
3366
|
z
|
|
3344
3367
|
);
|
|
@@ -3362,12 +3385,12 @@ function Dn() {
|
|
|
3362
3385
|
partner_name: "",
|
|
3363
3386
|
partner_email: "",
|
|
3364
3387
|
cover_letter: ""
|
|
3365
|
-
}), [
|
|
3388
|
+
}), [y, d] = v([Tt()]), [p, m] = v(null), [f, w] = v(!1), [b, g] = v(null), P = X(null), D = (N, B) => l((C) => ({ ...C, [N]: B })), { data: T } = le({
|
|
3366
3389
|
queryKey: ["document", "proposal", t],
|
|
3367
3390
|
queryFn: () => L.getDocument("proposal", t),
|
|
3368
3391
|
enabled: !n
|
|
3369
3392
|
});
|
|
3370
|
-
|
|
3393
|
+
se(() => {
|
|
3371
3394
|
if (!T) return;
|
|
3372
3395
|
l({
|
|
3373
3396
|
title: T.title ?? "Offerte",
|
|
@@ -3388,52 +3411,52 @@ function Dn() {
|
|
|
3388
3411
|
} catch {
|
|
3389
3412
|
}
|
|
3390
3413
|
};
|
|
3391
|
-
|
|
3414
|
+
se(() => {
|
|
3392
3415
|
n && c.customer && !c.cover_letter && u();
|
|
3393
3416
|
}, [c.customer, c.company]);
|
|
3394
3417
|
const h = () => ({
|
|
3395
3418
|
...c,
|
|
3396
|
-
quotations:
|
|
3419
|
+
quotations: y.filter((N) => N.quotation).map((N, B) => ({ ...N, idx: B + 1, is_recommended: N.is_recommended ? 1 : 0 }))
|
|
3397
3420
|
}), A = oe({
|
|
3398
3421
|
mutationFn: async () => n ? L.createDocument("proposal", h()) : L.updateDocument("proposal", t, h()),
|
|
3399
3422
|
onSuccess: (N) => {
|
|
3400
|
-
|
|
3423
|
+
g(null), s.invalidateQueries({ queryKey: ["documents", "proposal"] }), s.invalidateQueries({ queryKey: ["document", "proposal", N.name] }), n && a(`/app/proposal/${encodeURIComponent(N.name)}`);
|
|
3401
3424
|
},
|
|
3402
|
-
onError: (N) =>
|
|
3425
|
+
onError: (N) => g((N == null ? void 0 : N.message) ?? "Save failed")
|
|
3403
3426
|
}), R = oe({
|
|
3404
3427
|
mutationFn: () => L.discardDocument("proposal", t),
|
|
3405
3428
|
onSuccess: () => {
|
|
3406
3429
|
s.invalidateQueries({ queryKey: ["documents", "proposal"] }), a("/app/proposal");
|
|
3407
3430
|
},
|
|
3408
|
-
onError: (N) =>
|
|
3409
|
-
}),
|
|
3431
|
+
onError: (N) => g((N == null ? void 0 : N.message) ?? "Discard failed")
|
|
3432
|
+
}), S = (N, B) => d((C) => C.map((F, Z) => Z === N ? { ...F, ...B } : F)), H = () => d((N) => [...N, Tt()]), $ = (N) => d((B) => B.length > 1 ? B.filter((C, F) => F !== N) : B), z = (N, B) => d((C) => {
|
|
3410
3433
|
const F = N + B;
|
|
3411
3434
|
if (F < 0 || F >= C.length) return C;
|
|
3412
3435
|
const Z = [...C];
|
|
3413
3436
|
return [Z[N], Z[F]] = [Z[F], Z[N]], Z;
|
|
3414
|
-
}),
|
|
3437
|
+
}), k = async (N) => {
|
|
3415
3438
|
var C;
|
|
3416
3439
|
const B = (C = N.target.files) == null ? void 0 : C[0];
|
|
3417
3440
|
if (N.target.value = "", !(!B || n)) {
|
|
3418
|
-
|
|
3441
|
+
w(!0), g(null);
|
|
3419
3442
|
try {
|
|
3420
3443
|
const F = await L.uploadProposalAppendix(t, B);
|
|
3421
3444
|
m(F.appendix_filename), s.invalidateQueries({ queryKey: ["document", "proposal", t] });
|
|
3422
3445
|
} catch (F) {
|
|
3423
|
-
|
|
3446
|
+
g((F == null ? void 0 : F.message) ?? "Upload failed");
|
|
3424
3447
|
} finally {
|
|
3425
|
-
|
|
3448
|
+
w(!1);
|
|
3426
3449
|
}
|
|
3427
3450
|
}
|
|
3428
3451
|
}, K = async () => {
|
|
3429
3452
|
if (!n) {
|
|
3430
|
-
|
|
3453
|
+
w(!0);
|
|
3431
3454
|
try {
|
|
3432
3455
|
await L.deleteProposalAppendix(t), m(null);
|
|
3433
3456
|
} catch (N) {
|
|
3434
|
-
|
|
3457
|
+
g((N == null ? void 0 : N.message) ?? "Failed");
|
|
3435
3458
|
} finally {
|
|
3436
|
-
|
|
3459
|
+
w(!1);
|
|
3437
3460
|
}
|
|
3438
3461
|
}
|
|
3439
3462
|
};
|
|
@@ -3459,15 +3482,15 @@ function Dn() {
|
|
|
3459
3482
|
/* @__PURE__ */ e(J, { onClick: () => A.mutate(), disabled: A.isPending, children: A.isPending ? i("common.saving", "Saving…") : i("common.save", "Save") })
|
|
3460
3483
|
] })
|
|
3461
3484
|
] }),
|
|
3462
|
-
|
|
3485
|
+
b && /* @__PURE__ */ e("div", { className: "rounded-lg bg-red-50 px-4 py-2 text-sm text-red-700 ring-1 ring-red-200", children: b }),
|
|
3463
3486
|
/* @__PURE__ */ r(U, { className: "space-y-4 p-5", children: [
|
|
3464
3487
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
3465
|
-
/* @__PURE__ */ e(
|
|
3466
|
-
/* @__PURE__ */ e(
|
|
3488
|
+
/* @__PURE__ */ e(ee, { label: i("fields.Title", "Title"), value: c.title, onChange: (N) => D("title", N.target.value) }),
|
|
3489
|
+
/* @__PURE__ */ e(ee, { label: i("fields.Date", "Date"), type: "date", value: c.proposal_date, onChange: (N) => D("proposal_date", N.target.value) }),
|
|
3467
3490
|
/* @__PURE__ */ e(ke, { label: i("fields.Customer", "Customer"), value: c.customer, onChange: (N) => D("customer", N), linkDoctype: "customer", readOnly: !1 }),
|
|
3468
3491
|
/* @__PURE__ */ e(ke, { label: i("fields.Company", "Company"), value: c.company, onChange: (N) => D("company", N), linkDoctype: "company", readOnly: !1 }),
|
|
3469
|
-
/* @__PURE__ */ e(
|
|
3470
|
-
/* @__PURE__ */ e(
|
|
3492
|
+
/* @__PURE__ */ e(ee, { label: i("fields.Partner", "Account Manager"), value: c.partner_name, onChange: (N) => D("partner_name", N.target.value) }),
|
|
3493
|
+
/* @__PURE__ */ e(ee, { label: i("fields.Partner Email", "Account Manager Email"), value: c.partner_email, onChange: (N) => D("partner_email", N.target.value) })
|
|
3471
3494
|
] }),
|
|
3472
3495
|
/* @__PURE__ */ r("div", { children: [
|
|
3473
3496
|
/* @__PURE__ */ r("div", { className: "mb-1.5 flex items-center justify-between", children: [
|
|
@@ -3490,21 +3513,21 @@ function Dn() {
|
|
|
3490
3513
|
/* @__PURE__ */ e("h2", { className: "font-semibold text-fg", children: i("proposal.offers", "Offers") }),
|
|
3491
3514
|
/* @__PURE__ */ e(J, { size: "sm", variant: "secondary", onClick: H, children: i("proposal.addOffer", "Add offer") })
|
|
3492
3515
|
] }),
|
|
3493
|
-
|
|
3516
|
+
y.map((N, B) => /* @__PURE__ */ r("div", { className: "rounded-lg p-3 ring-1 ring-line", children: [
|
|
3494
3517
|
/* @__PURE__ */ r("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
3495
3518
|
/* @__PURE__ */ e("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-brand/10 text-sm font-bold text-brand", children: Er[B] ?? B + 1 }),
|
|
3496
|
-
/* @__PURE__ */ e("div", { className: "flex-1", children: /* @__PURE__ */ e(ke, { label: "", value: N.quotation, onChange: (C) =>
|
|
3519
|
+
/* @__PURE__ */ e("div", { className: "flex-1", children: /* @__PURE__ */ e(ke, { label: "", value: N.quotation, onChange: (C) => S(B, { quotation: C }), linkDoctype: "quotation", readOnly: !1 }) }),
|
|
3497
3520
|
/* @__PURE__ */ e("button", { type: "button", onClick: () => z(B, -1), disabled: B === 0, className: "px-1 text-fg-muted disabled:opacity-30", children: "↑" }),
|
|
3498
|
-
/* @__PURE__ */ e("button", { type: "button", onClick: () => z(B, 1), disabled: B ===
|
|
3521
|
+
/* @__PURE__ */ e("button", { type: "button", onClick: () => z(B, 1), disabled: B === y.length - 1, className: "px-1 text-fg-muted disabled:opacity-30", children: "↓" }),
|
|
3499
3522
|
/* @__PURE__ */ e("button", { type: "button", onClick: () => $(B), className: "px-1 text-red-500 hover:text-red-700", children: "✕" })
|
|
3500
3523
|
] }),
|
|
3501
3524
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-1 gap-2 pl-8 sm:grid-cols-2", children: [
|
|
3502
|
-
/* @__PURE__ */ e(
|
|
3525
|
+
/* @__PURE__ */ e(ee, { label: i("proposal.positionTitle", "Position title"), value: N.position_title, onChange: (C) => S(B, { position_title: C.target.value }), placeholder: i("proposal.positionTitleHint", "defaults to the offer's first item") }),
|
|
3503
3526
|
/* @__PURE__ */ r("label", { className: "flex items-center gap-2 self-end pb-2 text-sm text-fg", children: [
|
|
3504
|
-
/* @__PURE__ */ e("input", { type: "checkbox", checked: !!N.is_recommended, onChange: (C) =>
|
|
3527
|
+
/* @__PURE__ */ e("input", { type: "checkbox", checked: !!N.is_recommended, onChange: (C) => S(B, { is_recommended: C.target.checked ? 1 : 0 }) }),
|
|
3505
3528
|
i("proposal.recommended", "Mark as recommendation")
|
|
3506
3529
|
] }),
|
|
3507
|
-
/* @__PURE__ */ e("div", { className: "sm:col-span-2", children: /* @__PURE__ */ e(
|
|
3530
|
+
/* @__PURE__ */ e("div", { className: "sm:col-span-2", children: /* @__PURE__ */ e(ee, { label: i("proposal.blurb", "Description"), value: N.position_blurb, onChange: (C) => S(B, { position_blurb: C.target.value }), placeholder: i("proposal.blurbHint", "defaults to the offer's notes") }) })
|
|
3508
3531
|
] })
|
|
3509
3532
|
] }, B))
|
|
3510
3533
|
] }),
|
|
@@ -3517,7 +3540,7 @@ function Dn() {
|
|
|
3517
3540
|
] }),
|
|
3518
3541
|
/* @__PURE__ */ e("button", { type: "button", onClick: K, disabled: f, className: "text-red-500 hover:underline", children: i("common.remove", "Remove") })
|
|
3519
3542
|
] }) : /* @__PURE__ */ r("div", { children: [
|
|
3520
|
-
/* @__PURE__ */ e("input", { ref: P, type: "file", accept: "application/pdf", onChange:
|
|
3543
|
+
/* @__PURE__ */ e("input", { ref: P, type: "file", accept: "application/pdf", onChange: k, className: "hidden" }),
|
|
3521
3544
|
/* @__PURE__ */ e(J, { size: "sm", variant: "secondary", disabled: f, onClick: () => {
|
|
3522
3545
|
var N;
|
|
3523
3546
|
return (N = P.current) == null ? void 0 : N.click();
|
|
@@ -3530,7 +3553,7 @@ function Dn() {
|
|
|
3530
3553
|
const Or = ["25", "50", "100", "200"];
|
|
3531
3554
|
function qr() {
|
|
3532
3555
|
var u;
|
|
3533
|
-
const { type: t } = ft(), n = Oe(), s = (u = Ct().state) == null ? void 0 : u.notice, [o] = ne("per_page", 50), [i] = ne("page", 1), c = i - 1, l = Qe(),
|
|
3556
|
+
const { type: t } = ft(), n = Oe(), s = (u = Ct().state) == null ? void 0 : u.notice, [o] = ne("per_page", 50), [i] = ne("page", 1), c = i - 1, l = Qe(), y = (h) => l({ page: h === 0 ? null : h + 1 }), d = (h) => l({ per_page: h, page: null }), { data: p, isLoading: m } = le({
|
|
3534
3557
|
queryKey: ["masters", t, c, o],
|
|
3535
3558
|
queryFn: () => L.listMasters(t, {
|
|
3536
3559
|
include_disabled: 1,
|
|
@@ -3538,16 +3561,16 @@ function qr() {
|
|
|
3538
3561
|
offset: c * o
|
|
3539
3562
|
}),
|
|
3540
3563
|
enabled: !!t
|
|
3541
|
-
}), f = (p == null ? void 0 : p.rows) ?? [],
|
|
3564
|
+
}), f = (p == null ? void 0 : p.rows) ?? [], w = (p == null ? void 0 : p.total) ?? 0, b = Math.max(1, Math.ceil(w / o)), g = w === 0 ? 0 : c * o + 1, P = Math.min(w, (c + 1) * o), D = Ie(() => {
|
|
3542
3565
|
if (!f || f.length === 0) return [];
|
|
3543
3566
|
const h = Wn();
|
|
3544
3567
|
return Object.keys(f[0]).map(
|
|
3545
3568
|
(R) => h.accessor(R, {
|
|
3546
|
-
header: R.split("_").map((
|
|
3547
|
-
cell: (
|
|
3548
|
-
const H =
|
|
3569
|
+
header: R.split("_").map((S) => S.charAt(0).toUpperCase() + S.slice(1)).join(" "),
|
|
3570
|
+
cell: (S) => {
|
|
3571
|
+
const H = S.getValue();
|
|
3549
3572
|
if (R === "name") {
|
|
3550
|
-
const $ =
|
|
3573
|
+
const $ = S.row.original.disabled === 1;
|
|
3551
3574
|
return /* @__PURE__ */ e(
|
|
3552
3575
|
Ne,
|
|
3553
3576
|
{
|
|
@@ -3599,13 +3622,13 @@ function qr() {
|
|
|
3599
3622
|
/* @__PURE__ */ r("div", { children: [
|
|
3600
3623
|
"Showing ",
|
|
3601
3624
|
/* @__PURE__ */ r("span", { className: "font-medium text-fg", children: [
|
|
3602
|
-
|
|
3625
|
+
g,
|
|
3603
3626
|
"–",
|
|
3604
3627
|
P
|
|
3605
3628
|
] }),
|
|
3606
3629
|
" ",
|
|
3607
3630
|
"of ",
|
|
3608
|
-
/* @__PURE__ */ e("span", { className: "font-medium text-fg", children:
|
|
3631
|
+
/* @__PURE__ */ e("span", { className: "font-medium text-fg", children: w })
|
|
3609
3632
|
] }),
|
|
3610
3633
|
/* @__PURE__ */ r("div", { className: "flex items-center gap-2", children: [
|
|
3611
3634
|
/* @__PURE__ */ r("label", { className: "flex items-center gap-1.5", children: [
|
|
@@ -3623,7 +3646,7 @@ function qr() {
|
|
|
3623
3646
|
/* @__PURE__ */ e(
|
|
3624
3647
|
"button",
|
|
3625
3648
|
{
|
|
3626
|
-
onClick: () =>
|
|
3649
|
+
onClick: () => y(Math.max(0, c - 1)),
|
|
3627
3650
|
disabled: c === 0,
|
|
3628
3651
|
className: "rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40",
|
|
3629
3652
|
children: "Prev"
|
|
@@ -3634,13 +3657,13 @@ function qr() {
|
|
|
3634
3657
|
/* @__PURE__ */ e("span", { className: "font-medium text-fg", children: c + 1 }),
|
|
3635
3658
|
" of",
|
|
3636
3659
|
" ",
|
|
3637
|
-
/* @__PURE__ */ e("span", { className: "font-medium text-fg", children:
|
|
3660
|
+
/* @__PURE__ */ e("span", { className: "font-medium text-fg", children: b })
|
|
3638
3661
|
] }),
|
|
3639
3662
|
/* @__PURE__ */ e(
|
|
3640
3663
|
"button",
|
|
3641
3664
|
{
|
|
3642
|
-
onClick: () =>
|
|
3643
|
-
disabled: c >=
|
|
3665
|
+
onClick: () => y(Math.min(b - 1, c + 1)),
|
|
3666
|
+
disabled: c >= b - 1,
|
|
3644
3667
|
className: "rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40",
|
|
3645
3668
|
children: "Next"
|
|
3646
3669
|
}
|
|
@@ -3720,40 +3743,40 @@ const Fr = {
|
|
|
3720
3743
|
}, _n = /* @__PURE__ */ new Set(["customer", "supplier", "item", "warehouse"]);
|
|
3721
3744
|
function Pn() {
|
|
3722
3745
|
var R;
|
|
3723
|
-
const { type: t, name: n } = ft(), a = Oe(), s = We(), { t: o } = ae(), i = !n || n === "new", c = Mr[t ?? ""] ?? t ?? "", l = o(`masters.${t}.one`, { defaultValue: c }),
|
|
3746
|
+
const { type: t, name: n } = ft(), a = Oe(), s = We(), { t: o } = ae(), i = !n || n === "new", c = Mr[t ?? ""] ?? t ?? "", l = o(`masters.${t}.one`, { defaultValue: c }), y = Fr[t ?? ""] ?? [], d = (S) => o(`fields.${S.label}`, { defaultValue: S.label }), [p, m] = v({}), { data: f, isLoading: w } = le({
|
|
3724
3747
|
queryKey: ["master", t, n],
|
|
3725
3748
|
queryFn: () => L.getMaster(t, n),
|
|
3726
3749
|
enabled: !!t && !!n && !i
|
|
3727
3750
|
});
|
|
3728
|
-
|
|
3751
|
+
se(() => {
|
|
3729
3752
|
if (i) {
|
|
3730
|
-
const
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
}), m(
|
|
3753
|
+
const S = {};
|
|
3754
|
+
y.forEach((H) => {
|
|
3755
|
+
S[H.name] = H.default ?? "";
|
|
3756
|
+
}), m(S);
|
|
3734
3757
|
} else f && m(f);
|
|
3735
|
-
}, [i, f,
|
|
3736
|
-
const
|
|
3737
|
-
mutationFn: (
|
|
3738
|
-
onSuccess: (
|
|
3739
|
-
s.invalidateQueries({ queryKey: ["masters", t] }), a(`/masters/${t}/${
|
|
3758
|
+
}, [i, f, y]);
|
|
3759
|
+
const b = oe({
|
|
3760
|
+
mutationFn: (S) => L.createMaster(t, S),
|
|
3761
|
+
onSuccess: (S) => {
|
|
3762
|
+
s.invalidateQueries({ queryKey: ["masters", t] }), a(`/masters/${t}/${S.name}`, { replace: !0 });
|
|
3740
3763
|
}
|
|
3741
|
-
}),
|
|
3742
|
-
mutationFn: (
|
|
3764
|
+
}), g = oe({
|
|
3765
|
+
mutationFn: (S) => L.updateMaster(t, n, S),
|
|
3743
3766
|
onSuccess: () => {
|
|
3744
3767
|
s.invalidateQueries({ queryKey: ["master", t, n] }), s.invalidateQueries({ queryKey: ["masters", t] });
|
|
3745
3768
|
}
|
|
3746
3769
|
}), P = oe({
|
|
3747
3770
|
mutationFn: () => L.deleteMaster(t, n),
|
|
3748
|
-
onSuccess: (
|
|
3749
|
-
if (s.invalidateQueries({ queryKey: ["masters", t] }), (
|
|
3771
|
+
onSuccess: (S) => {
|
|
3772
|
+
if (s.invalidateQueries({ queryKey: ["masters", t] }), (S == null ? void 0 : S.status) === "disabled") {
|
|
3750
3773
|
a(`/masters/${t}`, {
|
|
3751
3774
|
replace: !0,
|
|
3752
3775
|
state: {
|
|
3753
3776
|
notice: o("masterForm.disabledOnDelete", {
|
|
3754
3777
|
label: l,
|
|
3755
3778
|
name: n,
|
|
3756
|
-
reason:
|
|
3779
|
+
reason: S.reason ?? "other records"
|
|
3757
3780
|
})
|
|
3758
3781
|
}
|
|
3759
3782
|
});
|
|
@@ -3763,18 +3786,18 @@ function Pn() {
|
|
|
3763
3786
|
}
|
|
3764
3787
|
}), D = () => {
|
|
3765
3788
|
if (A.length > 0) return;
|
|
3766
|
-
const
|
|
3767
|
-
i ?
|
|
3789
|
+
const S = t === "company" && !p.name ? { ...p, name: p.company_name } : p;
|
|
3790
|
+
i ? b.mutate(S) : g.mutate(S);
|
|
3768
3791
|
}, T = () => {
|
|
3769
3792
|
window.confirm(o("masterForm.deleteConfirm", { label: l })) && P.mutate();
|
|
3770
|
-
}, u = (
|
|
3771
|
-
m(($) => ({ ...$, [
|
|
3793
|
+
}, u = (S, H) => {
|
|
3794
|
+
m(($) => ({ ...$, [S]: H }));
|
|
3772
3795
|
};
|
|
3773
|
-
if (!i &&
|
|
3796
|
+
if (!i && w)
|
|
3774
3797
|
return /* @__PURE__ */ e("p", { className: "text-fg-muted", children: o("common.loading") });
|
|
3775
|
-
const h =
|
|
3776
|
-
if (!
|
|
3777
|
-
const H = p[
|
|
3798
|
+
const h = b.isPending || g.isPending, A = y.filter((S) => {
|
|
3799
|
+
if (!S.required || S.readOnly || i && S.name === "name" && _n.has(t ?? "")) return !1;
|
|
3800
|
+
const H = p[S.name];
|
|
3778
3801
|
return H == null || String(H).trim() === "";
|
|
3779
3802
|
});
|
|
3780
3803
|
return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
@@ -3790,56 +3813,56 @@ function Pn() {
|
|
|
3790
3813
|
}
|
|
3791
3814
|
)
|
|
3792
3815
|
] }) }),
|
|
3793
|
-
(
|
|
3816
|
+
(b.error || g.error || P.error) && /* @__PURE__ */ e("div", { className: "rounded-lg bg-rose-50 p-4 text-sm text-rose-700 ring-1 ring-rose-200", children: ((R = b.error ?? g.error ?? P.error) == null ? void 0 : R.message) ?? o("common.errorOccurred") }),
|
|
3794
3817
|
A.length > 0 && /* @__PURE__ */ e("div", { className: "rounded-lg bg-amber-50 p-4 text-sm text-amber-800 ring-1 ring-amber-200", children: o("masterForm.required", { fields: A.map(d).join(", ") }) }),
|
|
3795
3818
|
p.disabled === 1 && /* @__PURE__ */ e("div", { className: "rounded-lg bg-amber-50 p-4 text-sm text-amber-800 ring-1 ring-amber-200", children: o("masterForm.disabledNotice", { label: l }) }),
|
|
3796
|
-
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children:
|
|
3797
|
-
const $ =
|
|
3798
|
-
if (
|
|
3819
|
+
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: y.map((S) => {
|
|
3820
|
+
const $ = S.name === "name" && !i || S.readOnly, z = S.required && !(i && S.name === "name" && _n.has(t ?? ""));
|
|
3821
|
+
if (S.type === "select" && S.options)
|
|
3799
3822
|
return /* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
|
|
3800
3823
|
rt,
|
|
3801
3824
|
{
|
|
3802
|
-
label: d(
|
|
3803
|
-
options:
|
|
3804
|
-
value: p[
|
|
3825
|
+
label: d(S),
|
|
3826
|
+
options: S.options,
|
|
3827
|
+
value: p[S.name] ?? "",
|
|
3805
3828
|
required: z,
|
|
3806
3829
|
disabled: $,
|
|
3807
|
-
onChange: (K) => u(
|
|
3830
|
+
onChange: (K) => u(S.name, K.target.value)
|
|
3808
3831
|
}
|
|
3809
|
-
) },
|
|
3810
|
-
if (
|
|
3832
|
+
) }, S.name);
|
|
3833
|
+
if (S.type === "textarea")
|
|
3811
3834
|
return /* @__PURE__ */ r("div", { className: "sm:col-span-2", children: [
|
|
3812
|
-
/* @__PURE__ */ e("label", { className: "mb-1.5 block text-sm font-medium text-fg", children: d(
|
|
3835
|
+
/* @__PURE__ */ e("label", { className: "mb-1.5 block text-sm font-medium text-fg", children: d(S) }),
|
|
3813
3836
|
/* @__PURE__ */ e(
|
|
3814
3837
|
"textarea",
|
|
3815
3838
|
{
|
|
3816
3839
|
className: "block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30 disabled:bg-surface-subtle disabled:text-fg-muted",
|
|
3817
3840
|
rows: 3,
|
|
3818
|
-
value: p[
|
|
3841
|
+
value: p[S.name] ?? "",
|
|
3819
3842
|
required: z,
|
|
3820
3843
|
readOnly: $,
|
|
3821
3844
|
disabled: $,
|
|
3822
|
-
onChange: (K) => u(
|
|
3845
|
+
onChange: (K) => u(S.name, K.target.value)
|
|
3823
3846
|
}
|
|
3824
3847
|
)
|
|
3825
|
-
] },
|
|
3826
|
-
const
|
|
3848
|
+
] }, S.name);
|
|
3849
|
+
const k = S.type === "number" || S.type === "currency" ? "number" : S.type === "date" ? "date" : "text";
|
|
3827
3850
|
return /* @__PURE__ */ e(
|
|
3828
|
-
|
|
3851
|
+
ee,
|
|
3829
3852
|
{
|
|
3830
|
-
label: d(
|
|
3831
|
-
type:
|
|
3832
|
-
step:
|
|
3853
|
+
label: d(S),
|
|
3854
|
+
type: k,
|
|
3855
|
+
step: S.type === "currency" ? "0.01" : void 0,
|
|
3833
3856
|
required: z,
|
|
3834
3857
|
readOnly: $,
|
|
3835
3858
|
disabled: $,
|
|
3836
|
-
value: p[
|
|
3859
|
+
value: p[S.name] ?? "",
|
|
3837
3860
|
onChange: (K) => u(
|
|
3838
|
-
|
|
3839
|
-
|
|
3861
|
+
S.name,
|
|
3862
|
+
k === "number" ? parseFloat(K.target.value) || 0 : K.target.value
|
|
3840
3863
|
)
|
|
3841
3864
|
},
|
|
3842
|
-
|
|
3865
|
+
S.name
|
|
3843
3866
|
);
|
|
3844
3867
|
}) }) })
|
|
3845
3868
|
] });
|
|
@@ -3894,16 +3917,16 @@ function Kr(t) {
|
|
|
3894
3917
|
return { data: n, isLoading: a, error: s, refetch: o };
|
|
3895
3918
|
}
|
|
3896
3919
|
function Wr() {
|
|
3897
|
-
const { t } = ae(), [n] = ne("company", ""), [a] = ne("from", ""), [s] = ne("to", ""), o = Qe(), [i, c] = v(n), [l,
|
|
3920
|
+
const { t } = ae(), [n] = ne("company", ""), [a] = ne("from", ""), [s] = ne("to", ""), o = Qe(), [i, c] = v(n), [l, y] = v(a), [d, p] = v(s), m = He(i), f = (u) => qe(u, m), w = Ie(() => {
|
|
3898
3921
|
const u = {};
|
|
3899
3922
|
return n && (u.company = n), a && (u.from_date = a), s && (u.to_date = s), u;
|
|
3900
|
-
}, [n, a, s]), { data:
|
|
3923
|
+
}, [n, a, s]), { data: b, isLoading: g, refetch: P } = zr(w), D = () => {
|
|
3901
3924
|
o({
|
|
3902
3925
|
company: i || null,
|
|
3903
3926
|
from: l || null,
|
|
3904
3927
|
to: d || null
|
|
3905
3928
|
}), P();
|
|
3906
|
-
}, T =
|
|
3929
|
+
}, T = b ? b.difference === 0 : !1;
|
|
3907
3930
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
3908
3931
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
3909
3932
|
/* @__PURE__ */ e(
|
|
@@ -3917,16 +3940,16 @@ function Wr() {
|
|
|
3917
3940
|
}
|
|
3918
3941
|
),
|
|
3919
3942
|
/* @__PURE__ */ e(
|
|
3920
|
-
|
|
3943
|
+
ee,
|
|
3921
3944
|
{
|
|
3922
3945
|
label: t("fields.From Date", { defaultValue: "From Date" }),
|
|
3923
3946
|
type: "date",
|
|
3924
3947
|
value: l,
|
|
3925
|
-
onChange: (u) =>
|
|
3948
|
+
onChange: (u) => y(u.target.value)
|
|
3926
3949
|
}
|
|
3927
3950
|
),
|
|
3928
3951
|
/* @__PURE__ */ e(
|
|
3929
|
-
|
|
3952
|
+
ee,
|
|
3930
3953
|
{
|
|
3931
3954
|
label: t("fields.To Date", { defaultValue: "To Date" }),
|
|
3932
3955
|
type: "date",
|
|
@@ -3937,9 +3960,9 @@ function Wr() {
|
|
|
3937
3960
|
/* @__PURE__ */ e(J, { onClick: D, children: t("common.apply") })
|
|
3938
3961
|
] }),
|
|
3939
3962
|
/* @__PURE__ */ e(Ft, { onSelect: (u, h) => {
|
|
3940
|
-
|
|
3963
|
+
y(u), p(h), o({ from: u, to: h });
|
|
3941
3964
|
} }),
|
|
3942
|
-
|
|
3965
|
+
g ? /* @__PURE__ */ e("p", { className: "text-fg-muted", children: t("common.loading") }) : !b || !b.rows || b.rows.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-fg-muted", children: t("reports.noData") }) : /* @__PURE__ */ r(U, { children: [
|
|
3943
3966
|
/* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-line text-sm", children: [
|
|
3944
3967
|
/* @__PURE__ */ e("thead", { className: "bg-surface-subtle", children: /* @__PURE__ */ r("tr", { children: [
|
|
3945
3968
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted", children: t("fields.Account", { defaultValue: "Account" }) }),
|
|
@@ -3947,7 +3970,7 @@ function Wr() {
|
|
|
3947
3970
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-fg-muted", children: t("fields.Credit", { defaultValue: "Credit" }) }),
|
|
3948
3971
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-fg-muted", children: t("fields.Balance", { defaultValue: "Balance" }) })
|
|
3949
3972
|
] }) }),
|
|
3950
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-line", children:
|
|
3973
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-line", children: b.rows.map((u, h) => /* @__PURE__ */ r("tr", { className: "transition-colors hover:bg-surface-subtle", children: [
|
|
3951
3974
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-fg", children: u.account }),
|
|
3952
3975
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right tabular-nums text-fg", children: f(u.debit) }),
|
|
3953
3976
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right tabular-nums text-fg", children: f(u.credit) }),
|
|
@@ -3955,9 +3978,9 @@ function Wr() {
|
|
|
3955
3978
|
] }, h)) }),
|
|
3956
3979
|
/* @__PURE__ */ e("tfoot", { className: "border-t border-line bg-surface-subtle font-semibold", children: /* @__PURE__ */ r("tr", { children: [
|
|
3957
3980
|
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-fg", children: t("common.total") }),
|
|
3958
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right tabular-nums text-fg", children: f(
|
|
3959
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right tabular-nums text-fg", children: f(
|
|
3960
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right tabular-nums text-fg", children: f(
|
|
3981
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right tabular-nums text-fg", children: f(b.total_debit) }),
|
|
3982
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right tabular-nums text-fg", children: f(b.total_credit) }),
|
|
3983
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right tabular-nums text-fg", children: f(b.difference) })
|
|
3961
3984
|
] }) })
|
|
3962
3985
|
] }) }),
|
|
3963
3986
|
/* @__PURE__ */ e("div", { className: "mt-4 text-center", children: T ? /* @__PURE__ */ r("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-emerald-50 px-4 py-1.5 text-sm font-semibold text-emerald-700 ring-1 ring-emerald-200", children: [
|
|
@@ -3975,14 +3998,14 @@ function Hr(t) {
|
|
|
3975
3998
|
}
|
|
3976
3999
|
const Qr = ["25", "50", "100", "200"];
|
|
3977
4000
|
function Jr() {
|
|
3978
|
-
const { t } = ae(), [n] = ne("account", ""), [a] = ne("party", ""), [s] = ne("from", ""), [o] = ne("to", ""), [i] = ne("per_page", 50), [c] = ne("page", 1), l = c - 1,
|
|
4001
|
+
const { t } = ae(), [n] = ne("account", ""), [a] = ne("party", ""), [s] = ne("from", ""), [o] = ne("to", ""), [i] = ne("per_page", 50), [c] = ne("page", 1), l = c - 1, y = Qe(), d = (C) => y({ page: C === 0 ? null : C + 1 }), p = (C) => y({ per_page: C, page: null }), [m, f] = v(n), [w, b] = v(a), [g, P] = v(s), [D, T] = v(o), u = He(), h = (C) => qe(C, u), A = Ie(() => {
|
|
3979
4002
|
const C = {};
|
|
3980
4003
|
return n && (C.account = n), a && (C.party = a), s && (C.from_date = s), o && (C.to_date = o), C.limit = String(i), C.offset = String(l * i), C;
|
|
3981
|
-
}, [n, a, s, o, i, l]), { data: R, isLoading:
|
|
3982
|
-
|
|
4004
|
+
}, [n, a, s, o, i, l]), { data: R, isLoading: S, refetch: H } = $r(A), $ = (R == null ? void 0 : R.rows) ?? [], z = (R == null ? void 0 : R.total) ?? 0, k = Math.max(1, Math.ceil(z / i)), K = z === 0 ? 0 : l * i + 1, N = Math.min(z, (l + 1) * i), B = () => {
|
|
4005
|
+
y({
|
|
3983
4006
|
account: m || null,
|
|
3984
|
-
party:
|
|
3985
|
-
from:
|
|
4007
|
+
party: w || null,
|
|
4008
|
+
from: g || null,
|
|
3986
4009
|
to: D || null,
|
|
3987
4010
|
page: null
|
|
3988
4011
|
}), H();
|
|
@@ -4003,23 +4026,23 @@ function Jr() {
|
|
|
4003
4026
|
ke,
|
|
4004
4027
|
{
|
|
4005
4028
|
label: t("fields.Party", { defaultValue: "Party" }),
|
|
4006
|
-
value:
|
|
4007
|
-
onChange:
|
|
4029
|
+
value: w,
|
|
4030
|
+
onChange: b,
|
|
4008
4031
|
linkDoctype: "customer",
|
|
4009
4032
|
readOnly: !1
|
|
4010
4033
|
}
|
|
4011
4034
|
),
|
|
4012
4035
|
/* @__PURE__ */ e(
|
|
4013
|
-
|
|
4036
|
+
ee,
|
|
4014
4037
|
{
|
|
4015
4038
|
label: t("fields.From Date", { defaultValue: "From Date" }),
|
|
4016
4039
|
type: "date",
|
|
4017
|
-
value:
|
|
4040
|
+
value: g,
|
|
4018
4041
|
onChange: (C) => P(C.target.value)
|
|
4019
4042
|
}
|
|
4020
4043
|
),
|
|
4021
4044
|
/* @__PURE__ */ e(
|
|
4022
|
-
|
|
4045
|
+
ee,
|
|
4023
4046
|
{
|
|
4024
4047
|
label: t("fields.To Date", { defaultValue: "To Date" }),
|
|
4025
4048
|
type: "date",
|
|
@@ -4030,9 +4053,9 @@ function Jr() {
|
|
|
4030
4053
|
/* @__PURE__ */ e(J, { onClick: B, children: t("common.apply") })
|
|
4031
4054
|
] }),
|
|
4032
4055
|
/* @__PURE__ */ e(Ft, { onSelect: (C, F) => {
|
|
4033
|
-
P(C), T(F),
|
|
4056
|
+
P(C), T(F), y({ from: C, to: F, page: null });
|
|
4034
4057
|
} }),
|
|
4035
|
-
|
|
4058
|
+
S ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) : $.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-gray-400", children: t("reports.noEntries") }) : /* @__PURE__ */ r(Se, { children: [
|
|
4036
4059
|
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
4037
4060
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
4038
4061
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Date", { defaultValue: "Date" }) }),
|
|
@@ -4105,13 +4128,13 @@ function Jr() {
|
|
|
4105
4128
|
" ",
|
|
4106
4129
|
t("common.of"),
|
|
4107
4130
|
" ",
|
|
4108
|
-
/* @__PURE__ */ e("span", { className: "font-medium text-gray-900", children:
|
|
4131
|
+
/* @__PURE__ */ e("span", { className: "font-medium text-gray-900", children: k })
|
|
4109
4132
|
] }),
|
|
4110
4133
|
/* @__PURE__ */ e(
|
|
4111
4134
|
"button",
|
|
4112
4135
|
{
|
|
4113
|
-
onClick: () => d(Math.min(
|
|
4114
|
-
disabled: l >=
|
|
4136
|
+
onClick: () => d(Math.min(k - 1, l + 1)),
|
|
4137
|
+
disabled: l >= k - 1,
|
|
4115
4138
|
className: "rounded border border-gray-300 bg-white px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40",
|
|
4116
4139
|
children: t("common.next")
|
|
4117
4140
|
}
|
|
@@ -4122,14 +4145,14 @@ function Jr() {
|
|
|
4122
4145
|
] });
|
|
4123
4146
|
}
|
|
4124
4147
|
function Yr() {
|
|
4125
|
-
const { t } = ae(), [n] = ne("item_code", ""), [a] = ne("warehouse", ""), s = Qe(), [o, i] = v(n), [c, l] = v(a),
|
|
4126
|
-
const
|
|
4127
|
-
return n && (
|
|
4128
|
-
}, [n, a]), { data: m, isLoading: f, refetch:
|
|
4148
|
+
const { t } = ae(), [n] = ne("item_code", ""), [a] = ne("warehouse", ""), s = Qe(), [o, i] = v(n), [c, l] = v(a), y = He(), d = (g) => qe(g, y), p = Ie(() => {
|
|
4149
|
+
const g = {};
|
|
4150
|
+
return n && (g.item_code = n), a && (g.warehouse = a), g;
|
|
4151
|
+
}, [n, a]), { data: m, isLoading: f, refetch: w } = Ur(p), b = () => {
|
|
4129
4152
|
s({
|
|
4130
4153
|
item_code: o || null,
|
|
4131
4154
|
warehouse: c || null
|
|
4132
|
-
}),
|
|
4155
|
+
}), w();
|
|
4133
4156
|
};
|
|
4134
4157
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4135
4158
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
@@ -4153,7 +4176,7 @@ function Yr() {
|
|
|
4153
4176
|
readOnly: !1
|
|
4154
4177
|
}
|
|
4155
4178
|
),
|
|
4156
|
-
/* @__PURE__ */ e(J, { onClick:
|
|
4179
|
+
/* @__PURE__ */ e(J, { onClick: b, children: t("common.apply") })
|
|
4157
4180
|
] }),
|
|
4158
4181
|
f ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) : !m || !m.rows || m.rows.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-gray-400", children: t("reports.noStockData") }) : /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
4159
4182
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
@@ -4164,39 +4187,39 @@ function Yr() {
|
|
|
4164
4187
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-right font-medium text-gray-500", children: t("fields.Valuation Rate", { defaultValue: "Valuation Rate" }) }),
|
|
4165
4188
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-right font-medium text-gray-500", children: t("fields.Stock Value", { defaultValue: "Stock Value" }) })
|
|
4166
4189
|
] }) }),
|
|
4167
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: m.rows.map((
|
|
4168
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 font-medium text-gray-900", children:
|
|
4169
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children:
|
|
4170
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children:
|
|
4171
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: Ht(
|
|
4172
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: d(
|
|
4173
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right font-medium", children: d(
|
|
4190
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: m.rows.map((g, P) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
|
|
4191
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 font-medium text-gray-900", children: g.item_code }),
|
|
4192
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: g.item_name }),
|
|
4193
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: g.warehouse }),
|
|
4194
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: Ht(g.actual_qty) }),
|
|
4195
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: d(g.valuation_rate) }),
|
|
4196
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right font-medium", children: d(g.stock_value) })
|
|
4174
4197
|
] }, P)) })
|
|
4175
4198
|
] }) }) })
|
|
4176
4199
|
] });
|
|
4177
4200
|
}
|
|
4178
4201
|
function Zr() {
|
|
4179
|
-
const { t } = ae(), [n] = ne("company", ""), [a] = ne("from", ""), [s] = ne("to", ""), o = Qe(), [i, c] = v(n), l = He(i),
|
|
4202
|
+
const { t } = ae(), [n] = ne("company", ""), [a] = ne("from", ""), [s] = ne("to", ""), o = Qe(), [i, c] = v(n), l = He(i), y = (u) => qe(u, l), [d, p] = v(a), [m, f] = v(s), w = Ie(() => {
|
|
4180
4203
|
const u = {};
|
|
4181
4204
|
return n && (u.company = n), a && (u.from_date = a), s && (u.to_date = s), u;
|
|
4182
|
-
}, [n, a, s]), { data:
|
|
4205
|
+
}, [n, a, s]), { data: b, isLoading: g, refetch: P } = Vr(w), D = () => {
|
|
4183
4206
|
o({
|
|
4184
4207
|
company: i || null,
|
|
4185
4208
|
from: d || null,
|
|
4186
4209
|
to: m || null
|
|
4187
4210
|
}), P();
|
|
4188
|
-
}, T =
|
|
4211
|
+
}, T = b && (b.income && b.income.length > 0 || b.expense && b.expense.length > 0);
|
|
4189
4212
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4190
4213
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
4191
4214
|
/* @__PURE__ */ e(ke, { label: t("fields.Company", { defaultValue: "Company" }), value: i, onChange: c, linkDoctype: "company", readOnly: !1 }),
|
|
4192
|
-
/* @__PURE__ */ e(
|
|
4193
|
-
/* @__PURE__ */ e(
|
|
4215
|
+
/* @__PURE__ */ e(ee, { label: t("fields.From Date", { defaultValue: "From Date" }), type: "date", value: d, onChange: (u) => p(u.target.value) }),
|
|
4216
|
+
/* @__PURE__ */ e(ee, { label: t("fields.To Date", { defaultValue: "To Date" }), type: "date", value: m, onChange: (u) => f(u.target.value) }),
|
|
4194
4217
|
/* @__PURE__ */ e(J, { onClick: D, children: t("common.apply") })
|
|
4195
4218
|
] }),
|
|
4196
4219
|
/* @__PURE__ */ e(Ft, { onSelect: (u, h) => {
|
|
4197
4220
|
p(u), f(h), o({ from: u, to: h });
|
|
4198
4221
|
} }),
|
|
4199
|
-
|
|
4222
|
+
g ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) : T ? /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4200
4223
|
/* @__PURE__ */ r(U, { children: [
|
|
4201
4224
|
/* @__PURE__ */ e("h3", { className: "mb-3 text-base font-semibold text-gray-800", children: t("reports.income") }),
|
|
4202
4225
|
/* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
@@ -4204,13 +4227,13 @@ function Zr() {
|
|
|
4204
4227
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Account", { defaultValue: "Account" }) }),
|
|
4205
4228
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-right font-medium text-gray-500", children: t("fields.Amount", { defaultValue: "Amount" }) })
|
|
4206
4229
|
] }) }),
|
|
4207
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: (
|
|
4230
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: (b.income || []).map((u, h) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
|
|
4208
4231
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-900", children: u.account }),
|
|
4209
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children:
|
|
4232
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: y(u.amount) })
|
|
4210
4233
|
] }, h)) }),
|
|
4211
4234
|
/* @__PURE__ */ e("tfoot", { className: "border-t-2 border-gray-300 bg-gray-50 font-semibold", children: /* @__PURE__ */ r("tr", { children: [
|
|
4212
4235
|
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-gray-900", children: t("reports.totalIncome") }),
|
|
4213
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right", children:
|
|
4236
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right", children: y(b.total_income) })
|
|
4214
4237
|
] }) })
|
|
4215
4238
|
] })
|
|
4216
4239
|
] }),
|
|
@@ -4221,20 +4244,20 @@ function Zr() {
|
|
|
4221
4244
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Account", { defaultValue: "Account" }) }),
|
|
4222
4245
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-right font-medium text-gray-500", children: t("fields.Amount", { defaultValue: "Amount" }) })
|
|
4223
4246
|
] }) }),
|
|
4224
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: (
|
|
4247
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: (b.expense || []).map((u, h) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
|
|
4225
4248
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-900", children: u.account }),
|
|
4226
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children:
|
|
4249
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: y(u.amount) })
|
|
4227
4250
|
] }, h)) }),
|
|
4228
4251
|
/* @__PURE__ */ e("tfoot", { className: "border-t-2 border-gray-300 bg-gray-50 font-semibold", children: /* @__PURE__ */ r("tr", { children: [
|
|
4229
4252
|
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-gray-900", children: t("reports.totalExpenses") }),
|
|
4230
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right", children:
|
|
4253
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right", children: y(b.total_expense) })
|
|
4231
4254
|
] }) })
|
|
4232
4255
|
] })
|
|
4233
4256
|
] }),
|
|
4234
|
-
/* @__PURE__ */ e("div", { className: "text-center", children: /* @__PURE__ */ r("span", { className: `inline-flex items-center rounded-full px-5 py-2 text-sm font-semibold ${
|
|
4235
|
-
|
|
4257
|
+
/* @__PURE__ */ e("div", { className: "text-center", children: /* @__PURE__ */ r("span", { className: `inline-flex items-center rounded-full px-5 py-2 text-sm font-semibold ${b.net_profit >= 0 ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`, children: [
|
|
4258
|
+
b.net_profit >= 0 ? t("reports.netProfit") : t("reports.netLoss"),
|
|
4236
4259
|
": ",
|
|
4237
|
-
|
|
4260
|
+
y(Math.abs(b.net_profit))
|
|
4238
4261
|
] }) })
|
|
4239
4262
|
] }) : /* @__PURE__ */ e("p", { className: "py-8 text-center text-gray-400", children: t("reports.noData") })
|
|
4240
4263
|
] });
|
|
@@ -4248,10 +4271,10 @@ function Vt({ title: t, rows: n, total: a, totalLabel: s, currency: o }) {
|
|
|
4248
4271
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: i("fields.Account", { defaultValue: "Account" }) }),
|
|
4249
4272
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-right font-medium text-gray-500", children: i("fields.Balance", { defaultValue: "Balance" }) })
|
|
4250
4273
|
] }) }),
|
|
4251
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: n.map((l,
|
|
4274
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: n.map((l, y) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
|
|
4252
4275
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-900", children: l.account }),
|
|
4253
4276
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: c(l.balance) })
|
|
4254
|
-
] },
|
|
4277
|
+
] }, y)) }),
|
|
4255
4278
|
/* @__PURE__ */ e("tfoot", { className: "border-t-2 border-gray-300 bg-gray-50 font-semibold", children: /* @__PURE__ */ r("tr", { children: [
|
|
4256
4279
|
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-gray-900", children: s }),
|
|
4257
4280
|
/* @__PURE__ */ e("td", { className: "px-4 py-3 text-right", children: c(a) })
|
|
@@ -4261,25 +4284,25 @@ function Vt({ title: t, rows: n, total: a, totalLabel: s, currency: o }) {
|
|
|
4261
4284
|
}
|
|
4262
4285
|
function Xr() {
|
|
4263
4286
|
var D, T, u;
|
|
4264
|
-
const { t } = ae(), [n] = ne("company", ""), [a] = ne("as_of_date", ""), s = Qe(), [o, i] = v(n), [c, l] = v(a),
|
|
4287
|
+
const { t } = ae(), [n] = ne("company", ""), [a] = ne("as_of_date", ""), s = Qe(), [o, i] = v(n), [c, l] = v(a), y = He(o), d = (h) => qe(h, y), p = Ie(() => {
|
|
4265
4288
|
const h = {};
|
|
4266
4289
|
return n && (h.company = n), a && (h.as_of_date = a), h;
|
|
4267
|
-
}, [n, a]), { data: m, isLoading: f, refetch:
|
|
4268
|
-
s({ company: o || null, as_of_date: c || null }),
|
|
4269
|
-
},
|
|
4290
|
+
}, [n, a]), { data: m, isLoading: f, refetch: w } = jr(p), b = () => {
|
|
4291
|
+
s({ company: o || null, as_of_date: c || null }), w();
|
|
4292
|
+
}, g = m && (((D = m.assets) == null ? void 0 : D.length) > 0 || ((T = m.liabilities) == null ? void 0 : T.length) > 0 || ((u = m.equity) == null ? void 0 : u.length) > 0), P = m ? Math.abs(m.total_assets - m.total_liabilities_and_equity) < 0.01 : !1;
|
|
4270
4293
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4271
4294
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
4272
4295
|
/* @__PURE__ */ e(ke, { label: t("fields.Company", { defaultValue: "Company" }), value: o, onChange: i, linkDoctype: "company", readOnly: !1 }),
|
|
4273
|
-
/* @__PURE__ */ e(
|
|
4274
|
-
/* @__PURE__ */ e(J, { onClick:
|
|
4296
|
+
/* @__PURE__ */ e(ee, { label: t("fields.As of Date", { defaultValue: "As of Date" }), type: "date", value: c, onChange: (h) => l(h.target.value) }),
|
|
4297
|
+
/* @__PURE__ */ e(J, { onClick: b, children: t("common.apply") })
|
|
4275
4298
|
] }),
|
|
4276
4299
|
/* @__PURE__ */ e(ln, { onSelect: (h) => {
|
|
4277
4300
|
l(h), s({ as_of_date: h });
|
|
4278
4301
|
} }),
|
|
4279
|
-
f ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) :
|
|
4280
|
-
/* @__PURE__ */ e(Vt, { title: t("reports.assets"), rows: m.assets || [], total: m.total_assets, totalLabel: t("reports.totalAssets"), currency:
|
|
4281
|
-
/* @__PURE__ */ e(Vt, { title: t("reports.liabilities"), rows: m.liabilities || [], total: m.total_liabilities, totalLabel: t("reports.totalLiabilities"), currency:
|
|
4282
|
-
/* @__PURE__ */ e(Vt, { title: t("reports.equity"), rows: m.equity || [], total: m.total_equity, totalLabel: t("reports.totalEquity"), currency:
|
|
4302
|
+
f ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) : g ? /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4303
|
+
/* @__PURE__ */ e(Vt, { title: t("reports.assets"), rows: m.assets || [], total: m.total_assets, totalLabel: t("reports.totalAssets"), currency: y }),
|
|
4304
|
+
/* @__PURE__ */ e(Vt, { title: t("reports.liabilities"), rows: m.liabilities || [], total: m.total_liabilities, totalLabel: t("reports.totalLiabilities"), currency: y }),
|
|
4305
|
+
/* @__PURE__ */ e(Vt, { title: t("reports.equity"), rows: m.equity || [], total: m.total_equity, totalLabel: t("reports.totalEquity"), currency: y }),
|
|
4283
4306
|
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
|
|
4284
4307
|
/* @__PURE__ */ r("div", { className: "text-sm", children: [
|
|
4285
4308
|
/* @__PURE__ */ r("div", { className: "text-gray-500", children: [
|
|
@@ -4299,20 +4322,20 @@ function Xr() {
|
|
|
4299
4322
|
] });
|
|
4300
4323
|
}
|
|
4301
4324
|
function es() {
|
|
4302
|
-
const { t } = ae(), [n] = ne("company", ""), [a] = ne("as_of_date", ""), s = Qe(), [o, i] = v(n), [c, l] = v(a),
|
|
4303
|
-
const
|
|
4304
|
-
return n && (
|
|
4305
|
-
}, [n, a]), { data: m, isLoading: f, refetch:
|
|
4306
|
-
s({ company: o || null, as_of_date: c || null }),
|
|
4325
|
+
const { t } = ae(), [n] = ne("company", ""), [a] = ne("as_of_date", ""), s = Qe(), [o, i] = v(n), [c, l] = v(a), y = He(o), d = (g) => qe(g, y), p = Ie(() => {
|
|
4326
|
+
const g = {};
|
|
4327
|
+
return n && (g.company = n), a && (g.as_of_date = a), g;
|
|
4328
|
+
}, [n, a]), { data: m, isLoading: f, refetch: w } = Gr(p), b = () => {
|
|
4329
|
+
s({ company: o || null, as_of_date: c || null }), w();
|
|
4307
4330
|
};
|
|
4308
4331
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4309
4332
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
4310
4333
|
/* @__PURE__ */ e(ke, { label: t("fields.Company", { defaultValue: "Company" }), value: o, onChange: i, linkDoctype: "company", readOnly: !1 }),
|
|
4311
|
-
/* @__PURE__ */ e(
|
|
4312
|
-
/* @__PURE__ */ e(J, { onClick:
|
|
4334
|
+
/* @__PURE__ */ e(ee, { label: t("fields.As of Date", { defaultValue: "As of Date" }), type: "date", value: c, onChange: (g) => l(g.target.value) }),
|
|
4335
|
+
/* @__PURE__ */ e(J, { onClick: b, children: t("common.apply") })
|
|
4313
4336
|
] }),
|
|
4314
|
-
/* @__PURE__ */ e(ln, { onSelect: (
|
|
4315
|
-
l(
|
|
4337
|
+
/* @__PURE__ */ e(ln, { onSelect: (g) => {
|
|
4338
|
+
l(g), s({ as_of_date: g });
|
|
4316
4339
|
} }),
|
|
4317
4340
|
f ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) : !m || !m.rows || m.rows.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-gray-400", children: t("reports.noReceivables") }) : /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
4318
4341
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
@@ -4326,23 +4349,23 @@ function es() {
|
|
|
4326
4349
|
/* @__PURE__ */ e("th", { className: "px-3 py-3 text-right font-medium text-gray-500", children: "61-90" }),
|
|
4327
4350
|
/* @__PURE__ */ e("th", { className: "px-3 py-3 text-right font-medium text-gray-500", children: "90+" })
|
|
4328
4351
|
] }) }),
|
|
4329
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: m.rows.map((
|
|
4352
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: m.rows.map((g, P) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
|
|
4330
4353
|
/* @__PURE__ */ e("td", { className: "px-3 py-2", children: /* @__PURE__ */ e(
|
|
4331
4354
|
Ne,
|
|
4332
4355
|
{
|
|
4333
|
-
to: `/app/sales-invoice/${encodeURIComponent(
|
|
4356
|
+
to: `/app/sales-invoice/${encodeURIComponent(g.invoice)}`,
|
|
4334
4357
|
className: "font-medium text-blue-600 hover:text-blue-800",
|
|
4335
|
-
children:
|
|
4358
|
+
children: g.invoice
|
|
4336
4359
|
}
|
|
4337
4360
|
) }),
|
|
4338
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-gray-900", children:
|
|
4339
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-gray-600", children:
|
|
4340
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right font-medium", children: d(
|
|
4341
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children:
|
|
4342
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children:
|
|
4343
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children:
|
|
4344
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children:
|
|
4345
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right text-red-600", children:
|
|
4361
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-gray-900", children: g.customer_name }),
|
|
4362
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-gray-600", children: g.due_date }),
|
|
4363
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right font-medium", children: d(g.outstanding) }),
|
|
4364
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children: g.current ? d(g.current) : "" }),
|
|
4365
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children: g.b1_30 ? d(g.b1_30) : "" }),
|
|
4366
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children: g.b31_60 ? d(g.b31_60) : "" }),
|
|
4367
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children: g.b61_90 ? d(g.b61_90) : "" }),
|
|
4368
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right text-red-600", children: g.b90_plus ? d(g.b90_plus) : "" })
|
|
4346
4369
|
] }, P)) }),
|
|
4347
4370
|
/* @__PURE__ */ e("tfoot", { className: "border-t-2 border-gray-300 bg-gray-50 font-semibold", children: /* @__PURE__ */ r("tr", { children: [
|
|
4348
4371
|
/* @__PURE__ */ e("td", { className: "px-3 py-3", colSpan: 3, children: t("common.total") }),
|
|
@@ -4357,20 +4380,20 @@ function es() {
|
|
|
4357
4380
|
] });
|
|
4358
4381
|
}
|
|
4359
4382
|
function ts() {
|
|
4360
|
-
const { t } = ae(), [n] = ne("company", ""), [a] = ne("as_of_date", ""), s = Qe(), [o, i] = v(n), [c, l] = v(a),
|
|
4361
|
-
const
|
|
4362
|
-
return n && (
|
|
4363
|
-
}, [n, a]), { data: m, isLoading: f, refetch:
|
|
4364
|
-
s({ company: o || null, as_of_date: c || null }),
|
|
4383
|
+
const { t } = ae(), [n] = ne("company", ""), [a] = ne("as_of_date", ""), s = Qe(), [o, i] = v(n), [c, l] = v(a), y = He(o), d = (g) => qe(g, y), p = Ie(() => {
|
|
4384
|
+
const g = {};
|
|
4385
|
+
return n && (g.company = n), a && (g.as_of_date = a), g;
|
|
4386
|
+
}, [n, a]), { data: m, isLoading: f, refetch: w } = Kr(p), b = () => {
|
|
4387
|
+
s({ company: o || null, as_of_date: c || null }), w();
|
|
4365
4388
|
};
|
|
4366
4389
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4367
4390
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
4368
4391
|
/* @__PURE__ */ e(ke, { label: t("fields.Company", { defaultValue: "Company" }), value: o, onChange: i, linkDoctype: "company", readOnly: !1 }),
|
|
4369
|
-
/* @__PURE__ */ e(
|
|
4370
|
-
/* @__PURE__ */ e(J, { onClick:
|
|
4392
|
+
/* @__PURE__ */ e(ee, { label: t("fields.As of Date", { defaultValue: "As of Date" }), type: "date", value: c, onChange: (g) => l(g.target.value) }),
|
|
4393
|
+
/* @__PURE__ */ e(J, { onClick: b, children: t("common.apply") })
|
|
4371
4394
|
] }),
|
|
4372
|
-
/* @__PURE__ */ e(ln, { onSelect: (
|
|
4373
|
-
l(
|
|
4395
|
+
/* @__PURE__ */ e(ln, { onSelect: (g) => {
|
|
4396
|
+
l(g), s({ as_of_date: g });
|
|
4374
4397
|
} }),
|
|
4375
4398
|
f ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) : !m || !m.rows || m.rows.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-gray-400", children: t("reports.noPayables") }) : /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
4376
4399
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
@@ -4384,23 +4407,23 @@ function ts() {
|
|
|
4384
4407
|
/* @__PURE__ */ e("th", { className: "px-3 py-3 text-right font-medium text-gray-500", children: "61-90" }),
|
|
4385
4408
|
/* @__PURE__ */ e("th", { className: "px-3 py-3 text-right font-medium text-gray-500", children: "90+" })
|
|
4386
4409
|
] }) }),
|
|
4387
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: m.rows.map((
|
|
4410
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: m.rows.map((g, P) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
|
|
4388
4411
|
/* @__PURE__ */ e("td", { className: "px-3 py-2", children: /* @__PURE__ */ e(
|
|
4389
4412
|
Ne,
|
|
4390
4413
|
{
|
|
4391
|
-
to: `/app/purchase-invoice/${encodeURIComponent(
|
|
4414
|
+
to: `/app/purchase-invoice/${encodeURIComponent(g.invoice)}`,
|
|
4392
4415
|
className: "font-medium text-blue-600 hover:text-blue-800",
|
|
4393
|
-
children:
|
|
4416
|
+
children: g.invoice
|
|
4394
4417
|
}
|
|
4395
4418
|
) }),
|
|
4396
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-gray-900", children:
|
|
4397
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-gray-600", children:
|
|
4398
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right font-medium", children: d(
|
|
4399
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children:
|
|
4400
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children:
|
|
4401
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children:
|
|
4402
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children:
|
|
4403
|
-
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right text-red-600", children:
|
|
4419
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-gray-900", children: g.supplier_name }),
|
|
4420
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-gray-600", children: g.due_date }),
|
|
4421
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right font-medium", children: d(g.outstanding) }),
|
|
4422
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children: g.current ? d(g.current) : "" }),
|
|
4423
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children: g.b1_30 ? d(g.b1_30) : "" }),
|
|
4424
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children: g.b31_60 ? d(g.b31_60) : "" }),
|
|
4425
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right", children: g.b61_90 ? d(g.b61_90) : "" }),
|
|
4426
|
+
/* @__PURE__ */ e("td", { className: "px-3 py-2 text-right text-red-600", children: g.b90_plus ? d(g.b90_plus) : "" })
|
|
4404
4427
|
] }, P)) }),
|
|
4405
4428
|
/* @__PURE__ */ e("tfoot", { className: "border-t-2 border-gray-300 bg-gray-50 font-semibold", children: /* @__PURE__ */ r("tr", { children: [
|
|
4406
4429
|
/* @__PURE__ */ e("td", { className: "px-3 py-3", colSpan: 3, children: t("common.total") }),
|
|
@@ -4414,7 +4437,7 @@ function ts() {
|
|
|
4414
4437
|
] }) }) })
|
|
4415
4438
|
] });
|
|
4416
4439
|
}
|
|
4417
|
-
const
|
|
4440
|
+
const ia = '(function(){"use strict";function u(r,t){const e=Number(r??0)||0;return t==null?e:Number(e.toFixed(t))}const p={flt:u,sum(r,t){return r.reduce((e,a)=>typeof t=="function"?e+u(t(a)):typeof t=="string"?e+u(a[t]):e+u(a),0)},count(r){return r.length},sortBy(r,t,e="asc"){const n=(e===!0?"desc":e===!1?"asc":e)==="desc"?-1:1;return[...r].sort((s,i)=>{const c=s[t],o=i[t];return c==null&&o==null?0:c==null?1:o==null?-1:c<o?-1*n:c>o?1*n:0})},topN(r,t,e=10){return typeof t=="number"?r.slice(0,t):p.sortBy(r,t,"desc").slice(0,e)},group(r,t,e){if(typeof t=="function"){const s=new Map;for(const i of r){const c=t(i),o=JSON.stringify(c);s.has(o)||s.set(o,{key:c,rows:[]}),s.get(o).rows.push(i)}return Array.from(s.values())}const a=t,n=new Map;for(const s of r){const i=a.map(f=>s[f]),c=JSON.stringify(i);if(!n.has(c)){const f={};a.forEach((l,m)=>{f[l]=i[m]});for(const[l,[m]]of Object.entries(e||{}))f[l]=0;n.set(c,f)}const o=n.get(c);for(const[f,[l,m]]of Object.entries(e||{}))l==="count"?o[f]=u(o[f])+1:o[f]=u(o[f])+u(s[m||f])}return Array.from(n.values())},leftJoin(r,t,e,a=e){const n=new Map(t.map(s=>[s[a],s]));return r.map(s=>({...s,...n.get(s[e])||{}}))},monthKey(r){return String(r??"").slice(0,7)},quarterKey(r){const t=String(r??""),e=t.slice(0,4),a=Number(t.slice(5,7));return!e||!a?"":`${e}-Q${Math.floor((a+2)/3)}`},yearKey(r){return String(r??"").slice(0,4)},pivot(r,t,e,a){const n=new Map;for(const s of r){const i=String(s[t]??"—"),c=String(s[e]??"—");n.has(i)||n.set(i,{[t]:i});const o=n.get(i);o[c]=u(o[c])+u(s[a])}return Array.from(n.values())}};function y(r){if(!r||typeof r!="object")throw new Error("Transform must return an object");if(r.tables&&!Array.isArray(r.tables))throw new Error("tables must be an array");if(r.charts&&!Array.isArray(r.charts))throw new Error("charts must be an array");if(r.kpis&&!Array.isArray(r.kpis))throw new Error("kpis must be an array");return r}self.onmessage=r=>{try{const t=Object.fromEntries(r.data.datasets.map(s=>[s.name,s.rows])),e=r.data.datasets.map(s=>s.name).filter(s=>/^[$A-Z_][0-9A-Z_$]*$/i.test(s)).map(s=>`const ${s} = datasets[${JSON.stringify(s)}];`).join(`\n`),n=new Function("datasets","params","helpers",`"use strict";\n${e}\n${r.data.transformJs}`)(t,r.data.params||{},p);self.postMessage({ok:!0,output:y(n)})}catch(t){self.postMessage({ok:!1,error:t instanceof Error?t.message:String(t)})}}})();\n//# sourceMappingURL=report-runtime.worker-DrBTCfV6.js.map\n', Tn = typeof self < "u" && self.Blob && new Blob([ia], { type: "text/javascript;charset=utf-8" });
|
|
4418
4441
|
function ns(t) {
|
|
4419
4442
|
let n;
|
|
4420
4443
|
try {
|
|
@@ -4427,7 +4450,7 @@ function ns(t) {
|
|
|
4427
4450
|
}), a;
|
|
4428
4451
|
} catch {
|
|
4429
4452
|
return new Worker(
|
|
4430
|
-
"data:text/javascript;charset=utf-8," + encodeURIComponent(
|
|
4453
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(ia),
|
|
4431
4454
|
{
|
|
4432
4455
|
name: t == null ? void 0 : t.name
|
|
4433
4456
|
}
|
|
@@ -4507,31 +4530,31 @@ return {
|
|
|
4507
4530
|
2
|
|
4508
4531
|
);
|
|
4509
4532
|
}
|
|
4510
|
-
const
|
|
4533
|
+
const oa = as();
|
|
4511
4534
|
function rs() {
|
|
4512
|
-
const t = Oe(), { sessions: n, createSession: a } = ct(), [s] = ne("report_id", ""), [o] = ne("metric", ""), [i] = ne("group_by", ""), [c] = ne("from", ""), [l] = ne("to", ""), [
|
|
4535
|
+
const t = Oe(), { sessions: n, createSession: a } = ct(), [s] = ne("report_id", ""), [o] = ne("metric", ""), [i] = ne("group_by", ""), [c] = ne("from", ""), [l] = ne("to", ""), [y] = ne("company", ""), [d, p] = v(oa), [m, f] = v([]), [w, b] = v(null), [g, P] = v(""), [D, T] = v(!1), [u, h] = v(!1), [A, R] = v(""), S = X(null), H = X(""), $ = X(""), z = X(0), k = Ie(() => !o || !i ? "" : JSON.stringify(ls({
|
|
4513
4536
|
metric: o,
|
|
4514
4537
|
groupBy: i,
|
|
4515
4538
|
fromDate: c || void 0,
|
|
4516
4539
|
toDate: l || void 0,
|
|
4517
|
-
company:
|
|
4518
|
-
}), null, 2), [o, i, c, l,
|
|
4540
|
+
company: y || void 0
|
|
4541
|
+
}), null, 2), [o, i, c, l, y]), K = async (F) => {
|
|
4519
4542
|
var he;
|
|
4520
4543
|
const Z = ++z.current, re = () => z.current === Z;
|
|
4521
4544
|
P(""), T(!0);
|
|
4522
4545
|
try {
|
|
4523
4546
|
const _e = JSON.parse(F ?? d), me = await L.runtimeData({ requests: _e.data_requests || [] });
|
|
4524
4547
|
if (!re()) return;
|
|
4525
|
-
f(me.datasets), (he =
|
|
4548
|
+
f(me.datasets), (he = S.current) == null || he.terminate();
|
|
4526
4549
|
const ye = new ns();
|
|
4527
|
-
|
|
4550
|
+
S.current = ye;
|
|
4528
4551
|
const ze = await new Promise((I, te) => {
|
|
4529
4552
|
const Ae = window.setTimeout(() => {
|
|
4530
4553
|
ye.terminate(), te(new Error("Report runtime exceeded 4 seconds"));
|
|
4531
4554
|
}, 4e3);
|
|
4532
4555
|
ye.onmessage = (Ce) => {
|
|
4533
4556
|
var $e, Fe;
|
|
4534
|
-
window.clearTimeout(Ae), ye.terminate(),
|
|
4557
|
+
window.clearTimeout(Ae), ye.terminate(), S.current === ye && (S.current = null), ($e = Ce.data) != null && $e.ok ? I(Ce.data.output) : te(new Error(((Fe = Ce.data) == null ? void 0 : Fe.error) || "Runtime failed"));
|
|
4535
4558
|
}, ye.postMessage({
|
|
4536
4559
|
datasets: me.datasets,
|
|
4537
4560
|
params: {},
|
|
@@ -4539,31 +4562,31 @@ function rs() {
|
|
|
4539
4562
|
});
|
|
4540
4563
|
});
|
|
4541
4564
|
if (!re()) return;
|
|
4542
|
-
|
|
4565
|
+
b(ze);
|
|
4543
4566
|
} catch (ge) {
|
|
4544
4567
|
if (!re()) return;
|
|
4545
|
-
|
|
4568
|
+
b(null), P(ge instanceof Error ? ge.message : String(ge));
|
|
4546
4569
|
} finally {
|
|
4547
4570
|
re() && T(!1);
|
|
4548
4571
|
}
|
|
4549
4572
|
};
|
|
4550
|
-
|
|
4573
|
+
se(() => {
|
|
4551
4574
|
let F = !1;
|
|
4552
4575
|
return s ? H.current === s ? void 0 : (h(!0), P(""), L.getRuntimeDraft(s).then((Z) => {
|
|
4553
4576
|
if (F) return;
|
|
4554
4577
|
const re = JSON.stringify(Z.definition, null, 2);
|
|
4555
4578
|
return H.current = s, $.current = re, R(Z.source_chat_session_id || ""), p(re), K(re);
|
|
4556
4579
|
}).catch((Z) => {
|
|
4557
|
-
F || (
|
|
4580
|
+
F || (b(null), P(Z instanceof Error ? Z.message : String(Z)));
|
|
4558
4581
|
}).finally(() => {
|
|
4559
4582
|
F || h(!1);
|
|
4560
4583
|
}), () => {
|
|
4561
4584
|
F = !0;
|
|
4562
|
-
}) : (H.current = "", $.current = "", R(""),
|
|
4585
|
+
}) : (H.current = "", $.current = "", R(""), k && ($.current = k, p(k), K(k)), () => {
|
|
4563
4586
|
F = !0;
|
|
4564
4587
|
});
|
|
4565
|
-
}, [s,
|
|
4566
|
-
const N = !!(!s &&
|
|
4588
|
+
}, [s, k]);
|
|
4589
|
+
const N = !!(!s && k), B = Ie(() => os(w), [w]), C = async () => {
|
|
4567
4590
|
var me;
|
|
4568
4591
|
const F = d.trim() !== $.current.trim(), Z = s || "unsaved-runtime-report", re = m.map((ye) => ({
|
|
4569
4592
|
name: ye.name,
|
|
@@ -4576,7 +4599,7 @@ function rs() {
|
|
|
4576
4599
|
`Report ID: ${Z}`,
|
|
4577
4600
|
"",
|
|
4578
4601
|
"Current issue summary:",
|
|
4579
|
-
|
|
4602
|
+
g || B.join(`
|
|
4580
4603
|
`) || "No runtime error captured; please review and improve the report definition."
|
|
4581
4604
|
];
|
|
4582
4605
|
F ? he.push(
|
|
@@ -4615,7 +4638,7 @@ function rs() {
|
|
|
4615
4638
|
/* @__PURE__ */ e(J, { onClick: () => void K(), disabled: D, children: D ? "Running..." : "Run Report" })
|
|
4616
4639
|
] })
|
|
4617
4640
|
] }) }),
|
|
4618
|
-
u ? /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("p", { className: "text-sm text-gray-600", children: "Loading draft..." }) }) :
|
|
4641
|
+
u ? /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("p", { className: "text-sm text-gray-600", children: "Loading draft..." }) }) : g ? /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("p", { className: "text-sm text-red-600", children: g }) }) : w ? /* @__PURE__ */ e(ss, { output: w }) : /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("p", { className: "text-sm text-gray-600", children: "Edit the runtime JSON below or open a draft from chat, then run the report." }) }),
|
|
4619
4642
|
m.length > 0 && /* @__PURE__ */ e(U, { title: "Fetched Datasets", children: /* @__PURE__ */ e("div", { className: "space-y-4", children: m.map((F) => /* @__PURE__ */ r("div", { className: "rounded-md border border-gray-200 p-4", children: [
|
|
4620
4643
|
/* @__PURE__ */ r("div", { className: "flex items-baseline justify-between gap-4", children: [
|
|
4621
4644
|
/* @__PURE__ */ r("div", { children: [
|
|
@@ -4649,7 +4672,7 @@ function ss({ output: t }) {
|
|
|
4649
4672
|
const n = (t.tables ?? []).map((i, c) => ({
|
|
4650
4673
|
...i,
|
|
4651
4674
|
id: i.id || `table_${c + 1}`
|
|
4652
|
-
})), a =
|
|
4675
|
+
})), a = la(n);
|
|
4653
4676
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4654
4677
|
/* @__PURE__ */ r(U, { children: [
|
|
4655
4678
|
/* @__PURE__ */ e("div", { className: "flex items-baseline justify-between gap-4", children: /* @__PURE__ */ r("div", { children: [
|
|
@@ -4662,13 +4685,13 @@ function ss({ output: t }) {
|
|
|
4662
4685
|
] }, `${i.label}-${c}`)) }) : null
|
|
4663
4686
|
] }),
|
|
4664
4687
|
(o = t.charts) == null ? void 0 : o.map((i, c) => {
|
|
4665
|
-
const l = i.dataTable ? a.get(i.dataTable) : void 0,
|
|
4666
|
-
if (!
|
|
4688
|
+
const l = i.dataTable ? a.get(i.dataTable) : void 0, y = i.data ?? (l == null ? void 0 : l.rows) ?? [];
|
|
4689
|
+
if (!y.length)
|
|
4667
4690
|
return /* @__PURE__ */ e(U, { title: i.title, children: /* @__PURE__ */ e("p", { className: "text-sm text-red-600", children: "Chart has no usable data." }) }, i.id || `chart_${c + 1}`);
|
|
4668
|
-
const d = i.type === "pie" ? [] :
|
|
4691
|
+
const d = i.type === "pie" ? [] : y.map((f) => String(f[i.x] ?? "")), p = ms(d), m = Math.max(320, 200 + p.axisHeight);
|
|
4669
4692
|
return /* @__PURE__ */ r(U, { children: [
|
|
4670
4693
|
/* @__PURE__ */ e("div", { className: "pb-3 text-sm font-semibold text-gray-700", children: i.title }),
|
|
4671
|
-
/* @__PURE__ */ e("div", { style: { height: m }, className: "w-full", children: /* @__PURE__ */ e(Ma, { width: "100%", height: "100%", children: i.type === "line" ? /* @__PURE__ */ r(za, { data:
|
|
4694
|
+
/* @__PURE__ */ e("div", { style: { height: m }, className: "w-full", children: /* @__PURE__ */ e(Ma, { width: "100%", height: "100%", children: i.type === "line" ? /* @__PURE__ */ r(za, { data: y, margin: { top: 10, right: 20, left: 0, bottom: 0 }, children: [
|
|
4672
4695
|
/* @__PURE__ */ e(un, { strokeDasharray: "3 3", stroke: "#f3f4f6" }),
|
|
4673
4696
|
/* @__PURE__ */ e(
|
|
4674
4697
|
mn,
|
|
@@ -4686,8 +4709,8 @@ function ss({ output: t }) {
|
|
|
4686
4709
|
/* @__PURE__ */ e($a, { type: "monotone", dataKey: i.y, stroke: "#3b82f6", strokeWidth: 2, dot: { r: 3 } })
|
|
4687
4710
|
] }) : i.type === "pie" ? /* @__PURE__ */ r(Ua, { children: [
|
|
4688
4711
|
/* @__PURE__ */ e(zt, { formatter: (f) => kt(f, jt(l, i.y)) }),
|
|
4689
|
-
/* @__PURE__ */ e(Va, { data:
|
|
4690
|
-
] }) : /* @__PURE__ */ r(Ga, { data:
|
|
4712
|
+
/* @__PURE__ */ e(Va, { data: y, dataKey: i.y, nameKey: i.x, outerRadius: 110, children: y.map((f, w) => /* @__PURE__ */ e(ja, { fill: Rn[w % Rn.length] }, w)) })
|
|
4713
|
+
] }) : /* @__PURE__ */ r(Ga, { data: y, margin: { top: 10, right: 20, left: 0, bottom: 0 }, children: [
|
|
4691
4714
|
/* @__PURE__ */ e(un, { strokeDasharray: "3 3", stroke: "#f3f4f6" }),
|
|
4692
4715
|
/* @__PURE__ */ e(
|
|
4693
4716
|
mn,
|
|
@@ -4708,14 +4731,14 @@ function ss({ output: t }) {
|
|
|
4708
4731
|
}),
|
|
4709
4732
|
n.map((i) => /* @__PURE__ */ e(U, { title: i.title, children: /* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
4710
4733
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ e("tr", { children: i.columns.map((c) => /* @__PURE__ */ e("th", { className: "px-4 py-2 text-left font-medium text-gray-500", children: c.label }, c.key)) }) }),
|
|
4711
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: i.rows.map((c, l) => /* @__PURE__ */ e("tr", { className: "hover:bg-gray-50", children: i.columns.map((
|
|
4734
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: i.rows.map((c, l) => /* @__PURE__ */ e("tr", { className: "hover:bg-gray-50", children: i.columns.map((y) => /* @__PURE__ */ e("td", { className: "px-4 py-1.5 text-gray-900", children: kt(c[y.key], y.type) }, y.key)) }, l)) })
|
|
4712
4735
|
] }) }) }, i.id))
|
|
4713
4736
|
] });
|
|
4714
4737
|
}
|
|
4715
4738
|
function is(t) {
|
|
4716
4739
|
return t.replace(/_/g, " ").replace(/\b\w/g, (n) => n.toUpperCase());
|
|
4717
4740
|
}
|
|
4718
|
-
function
|
|
4741
|
+
function la(t) {
|
|
4719
4742
|
const n = /* @__PURE__ */ new Map();
|
|
4720
4743
|
for (const a of t)
|
|
4721
4744
|
n.set(a.id, a), a.title && n.set(a.title, a);
|
|
@@ -4726,7 +4749,7 @@ function os(t) {
|
|
|
4726
4749
|
const n = (t.tables ?? []).map((o, i) => ({
|
|
4727
4750
|
...o,
|
|
4728
4751
|
id: o.id || `table_${i + 1}`
|
|
4729
|
-
})), a =
|
|
4752
|
+
})), a = la(n), s = [];
|
|
4730
4753
|
for (const o of t.charts ?? []) {
|
|
4731
4754
|
const i = o.dataTable ? a.get(o.dataTable) : void 0, c = o.data ?? (i == null ? void 0 : i.rows) ?? [];
|
|
4732
4755
|
if (!c.length) {
|
|
@@ -4841,7 +4864,7 @@ function ls(t) {
|
|
|
4841
4864
|
},
|
|
4842
4865
|
fields: [t.groupBy === "warehouse" ? "warehouse" : "item_code", "stock_value"],
|
|
4843
4866
|
chartType: "bar"
|
|
4844
|
-
}) : JSON.parse(
|
|
4867
|
+
}) : JSON.parse(oa);
|
|
4845
4868
|
}
|
|
4846
4869
|
function gt(t) {
|
|
4847
4870
|
const n = Object.fromEntries(Object.entries(t.filters).filter(([, s]) => s !== void 0)), a = ["month", "quarter", "year"].includes(t.groupBy) ? `${t.timeBucket}(row.${t.keyField})` : `row.${t.keyField} || "—"`;
|
|
@@ -4941,7 +4964,7 @@ function hs() {
|
|
|
4941
4964
|
const t = We(), { data: n, isLoading: a } = le({
|
|
4942
4965
|
queryKey: ["setup-status"],
|
|
4943
4966
|
queryFn: () => L.setupStatus()
|
|
4944
|
-
}), [s, o] = v(""), [i, c] = v("USD"), [l,
|
|
4967
|
+
}), [s, o] = v(""), [i, c] = v("USD"), [l, y] = v({
|
|
4945
4968
|
address: "",
|
|
4946
4969
|
city: "",
|
|
4947
4970
|
zip_code: "",
|
|
@@ -4949,7 +4972,7 @@ function hs() {
|
|
|
4949
4972
|
email: "",
|
|
4950
4973
|
phone: "",
|
|
4951
4974
|
tax_id: ""
|
|
4952
|
-
}), d = (R) => (
|
|
4975
|
+
}), d = (R) => (S) => y((H) => ({ ...H, [R]: S.target.value })), [p, m] = v("quick"), [f, w] = v(!1), [b, g] = v(null), P = oe({
|
|
4953
4976
|
mutationFn: () => L.createCompany({ name: s, currency: i, ...l })
|
|
4954
4977
|
}), D = oe({
|
|
4955
4978
|
mutationFn: () => L.seedDemo()
|
|
@@ -4960,9 +4983,9 @@ function hs() {
|
|
|
4960
4983
|
try {
|
|
4961
4984
|
if (await P.mutateAsync(), p === "history") {
|
|
4962
4985
|
const R = await T.mutateAsync();
|
|
4963
|
-
|
|
4986
|
+
g(R.stats);
|
|
4964
4987
|
} else p === "quick" && await D.mutateAsync();
|
|
4965
|
-
t.invalidateQueries({ queryKey: ["setup-status"] }),
|
|
4988
|
+
t.invalidateQueries({ queryKey: ["setup-status"] }), w(!0);
|
|
4966
4989
|
} catch {
|
|
4967
4990
|
}
|
|
4968
4991
|
};
|
|
@@ -4970,18 +4993,18 @@ function hs() {
|
|
|
4970
4993
|
return /* @__PURE__ */ e("p", { className: "text-gray-500", children: "Loading..." });
|
|
4971
4994
|
if (n != null && n.setup_complete && !f)
|
|
4972
4995
|
return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
4973
|
-
/* @__PURE__ */ e(U, { title: "Companies", children: n.companies && n.companies.length > 0 ? /* @__PURE__ */ e("ul", { className: "divide-y divide-gray-100", children: n.companies.map((R,
|
|
4996
|
+
/* @__PURE__ */ e(U, { title: "Companies", children: n.companies && n.companies.length > 0 ? /* @__PURE__ */ e("ul", { className: "divide-y divide-gray-100", children: n.companies.map((R, S) => /* @__PURE__ */ e("li", { className: "py-3", children: /* @__PURE__ */ e(gs, { company: R }) }, S)) }) : /* @__PURE__ */ e("p", { className: "text-gray-400", children: "No companies found" }) }),
|
|
4974
4997
|
/* @__PURE__ */ e(Ne, { to: "/", className: "text-blue-600 hover:text-blue-800 text-sm font-medium", children: "Go to Dashboard" })
|
|
4975
4998
|
] });
|
|
4976
4999
|
if (f)
|
|
4977
5000
|
return /* @__PURE__ */ e("div", { className: "space-y-6", children: /* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "py-8 text-center", children: [
|
|
4978
5001
|
/* @__PURE__ */ e("p", { className: "text-lg font-semibold text-green-700", children: "Setup complete!" }),
|
|
4979
5002
|
/* @__PURE__ */ e("p", { className: "mt-2 text-sm text-gray-500", children: p === "history" ? "Your company has been created and three years of history has been simulated." : p === "quick" ? "Your company has been created and demo data has been seeded." : "Your company has been created. No demo data was added." }),
|
|
4980
|
-
|
|
5003
|
+
b && /* @__PURE__ */ r("div", { className: "mx-auto mt-6 max-w-sm text-left", children: [
|
|
4981
5004
|
/* @__PURE__ */ e("p", { className: "mb-2 text-sm font-medium text-gray-700", children: "Generated documents:" }),
|
|
4982
|
-
/* @__PURE__ */ e("ul", { className: "divide-y divide-gray-100 text-sm", children: Object.entries(
|
|
5005
|
+
/* @__PURE__ */ e("ul", { className: "divide-y divide-gray-100 text-sm", children: Object.entries(b).sort(([R], [S]) => R.localeCompare(S)).map(([R, S]) => /* @__PURE__ */ r("li", { className: "flex justify-between py-1", children: [
|
|
4983
5006
|
/* @__PURE__ */ e("span", { className: "text-gray-600", children: R.replace(/_/g, " ") }),
|
|
4984
|
-
/* @__PURE__ */ e("span", { className: "font-mono text-gray-900", children:
|
|
5007
|
+
/* @__PURE__ */ e("span", { className: "font-mono text-gray-900", children: S.toLocaleString() })
|
|
4985
5008
|
] }, R)) })
|
|
4986
5009
|
] }),
|
|
4987
5010
|
/* @__PURE__ */ e("div", { className: "mt-6", children: /* @__PURE__ */ e(Ne, { to: "/", children: /* @__PURE__ */ e(J, { children: "Go to Dashboard" }) }) })
|
|
@@ -4992,7 +5015,7 @@ function hs() {
|
|
|
4992
5015
|
A && /* @__PURE__ */ e("div", { className: "rounded-md bg-red-50 p-4 text-sm text-red-700", children: A.message ?? "An error occurred during setup" }),
|
|
4993
5016
|
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4994
5017
|
/* @__PURE__ */ e(
|
|
4995
|
-
|
|
5018
|
+
ee,
|
|
4996
5019
|
{
|
|
4997
5020
|
label: "Company Name",
|
|
4998
5021
|
value: s,
|
|
@@ -5014,7 +5037,7 @@ function hs() {
|
|
|
5014
5037
|
/* @__PURE__ */ e("legend", { className: "mb-1 text-sm font-medium text-gray-700", children: "Company details" }),
|
|
5015
5038
|
/* @__PURE__ */ e("p", { className: "text-xs text-gray-500", children: "These appear on your invoices and other PDFs. Optional now — you can fill or change them later under Masters → Company." }),
|
|
5016
5039
|
/* @__PURE__ */ e(
|
|
5017
|
-
|
|
5040
|
+
ee,
|
|
5018
5041
|
{
|
|
5019
5042
|
label: "Address",
|
|
5020
5043
|
value: l.address,
|
|
@@ -5023,16 +5046,16 @@ function hs() {
|
|
|
5023
5046
|
}
|
|
5024
5047
|
),
|
|
5025
5048
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
5026
|
-
/* @__PURE__ */ e(
|
|
5027
|
-
/* @__PURE__ */ e(
|
|
5049
|
+
/* @__PURE__ */ e(ee, { label: "City", value: l.city, onChange: d("city") }),
|
|
5050
|
+
/* @__PURE__ */ e(ee, { label: "ZIP / Postal code", value: l.zip_code, onChange: d("zip_code") })
|
|
5028
5051
|
] }),
|
|
5029
5052
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
5030
|
-
/* @__PURE__ */ e(
|
|
5031
|
-
/* @__PURE__ */ e(
|
|
5053
|
+
/* @__PURE__ */ e(ee, { label: "Country", value: l.country, onChange: d("country") }),
|
|
5054
|
+
/* @__PURE__ */ e(ee, { label: "Tax ID / VAT", value: l.tax_id, onChange: d("tax_id") })
|
|
5032
5055
|
] }),
|
|
5033
5056
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
5034
|
-
/* @__PURE__ */ e(
|
|
5035
|
-
/* @__PURE__ */ e(
|
|
5057
|
+
/* @__PURE__ */ e(ee, { label: "Email", value: l.email, onChange: d("email") }),
|
|
5058
|
+
/* @__PURE__ */ e(ee, { label: "Phone", value: l.phone, onChange: d("phone") })
|
|
5036
5059
|
] })
|
|
5037
5060
|
] }),
|
|
5038
5061
|
/* @__PURE__ */ r("fieldset", { className: "space-y-2", children: [
|
|
@@ -5280,8 +5303,8 @@ const ys = [
|
|
|
5280
5303
|
];
|
|
5281
5304
|
function fs() {
|
|
5282
5305
|
const t = Oe(), { t: n } = ae(), { sessions: a, createSession: s } = ct(), o = async (c) => {
|
|
5283
|
-
var
|
|
5284
|
-
let l = ((
|
|
5306
|
+
var y;
|
|
5307
|
+
let l = ((y = a[0]) == null ? void 0 : y.id) || "";
|
|
5285
5308
|
if (!l)
|
|
5286
5309
|
try {
|
|
5287
5310
|
l = (await s()).id;
|
|
@@ -5583,14 +5606,14 @@ function Ln(t) {
|
|
|
5583
5606
|
});
|
|
5584
5607
|
}
|
|
5585
5608
|
function Bn() {
|
|
5586
|
-
const { t } = ae(), { sessionId: n } = ft(), a = Oe(), s = Ct(), [o] = Ot(), i = o.get("demo") === "1", [c, l] = v(""), [
|
|
5609
|
+
const { t } = ae(), { sessionId: n } = ft(), a = Oe(), s = Ct(), [o] = Ot(), i = o.get("demo") === "1", [c, l] = v(""), [y, d] = v(""), [p, m] = v([]), [f, w] = v(""), [b, g] = v(!1), [P, D] = v("idle"), T = X(null), u = X(null), h = X([]), {
|
|
5587
5610
|
connectionStatus: A,
|
|
5588
5611
|
connectionVersion: R,
|
|
5589
|
-
createSession:
|
|
5612
|
+
createSession: S,
|
|
5590
5613
|
startDemo: H,
|
|
5591
5614
|
completeDemoTyping: $,
|
|
5592
5615
|
loadHistory: z,
|
|
5593
|
-
loadMoreHistory:
|
|
5616
|
+
loadMoreHistory: k,
|
|
5594
5617
|
sendMessage: K,
|
|
5595
5618
|
transcribeAudio: N,
|
|
5596
5619
|
getMessages: B,
|
|
@@ -5599,14 +5622,14 @@ function Bn() {
|
|
|
5599
5622
|
isThinking: Z,
|
|
5600
5623
|
getDemoStatus: re,
|
|
5601
5624
|
getDemoTypingCue: he
|
|
5602
|
-
} = ct(), ge =
|
|
5625
|
+
} = ct(), ge = X(null), _e = X(null), me = X(null), ye = X(null), [ze, I] = v(0), te = X(!1), Ae = X(null), Ce = X(0), $e = X(!0), Fe = X(null), xt = X(!1), dt = X(null), Je = B(n), we = A === "connected", Pe = Z(n), Ue = re(n), Ke = he(n), Re = i || Ue === "running", ut = C(n), st = F(n), mt = Je[Je.length - 1], _ = mt ? `${mt.type}:${mt.timestamp || ""}:${mt.content}` : "empty", V = Te(() => {
|
|
5603
5626
|
xt.current = !0, dt.current !== null && window.clearTimeout(dt.current), dt.current = window.setTimeout(() => {
|
|
5604
5627
|
xt.current = !1, dt.current = null;
|
|
5605
5628
|
}, 600);
|
|
5606
|
-
}, []), W = Te((
|
|
5629
|
+
}, []), W = Te((x = "smooth") => {
|
|
5607
5630
|
const M = ge.current;
|
|
5608
5631
|
if (!M) return;
|
|
5609
|
-
V(), M.scrollTo({ top: M.scrollHeight, behavior:
|
|
5632
|
+
V(), M.scrollTo({ top: M.scrollHeight, behavior: x });
|
|
5610
5633
|
const Y = () => {
|
|
5611
5634
|
const ce = ge.current;
|
|
5612
5635
|
ce && (!$e.current && !Re && !Pe || ce.scrollTop + ce.clientHeight >= ce.scrollHeight - 2 || (V(), ce.scrollTo({ top: ce.scrollHeight, behavior: "auto" })));
|
|
@@ -5614,15 +5637,15 @@ function Bn() {
|
|
|
5614
5637
|
requestAnimationFrame(Y), window.setTimeout(Y, 120);
|
|
5615
5638
|
}, [Re, Pe, V]);
|
|
5616
5639
|
cn(() => {
|
|
5617
|
-
const
|
|
5618
|
-
if (!
|
|
5619
|
-
const Y =
|
|
5620
|
-
Y > 0 && (
|
|
5621
|
-
}, [Je.length]),
|
|
5640
|
+
const x = ge.current, M = Fe.current;
|
|
5641
|
+
if (!x || M === null) return;
|
|
5642
|
+
const Y = x.scrollHeight - M;
|
|
5643
|
+
Y > 0 && (x.scrollTop = x.scrollTop + Y), Fe.current = null;
|
|
5644
|
+
}, [Je.length]), se(() => {
|
|
5622
5645
|
Fe.current === null && (!$e.current && !Re && !Pe || W(Re ? "auto" : "smooth"));
|
|
5623
|
-
}, [_, Re, Pe, W]),
|
|
5624
|
-
const
|
|
5625
|
-
if (!
|
|
5646
|
+
}, [_, Re, Pe, W]), se(() => {
|
|
5647
|
+
const x = ge.current;
|
|
5648
|
+
if (!x || typeof ResizeObserver > "u") return;
|
|
5626
5649
|
let M = 0;
|
|
5627
5650
|
const Y = new ResizeObserver(() => {
|
|
5628
5651
|
Fe.current === null && (!$e.current && !Re && !Pe || (cancelAnimationFrame(M), M = requestAnimationFrame(() => {
|
|
@@ -5630,102 +5653,102 @@ function Bn() {
|
|
|
5630
5653
|
if (!pe) return;
|
|
5631
5654
|
pe.scrollHeight - pe.scrollTop - pe.clientHeight <= 120 && (V(), pe.scrollTo({ top: pe.scrollHeight, behavior: "auto" }));
|
|
5632
5655
|
})));
|
|
5633
|
-
}), ce =
|
|
5634
|
-
return ce && Y.observe(ce), Y.observe(
|
|
5656
|
+
}), ce = x.firstElementChild;
|
|
5657
|
+
return ce && Y.observe(ce), Y.observe(x), () => {
|
|
5635
5658
|
Y.disconnect(), cancelAnimationFrame(M);
|
|
5636
5659
|
};
|
|
5637
5660
|
}, [Re, Pe, V]), cn(() => {
|
|
5638
|
-
const
|
|
5639
|
-
if (!
|
|
5640
|
-
const M = new ResizeObserver(() => I(
|
|
5641
|
-
return M.observe(
|
|
5661
|
+
const x = ye.current;
|
|
5662
|
+
if (!x || (I(x.offsetHeight), typeof ResizeObserver > "u")) return;
|
|
5663
|
+
const M = new ResizeObserver(() => I(x.offsetHeight));
|
|
5664
|
+
return M.observe(x), () => M.disconnect();
|
|
5642
5665
|
}, []);
|
|
5643
5666
|
const be = Te(() => {
|
|
5644
5667
|
if (!n || st || !ut) return;
|
|
5645
|
-
const
|
|
5646
|
-
Fe.current =
|
|
5668
|
+
const x = ge.current;
|
|
5669
|
+
Fe.current = x ? x.scrollHeight : null, $e.current = !1, k(n).catch(() => {
|
|
5647
5670
|
Fe.current = null;
|
|
5648
5671
|
});
|
|
5649
|
-
}, [n, st, ut,
|
|
5650
|
-
|
|
5651
|
-
d(""), Ae.current = null, Ce.current += 1, n &&
|
|
5652
|
-
const
|
|
5653
|
-
|
|
5672
|
+
}, [n, st, ut, k]), xe = X(null);
|
|
5673
|
+
se(() => {
|
|
5674
|
+
d(""), Ae.current = null, Ce.current += 1, n && na(n);
|
|
5675
|
+
const x = s.state;
|
|
5676
|
+
x != null && x.prefillMessage && xe.current !== x ? (xe.current = x, l(x.prefillMessage), window.setTimeout(() => {
|
|
5654
5677
|
var M;
|
|
5655
5678
|
return (M = me.current) == null ? void 0 : M.focus();
|
|
5656
|
-
}, 50)) :
|
|
5657
|
-
}, [n, i, s.state]),
|
|
5679
|
+
}, 50)) : x != null && x.prefillMessage || (xe.current = null, l(""));
|
|
5680
|
+
}, [n, i, s.state]), se(() => {
|
|
5658
5681
|
if (n || !we) return;
|
|
5659
|
-
let
|
|
5660
|
-
return
|
|
5661
|
-
|
|
5682
|
+
let x = !1;
|
|
5683
|
+
return S().then((M) => {
|
|
5684
|
+
x || a(`/chat/${M.id}`, { replace: !0 });
|
|
5662
5685
|
}).catch(() => {
|
|
5663
5686
|
}), () => {
|
|
5664
|
-
|
|
5687
|
+
x = !0;
|
|
5665
5688
|
};
|
|
5666
5689
|
}, [n, we, a]);
|
|
5667
|
-
const De =
|
|
5668
|
-
|
|
5690
|
+
const De = X(z);
|
|
5691
|
+
se(() => {
|
|
5669
5692
|
De.current = z;
|
|
5670
|
-
}, [z]),
|
|
5693
|
+
}, [z]), se(() => {
|
|
5671
5694
|
!n || !we || i || Ue === "running" || De.current(n).catch(() => {
|
|
5672
5695
|
});
|
|
5673
|
-
}, [n, we, R, i, Ue]),
|
|
5696
|
+
}, [n, we, R, i, Ue]), se(() => {
|
|
5674
5697
|
te.current && !Pe && we && setTimeout(() => {
|
|
5675
|
-
var
|
|
5676
|
-
return (
|
|
5698
|
+
var x;
|
|
5699
|
+
return (x = me.current) == null ? void 0 : x.focus();
|
|
5677
5700
|
}, 50), te.current = Pe;
|
|
5678
5701
|
}, [Pe, we]);
|
|
5679
|
-
function it(
|
|
5702
|
+
function it(x) {
|
|
5680
5703
|
if (xt.current) return;
|
|
5681
|
-
const M =
|
|
5704
|
+
const M = x.currentTarget, Y = M.scrollHeight - M.scrollTop - M.clientHeight;
|
|
5682
5705
|
$e.current = Y < 80;
|
|
5683
5706
|
}
|
|
5684
|
-
|
|
5685
|
-
!n || !we || !i || Ae.current !== n && (Ae.current = n, d(""), H(n).catch((
|
|
5686
|
-
Ae.current = null, d(
|
|
5707
|
+
se(() => {
|
|
5708
|
+
!n || !we || !i || Ae.current !== n && (Ae.current = n, d(""), H(n).catch((x) => {
|
|
5709
|
+
Ae.current = null, d(x instanceof Error ? x.message : t("chat.demoError"));
|
|
5687
5710
|
}));
|
|
5688
|
-
}, [n, we, i, H]),
|
|
5711
|
+
}, [n, we, i, H]), se(() => {
|
|
5689
5712
|
!n || !i || Ue !== "complete" || (l(""), a(`/chat/${n}`, { replace: !0 }));
|
|
5690
5713
|
}, [n, i, Ue, a]);
|
|
5691
|
-
const j =
|
|
5692
|
-
|
|
5714
|
+
const j = X($);
|
|
5715
|
+
se(() => {
|
|
5693
5716
|
j.current = $;
|
|
5694
5717
|
}, [$]);
|
|
5695
|
-
const Ye =
|
|
5696
|
-
|
|
5718
|
+
const Ye = X(null);
|
|
5719
|
+
se(() => {
|
|
5697
5720
|
if (!Ke || !n || Ye.current === Ke.seq) return;
|
|
5698
5721
|
Ye.current = Ke.seq;
|
|
5699
|
-
const
|
|
5722
|
+
const x = n, M = Ke.content, Y = M.length > 0 ? Math.max(8, Ke.typingMs / M.length) : 0, ce = Ke.seq, pe = ++Ce.current;
|
|
5700
5723
|
async function Xe() {
|
|
5701
5724
|
l("");
|
|
5702
5725
|
for (const ht of M) {
|
|
5703
5726
|
if (pe !== Ce.current) return;
|
|
5704
5727
|
l((Ve) => Ve + ht), await ks(Y);
|
|
5705
5728
|
}
|
|
5706
|
-
pe === Ce.current && j.current(
|
|
5729
|
+
pe === Ce.current && j.current(x, ce);
|
|
5707
5730
|
}
|
|
5708
5731
|
Xe();
|
|
5709
|
-
}, [Ke, n]),
|
|
5732
|
+
}, [Ke, n]), se(() => {
|
|
5710
5733
|
Ue === "complete" && (Ce.current += 1, l(""));
|
|
5711
5734
|
}, [Ue]);
|
|
5712
|
-
const ue = Te((
|
|
5735
|
+
const ue = Te((x) => {
|
|
5713
5736
|
if (!n) return;
|
|
5714
|
-
|
|
5715
|
-
const M = Array.from(
|
|
5737
|
+
w("");
|
|
5738
|
+
const M = Array.from(x);
|
|
5716
5739
|
m((Y) => {
|
|
5717
5740
|
const ce = [...Y];
|
|
5718
5741
|
for (const pe of M) {
|
|
5719
5742
|
if (ce.length >= Kt) {
|
|
5720
|
-
|
|
5743
|
+
w(`Maximum ${Kt} attachments per message.`);
|
|
5721
5744
|
break;
|
|
5722
5745
|
}
|
|
5723
5746
|
if (!ws.has(pe.type)) {
|
|
5724
|
-
|
|
5747
|
+
w(`Unsupported file type: ${pe.type || pe.name}`);
|
|
5725
5748
|
continue;
|
|
5726
5749
|
}
|
|
5727
5750
|
if (pe.size > Ns) {
|
|
5728
|
-
|
|
5751
|
+
w(`"${pe.name}" is too large (max 10 MB).`);
|
|
5729
5752
|
continue;
|
|
5730
5753
|
}
|
|
5731
5754
|
const Xe = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, ht = pe.type.startsWith("image/") ? URL.createObjectURL(pe) : void 0, Ve = { localId: Xe, file: pe, previewUrl: ht, uploading: !0 };
|
|
@@ -5737,7 +5760,7 @@ function Bn() {
|
|
|
5737
5760
|
);
|
|
5738
5761
|
}).catch((ot) => {
|
|
5739
5762
|
const Dt = (ot == null ? void 0 : ot.message) || "Upload failed";
|
|
5740
|
-
|
|
5763
|
+
w(`"${pe.name}": ${Dt}`), m(
|
|
5741
5764
|
(Nt) => Nt.map(
|
|
5742
5765
|
(Mt) => Mt.localId === Xe ? { ...Mt, uploading: !1, error: Dt } : Mt
|
|
5743
5766
|
)
|
|
@@ -5746,61 +5769,61 @@ function Bn() {
|
|
|
5746
5769
|
}
|
|
5747
5770
|
return ce;
|
|
5748
5771
|
});
|
|
5749
|
-
}, [n]), E = (
|
|
5772
|
+
}, [n]), E = (x) => {
|
|
5750
5773
|
m((M) => {
|
|
5751
|
-
const Y = M.find((ce) => ce.localId ===
|
|
5752
|
-
return Y != null && Y.previewUrl && URL.revokeObjectURL(Y.previewUrl), M.filter((ce) => ce.localId !==
|
|
5774
|
+
const Y = M.find((ce) => ce.localId === x);
|
|
5775
|
+
return Y != null && Y.previewUrl && URL.revokeObjectURL(Y.previewUrl), M.filter((ce) => ce.localId !== x);
|
|
5753
5776
|
});
|
|
5754
|
-
}, q = (
|
|
5755
|
-
|
|
5756
|
-
}, G = (
|
|
5757
|
-
const M =
|
|
5758
|
-
(!M || !
|
|
5759
|
-
}, Q = (
|
|
5760
|
-
|
|
5761
|
-
}, Ee = (
|
|
5777
|
+
}, q = (x) => {
|
|
5778
|
+
x.dataTransfer.types.includes("Files") && (x.preventDefault(), g(!0));
|
|
5779
|
+
}, G = (x) => {
|
|
5780
|
+
const M = x.relatedTarget;
|
|
5781
|
+
(!M || !x.currentTarget.contains(M)) && g(!1);
|
|
5782
|
+
}, Q = (x) => {
|
|
5783
|
+
x.preventDefault(), g(!1), x.dataTransfer.files && x.dataTransfer.files.length > 0 && ue(x.dataTransfer.files);
|
|
5784
|
+
}, Ee = (x) => {
|
|
5762
5785
|
const M = [];
|
|
5763
|
-
for (const Y of
|
|
5786
|
+
for (const Y of x.clipboardData.items)
|
|
5764
5787
|
if (Y.kind === "file") {
|
|
5765
5788
|
const ce = Y.getAsFile();
|
|
5766
5789
|
ce && M.push(ce);
|
|
5767
5790
|
}
|
|
5768
|
-
M.length > 0 && (
|
|
5769
|
-
}, ve = p.some((
|
|
5791
|
+
M.length > 0 && (x.preventDefault(), ue(M));
|
|
5792
|
+
}, ve = p.some((x) => x.uploading), ie = p.some((x) => x.error), de = p.filter((x) => x.uploadedId && !x.error).map((x) => x.uploadedId);
|
|
5770
5793
|
function pt() {
|
|
5771
|
-
const
|
|
5772
|
-
if (n && !(!
|
|
5794
|
+
const x = c.trim();
|
|
5795
|
+
if (n && !(!x && de.length === 0) && !ve && K(n, x, de.length > 0 ? de : void 0)) {
|
|
5773
5796
|
for (const M of p)
|
|
5774
5797
|
M.previewUrl && URL.revokeObjectURL(M.previewUrl);
|
|
5775
|
-
m([]),
|
|
5798
|
+
m([]), w(""), l("");
|
|
5776
5799
|
}
|
|
5777
5800
|
}
|
|
5778
|
-
function vt(
|
|
5779
|
-
|
|
5801
|
+
function vt(x) {
|
|
5802
|
+
x.key === "Enter" && !x.shiftKey && (x.preventDefault(), pt());
|
|
5780
5803
|
}
|
|
5781
|
-
function Ze(
|
|
5782
|
-
const M =
|
|
5804
|
+
function Ze(x) {
|
|
5805
|
+
const M = x.trim();
|
|
5783
5806
|
M && (l((Y) => Y.trim() ? `${Y.trim()} ${M}` : M), window.setTimeout(() => {
|
|
5784
5807
|
const Y = me.current;
|
|
5785
5808
|
Y && (Y.focus(), Y.style.height = "auto", Y.style.height = Math.min(Math.max(Y.scrollHeight, 48), 120) + "px");
|
|
5786
5809
|
}, 0));
|
|
5787
5810
|
}
|
|
5788
|
-
async function
|
|
5811
|
+
async function ga() {
|
|
5789
5812
|
if (P !== "idle") return;
|
|
5790
|
-
let
|
|
5813
|
+
let x;
|
|
5791
5814
|
try {
|
|
5792
|
-
|
|
5815
|
+
x = await navigator.mediaDevices.getUserMedia({ audio: !0 });
|
|
5793
5816
|
} catch {
|
|
5794
|
-
|
|
5817
|
+
w(t("chat.micDenied"));
|
|
5795
5818
|
return;
|
|
5796
5819
|
}
|
|
5797
|
-
|
|
5798
|
-
const M = new MediaRecorder(
|
|
5820
|
+
w("");
|
|
5821
|
+
const M = new MediaRecorder(x);
|
|
5799
5822
|
u.current = M, h.current = [], M.ondataavailable = (Y) => {
|
|
5800
5823
|
Y.data.size > 0 && h.current.push(Y.data);
|
|
5801
5824
|
}, M.onstop = async () => {
|
|
5802
5825
|
var ht;
|
|
5803
|
-
|
|
5826
|
+
x.getTracks().forEach((Ve) => Ve.stop());
|
|
5804
5827
|
const Y = h.current;
|
|
5805
5828
|
if (h.current = [], u.current = null, Y.length === 0) {
|
|
5806
5829
|
D("idle");
|
|
@@ -5812,18 +5835,18 @@ function Bn() {
|
|
|
5812
5835
|
const Ve = await Ss(pe), ot = await N(Ve, Xe, n);
|
|
5813
5836
|
Ze(ot);
|
|
5814
5837
|
} catch (Ve) {
|
|
5815
|
-
|
|
5838
|
+
w(Ve instanceof Error ? Ve.message : t("chat.transcribeFailed"));
|
|
5816
5839
|
} finally {
|
|
5817
5840
|
D("idle");
|
|
5818
5841
|
}
|
|
5819
5842
|
}, M.start(), D("recording");
|
|
5820
5843
|
}
|
|
5821
|
-
function ga() {
|
|
5822
|
-
const b = u.current;
|
|
5823
|
-
b && b.state !== "inactive" && b.stop();
|
|
5824
|
-
}
|
|
5825
5844
|
function ya() {
|
|
5826
|
-
|
|
5845
|
+
const x = u.current;
|
|
5846
|
+
x && x.state !== "inactive" && x.stop();
|
|
5847
|
+
}
|
|
5848
|
+
function fa() {
|
|
5849
|
+
P === "recording" ? ya() : P === "idle" && ga();
|
|
5827
5850
|
}
|
|
5828
5851
|
return n ? /* @__PURE__ */ r(
|
|
5829
5852
|
"div",
|
|
@@ -5833,7 +5856,7 @@ function Bn() {
|
|
|
5833
5856
|
onDragLeave: G,
|
|
5834
5857
|
onDrop: Q,
|
|
5835
5858
|
children: [
|
|
5836
|
-
|
|
5859
|
+
b && /* @__PURE__ */ e("div", { className: "pointer-events-none absolute inset-3 z-50 flex items-center justify-center rounded-lg border-2 border-dashed border-brand bg-brand/5 text-sm font-medium text-brand", children: t("chat.dropToAttach") }),
|
|
5837
5860
|
/* @__PURE__ */ e(
|
|
5838
5861
|
"div",
|
|
5839
5862
|
{
|
|
@@ -5855,7 +5878,7 @@ function Bn() {
|
|
|
5855
5878
|
children: t(st ? "common.loading" : "chat.loadOlder")
|
|
5856
5879
|
}
|
|
5857
5880
|
) }),
|
|
5858
|
-
|
|
5881
|
+
y && /* @__PURE__ */ e("div", { className: "rounded-md bg-rose-50 px-4 py-3 text-sm text-rose-700 ring-1 ring-rose-200", children: y }),
|
|
5859
5882
|
Je.length === 0 && Ue !== "running" && !i && /* @__PURE__ */ r("div", { className: "py-20 text-center", children: [
|
|
5860
5883
|
/* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-fg-muted", children: t("chat.title") }),
|
|
5861
5884
|
/* @__PURE__ */ e("p", { className: "mt-2 text-sm text-fg-muted", children: t("chat.subtitle") }),
|
|
@@ -5864,20 +5887,20 @@ function Bn() {
|
|
|
5864
5887
|
t("chat.s2"),
|
|
5865
5888
|
t("chat.s3"),
|
|
5866
5889
|
t("chat.s4")
|
|
5867
|
-
].map((
|
|
5890
|
+
].map((x) => /* @__PURE__ */ e(
|
|
5868
5891
|
"button",
|
|
5869
5892
|
{
|
|
5870
5893
|
onClick: () => {
|
|
5871
5894
|
var M;
|
|
5872
|
-
l(
|
|
5895
|
+
l(x), (M = me.current) == null || M.focus();
|
|
5873
5896
|
},
|
|
5874
5897
|
className: "rounded-full bg-surface px-3 py-1.5 text-xs text-fg-muted ring-1 ring-line transition-all hover:bg-surface-subtle hover:text-fg hover:ring-brand/30",
|
|
5875
|
-
children:
|
|
5898
|
+
children: x
|
|
5876
5899
|
},
|
|
5877
|
-
|
|
5900
|
+
x
|
|
5878
5901
|
)) })
|
|
5879
5902
|
] }),
|
|
5880
|
-
Je.map((
|
|
5903
|
+
Je.map((x, M) => /* @__PURE__ */ e(Ds, { message: x }, M)),
|
|
5881
5904
|
/* @__PURE__ */ e("div", { ref: _e })
|
|
5882
5905
|
]
|
|
5883
5906
|
}
|
|
@@ -5890,20 +5913,20 @@ function Bn() {
|
|
|
5890
5913
|
ref: ye,
|
|
5891
5914
|
className: "absolute bottom-0 left-0 right-0 bg-surface-muted px-4 pb-[max(0.75rem,env(safe-area-inset-bottom))] md:right-6 md:pl-6 md:pr-0",
|
|
5892
5915
|
children: /* @__PURE__ */ r("div", { className: "mx-auto max-w-3xl", children: [
|
|
5893
|
-
p.length > 0 && /* @__PURE__ */ e("div", { className: "mb-2 flex flex-wrap gap-2", children: p.map((
|
|
5916
|
+
p.length > 0 && /* @__PURE__ */ e("div", { className: "mb-2 flex flex-wrap gap-2", children: p.map((x) => /* @__PURE__ */ r(
|
|
5894
5917
|
"div",
|
|
5895
5918
|
{
|
|
5896
5919
|
className: "relative flex items-center gap-2 rounded-lg bg-surface px-2 py-1.5 text-xs ring-1 ring-line shadow-card",
|
|
5897
5920
|
children: [
|
|
5898
|
-
|
|
5921
|
+
x.previewUrl ? /* @__PURE__ */ e("img", { src: x.previewUrl, alt: "", className: "h-10 w-10 rounded object-cover" }) : /* @__PURE__ */ e("div", { className: "flex h-10 w-10 items-center justify-center rounded bg-rose-100 text-[10px] font-bold text-rose-700", children: "PDF" }),
|
|
5899
5922
|
/* @__PURE__ */ r("div", { className: "flex min-w-0 flex-col", children: [
|
|
5900
|
-
/* @__PURE__ */ e("span", { className: "max-w-[160px] truncate text-fg", children:
|
|
5901
|
-
/* @__PURE__ */ e("span", { className: "text-[10px] text-fg-muted", children:
|
|
5923
|
+
/* @__PURE__ */ e("span", { className: "max-w-[160px] truncate text-fg", children: x.file.name }),
|
|
5924
|
+
/* @__PURE__ */ e("span", { className: "text-[10px] text-fg-muted", children: x.uploading ? t("chat.uploading") : x.error ? t("chat.failed") : `${Math.round(x.file.size / 1024)} KB` })
|
|
5902
5925
|
] }),
|
|
5903
5926
|
/* @__PURE__ */ e(
|
|
5904
5927
|
"button",
|
|
5905
5928
|
{
|
|
5906
|
-
onClick: () => E(
|
|
5929
|
+
onClick: () => E(x.localId),
|
|
5907
5930
|
className: "ml-1 text-fg-muted transition-colors hover:text-red-500",
|
|
5908
5931
|
title: t("chat.remove"),
|
|
5909
5932
|
children: /* @__PURE__ */ e("svg", { viewBox: "0 0 24 24", width: "14", height: "14", fill: "currentColor", children: /* @__PURE__ */ e("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) })
|
|
@@ -5911,7 +5934,7 @@ function Bn() {
|
|
|
5911
5934
|
)
|
|
5912
5935
|
]
|
|
5913
5936
|
},
|
|
5914
|
-
|
|
5937
|
+
x.localId
|
|
5915
5938
|
)) }),
|
|
5916
5939
|
f && /* @__PURE__ */ e("div", { className: "mb-2 rounded-md bg-rose-50 px-3 py-1.5 text-xs text-rose-700 ring-1 ring-rose-200 shadow-card", children: f }),
|
|
5917
5940
|
/* @__PURE__ */ e(
|
|
@@ -5922,8 +5945,8 @@ function Bn() {
|
|
|
5922
5945
|
accept: "image/png,image/jpeg,image/gif,image/webp,application/pdf",
|
|
5923
5946
|
multiple: !0,
|
|
5924
5947
|
className: "hidden",
|
|
5925
|
-
onChange: (
|
|
5926
|
-
|
|
5948
|
+
onChange: (x) => {
|
|
5949
|
+
x.target.files && x.target.files.length > 0 && (ue(x.target.files), x.target.value = "");
|
|
5927
5950
|
}
|
|
5928
5951
|
}
|
|
5929
5952
|
),
|
|
@@ -5933,7 +5956,7 @@ function Bn() {
|
|
|
5933
5956
|
{
|
|
5934
5957
|
ref: me,
|
|
5935
5958
|
value: c,
|
|
5936
|
-
onChange: (
|
|
5959
|
+
onChange: (x) => l(x.target.value),
|
|
5937
5960
|
onKeyDown: vt,
|
|
5938
5961
|
onPaste: Ee,
|
|
5939
5962
|
placeholder: t(Re ? "chat.placeholderDemo" : we ? "chat.placeholderType" : "chat.placeholderConnecting"),
|
|
@@ -5941,8 +5964,8 @@ function Bn() {
|
|
|
5941
5964
|
rows: 2,
|
|
5942
5965
|
className: "block flex-1 resize-none bg-transparent px-2.5 py-1.5 text-sm text-fg outline-none placeholder:text-fg-muted/70 disabled:text-fg-muted",
|
|
5943
5966
|
style: { minHeight: "3rem", maxHeight: "120px" },
|
|
5944
|
-
onInput: (
|
|
5945
|
-
const M =
|
|
5967
|
+
onInput: (x) => {
|
|
5968
|
+
const M = x.target;
|
|
5946
5969
|
M.style.height = "auto", M.style.height = Math.min(Math.max(M.scrollHeight, 48), 120) + "px";
|
|
5947
5970
|
}
|
|
5948
5971
|
}
|
|
@@ -5951,8 +5974,8 @@ function Bn() {
|
|
|
5951
5974
|
"button",
|
|
5952
5975
|
{
|
|
5953
5976
|
onClick: () => {
|
|
5954
|
-
var
|
|
5955
|
-
return (
|
|
5977
|
+
var x;
|
|
5978
|
+
return (x = T.current) == null ? void 0 : x.click();
|
|
5956
5979
|
},
|
|
5957
5980
|
disabled: !we || !n || Pe || Re || p.length >= Kt,
|
|
5958
5981
|
className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-lg text-fg-muted transition-all hover:bg-surface-subtle hover:text-fg disabled:cursor-not-allowed disabled:opacity-40 md:h-10 md:w-10",
|
|
@@ -5963,7 +5986,7 @@ function Bn() {
|
|
|
5963
5986
|
/* @__PURE__ */ e(
|
|
5964
5987
|
"button",
|
|
5965
5988
|
{
|
|
5966
|
-
onClick:
|
|
5989
|
+
onClick: fa,
|
|
5967
5990
|
disabled: !we || !n || Pe || Re || P === "transcribing",
|
|
5968
5991
|
className: `flex h-11 w-11 shrink-0 items-center justify-center rounded-lg transition-all disabled:cursor-not-allowed disabled:opacity-40 md:h-10 md:w-10 ${P === "recording" ? "bg-rose-500/10 text-rose-600 hover:bg-rose-500/20" : "text-fg-muted hover:bg-surface-subtle hover:text-fg"}`,
|
|
5969
5992
|
title: t(P === "recording" ? "chat.voiceStop" : P === "transcribing" ? "chat.voiceTranscribing" : "chat.voiceStart"),
|
|
@@ -5979,7 +6002,7 @@ function Bn() {
|
|
|
5979
6002
|
"button",
|
|
5980
6003
|
{
|
|
5981
6004
|
onClick: pt,
|
|
5982
|
-
disabled: !c.trim() && de.length === 0 || !we || !n || Pe || Re || ve ||
|
|
6005
|
+
disabled: !c.trim() && de.length === 0 || !we || !n || Pe || Re || ve || ie,
|
|
5983
6006
|
className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-lg text-brand transition-all hover:bg-brand/10 active:translate-y-px disabled:cursor-not-allowed disabled:text-fg-muted disabled:active:translate-y-0 md:h-10 md:w-10",
|
|
5984
6007
|
children: /* @__PURE__ */ e(
|
|
5985
6008
|
"svg",
|
|
@@ -6120,7 +6143,7 @@ function _s({ content: t }) {
|
|
|
6120
6143
|
);
|
|
6121
6144
|
}), /* @__PURE__ */ e("div", { children: a });
|
|
6122
6145
|
}
|
|
6123
|
-
function
|
|
6146
|
+
function ca(t, n, a) {
|
|
6124
6147
|
const s = t.startsWith("/") && !t.startsWith("/api/"), o = "font-medium text-brand underline decoration-brand/40 underline-offset-2 transition-colors hover:decoration-brand";
|
|
6125
6148
|
return s ? /* @__PURE__ */ e(Ne, { to: t, className: o, children: n }, a) : /* @__PURE__ */ e(
|
|
6126
6149
|
"a",
|
|
@@ -6140,7 +6163,7 @@ function Bt(t) {
|
|
|
6140
6163
|
const o = a.match(/^\[([^\]]+)\]\(([^)]+)\)$/);
|
|
6141
6164
|
if (o) {
|
|
6142
6165
|
const [, i, c] = o;
|
|
6143
|
-
return
|
|
6166
|
+
return ca(c, Bt(i), s);
|
|
6144
6167
|
}
|
|
6145
6168
|
return a.startsWith("**") && a.endsWith("**") && a.length > 4 ? /* @__PURE__ */ e("strong", { className: "font-semibold", children: Bt(a.slice(2, -2)) }, s) : a.startsWith("`") && a.endsWith("`") ? /* @__PURE__ */ e(
|
|
6146
6169
|
"code",
|
|
@@ -6159,26 +6182,26 @@ function Ts(t, n) {
|
|
|
6159
6182
|
let c = 0;
|
|
6160
6183
|
for (; (o = i.exec(t)) !== null; ) {
|
|
6161
6184
|
const l = o.index;
|
|
6162
|
-
let
|
|
6163
|
-
for (;
|
|
6164
|
-
d =
|
|
6165
|
-
l > s && a.push(t.slice(s, l)), a.push(
|
|
6185
|
+
let y = o[0], d = "";
|
|
6186
|
+
for (; y.length > 0 && /[.,;:!?]$/.test(y); )
|
|
6187
|
+
d = y.slice(-1) + d, y = y.slice(0, -1);
|
|
6188
|
+
l > s && a.push(t.slice(s, l)), a.push(ca(y, y, `${n}-u${c}`)), d && a.push(d), s = l + o[0].length, c += 1;
|
|
6166
6189
|
}
|
|
6167
6190
|
return s < t.length && a.push(t.slice(s)), a.length > 0 ? a : [t];
|
|
6168
6191
|
}
|
|
6169
6192
|
function As() {
|
|
6170
|
-
const t = Oe(), [n] = Ot(), { user: a, login: s, register: o } = bt(), { t: i } = ae(), c = n.get("invite") || "", [l,
|
|
6171
|
-
|
|
6193
|
+
const t = Oe(), [n] = Ot(), { user: a, login: s, register: o } = bt(), { t: i } = ae(), c = n.get("invite") || "", [l, y] = v(c ? "register" : "login"), [d, p] = v(!1), [m, f] = v(!1), [w, b] = v(!0), [g, P] = v(""), [D, T] = v(""), [u, h] = v(""), [A, R] = v(""), [S, H] = v("");
|
|
6194
|
+
se(() => {
|
|
6172
6195
|
a && a.role !== "public_manager" && t("/", { replace: !0 });
|
|
6173
|
-
}, [a, t]),
|
|
6196
|
+
}, [a, t]), se(() => {
|
|
6174
6197
|
L.authSetupStatus().then((z) => {
|
|
6175
|
-
p(z.registration_open), f(z.first_run), z.first_run &&
|
|
6198
|
+
p(z.registration_open), f(z.first_run), z.first_run && y("register");
|
|
6176
6199
|
}).catch(() => {
|
|
6177
|
-
}).finally(() =>
|
|
6200
|
+
}).finally(() => b(!1));
|
|
6178
6201
|
}, []);
|
|
6179
6202
|
const $ = async (z) => {
|
|
6180
6203
|
if (z.preventDefault(), P(""), l === "register") {
|
|
6181
|
-
if (A !==
|
|
6204
|
+
if (A !== S) {
|
|
6182
6205
|
P(i("login.passwordsNoMatch"));
|
|
6183
6206
|
return;
|
|
6184
6207
|
}
|
|
@@ -6188,26 +6211,26 @@ function As() {
|
|
|
6188
6211
|
}
|
|
6189
6212
|
try {
|
|
6190
6213
|
await o(D, u, A, c || void 0), t("/", { replace: !0 });
|
|
6191
|
-
} catch (
|
|
6192
|
-
P(
|
|
6214
|
+
} catch (k) {
|
|
6215
|
+
P(k instanceof Ge ? k.message : i("login.registrationFailed"));
|
|
6193
6216
|
}
|
|
6194
6217
|
} else
|
|
6195
6218
|
try {
|
|
6196
6219
|
await s(D, A), t("/", { replace: !0 });
|
|
6197
|
-
} catch (
|
|
6198
|
-
P(
|
|
6220
|
+
} catch (k) {
|
|
6221
|
+
P(k instanceof Ge ? k.message : i("login.loginFailed"));
|
|
6199
6222
|
}
|
|
6200
6223
|
};
|
|
6201
|
-
return
|
|
6224
|
+
return w ? /* @__PURE__ */ e("div", { className: "flex h-dvh items-center justify-center bg-surface-muted", children: /* @__PURE__ */ e("div", { className: "text-fg-muted", children: i("common.loading") }) }) : /* @__PURE__ */ e("div", { className: "flex min-h-dvh items-center justify-center bg-surface-muted px-4", children: /* @__PURE__ */ r("div", { className: "w-full max-w-sm space-y-6", children: [
|
|
6202
6225
|
/* @__PURE__ */ r("div", { className: "text-center", children: [
|
|
6203
6226
|
/* @__PURE__ */ e("h1", { className: "text-2xl font-bold text-brand", children: "Lambda ERP" }),
|
|
6204
6227
|
/* @__PURE__ */ e("p", { className: "mt-1 text-sm text-fg-muted", children: i(m ? "login.taglineFirstRun" : l === "register" ? "login.taglineRegister" : "login.taglineSignIn") }),
|
|
6205
6228
|
(a == null ? void 0 : a.role) === "public_manager" && /* @__PURE__ */ e("p", { className: "mt-2 text-xs text-amber-700", children: i("login.demoBanner") })
|
|
6206
6229
|
] }),
|
|
6207
|
-
|
|
6230
|
+
g && /* @__PURE__ */ e("div", { className: "rounded-lg bg-rose-50 px-4 py-3 text-sm text-rose-700 ring-1 ring-rose-200", children: g }),
|
|
6208
6231
|
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("form", { onSubmit: $, className: "space-y-4", children: [
|
|
6209
6232
|
l === "register" && /* @__PURE__ */ e(
|
|
6210
|
-
|
|
6233
|
+
ee,
|
|
6211
6234
|
{
|
|
6212
6235
|
label: i("login.fullName"),
|
|
6213
6236
|
value: u,
|
|
@@ -6216,7 +6239,7 @@ function As() {
|
|
|
6216
6239
|
}
|
|
6217
6240
|
),
|
|
6218
6241
|
/* @__PURE__ */ e(
|
|
6219
|
-
|
|
6242
|
+
ee,
|
|
6220
6243
|
{
|
|
6221
6244
|
label: i("login.email"),
|
|
6222
6245
|
type: "email",
|
|
@@ -6226,7 +6249,7 @@ function As() {
|
|
|
6226
6249
|
}
|
|
6227
6250
|
),
|
|
6228
6251
|
/* @__PURE__ */ e(
|
|
6229
|
-
|
|
6252
|
+
ee,
|
|
6230
6253
|
{
|
|
6231
6254
|
label: i("login.password"),
|
|
6232
6255
|
type: "password",
|
|
@@ -6236,11 +6259,11 @@ function As() {
|
|
|
6236
6259
|
}
|
|
6237
6260
|
),
|
|
6238
6261
|
l === "register" && /* @__PURE__ */ e(
|
|
6239
|
-
|
|
6262
|
+
ee,
|
|
6240
6263
|
{
|
|
6241
6264
|
label: i("login.confirmPassword"),
|
|
6242
6265
|
type: "password",
|
|
6243
|
-
value:
|
|
6266
|
+
value: S,
|
|
6244
6267
|
onChange: (z) => H(z.target.value),
|
|
6245
6268
|
required: !0
|
|
6246
6269
|
}
|
|
@@ -6265,17 +6288,17 @@ function As() {
|
|
|
6265
6288
|
!m && !c && /* @__PURE__ */ e("p", { className: "text-center text-sm text-fg-muted", children: l === "login" ? /* @__PURE__ */ r(Se, { children: [
|
|
6266
6289
|
i(d ? "login.noAccountPrompt" : "login.haveInvite"),
|
|
6267
6290
|
" ",
|
|
6268
|
-
/* @__PURE__ */ e("button", { onClick: () =>
|
|
6291
|
+
/* @__PURE__ */ e("button", { onClick: () => y("register"), className: "font-medium text-brand transition-colors hover:text-brand/80", children: i("login.registerLink") })
|
|
6269
6292
|
] }) : /* @__PURE__ */ r(Se, { children: [
|
|
6270
6293
|
i("login.alreadyHaveAccount"),
|
|
6271
6294
|
" ",
|
|
6272
|
-
/* @__PURE__ */ e("button", { onClick: () =>
|
|
6295
|
+
/* @__PURE__ */ e("button", { onClick: () => y("login"), className: "font-medium text-brand transition-colors hover:text-brand/80", children: i("login.signInLink") })
|
|
6273
6296
|
] }) })
|
|
6274
6297
|
] }) });
|
|
6275
6298
|
}
|
|
6276
6299
|
function Rs() {
|
|
6277
|
-
const t = Oe(), n =
|
|
6278
|
-
return
|
|
6300
|
+
const t = Oe(), n = X(!1), [a, s] = v("");
|
|
6301
|
+
return se(() => {
|
|
6279
6302
|
n.current || (n.current = !0, L.createChatSession().then((o) => {
|
|
6280
6303
|
t(`/chat/${o.id}?demo=1`, { replace: !0 });
|
|
6281
6304
|
}).catch((o) => {
|
|
@@ -6306,11 +6329,11 @@ function qn() {
|
|
|
6306
6329
|
return { type: "sales", party: "", amount: "", due_date: "", remarks: "" };
|
|
6307
6330
|
}
|
|
6308
6331
|
function Is() {
|
|
6309
|
-
const t = Oe(), n = We(), [a, s] = v(""), [o, i] = v((/* @__PURE__ */ new Date()).toISOString().split("T")[0]), [c, l] = v(""), [
|
|
6332
|
+
const t = Oe(), n = We(), [a, s] = v(""), [o, i] = v((/* @__PURE__ */ new Date()).toISOString().split("T")[0]), [c, l] = v(""), [y, d] = v([En()]), [p, m] = v([On()]), [f, w] = v([qn()]), [b, g] = v({}), P = oe({
|
|
6310
6333
|
mutationFn: () => L.importAccountBalances({
|
|
6311
6334
|
company: a,
|
|
6312
6335
|
posting_date: o,
|
|
6313
|
-
entries:
|
|
6336
|
+
entries: y.filter((h) => h.account && (h.debit || h.credit)).map((h) => ({
|
|
6314
6337
|
account: h.account,
|
|
6315
6338
|
debit: parseFloat(h.debit) || 0,
|
|
6316
6339
|
credit: parseFloat(h.credit) || 0,
|
|
@@ -6318,7 +6341,7 @@ function Is() {
|
|
|
6318
6341
|
party: h.party || void 0
|
|
6319
6342
|
}))
|
|
6320
6343
|
}),
|
|
6321
|
-
onSuccess: (h) =>
|
|
6344
|
+
onSuccess: (h) => g((A) => ({ ...A, accounts: h }))
|
|
6322
6345
|
}), D = oe({
|
|
6323
6346
|
mutationFn: () => L.importStockBalances({
|
|
6324
6347
|
company: a,
|
|
@@ -6330,7 +6353,7 @@ function Is() {
|
|
|
6330
6353
|
rate: parseFloat(h.rate) || 0
|
|
6331
6354
|
}))
|
|
6332
6355
|
}),
|
|
6333
|
-
onSuccess: (h) =>
|
|
6356
|
+
onSuccess: (h) => g((A) => ({ ...A, stock: h }))
|
|
6334
6357
|
}), T = oe({
|
|
6335
6358
|
mutationFn: () => L.importOutstandingInvoices({
|
|
6336
6359
|
company: a,
|
|
@@ -6343,17 +6366,17 @@ function Is() {
|
|
|
6343
6366
|
posting_date: o
|
|
6344
6367
|
}))
|
|
6345
6368
|
}),
|
|
6346
|
-
onSuccess: (h) =>
|
|
6369
|
+
onSuccess: (h) => g((A) => ({ ...A, invoices: h }))
|
|
6347
6370
|
});
|
|
6348
|
-
function u(h, A, R,
|
|
6371
|
+
function u(h, A, R, S, H) {
|
|
6349
6372
|
const $ = [...h];
|
|
6350
|
-
$[R][
|
|
6373
|
+
$[R][S] = H, A($);
|
|
6351
6374
|
}
|
|
6352
6375
|
return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
6353
6376
|
/* @__PURE__ */ e("p", { className: "text-sm text-gray-500", children: "Import balances from your previous system. Each section creates the appropriate documents (Journal Entry, Stock Entry, or Invoices) and submits them automatically." }),
|
|
6354
6377
|
/* @__PURE__ */ e(U, { title: "Common Settings", children: /* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
6355
6378
|
/* @__PURE__ */ e(ke, { label: "Company", value: a, onChange: s, linkDoctype: "company", readOnly: !1 }),
|
|
6356
|
-
/* @__PURE__ */ e(
|
|
6379
|
+
/* @__PURE__ */ e(ee, { label: "As-of Date", type: "date", value: o, onChange: (h) => i(h.target.value) })
|
|
6357
6380
|
] }) }),
|
|
6358
6381
|
/* @__PURE__ */ r(U, { title: "1. Account Balances", children: [
|
|
6359
6382
|
/* @__PURE__ */ e("p", { className: "mb-3 text-xs text-gray-500", children: "Enter your trial balance from the old system. The difference will be automatically balanced against Opening Balance Equity. For receivable/payable accounts, also set the party type and party." }),
|
|
@@ -6365,25 +6388,25 @@ function Is() {
|
|
|
6365
6388
|
/* @__PURE__ */ e("th", { className: "px-2 py-2 text-right font-medium text-gray-500", children: "Debit" }),
|
|
6366
6389
|
/* @__PURE__ */ e("th", { className: "px-2 py-2 text-right font-medium text-gray-500", children: "Credit" })
|
|
6367
6390
|
] }) }),
|
|
6368
|
-
/* @__PURE__ */ e("tbody", { children:
|
|
6369
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e(ke, { value: h.account, onChange: (R) => u(
|
|
6370
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ r("select", { value: h.party_type, onChange: (R) => u(
|
|
6391
|
+
/* @__PURE__ */ e("tbody", { children: y.map((h, A) => /* @__PURE__ */ r("tr", { children: [
|
|
6392
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e(ke, { value: h.account, onChange: (R) => u(y, d, A, "account", R), linkDoctype: "account", readOnly: !1, label: "" }) }),
|
|
6393
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ r("select", { value: h.party_type, onChange: (R) => u(y, d, A, "party_type", R.target.value), className: "w-full rounded border border-gray-300 px-2 py-1.5 text-sm", children: [
|
|
6371
6394
|
/* @__PURE__ */ e("option", { value: "", children: "—" }),
|
|
6372
6395
|
/* @__PURE__ */ e("option", { value: "Customer", children: "Customer" }),
|
|
6373
6396
|
/* @__PURE__ */ e("option", { value: "Supplier", children: "Supplier" })
|
|
6374
6397
|
] }) }),
|
|
6375
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: h.party_type ? /* @__PURE__ */ e(ke, { label: "", value: h.party, onChange: (R) => u(
|
|
6376
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "number", value: h.debit, onChange: (R) => u(
|
|
6377
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "number", value: h.credit, onChange: (R) => u(
|
|
6398
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: h.party_type ? /* @__PURE__ */ e(ke, { label: "", value: h.party, onChange: (R) => u(y, d, A, "party", R), linkDoctype: h.party_type.toLowerCase(), readOnly: !1 }) : /* @__PURE__ */ e("span", { className: "text-gray-300 text-xs", children: "set party type first" }) }),
|
|
6399
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "number", value: h.debit, onChange: (R) => u(y, d, A, "debit", R.target.value), className: "w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm", placeholder: "0.00" }) }),
|
|
6400
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "number", value: h.credit, onChange: (R) => u(y, d, A, "credit", R.target.value), className: "w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm", placeholder: "0.00" }) })
|
|
6378
6401
|
] }, A)) })
|
|
6379
6402
|
] }) }),
|
|
6380
|
-
/* @__PURE__ */ e("div", { className: "mt-2 flex gap-2", children: /* @__PURE__ */ e("button", { onClick: () => d([...
|
|
6403
|
+
/* @__PURE__ */ e("div", { className: "mt-2 flex gap-2", children: /* @__PURE__ */ e("button", { onClick: () => d([...y, En()]), className: "text-xs text-blue-600 hover:text-blue-800", children: "+ Add Row" }) }),
|
|
6381
6404
|
/* @__PURE__ */ r("div", { className: "mt-3 flex items-center gap-3", children: [
|
|
6382
6405
|
/* @__PURE__ */ e(J, { onClick: () => P.mutate(), disabled: !a || P.isPending, children: P.isPending ? "Importing..." : "Import Account Balances" }),
|
|
6383
6406
|
P.error && /* @__PURE__ */ e("span", { className: "text-xs text-red-600", children: P.error.message }),
|
|
6384
|
-
|
|
6407
|
+
b.accounts && /* @__PURE__ */ r("span", { className: "text-xs text-green-600", children: [
|
|
6385
6408
|
"Created ",
|
|
6386
|
-
|
|
6409
|
+
b.accounts.journal_entry
|
|
6387
6410
|
] })
|
|
6388
6411
|
] })
|
|
6389
6412
|
] }),
|
|
@@ -6406,11 +6429,11 @@ function Is() {
|
|
|
6406
6429
|
/* @__PURE__ */ r("div", { className: "mt-3 flex items-center gap-3", children: [
|
|
6407
6430
|
/* @__PURE__ */ e(J, { onClick: () => D.mutate(), disabled: !a || !c || D.isPending, children: D.isPending ? "Importing..." : "Import Stock Balances" }),
|
|
6408
6431
|
D.error && /* @__PURE__ */ e("span", { className: "text-xs text-red-600", children: D.error.message }),
|
|
6409
|
-
|
|
6432
|
+
b.stock && /* @__PURE__ */ r("span", { className: "text-xs text-green-600", children: [
|
|
6410
6433
|
"Created ",
|
|
6411
|
-
|
|
6434
|
+
b.stock.stock_entry,
|
|
6412
6435
|
" (",
|
|
6413
|
-
|
|
6436
|
+
b.stock.items_count,
|
|
6414
6437
|
" items)"
|
|
6415
6438
|
] })
|
|
6416
6439
|
] })
|
|
@@ -6426,7 +6449,7 @@ function Is() {
|
|
|
6426
6449
|
/* @__PURE__ */ e("th", { className: "px-2 py-2 text-left font-medium text-gray-500", children: "Ref / Remarks" })
|
|
6427
6450
|
] }) }),
|
|
6428
6451
|
/* @__PURE__ */ e("tbody", { children: f.map((h, A) => /* @__PURE__ */ r("tr", { children: [
|
|
6429
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ r("select", { value: h.type, onChange: (R) => u(f,
|
|
6452
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ r("select", { value: h.type, onChange: (R) => u(f, w, A, "type", R.target.value), className: "rounded border border-gray-300 px-2 py-1.5 text-sm", children: [
|
|
6430
6453
|
/* @__PURE__ */ e("option", { value: "sales", children: "Sales (AR)" }),
|
|
6431
6454
|
/* @__PURE__ */ e("option", { value: "purchase", children: "Purchase (AP)" })
|
|
6432
6455
|
] }) }),
|
|
@@ -6435,23 +6458,23 @@ function Is() {
|
|
|
6435
6458
|
{
|
|
6436
6459
|
label: "",
|
|
6437
6460
|
value: h.party,
|
|
6438
|
-
onChange: (R) => u(f,
|
|
6461
|
+
onChange: (R) => u(f, w, A, "party", R),
|
|
6439
6462
|
linkDoctype: h.type === "sales" ? "customer" : "supplier",
|
|
6440
6463
|
readOnly: !1
|
|
6441
6464
|
}
|
|
6442
6465
|
) }),
|
|
6443
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "number", value: h.amount, onChange: (R) => u(f,
|
|
6444
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "date", value: h.due_date, onChange: (R) => u(f,
|
|
6445
|
-
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "text", value: h.remarks, onChange: (R) => u(f,
|
|
6466
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "number", value: h.amount, onChange: (R) => u(f, w, A, "amount", R.target.value), className: "w-28 rounded border border-gray-300 px-2 py-1.5 text-right text-sm", placeholder: "0.00" }) }),
|
|
6467
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "date", value: h.due_date, onChange: (R) => u(f, w, A, "due_date", R.target.value), className: "rounded border border-gray-300 px-2 py-1.5 text-sm" }) }),
|
|
6468
|
+
/* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e("input", { type: "text", value: h.remarks, onChange: (R) => u(f, w, A, "remarks", R.target.value), className: "w-full rounded border border-gray-300 px-2 py-1.5 text-sm", placeholder: "Old invoice ref" }) })
|
|
6446
6469
|
] }, A)) })
|
|
6447
6470
|
] }) }),
|
|
6448
|
-
/* @__PURE__ */ e("div", { className: "mt-2", children: /* @__PURE__ */ e("button", { onClick: () =>
|
|
6471
|
+
/* @__PURE__ */ e("div", { className: "mt-2", children: /* @__PURE__ */ e("button", { onClick: () => w([...f, qn()]), className: "text-xs text-blue-600 hover:text-blue-800", children: "+ Add Row" }) }),
|
|
6449
6472
|
/* @__PURE__ */ r("div", { className: "mt-3 flex items-center gap-3", children: [
|
|
6450
6473
|
/* @__PURE__ */ e(J, { onClick: () => T.mutate(), disabled: !a || T.isPending, children: T.isPending ? "Importing..." : "Import Outstanding Invoices" }),
|
|
6451
6474
|
T.error && /* @__PURE__ */ e("span", { className: "text-xs text-red-600", children: T.error.message }),
|
|
6452
|
-
|
|
6475
|
+
b.invoices && /* @__PURE__ */ r("span", { className: "text-xs text-green-600", children: [
|
|
6453
6476
|
"Created ",
|
|
6454
|
-
|
|
6477
|
+
b.invoices.invoices_created,
|
|
6455
6478
|
" invoices"
|
|
6456
6479
|
] })
|
|
6457
6480
|
] })
|
|
@@ -6478,7 +6501,7 @@ function Ls() {
|
|
|
6478
6501
|
}), { data: o } = le({
|
|
6479
6502
|
queryKey: ["auth-invites"],
|
|
6480
6503
|
queryFn: () => L.authListInvites()
|
|
6481
|
-
}), [i, c] = v(""), [l,
|
|
6504
|
+
}), [i, c] = v(""), [l, y] = v("viewer"), [d, p] = v(null), m = oe({
|
|
6482
6505
|
mutationFn: () => L.authInvite(i, l),
|
|
6483
6506
|
onSuccess: (u) => {
|
|
6484
6507
|
p(u), c(""), n.invalidateQueries({ queryKey: ["auth-invites"] });
|
|
@@ -6486,13 +6509,13 @@ function Ls() {
|
|
|
6486
6509
|
}), f = oe({
|
|
6487
6510
|
mutationFn: ({ name: u, role: h }) => L.authChangeRole(u, h),
|
|
6488
6511
|
onSuccess: () => n.invalidateQueries({ queryKey: ["auth-users"] })
|
|
6489
|
-
}),
|
|
6512
|
+
}), w = oe({
|
|
6490
6513
|
mutationFn: (u) => L.authDisableUser(u),
|
|
6491
6514
|
onSuccess: () => n.invalidateQueries({ queryKey: ["auth-users"] })
|
|
6492
|
-
}),
|
|
6515
|
+
}), b = oe({
|
|
6493
6516
|
mutationFn: (u) => L.authRevokeInvite(u),
|
|
6494
6517
|
onSuccess: () => n.invalidateQueries({ queryKey: ["auth-invites"] })
|
|
6495
|
-
}), [
|
|
6518
|
+
}), [g, P] = v(null), D = (u) => `${window.location.origin}/login?invite=${u}`, T = async (u) => {
|
|
6496
6519
|
try {
|
|
6497
6520
|
await navigator.clipboard.writeText(D(u)), P(u), setTimeout(() => P((h) => h === u ? null : h), 2e3);
|
|
6498
6521
|
} catch {
|
|
@@ -6517,7 +6540,7 @@ function Ls() {
|
|
|
6517
6540
|
/* @__PURE__ */ r(U, { title: "Invite User", children: [
|
|
6518
6541
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
6519
6542
|
/* @__PURE__ */ e(
|
|
6520
|
-
|
|
6543
|
+
ee,
|
|
6521
6544
|
{
|
|
6522
6545
|
label: "Email",
|
|
6523
6546
|
type: "email",
|
|
@@ -6532,7 +6555,7 @@ function Ls() {
|
|
|
6532
6555
|
label: "Role",
|
|
6533
6556
|
options: ["viewer", "manager", "admin"],
|
|
6534
6557
|
value: l,
|
|
6535
|
-
onChange: (u) =>
|
|
6558
|
+
onChange: (u) => y(u.target.value)
|
|
6536
6559
|
}
|
|
6537
6560
|
),
|
|
6538
6561
|
/* @__PURE__ */ e(
|
|
@@ -6577,7 +6600,7 @@ function Ls() {
|
|
|
6577
6600
|
variant: "secondary",
|
|
6578
6601
|
size: "sm",
|
|
6579
6602
|
onClick: () => T(u.token),
|
|
6580
|
-
children:
|
|
6603
|
+
children: g === u.token ? "Copied!" : "Copy link"
|
|
6581
6604
|
}
|
|
6582
6605
|
),
|
|
6583
6606
|
/* @__PURE__ */ e(
|
|
@@ -6585,8 +6608,8 @@ function Ls() {
|
|
|
6585
6608
|
{
|
|
6586
6609
|
variant: "danger",
|
|
6587
6610
|
size: "sm",
|
|
6588
|
-
onClick: () =>
|
|
6589
|
-
disabled:
|
|
6611
|
+
onClick: () => b.mutate(u.token),
|
|
6612
|
+
disabled: b.isPending,
|
|
6590
6613
|
children: "Revoke"
|
|
6591
6614
|
}
|
|
6592
6615
|
)
|
|
@@ -6623,7 +6646,7 @@ function Ls() {
|
|
|
6623
6646
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: u.name !== (t == null ? void 0 : t.name) && u.enabled ? /* @__PURE__ */ e(
|
|
6624
6647
|
"button",
|
|
6625
6648
|
{
|
|
6626
|
-
onClick: () =>
|
|
6649
|
+
onClick: () => w.mutate(u.name),
|
|
6627
6650
|
className: "text-xs text-red-500 hover:text-red-700",
|
|
6628
6651
|
children: "Disable"
|
|
6629
6652
|
}
|
|
@@ -6632,7 +6655,7 @@ function Ls() {
|
|
|
6632
6655
|
] }) })
|
|
6633
6656
|
] });
|
|
6634
6657
|
}
|
|
6635
|
-
const Bs = { save: "Save", saving: "Saving...", submit: "Submit", cancel: "Cancel", cancelDoc: "Cancel", cancelDocAbort: "Don't cancel", cancelDocConfirmBtn: "Yes, cancel document", discardDraft: "Discard draft", keepDraft: "Keep", discardDraftConfirm: "Discard draft", showDiscarded: "Show discarded", delete: "Delete", edit: "Edit", pdf: "PDF", addRow: "Add Row", loading: "Loading...", enable: "Enable", disable: "Disable", refresh: "Refresh", refreshing: "Refreshing", areYouSure: "Are you sure?", all: "All", apply: "Apply", new: "New", prev: "Prev", next: "Next", perPage: "Per page", page: "Page", of: "of", showing: "Showing", total: "Total", totals: "Totals", errorOccurred: "An error occurred" }, Es = { title: "Language", help: "Choose the language for the interface. Your choice is saved in this browser.", label: "Language" }, Os = { logout: "Logout", openMenu: "Open menu", closeMenu: "Close menu", new: "New {{label}}" }, qs = { dashboard: "Dashboard", setup: "Company Setup", tutorial: "Getting Started", chat: "Chat", reports: "Reports", "trial-balance": "Trial Balance", "general-ledger": "General Ledger", "stock-balance": "Stock Balance", "profit-and-loss": "Profit & Loss", "balance-sheet": "Balance Sheet", "ar-aging": "Accounts Receivable Aging", "ap-aging": "Accounts Payable Aging", analytics: "Analytics" }, Fs = { quotation: { one: "Quotation", other: "Quotations" }, proposal: { one: "Proposal", other: "Proposals" }, "sales-order": { one: "Sales Order", other: "Sales Orders" }, "sales-invoice": { one: "Sales Invoice", other: "Sales Invoices" }, "pos-invoice": { one: "POS Invoice", other: "POS Invoices" }, "purchase-order": { one: "Purchase Order", other: "Purchase Orders" }, "purchase-invoice": { one: "Purchase Invoice", other: "Purchase Invoices" }, "payment-entry": { one: "Payment Entry", other: "Payment Entries" }, "journal-entry": { one: "Journal Entry", other: "Journal Entries" }, "bank-transaction": { one: "Bank Transaction", other: "Bank Transactions" }, budget: { one: "Budget", other: "Budgets" }, subscription: { one: "Subscription", other: "Subscriptions" }, "stock-entry": { one: "Stock Entry", other: "Stock Entries" }, "delivery-note": { one: "Delivery Note", other: "Delivery Notes" }, "purchase-receipt": { one: "Purchase Receipt", other: "Purchase Receipts" }, "pricing-rule": { one: "Pricing Rule", other: "Pricing Rules" } }, Ms = { company: { one: "Company", other: "Companies" }, customer: { one: "Customer", other: "Customers" }, supplier: { one: "Supplier", other: "Suppliers" }, item: { one: "Item", other: "Items" }, warehouse: { one: "Warehouse", other: "Warehouses" } }, zs = { chats: "Chats", newChat: "New Chat", deleteChat: "Delete chat", customAnalytics: "Custom Analytics", newAnalytics: "New Analytics", deleteReport: "Delete report", groups: { Introduction: "Introduction", Selling: "Selling", Buying: "Buying", Accounting: "Accounting", Stock: "Stock", Reports: "Reports", Masters: "Masters", Settings: "Settings" }, items: { "Getting Started": "Getting Started", "Company Setup": "Company Setup", "Opening Balances": "Opening Balances", Quotation: "Quotation", Proposal: "Proposals", "Sales Order": "Sales Order", "Sales Invoice": "Sales Invoice", "POS Invoice": "POS Invoice", "Purchase Order": "Purchase Order", "Purchase Invoice": "Purchase Invoice", "Payment Entry": "Payment Entry", "Journal Entry": "Journal Entry", "Bank Transaction": "Bank Transaction", Budget: "Budget", Subscription: "Subscription", "Stock Entry": "Stock Entry", "Delivery Note": "Delivery Note", "Purchase Receipt": "Purchase Receipt", "Trial Balance": "Trial Balance", "Profit & Loss": "Profit & Loss", "Balance Sheet": "Balance Sheet", "General Ledger": "General Ledger", "AR Aging": "AR Aging", "AP Aging": "AP Aging", Analytics: "Analytics", "Stock Balance": "Stock Balance", Company: "Company", Customer: "Customer", Supplier: "Supplier", Item: "Item", Warehouse: "Warehouse", General: "General", "Pricing Rule": "Pricing Rule", "Users & Team": "Users & Team" } }, $s = { taglineFirstRun: "Create your admin account to get started", taglineRegister: "Create your account", taglineSignIn: "Sign in to your account", demoBanner: "Demo mode is active. Sign in with an admin account to manage settings or disable public access.", fullName: "Full Name", email: "Email", password: "Password", confirmPassword: "Confirm Password", createAdmin: "Create Admin Account", register: "Register", signIn: "Sign In", browsingTitle: "Just browsing?", browsingBody: "Start a fresh chat session and watch the live demo.", enterDemo: "Enter Live Demo", haveInvite: "Have an invite?", noAccountPrompt: "Need an account?", registerLink: "Register", alreadyHaveAccount: "Already have an account?", signInLink: "Sign in", passwordsNoMatch: "Passwords do not match", passwordTooShort: "Password must be at least 6 characters", registrationFailed: "Registration failed", loginFailed: "Login failed" }, Us = { pdfTitle: "PDF & Print", pageSize: "Page Size", pdfHelp: "A4 is standard internationally (210 x 297 mm). Letter is standard in the US (8.5 x 11 in).", passwordTitle: "Change Password", currentPassword: "Current password", newPassword: "New password", confirmNewPassword: "Confirm new password", changePassword: "Change password", changingPassword: "Changing...", passwordChanged: "Password changed.", openingTitle: "Opening Balances", openingBody: "The Opening Balances page allows importing account balances, stock, and outstanding invoices from a previous system.", openingEnabled: "Currently enabled — accessible under Introduction > Opening Balances.", openingDisabled: "Currently disabled — the page is hidden from the sidebar.", signupTitle: "Public Signup", signupBody: "Allow anyone to create their own account (as a viewer) without an invite. When off, new users can only join via an invite link.", signupEnabled: "Currently enabled — anyone with the URL can register as a viewer.", signupDisabled: "Currently disabled — registration is invite-only.", publicTitle: "Public Access (Demo Mode)", publicActive: "Active", publicActiveBody: "Public access is enabled. Anyone can use the application without logging in. All visitors get manager-level permissions.", disablePublic: "Disable Public Access", disabling: "Disabling...", publicInactiveBody: "Enable public access to let anyone use the application without an account. Useful for demos and showcases. All visitors get manager-level permissions and share the same identity.", enablePublic: "Enable Public Access", enableWarning: "This will allow anyone to access the application without logging in. They will be able to create, edit, and submit documents. Your admin account still requires login.", yesEnable: "Yes, Enable", enabling: "Enabling...", tokenSpendTitle: "Token Spend" }, Vs = { Draft: "Draft", Open: "Open", Submitted: "Submitted", "To Deliver and Bill": "To Deliver and Bill", "To Deliver": "To Deliver", "To Bill": "To Bill", Completed: "Completed", Ordered: "Ordered", Paid: "Paid", Unpaid: "Unpaid", Cancelled: "Cancelled", Discarded: "Discarded", Overdue: "Overdue", Return: "Return", Closed: "Closed" }, js = { balanced: "BALANCED", imbalanced: "IMBALANCED", income: "Income", expenses: "Expenses", totalIncome: "Total Income", totalExpenses: "Total Expenses", netProfit: "Net Profit", netLoss: "Net Loss", assets: "Assets", liabilities: "Liabilities", equity: "Equity", totalAssets: "Total Assets", totalLiabilities: "Total Liabilities", totalEquity: "Total Equity", totalLiabilitiesEquity: "Total Liabilities + Equity", current: "Current", noData: "No data found", noEntries: "No entries found", noStockData: "No stock data found", noReceivables: "No outstanding receivables", noPayables: "No outstanding payables", noDocuments: "No documents found" }, Gs = { required: "Required: {{fields}}", deleteConfirm: "Delete this {{label}}?", disabledNotice: "This {{label}} is disabled. It remains in the system because other records still reference it.", disabledOnDelete: "{{label}} {{name}} was disabled instead of deleted because it is referenced by {{reason}}." }, Ks = { totalRevenue: "Total Revenue", outstandingReceivable: "Outstanding Receivable", outstandingPayable: "Outstanding Payable", totalStockValue: "Total Stock Value", recentDocuments: "Recent Documents", noRecentDocuments: "No recent documents" }, Ws = { title: "Lambda ERP Chat", subtitle: "Ask me to create documents, look up data, or run reports.", s1: "What customers do we have?", s2: "Show me the trial balance", s3: "Create a quotation for 10 Bolt Pack M8", s4: "List all unpaid invoices", loadOlder: "Load older messages", uploading: "Uploading...", failed: "Failed", remove: "Remove", placeholderDemo: "Running live demo...", placeholderType: "Type a message...", placeholderConnecting: "Connecting...", attachTitle: "Attach file (PDF or image, max 10 MB)", creating: "Creating chat...", dropToAttach: "Drop file to attach (images or PDF, max 10 MB each)", demoError: "Could not start demo", voiceStart: "Record voice message", voiceStop: "Stop recording", voiceTranscribing: "Transcribing...", micDenied: "Microphone access was denied.", transcribeFailed: "Transcription failed. Please try again." }, Hs = { "Create Credit Note": "Create Credit Note", "Create Debit Note": "Create Debit Note", "Create Delivery Note": "Create Delivery Note", "Create Purchase Invoice": "Create Purchase Invoice", "Create Purchase Receipt": "Create Purchase Receipt", "Create Return": "Create Return", "Create Sales Invoice": "Create Sales Invoice", "Create Sales Order": "Create Sales Order" }, Qs = { "% Billed": "% Billed", "% Delivered": "% Delivered", Account: "Account", Address: "Address", Allocated: "Allocated", Amount: "Amount", "As of Date": "As of Date", Balance: "Balance", "Bank Account": "Bank Account", "Billing Interval": "Billing Interval", "Budget Amount": "Budget Amount", Buying: "Buying", Change: "Change", City: "City", Company: "Company", "Company Name": "Company Name", "Cost Center": "Cost Center", Country: "Country", Credit: "Credit", "Credit Limit": "Credit Limit", Currency: "Currency", "Current Period End": "Current Period End", "Contact Person": "Contact Person", "Contact Email": "Contact Email", "Contact Phone": "Contact Phone", "Current Period Start": "Current Period Start", Customer: "Customer", "Customer Group": "Customer Group", "Customer Name": "Customer Name", Date: "Date", Debit: "Debit", "Delivery Date": "Delivery Date", Deposit: "Deposit", Description: "Description", "Discount %": "Discount %", "Discount Amt": "Discount Amt", "Discount Percentage": "Discount Percentage", "Due Date": "Due Date", Email: "Email", Enabled: "Enabled", "End Date": "End Date", "Expense Account": "Expense Account", "Fiscal Year": "Fiscal Year", "From Date": "From Date", "Grand Total": "Grand Total", Frequency: "Frequency", ID: "ID", "If Exceeded": "If Exceeded", "Income Account": "Income Account", "Incoming Value": "Incoming Value", Invoice: "Invoice", Item: "Item", "Item Code": "Item Code", "Item Group": "Item Group", "Item Name": "Item Name", "Matched Doc": "Matched Doc", "Matched Type": "Matched Type", "Min Qty": "Min Qty", Mode: "Mode", Month: "Month", Name: "Name", "Net Total": "Net Total", "Notes / Terms": "Notes / Terms", "Outgoing Value": "Outgoing Value", Outstanding: "Outstanding", "Outstanding Amount": "Outstanding Amount", "Paid Amount": "Paid Amount", "Paid From": "Paid From", "Paid To": "Paid To", Party: "Party", "Party Type": "Party Type", "Payment Type": "Payment Type", Phone: "Phone", "Plan Items": "Plan Items", "Posting Date": "Posting Date", Priority: "Priority", Qty: "Qty", Rate: "Rate", "Rate (%)": "Rate (%)", "Rate Or Discount": "Rate Or Discount", "Reference No": "Reference No", Remark: "Remark", Selling: "Selling", Source: "Source", "Source Warehouse": "Source Warehouse", "Standard Rate": "Standard Rate", "Start Date": "Start Date", Status: "Status", "Stock Entry Type": "Stock Entry Type", "Stock UOM": "Stock UOM", "Stock Value": "Stock Value", Supplier: "Supplier", "Supplier Group": "Supplier Group", "Supplier Name": "Supplier Name", Target: "Target", "Target Warehouse": "Target Warehouse", Tax: "Tax", "Tax ID": "Tax ID", Territory: "Territory", Title: "Title", "To Date": "To Date", Total: "Total", "Total Amount": "Total Amount", "Total Credit": "Total Credit", "Total Debit": "Total Debit", "Transaction Date": "Transaction Date", Type: "Type", Unallocated: "Unallocated", "Update Stock": "Update Stock", "Valid From": "Valid From", "Valid Till": "Valid Till", "Valid Upto": "Valid Upto", "Valuation Rate": "Valuation Rate", "Voucher No": "Voucher No", "Voucher Type": "Voucher Type", Warehouse: "Warehouse", "Warehouse Name": "Warehouse Name", Withdrawal: "Withdrawal", "Zip Code": "Zip Code" }, Js = { accounts: "accounts", items: "items", monthly_distribution: "monthly_distribution", payments: "payments", plans: "plans", references: "references", taxes: "taxes" }, Ys = /* @__PURE__ */ JSON.parse(`{"chips":{"Cancelled":"Cancelled","Credit Note":"Credit Note","DN Return":"DN Return","Debit Note":"Debit Note","Delivery Note":"Delivery Note","Draft":"Draft","Payment Entry":"Payment Entry","Purchase Invoice":"Purchase Invoice","Purchase Order":"Purchase Order","Purchase Receipt":"Purchase Receipt","Quotation":"Quotation","Sales Invoice":"Sales Invoice","Sales Order":"Sales Order","Submitted":"Submitted"},"links":{"AP Aging":"AP Aging","AR Aging":"AR Aging","Balance Sheet":"Balance Sheet","Customers":"Customers","Delivery Notes":"Delivery Notes","General Ledger":"General Ledger","Go to Setup":"Go to Setup","Items":"Items","New Journal Entry":"New Journal Entry","New Payment Entry":"New Payment Entry","New Purchase Order":"New Purchase Order","New Quotation":"New Quotation","New Stock Entry":"New Stock Entry","Open AI Chat":"Open AI Chat","Profit & Loss":"Profit & Loss","Purchase Invoices":"Purchase Invoices","Purchase Receipts":"Purchase Receipts","Sales Invoices":"Sales Invoices","Stock Balance":"Stock Balance","Suppliers":"Suppliers","Trial Balance":"Trial Balance","View Quotations":"View Quotations","Warehouses":"Warehouses"},"steps":{"1":{"title":"Set Up Your Company","description":"Create a company with a base currency. This generates your Chart of Accounts (30 standard accounts across Assets, Liabilities, Equity, Income, and Expenses) and a default Cost Center. You can also seed demo data with sample customers, suppliers, and items to get started quickly."},"2":{"title":"Create Master Data","description":"Before you can transact, you need master records. Create at least one Customer, one Supplier, one Item (with a standard rate), and one Warehouse. If you seeded demo data in Step 1, these already exist.","tip":"Items have a standard rate that auto-fills when you add them to documents. You can always override the rate per transaction."},"3":{"title":"Create a Quotation","description":"A Quotation is a non-binding offer to a customer. Select a customer, add line items with quantities and rates, optionally add tax rows, then save. Quotations have no financial impact — they don't create accounting or stock entries. Set a validity date so the offer expires automatically."},"4":{"title":"Submit and Convert to Sales Order","description":"Open your saved Quotation and click Submit to confirm it. Then click “Create Sales Order” to convert it. The Sales Order represents a confirmed commitment from the customer. It still has no financial impact, but it reserves stock for planning purposes.","tip":"Only submitted documents can be converted to the next step. Draft → Submit → Convert is the standard flow. For quick deals, you can skip the Sales Order and go directly from Quotation to Sales Invoice or Delivery Note."},"5":{"title":"Check Stock Before Fulfilling","description":"Before you can deliver, check if you actually have the item in stock. Go to the Stock Balance report and look up the item. If your warehouse has zero quantity, you’ll need to bring stock in first — either through a Purchase Order (buying from a supplier) or a Stock Entry (manual receipt).","tip":"This is a common real-world scenario: you sell something, then realize you need to buy it first. The ERP handles both flows."},"6":{"title":"Purchase Cycle: Buy Stock from a Supplier","description":"If you need to buy stock, you have two valid paths. The standard path is Purchase Order -> Purchase Receipt -> Purchase Invoice: use this when goods arrive before or separately from the supplier bill. If the bill and receipt happen together, you can create the Purchase Invoice directly and enable Update Stock so the same document both receives inventory and records Accounts Payable.","tip":"Use Purchase Receipt first when receiving goods separately. Use Purchase Invoice with Update Stock when one step should both receive stock and book the supplier bill. In that direct path, set a warehouse on each stock item row."},"7":{"title":"Create a Delivery Note","description":"Now that you have stock, go back to your submitted Sales Order and click “Create Delivery Note.” Set the warehouse on each item row (where the goods ship from), then submit. This moves inventory out of the warehouse — your stock balance decreases.","tip":"The Delivery Note is the shipping document. It reduces stock but doesn’t create an invoice. You can deliver and invoice separately."},"8":{"title":"Create and Submit the Sales Invoice","description":"From the submitted Sales Order, create a Sales Invoice. When you submit the invoice, GL entries are posted: Accounts Receivable is debited (the customer owes you) and Sales Revenue is credited (income earned). If taxes are configured, Tax Payable is also credited. The outstanding amount shows what the customer still owes."},"9":{"title":"Record Customer Payments","description":"Create a Payment Entry to record money received from the customer. Set the payment type to “Receive,” select the customer, specify the amount, and allocate it against the Sales Invoice. You can make partial payments — the invoice’s outstanding amount updates accordingly. Create additional Payment Entries until the invoice is fully paid.","tip":"Partial payments are common. A 10,000 invoice might be paid as 3,000 now and 7,000 later. Each Payment Entry reduces the outstanding amount."},"10":{"title":"Stock Entries (Manual Inventory)","description":"Use Stock Entries for inventory movements that aren’t tied to purchases or sales. Material Receipt adds stock (opening balances, adjustments). Material Issue removes stock (write-offs, internal consumption). Material Transfer moves stock between warehouses. Each entry updates the stock ledger with moving-average valuation.","tip":"For purchased goods, use Purchase Receipts instead of Stock Entries — they link to the Purchase Order and give you a proper audit trail."},"11":{"title":"Journal Entries","description":"Journal Entries are manual accounting adjustments — expense accruals, corrections, reclassifications, opening balances. Each entry must have balanced debits and credits (total debit = total credit). Use these when no other document type fits."},"12":{"title":"Salary Payments","description":"Lambda ERP handles salaries through the existing accounting tools. First, accrue the salary expense: create a Journal Entry that debits Salary Expense and credits Salary Payable for the total payroll amount. Then pay the employees: create another Journal Entry (or Payment Entry) that debits Salary Payable and credits your bank account. This two-step process keeps your books accurate — the expense is recorded in the right period, and the cash outflow is tracked separately.","tip":"You can ask the AI assistant to do this for you: “Accrue 15,000 in salaries for April” followed by “Pay the April salaries from bank.” It will create the right journal entries automatically."},"13":{"title":"Returns and Credit Notes","description":"When a customer returns goods or you need to issue a credit, create a return. Returns use the same document type with negative quantities. Open a submitted Sales Invoice and create a Credit Note (Sales Invoice return) — this reverses the GL entries and reduces the original invoice’s outstanding amount. For stock, create a Delivery Note return to bring goods back into the warehouse. On the buying side, create a Debit Note (Purchase Invoice return) to reverse a supplier bill, or a Purchase Receipt return to send goods back.","tip":"A Credit Note is just a Sales Invoice with is_return=1 and negative quantities. The same GL logic runs — negative amounts automatically flip to the correct debit/credit sides. For a full sales return, you need both a Credit Note (financials) and a Delivery Note return (stock)."},"14":{"title":"Run Reports","description":"Check your books. The Profit & Loss shows income vs expenses and net profit for a period. The Balance Sheet shows your financial position (assets = liabilities + equity). AR Aging shows who owes you money and how overdue it is. AP Aging shows what you owe suppliers. The Trial Balance verifies double-entry integrity. The General Ledger shows every individual posting. Stock Balance shows current inventory."},"15":{"title":"Working in Foreign Currencies","description":"Your books are kept in a single base currency (chosen at company setup), but you can transact in any currency. Set a currency on an invoice or bill — or give a customer or supplier a default currency — and the exchange rate for that date is looked up automatically and stored on the document. The document keeps its amounts in its own currency, while the General Ledger always posts in your base currency. When you later collect or pay at a different rate, the realized exchange gain or loss is booked automatically to an Exchange Gain/Loss account. You can even hold a foreign-currency bank balance and convert it later at your bank’s rate — the difference versus its carried value is realized then. At month end you can revalue open foreign balances to the closing rate (an unrealized gain/loss that reverses next period), and you can view any financial statement translated into another currency for display.","tip":"This is easiest through the AI chat — try “Create a sales invoice for Lumiere Audio in EUR,” “Show me the balance sheet in EUR,” or “What’s our unrealized FX exposure at month end?” The seeded demo already includes a EUR customer (Lumiere Audio SARL) whose invoice was collected at a different rate, plus an open EUR supplier bill — open the General Ledger to see the realized FX postings."}},"caTitle":"Dynamic Analytics — Chat Your Way to Any Chart","caBadge":"Signature Feature","caBody":"Need a report the presets can’t give you? Just describe it in chat. The assistant calls a code-specialist model that writes the report for you, runs it live over your ERP data, and returns a sharable link. The chart or table renders in seconds and is saved as a draft under Custom Analytics in the sidebar — you can reopen it, share the URL with teammates, or ask the assistant to refine it.","caTryAsking":"Try asking (click to prefill in chat):","caPrompt1":"Show me top 10 customers by revenue this year as a bar chart","caPrompt2":"Monthly purchases trend by supplier over all months and label x-axis with supplier name","caPrompt3":"Best selling items by quantity, with a table and a chart","caPrompt4":"Which customers owe me the most right now?","caTryInChat":"Try it in chat","caOpenWorkspace":"Open Analytics workspace","flowTitle":"Document Flow Overview","salesCycle":"Sales Cycle","flowShortcut":"Shortcut: Quotation can skip Sales Order and go directly to Sales Invoice or Delivery Note","purchaseCycle":"Purchase Cycle","returns":"Returns","legendStock":"stock impact","legendGl":"GL impact","legendCash":"cash impact","legendReversal":"reversal","lifecycleTitle":"Document Lifecycle","lcDraftLabel":"Draft:","lcDraftDesc":"Editable. No financial or stock impact.","lcSubmittedLabel":"Submitted:","lcSubmittedDesc":"Locked. GL entries and stock ledger entries are posted.","lcCancelledLabel":"Cancelled:","lcCancelledDesc":"All entries reversed. Document is permanently archived.","lcNoDelete":"There is no delete. To void a draft: submit it, then cancel it.","lcCorrect":"To correct a submitted document: cancel it and create a new one.","pageTitle":"Getting Started with Lambda ERP","intro":"Lambda ERP is an AI Native ERP System, with all functionality — like creating orders, checking inventory, recording payments — being accessible through a chat interface. It instructs, reasons and checks all your daily business tasks.","openChat":"Open AI Chat","tipLabel":"Tip:","topTip":"The AI chat can also give you direct links to documents and downloadable PDFs. Just ask it to create or look up a document and it will include clickable links in its response.","manualIntro":"If you want to fully understand how things work under the hood, or prefer to do things manually, here’s a full business cycle step by step.","readyTitle":"You're Ready","readyBody1":"You now understand the full cycle. A typical real-world scenario looks like this: you receive a customer order (Quotation → Sales Order), check stock, buy what you need (Purchase Order → Purchase Receipt → Purchase Invoice → Payment), deliver to the customer (Delivery Note), bill them (Sales Invoice), and collect payment (Payment Entry). If something comes back, create a Credit Note and Delivery Note return to reverse the financials and stock. The Trial Balance confirms everything is balanced.","readyBody2":"You can also use the AI chat to do all of this through natural conversation — just describe what you need and it will create the right documents for you."}`), Zs = { title: "Formatting help", intro: "The Notes / Terms text supports light formatting on the PDF:", heading: "bold heading", emphasis: "italic / bold", price: "right-aligned price beside the text above (e.g. Monthly | CHF 380.—)", block: "Separate blocks with a blank line." }, Xs = {
|
|
6658
|
+
const Bs = { save: "Save", saving: "Saving...", submit: "Submit", cancel: "Cancel", cancelDoc: "Cancel", cancelDocAbort: "Don't cancel", cancelDocConfirmBtn: "Yes, cancel document", discardDraft: "Discard draft", keepDraft: "Keep", discardDraftConfirm: "Discard draft", showDiscarded: "Show discarded", delete: "Delete", edit: "Edit", pdf: "PDF", addRow: "Add Row", loading: "Loading...", enable: "Enable", disable: "Disable", refresh: "Refresh", refreshing: "Refreshing", areYouSure: "Are you sure?", all: "All", apply: "Apply", new: "New", prev: "Prev", next: "Next", perPage: "Per page", page: "Page", of: "of", showing: "Showing", total: "Total", totals: "Totals", errorOccurred: "An error occurred" }, Es = { title: "Language", help: "Choose the language for the interface. Your choice is saved in this browser.", label: "Language" }, Os = { logout: "Logout", openMenu: "Open menu", closeMenu: "Close menu", new: "New {{label}}" }, qs = { dashboard: "Dashboard", setup: "Company Setup", tutorial: "Getting Started", chat: "Chat", reports: "Reports", "trial-balance": "Trial Balance", "general-ledger": "General Ledger", "stock-balance": "Stock Balance", "profit-and-loss": "Profit & Loss", "balance-sheet": "Balance Sheet", "ar-aging": "Accounts Receivable Aging", "ap-aging": "Accounts Payable Aging", analytics: "Analytics" }, Fs = { quotation: { one: "Quotation", other: "Quotations" }, proposal: { one: "Proposal", other: "Proposals" }, "sales-order": { one: "Sales Order", other: "Sales Orders" }, "sales-invoice": { one: "Sales Invoice", other: "Sales Invoices" }, "pos-invoice": { one: "POS Invoice", other: "POS Invoices" }, "purchase-order": { one: "Purchase Order", other: "Purchase Orders" }, "purchase-invoice": { one: "Purchase Invoice", other: "Purchase Invoices" }, "payment-entry": { one: "Payment Entry", other: "Payment Entries" }, "journal-entry": { one: "Journal Entry", other: "Journal Entries" }, "bank-transaction": { one: "Bank Transaction", other: "Bank Transactions" }, budget: { one: "Budget", other: "Budgets" }, subscription: { one: "Subscription", other: "Subscriptions" }, "stock-entry": { one: "Stock Entry", other: "Stock Entries" }, "delivery-note": { one: "Delivery Note", other: "Delivery Notes" }, "purchase-receipt": { one: "Purchase Receipt", other: "Purchase Receipts" }, "pricing-rule": { one: "Pricing Rule", other: "Pricing Rules" } }, Ms = { company: { one: "Company", other: "Companies" }, customer: { one: "Customer", other: "Customers" }, supplier: { one: "Supplier", other: "Suppliers" }, item: { one: "Item", other: "Items" }, warehouse: { one: "Warehouse", other: "Warehouses" } }, zs = { chats: "Chats", newChat: "New Chat", deleteChat: "Delete chat", customAnalytics: "Custom Analytics", newAnalytics: "New Analytics", deleteReport: "Delete report", groups: { Introduction: "Introduction", Selling: "Selling", Buying: "Buying", Accounting: "Accounting", Stock: "Stock", Reports: "Reports", Masters: "Masters", Settings: "Settings" }, items: { "Getting Started": "Getting Started", "Company Setup": "Company Setup", "Opening Balances": "Opening Balances", Quotation: "Quotation", Proposal: "Proposals", "Sales Order": "Sales Order", "Sales Invoice": "Sales Invoice", "POS Invoice": "POS Invoice", "Purchase Order": "Purchase Order", "Purchase Invoice": "Purchase Invoice", "Payment Entry": "Payment Entry", "Journal Entry": "Journal Entry", "Bank Transaction": "Bank Transaction", Budget: "Budget", Subscription: "Subscription", "Stock Entry": "Stock Entry", "Delivery Note": "Delivery Note", "Purchase Receipt": "Purchase Receipt", "Trial Balance": "Trial Balance", "Profit & Loss": "Profit & Loss", "Balance Sheet": "Balance Sheet", "General Ledger": "General Ledger", "AR Aging": "AR Aging", "AP Aging": "AP Aging", Analytics: "Analytics", "Stock Balance": "Stock Balance", Company: "Company", Customer: "Customer", Supplier: "Supplier", Item: "Item", Warehouse: "Warehouse", General: "General", "Pricing Rule": "Pricing Rule", "Users & Team": "Users & Team" } }, $s = { taglineFirstRun: "Create your admin account to get started", taglineRegister: "Create your account", taglineSignIn: "Sign in to your account", demoBanner: "Demo mode is active. Sign in with an admin account to manage settings or disable public access.", fullName: "Full Name", email: "Email", password: "Password", confirmPassword: "Confirm Password", createAdmin: "Create Admin Account", register: "Register", signIn: "Sign In", browsingTitle: "Just browsing?", browsingBody: "Start a fresh chat session and watch the live demo.", enterDemo: "Enter Live Demo", haveInvite: "Have an invite?", noAccountPrompt: "Need an account?", registerLink: "Register", alreadyHaveAccount: "Already have an account?", signInLink: "Sign in", passwordsNoMatch: "Passwords do not match", passwordTooShort: "Password must be at least 6 characters", registrationFailed: "Registration failed", loginFailed: "Login failed" }, Us = { pdfTitle: "PDF & Print", pageSize: "Page Size", pdfHelp: "A4 is standard internationally (210 x 297 mm). Letter is standard in the US (8.5 x 11 in).", passwordTitle: "Change Password", currentPassword: "Current password", newPassword: "New password", confirmNewPassword: "Confirm new password", changePassword: "Change password", changingPassword: "Changing...", passwordChanged: "Password changed.", openingTitle: "Opening Balances", openingBody: "The Opening Balances page allows importing account balances, stock, and outstanding invoices from a previous system.", openingEnabled: "Currently enabled — accessible under Introduction > Opening Balances.", openingDisabled: "Currently disabled — the page is hidden from the sidebar.", signupTitle: "Public Signup", signupBody: "Allow anyone to create their own account (as a viewer) without an invite. When off, new users can only join via an invite link.", signupEnabled: "Currently enabled — anyone with the URL can register as a viewer.", signupDisabled: "Currently disabled — registration is invite-only.", publicTitle: "Public Access (Demo Mode)", publicActive: "Active", publicActiveBody: "Public access is enabled. Anyone can use the application without logging in. All visitors get manager-level permissions.", disablePublic: "Disable Public Access", disabling: "Disabling...", publicInactiveBody: "Enable public access to let anyone use the application without an account. Useful for demos and showcases. All visitors get manager-level permissions and share the same identity.", enablePublic: "Enable Public Access", enableWarning: "This will allow anyone to access the application without logging in. They will be able to create, edit, and submit documents. Your admin account still requires login.", yesEnable: "Yes, Enable", enabling: "Enabling...", tokenSpendTitle: "Token Spend" }, Vs = { Draft: "Draft", Open: "Open", Submitted: "Submitted", "To Deliver and Bill": "To Deliver and Bill", "To Deliver": "To Deliver", "To Bill": "To Bill", Completed: "Completed", Ordered: "Ordered", Paid: "Paid", Unpaid: "Unpaid", Cancelled: "Cancelled", Discarded: "Discarded", Overdue: "Overdue", Return: "Return", Closed: "Closed" }, js = { balanced: "BALANCED", imbalanced: "IMBALANCED", income: "Income", expenses: "Expenses", totalIncome: "Total Income", totalExpenses: "Total Expenses", netProfit: "Net Profit", netLoss: "Net Loss", assets: "Assets", liabilities: "Liabilities", equity: "Equity", totalAssets: "Total Assets", totalLiabilities: "Total Liabilities", totalEquity: "Total Equity", totalLiabilitiesEquity: "Total Liabilities + Equity", current: "Current", noData: "No data found", noEntries: "No entries found", noStockData: "No stock data found", noReceivables: "No outstanding receivables", noPayables: "No outstanding payables", noDocuments: "No documents found" }, Gs = { required: "Required: {{fields}}", deleteConfirm: "Delete this {{label}}?", disabledNotice: "This {{label}} is disabled. It remains in the system because other records still reference it.", disabledOnDelete: "{{label}} {{name}} was disabled instead of deleted because it is referenced by {{reason}}." }, Ks = { totalRevenue: "Total Revenue", outstandingReceivable: "Outstanding Receivable", outstandingPayable: "Outstanding Payable", totalStockValue: "Total Stock Value", recentDocuments: "Recent Documents", noRecentDocuments: "No recent documents" }, Ws = { title: "Lambda ERP Chat", subtitle: "Ask me to create documents, look up data, or run reports.", s1: "What customers do we have?", s2: "Show me the trial balance", s3: "Create a quotation for 10 Bolt Pack M8", s4: "List all unpaid invoices", loadOlder: "Load older messages", uploading: "Uploading...", failed: "Failed", remove: "Remove", placeholderDemo: "Running live demo...", placeholderType: "Type a message...", placeholderConnecting: "Connecting...", attachTitle: "Attach file (PDF or image, max 10 MB)", creating: "Creating chat...", dropToAttach: "Drop file to attach (images or PDF, max 10 MB each)", demoError: "Could not start demo", voiceStart: "Record voice message", voiceStop: "Stop recording", voiceTranscribing: "Transcribing...", micDenied: "Microphone access was denied.", transcribeFailed: "Transcription failed. Please try again." }, Hs = { "Create Credit Note": "Create Credit Note", "Create Debit Note": "Create Debit Note", "Create Delivery Note": "Create Delivery Note", "Create Purchase Invoice": "Create Purchase Invoice", "Create Purchase Receipt": "Create Purchase Receipt", "Create Return": "Create Return", "Create Sales Invoice": "Create Sales Invoice", "Create Sales Order": "Create Sales Order" }, Qs = { "% Billed": "% Billed", "% Delivered": "% Delivered", Account: "Account", Address: "Address", Allocated: "Allocated", Amount: "Amount", "As of Date": "As of Date", Balance: "Balance", "Bank Account": "Bank Account", "Billing Interval": "Billing Interval", "Budget Amount": "Budget Amount", Buying: "Buying", Change: "Change", City: "City", Company: "Company", "Company Name": "Company Name", "Cost Center": "Cost Center", Country: "Country", Credit: "Credit", "Credit Limit": "Credit Limit", Currency: "Currency", "Current Period End": "Current Period End", "Contact Person": "Contact Person", "Contact Email": "Contact Email", "Contact Phone": "Contact Phone", "Current Period Start": "Current Period Start", Customer: "Customer", "Customer Group": "Customer Group", "Customer Name": "Customer Name", Date: "Date", Debit: "Debit", "Delivery Date": "Delivery Date", Deposit: "Deposit", Description: "Description", "Discount %": "Discount %", "Discount Amt": "Discount Amt", "Discount Percentage": "Discount Percentage", "Due Date": "Due Date", Email: "Email", Enabled: "Enabled", "End Date": "End Date", "Expense Account": "Expense Account", "Fiscal Year": "Fiscal Year", "From Date": "From Date", "Grand Total": "Grand Total", Frequency: "Frequency", ID: "ID", "If Exceeded": "If Exceeded", "Income Account": "Income Account", "Incoming Value": "Incoming Value", Invoice: "Invoice", Item: "Item", "Item Code": "Item Code", "Item Group": "Item Group", "Item Name": "Item Name", "Matched Doc": "Matched Doc", "Matched Type": "Matched Type", "Min Qty": "Min Qty", Mode: "Mode", Month: "Month", Name: "Name", "Net Total": "Net Total", "Notes / Terms": "Notes / Terms", "Outgoing Value": "Outgoing Value", Outstanding: "Outstanding", "Outstanding Amount": "Outstanding Amount", "Paid Amount": "Paid Amount", "Paid From": "Paid From", "Paid To": "Paid To", Party: "Party", "Party Type": "Party Type", "Payment Type": "Payment Type", Phone: "Phone", "Plan Items": "Plan Items", "Posting Date": "Posting Date", Priority: "Priority", Qty: "Qty", Rate: "Rate", "Rate (%)": "Rate (%)", "Rate Or Discount": "Rate Or Discount", "Reference No": "Reference No", Remark: "Remark", Selling: "Selling", Source: "Source", "Source Warehouse": "Source Warehouse", "Standard Rate": "Standard Rate", "Start Date": "Start Date", Status: "Status", "Stock Entry Type": "Stock Entry Type", "Stock UOM": "Stock UOM", "Stock Value": "Stock Value", Supplier: "Supplier", "Supplier Group": "Supplier Group", "Supplier Name": "Supplier Name", Target: "Target", "Target Warehouse": "Target Warehouse", Tax: "Tax", "Tax ID": "Tax ID", Territory: "Territory", Title: "Title", "To Date": "To Date", Total: "Total", "Total Amount": "Total Amount", "Total Credit": "Total Credit", "Total Debit": "Total Debit", "Transaction Date": "Transaction Date", Type: "Type", Unallocated: "Unallocated", "Update Stock": "Update Stock", "Valid From": "Valid From", "Valid Till": "Valid Till", "Valid Upto": "Valid Upto", "Valuation Rate": "Valuation Rate", "Voucher No": "Voucher No", "Voucher Type": "Voucher Type", Warehouse: "Warehouse", "Warehouse Name": "Warehouse Name", Withdrawal: "Withdrawal", "Zip Code": "Zip Code" }, Js = { accounts: "accounts", items: "items", monthly_distribution: "monthly_distribution", payments: "payments", plans: "plans", references: "references", taxes: "taxes" }, Ys = /* @__PURE__ */ JSON.parse(`{"chips":{"Cancelled":"Cancelled","Credit Note":"Credit Note","DN Return":"DN Return","Debit Note":"Debit Note","Delivery Note":"Delivery Note","Draft":"Draft","Payment Entry":"Payment Entry","Purchase Invoice":"Purchase Invoice","Purchase Order":"Purchase Order","Purchase Receipt":"Purchase Receipt","Quotation":"Quotation","Sales Invoice":"Sales Invoice","Sales Order":"Sales Order","Submitted":"Submitted"},"links":{"AP Aging":"AP Aging","AR Aging":"AR Aging","Balance Sheet":"Balance Sheet","Customers":"Customers","Delivery Notes":"Delivery Notes","General Ledger":"General Ledger","Go to Setup":"Go to Setup","Items":"Items","New Journal Entry":"New Journal Entry","New Payment Entry":"New Payment Entry","New Purchase Order":"New Purchase Order","New Quotation":"New Quotation","New Stock Entry":"New Stock Entry","Open AI Chat":"Open AI Chat","Profit & Loss":"Profit & Loss","Purchase Invoices":"Purchase Invoices","Purchase Receipts":"Purchase Receipts","Sales Invoices":"Sales Invoices","Stock Balance":"Stock Balance","Suppliers":"Suppliers","Trial Balance":"Trial Balance","View Quotations":"View Quotations","Warehouses":"Warehouses"},"steps":{"1":{"title":"Set Up Your Company","description":"Create a company with a base currency. This generates your Chart of Accounts (30 standard accounts across Assets, Liabilities, Equity, Income, and Expenses) and a default Cost Center. You can also seed demo data with sample customers, suppliers, and items to get started quickly."},"2":{"title":"Create Master Data","description":"Before you can transact, you need master records. Create at least one Customer, one Supplier, one Item (with a standard rate), and one Warehouse. If you seeded demo data in Step 1, these already exist.","tip":"Items have a standard rate that auto-fills when you add them to documents. You can always override the rate per transaction."},"3":{"title":"Create a Quotation","description":"A Quotation is a non-binding offer to a customer. Select a customer, add line items with quantities and rates, optionally add tax rows, then save. Quotations have no financial impact — they don't create accounting or stock entries. Set a validity date so the offer expires automatically."},"4":{"title":"Submit and Convert to Sales Order","description":"Open your saved Quotation and click Submit to confirm it. Then click “Create Sales Order” to convert it. The Sales Order represents a confirmed commitment from the customer. It still has no financial impact, but it reserves stock for planning purposes.","tip":"Only submitted documents can be converted to the next step. Draft → Submit → Convert is the standard flow. For quick deals, you can skip the Sales Order and go directly from Quotation to Sales Invoice or Delivery Note."},"5":{"title":"Check Stock Before Fulfilling","description":"Before you can deliver, check if you actually have the item in stock. Go to the Stock Balance report and look up the item. If your warehouse has zero quantity, you’ll need to bring stock in first — either through a Purchase Order (buying from a supplier) or a Stock Entry (manual receipt).","tip":"This is a common real-world scenario: you sell something, then realize you need to buy it first. The ERP handles both flows."},"6":{"title":"Purchase Cycle: Buy Stock from a Supplier","description":"If you need to buy stock, you have two valid paths. The standard path is Purchase Order -> Purchase Receipt -> Purchase Invoice: use this when goods arrive before or separately from the supplier bill. If the bill and receipt happen together, you can create the Purchase Invoice directly and enable Update Stock so the same document both receives inventory and records Accounts Payable.","tip":"Use Purchase Receipt first when receiving goods separately. Use Purchase Invoice with Update Stock when one step should both receive stock and book the supplier bill. In that direct path, set a warehouse on each stock item row."},"7":{"title":"Create a Delivery Note","description":"Now that you have stock, go back to your submitted Sales Order and click “Create Delivery Note.” Set the warehouse on each item row (where the goods ship from), then submit. This moves inventory out of the warehouse — your stock balance decreases.","tip":"The Delivery Note is the shipping document. It reduces stock but doesn’t create an invoice. You can deliver and invoice separately."},"8":{"title":"Create and Submit the Sales Invoice","description":"From the submitted Sales Order, create a Sales Invoice. When you submit the invoice, GL entries are posted: Accounts Receivable is debited (the customer owes you) and Sales Revenue is credited (income earned). If taxes are configured, Tax Payable is also credited. The outstanding amount shows what the customer still owes."},"9":{"title":"Record Customer Payments","description":"Create a Payment Entry to record money received from the customer. Set the payment type to “Receive,” select the customer, specify the amount, and allocate it against the Sales Invoice. You can make partial payments — the invoice’s outstanding amount updates accordingly. Create additional Payment Entries until the invoice is fully paid.","tip":"Partial payments are common. A 10,000 invoice might be paid as 3,000 now and 7,000 later. Each Payment Entry reduces the outstanding amount."},"10":{"title":"Stock Entries (Manual Inventory)","description":"Use Stock Entries for inventory movements that aren’t tied to purchases or sales. Material Receipt adds stock (opening balances, adjustments). Material Issue removes stock (write-offs, internal consumption). Material Transfer moves stock between warehouses. Each entry updates the stock ledger with moving-average valuation.","tip":"For purchased goods, use Purchase Receipts instead of Stock Entries — they link to the Purchase Order and give you a proper audit trail."},"11":{"title":"Journal Entries","description":"Journal Entries are manual accounting adjustments — expense accruals, corrections, reclassifications, opening balances. Each entry must have balanced debits and credits (total debit = total credit). Use these when no other document type fits."},"12":{"title":"Salary Payments","description":"Lambda ERP handles salaries through the existing accounting tools. First, accrue the salary expense: create a Journal Entry that debits Salary Expense and credits Salary Payable for the total payroll amount. Then pay the employees: create another Journal Entry (or Payment Entry) that debits Salary Payable and credits your bank account. This two-step process keeps your books accurate — the expense is recorded in the right period, and the cash outflow is tracked separately.","tip":"You can ask the AI assistant to do this for you: “Accrue 15,000 in salaries for April” followed by “Pay the April salaries from bank.” It will create the right journal entries automatically."},"13":{"title":"Returns and Credit Notes","description":"When a customer returns goods or you need to issue a credit, create a return. Returns use the same document type with negative quantities. Open a submitted Sales Invoice and create a Credit Note (Sales Invoice return) — this reverses the GL entries and reduces the original invoice’s outstanding amount. For stock, create a Delivery Note return to bring goods back into the warehouse. On the buying side, create a Debit Note (Purchase Invoice return) to reverse a supplier bill, or a Purchase Receipt return to send goods back.","tip":"A Credit Note is just a Sales Invoice with is_return=1 and negative quantities. The same GL logic runs — negative amounts automatically flip to the correct debit/credit sides. For a full sales return, you need both a Credit Note (financials) and a Delivery Note return (stock)."},"14":{"title":"Run Reports","description":"Check your books. The Profit & Loss shows income vs expenses and net profit for a period. The Balance Sheet shows your financial position (assets = liabilities + equity). AR Aging shows who owes you money and how overdue it is. AP Aging shows what you owe suppliers. The Trial Balance verifies double-entry integrity. The General Ledger shows every individual posting. Stock Balance shows current inventory."},"15":{"title":"Working in Foreign Currencies","description":"Your books are kept in a single base currency (chosen at company setup), but you can transact in any currency. Set a currency on an invoice or bill — or give a customer or supplier a default currency — and the exchange rate for that date is looked up automatically and stored on the document. The document keeps its amounts in its own currency, while the General Ledger always posts in your base currency. When you later collect or pay at a different rate, the realized exchange gain or loss is booked automatically to an Exchange Gain/Loss account. You can even hold a foreign-currency bank balance and convert it later at your bank’s rate — the difference versus its carried value is realized then. At month end you can revalue open foreign balances to the closing rate (an unrealized gain/loss that reverses next period), and you can view any financial statement translated into another currency for display.","tip":"This is easiest through the AI chat — try “Create a sales invoice for Lumiere Audio in EUR,” “Show me the balance sheet in EUR,” or “What’s our unrealized FX exposure at month end?” The seeded demo already includes a EUR customer (Lumiere Audio SARL) whose invoice was collected at a different rate, plus an open EUR supplier bill — open the General Ledger to see the realized FX postings."}},"caTitle":"Dynamic Analytics — Chat Your Way to Any Chart","caBadge":"Signature Feature","caBody":"Need a report the presets can’t give you? Just describe it in chat. The assistant calls a code-specialist model that writes the report for you, runs it live over your ERP data, and returns a sharable link. The chart or table renders in seconds and is saved as a draft under Custom Analytics in the sidebar — you can reopen it, share the URL with teammates, or ask the assistant to refine it.","caTryAsking":"Try asking (click to prefill in chat):","caPrompt1":"Show me top 10 customers by revenue this year as a bar chart","caPrompt2":"Monthly purchases trend by supplier over all months and label x-axis with supplier name","caPrompt3":"Best selling items by quantity, with a table and a chart","caPrompt4":"Which customers owe me the most right now?","caTryInChat":"Try it in chat","caOpenWorkspace":"Open Analytics workspace","flowTitle":"Document Flow Overview","salesCycle":"Sales Cycle","flowShortcut":"Shortcut: Quotation can skip Sales Order and go directly to Sales Invoice or Delivery Note","purchaseCycle":"Purchase Cycle","returns":"Returns","legendStock":"stock impact","legendGl":"GL impact","legendCash":"cash impact","legendReversal":"reversal","lifecycleTitle":"Document Lifecycle","lcDraftLabel":"Draft:","lcDraftDesc":"Editable. No financial or stock impact.","lcSubmittedLabel":"Submitted:","lcSubmittedDesc":"Locked. GL entries and stock ledger entries are posted.","lcCancelledLabel":"Cancelled:","lcCancelledDesc":"All entries reversed. Document is permanently archived.","lcNoDelete":"There is no delete. To void a draft: submit it, then cancel it.","lcCorrect":"To correct a submitted document: cancel it and create a new one.","pageTitle":"Getting Started with Lambda ERP","intro":"Lambda ERP is an AI Native ERP System, with all functionality — like creating orders, checking inventory, recording payments — being accessible through a chat interface. It instructs, reasons and checks all your daily business tasks.","openChat":"Open AI Chat","tipLabel":"Tip:","topTip":"The AI chat can also give you direct links to documents and downloadable PDFs. Just ask it to create or look up a document and it will include clickable links in its response.","manualIntro":"If you want to fully understand how things work under the hood, or prefer to do things manually, here’s a full business cycle step by step.","readyTitle":"You're Ready","readyBody1":"You now understand the full cycle. A typical real-world scenario looks like this: you receive a customer order (Quotation → Sales Order), check stock, buy what you need (Purchase Order → Purchase Receipt → Purchase Invoice → Payment), deliver to the customer (Delivery Note), bill them (Sales Invoice), and collect payment (Payment Entry). If something comes back, create a Credit Note and Delivery Note return to reverse the financials and stock. The Trial Balance confirms everything is balanced.","readyBody2":"You can also use the AI chat to do all of this through natural conversation — just describe what you need and it will create the right documents for you."}`), Zs = { title: "Formatting help", intro: "The Notes / Terms text supports light formatting on the PDF:", heading: "bold heading", emphasis: "italic / bold", rule: "horizontal divider line", price: "right-aligned price beside the text above (e.g. Monthly | CHF 380.—)", block: "Separate blocks with a blank line." }, Xs = {
|
|
6636
6659
|
common: Bs,
|
|
6637
6660
|
language: Es,
|
|
6638
6661
|
header: Os,
|
|
@@ -6652,7 +6675,7 @@ const Bs = { save: "Save", saving: "Saving...", submit: "Submit", cancel: "Cance
|
|
|
6652
6675
|
tables: Js,
|
|
6653
6676
|
tutorial: Ys,
|
|
6654
6677
|
notesMarkup: Zs
|
|
6655
|
-
}, ei = { save: "Speichern", saving: "Speichern...", submit: "Buchen", cancel: "Abbrechen", cancelDoc: "Stornieren", cancelDocAbort: "Nicht stornieren", cancelDocConfirmBtn: "Definitiv stornieren", discardDraft: "Entwurf verwerfen", keepDraft: "Behalten", discardDraftConfirm: "Verwerfen", showDiscarded: "Verworfene anzeigen", delete: "Löschen", edit: "Bearbeiten", pdf: "PDF", addRow: "Zeile hinzufügen", loading: "Lädt...", enable: "Aktivieren", disable: "Deaktivieren", refresh: "Aktualisieren", refreshing: "Aktualisiert...", areYouSure: "Sind Sie sicher?", all: "Alle", apply: "Anwenden", new: "Neu", prev: "Zurück", next: "Weiter", perPage: "Pro Seite", page: "Seite", of: "von", showing: "Zeige", total: "Gesamt", totals: "Summen", errorOccurred: "Ein Fehler ist aufgetreten" }, ti = { title: "Sprache", help: "Wählen Sie die Sprache der Oberfläche. Ihre Auswahl wird in diesem Browser gespeichert.", label: "Sprache" }, ni = { logout: "Abmelden", openMenu: "Menü öffnen", closeMenu: "Menü schließen", new: "Neu: {{label}}" }, ai = { dashboard: "Dashboard", setup: "Unternehmenseinrichtung", tutorial: "Erste Schritte", chat: "Chat", reports: "Berichte", "trial-balance": "Rohbilanz", "general-ledger": "Hauptbuch", "stock-balance": "Lagerbestand", "profit-and-loss": "Gewinn- und Verlustrechnung", "balance-sheet": "Bilanz", "ar-aging": "Offene Posten Debitoren", "ap-aging": "Offene Posten Kreditoren", analytics: "Analysen" }, ri = { quotation: { one: "Angebot", other: "Angebote" }, proposal: { one: "Sammelofferte", other: "Sammelofferten" }, "sales-order": { one: "Kundenauftrag", other: "Kundenaufträge" }, "sales-invoice": { one: "Ausgangsrechnung", other: "Ausgangsrechnungen" }, "pos-invoice": { one: "Kassenbeleg", other: "Kassenbelege" }, "purchase-order": { one: "Bestellung", other: "Bestellungen" }, "purchase-invoice": { one: "Eingangsrechnung", other: "Eingangsrechnungen" }, "payment-entry": { one: "Zahlung", other: "Zahlungen" }, "journal-entry": { one: "Buchungssatz", other: "Buchungssätze" }, "bank-transaction": { one: "Banktransaktion", other: "Banktransaktionen" }, budget: { one: "Budget", other: "Budgets" }, subscription: { one: "Abonnement", other: "Abonnements" }, "stock-entry": { one: "Lagerbuchung", other: "Lagerbuchungen" }, "delivery-note": { one: "Lieferschein", other: "Lieferscheine" }, "purchase-receipt": { one: "Wareneingang", other: "Wareneingänge" }, "pricing-rule": { one: "Preisregel", other: "Preisregeln" } }, si = { company: { one: "Unternehmen", other: "Unternehmen" }, customer: { one: "Kunde", other: "Kunden" }, supplier: { one: "Lieferant", other: "Lieferanten" }, item: { one: "Artikel", other: "Artikel" }, warehouse: { one: "Lager", other: "Lager" } }, ii = { chats: "Chats", newChat: "Neuer Chat", deleteChat: "Chat löschen", customAnalytics: "Eigene Analysen", newAnalytics: "Neue Analyse", deleteReport: "Bericht löschen", groups: { Introduction: "Einführung", Selling: "Verkauf", Buying: "Einkauf", Accounting: "Buchhaltung", Stock: "Lager", Reports: "Berichte", Masters: "Stammdaten", Settings: "Einstellungen" }, items: { "Getting Started": "Erste Schritte", "Company Setup": "Unternehmenseinrichtung", "Opening Balances": "Eröffnungsbilanzen", Quotation: "Angebot", Proposal: "Sammelofferte", "Sales Order": "Kundenauftrag", "Sales Invoice": "Ausgangsrechnung", "POS Invoice": "Kassenbeleg", "Purchase Order": "Bestellung", "Purchase Invoice": "Eingangsrechnung", "Payment Entry": "Zahlung", "Journal Entry": "Buchungssatz", "Bank Transaction": "Banktransaktion", Budget: "Budget", Subscription: "Abonnement", "Stock Entry": "Lagerbuchung", "Delivery Note": "Lieferschein", "Purchase Receipt": "Wareneingang", "Trial Balance": "Rohbilanz", "Profit & Loss": "Gewinn- und Verlustrechnung", "Balance Sheet": "Bilanz", "General Ledger": "Hauptbuch", "AR Aging": "Offene Posten Debitoren", "AP Aging": "Offene Posten Kreditoren", Analytics: "Analysen", "Stock Balance": "Lagerbestand", Company: "Unternehmen", Customer: "Kunde", Supplier: "Lieferant", Item: "Artikel", Warehouse: "Lager", General: "Allgemein", "Pricing Rule": "Preisregel", "Users & Team": "Benutzer & Team" } }, oi = { taglineFirstRun: "Erstellen Sie Ihr Administratorkonto, um zu beginnen", taglineRegister: "Erstellen Sie Ihr Konto", taglineSignIn: "Melden Sie sich bei Ihrem Konto an", demoBanner: "Der Demomodus ist aktiv. Melden Sie sich mit einem Administratorkonto an, um Einstellungen zu verwalten oder den öffentlichen Zugriff zu deaktivieren.", fullName: "Vollständiger Name", email: "E-Mail", password: "Passwort", confirmPassword: "Passwort bestätigen", createAdmin: "Administratorkonto erstellen", register: "Registrieren", signIn: "Anmelden", browsingTitle: "Nur am Stöbern?", browsingBody: "Starten Sie eine neue Chat-Sitzung und sehen Sie sich die Live-Demo an.", enterDemo: "Live-Demo starten", haveInvite: "Haben Sie eine Einladung?", noAccountPrompt: "Noch kein Konto?", registerLink: "Registrieren", alreadyHaveAccount: "Haben Sie bereits ein Konto?", signInLink: "Anmelden", passwordsNoMatch: "Passwörter stimmen nicht überein", passwordTooShort: "Das Passwort muss mindestens 6 Zeichen lang sein", registrationFailed: "Registrierung fehlgeschlagen", loginFailed: "Anmeldung fehlgeschlagen" }, li = { pdfTitle: "PDF & Druck", pageSize: "Seitengröße", pdfHelp: "A4 ist international Standard (210 x 297 mm). Letter ist Standard in den USA (8,5 x 11 Zoll).", passwordTitle: "Passwort ändern", currentPassword: "Aktuelles Passwort", newPassword: "Neues Passwort", confirmNewPassword: "Neues Passwort bestätigen", changePassword: "Passwort ändern", changingPassword: "Wird geändert...", passwordChanged: "Passwort geändert.", openingTitle: "Eröffnungsbilanzen", openingBody: "Auf der Seite Eröffnungsbilanzen können Kontensalden, Lagerbestände und offene Rechnungen aus einem früheren System importiert werden.", openingEnabled: "Derzeit aktiviert — erreichbar unter Einführung > Eröffnungsbilanzen.", openingDisabled: "Derzeit deaktiviert — die Seite ist in der Seitenleiste ausgeblendet.", signupTitle: "Öffentliche Registrierung", signupBody: "Erlauben Sie es jedem, ohne Einladung ein eigenes Konto (als Betrachter) zu erstellen. Wenn deaktiviert, können neue Benutzer nur über einen Einladungslink beitreten.", signupEnabled: "Derzeit aktiviert — jeder mit der URL kann sich als Betrachter registrieren.", signupDisabled: "Derzeit deaktiviert — die Registrierung erfolgt nur per Einladung.", publicTitle: "Öffentlicher Zugriff (Demomodus)", publicActive: "Aktiv", publicActiveBody: "Der öffentliche Zugriff ist aktiviert. Jeder kann die Anwendung ohne Anmeldung nutzen. Alle Besucher erhalten Manager-Rechte.", disablePublic: "Öffentlichen Zugriff deaktivieren", disabling: "Wird deaktiviert...", publicInactiveBody: "Aktivieren Sie den öffentlichen Zugriff, damit jeder die Anwendung ohne Konto nutzen kann. Nützlich für Demos und Präsentationen. Alle Besucher erhalten Manager-Rechte und teilen sich dieselbe Identität.", enablePublic: "Öffentlichen Zugriff aktivieren", enableWarning: "Dadurch kann jeder ohne Anmeldung auf die Anwendung zugreifen. Besucher können Dokumente erstellen, bearbeiten und buchen. Ihr Administratorkonto erfordert weiterhin eine Anmeldung.", yesEnable: "Ja, aktivieren", enabling: "Wird aktiviert...", tokenSpendTitle: "Token-Ausgaben" }, ci = { Draft: "Entwurf", Open: "Offen", Submitted: "Gebucht", "To Deliver and Bill": "Zu liefern und abzurechnen", "To Deliver": "Zu liefern", "To Bill": "Abzurechnen", Completed: "Abgeschlossen", Ordered: "Bestellt", Paid: "Bezahlt", Unpaid: "Unbezahlt", Cancelled: "Storniert", Discarded: "Verworfen", Overdue: "Überfällig", Return: "Retoure", Closed: "Geschlossen" }, di = { balanced: "AUSGEGLICHEN", imbalanced: "NICHT AUSGEGLICHEN", income: "Erträge", expenses: "Aufwendungen", totalIncome: "Summe Erträge", totalExpenses: "Summe Aufwendungen", netProfit: "Gewinn", netLoss: "Verlust", assets: "Aktiva", liabilities: "Verbindlichkeiten", equity: "Eigenkapital", totalAssets: "Summe Aktiva", totalLiabilities: "Summe Verbindlichkeiten", totalEquity: "Summe Eigenkapital", totalLiabilitiesEquity: "Summe Verbindlichkeiten + Eigenkapital", current: "Laufend", noData: "Keine Daten gefunden", noEntries: "Keine Buchungen gefunden", noStockData: "Keine Lagerdaten gefunden", noReceivables: "Keine offenen Forderungen", noPayables: "Keine offenen Verbindlichkeiten", noDocuments: "Keine Dokumente gefunden" }, ui = { required: "Erforderlich: {{fields}}", deleteConfirm: "Diesen Datensatz löschen: {{label}}?", disabledNotice: "Dieser Datensatz ({{label}}) ist deaktiviert. Er verbleibt im System, weil andere Datensätze noch darauf verweisen.", disabledOnDelete: "{{label}} {{name}} wurde deaktiviert statt gelöscht, da er von {{reason}} referenziert wird." }, mi = { Account: "Konto", Amount: "Betrag", Balance: "Saldo", Credit: "Haben", Debit: "Soll", Date: "Datum", Party: "Partner", "Party Type": "Partnertyp", "Voucher Type": "Belegart", "Voucher No": "Belegnr.", Invoice: "Rechnung", Customer: "Kunde", Supplier: "Lieferant", "Due Date": "Fälligkeitsdatum", Outstanding: "Offen", "Outstanding Amount": "Offener Betrag", "Item Code": "Artikelnr.", "Item Name": "Artikelname", Item: "Artikel", Warehouse: "Lager", Qty: "Menge", "Valuation Rate": "Bewertungspreis", "Stock Value": "Lagerwert", Name: "Name", Status: "Status", Company: "Unternehmen", "From Date": "Von Datum", "To Date": "Bis Datum", "As of Date": "Stichtag", "Valid Till": "Gültig bis", "Net Total": "Nettobetrag", Tax: "Steuer", "Grand Total": "Gesamtbetrag", Frequency: "Frequenz", "Notes / Terms": "Notizen / Bedingungen", "Posting Date": "Buchungsdatum", "Transaction Date": "Belegdatum", "Delivery Date": "Lieferdatum", "% Delivered": "% geliefert", "% Billed": "% abgerechnet", "Update Stock": "Lager aktualisieren", "Payment Type": "Zahlungsart", "Paid From": "Bezahlt von", "Paid To": "Bezahlt an", "Paid Amount": "Zahlbetrag", Type: "Art", Total: "Gesamt", Allocated: "Zugeordnet", Unallocated: "Nicht zugeordnet", Remark: "Bemerkung", "Total Debit": "Summe Soll", "Total Credit": "Summe Haben", "Cost Center": "Kostenstelle", "Source Warehouse": "Quelllager", "Target Warehouse": "Ziellager", Source: "Quelle", Target: "Ziel", "Incoming Value": "Eingangswert", "Outgoing Value": "Ausgangswert", Rate: "Preis", "Income Account": "Ertragskonto", "Expense Account": "Aufwandskonto", Description: "Beschreibung", "Rate (%)": "Satz (%)", Mode: "Art", Change: "Rückgeld", Currency: "Währung", Title: "Titel", Selling: "Verkauf", Buying: "Einkauf", "Discount %": "Rabatt %", "Discount Amt": "Rabattbetrag", "Min Qty": "Mindestmenge", "Valid From": "Gültig ab", "Valid Upto": "Gültig bis", Priority: "Priorität", Enabled: "Aktiviert", "Fiscal Year": "Geschäftsjahr", "Budget Amount": "Budgetbetrag", "If Exceeded": "Bei Überschreitung", Month: "Monat", "Bank Account": "Bankkonto", Deposit: "Einzahlung", Withdrawal: "Auszahlung", "Reference No": "Referenznr.", "Matched Type": "Zugeordnete Art", "Matched Doc": "Zugeordneter Beleg", "Start Date": "Startdatum", "End Date": "Enddatum", "Billing Interval": "Abrechnungsintervall", "Current Period Start": "Aktueller Periodenbeginn", "Current Period End": "Aktuelles Periodenende", "Plan Items": "Planpositionen", "Total Amount": "Gesamtbetrag", "Stock Entry Type": "Lagerbuchungsart", "Rate Or Discount": "Preis oder Rabatt", "Discount Percentage": "Rabattprozentsatz", ID: "ID", "Customer Name": "Kundenname", "Customer Group": "Kundengruppe", Territory: "Region", "Credit Limit": "Kreditlimit", Email: "E-Mail", Phone: "Telefon", Address: "Adresse", City: "Stadt", "Zip Code": "PLZ", Country: "Land", "Tax ID": "Steuernummer", "Contact Person": "Ansprechperson", "Contact Email": "E-Mail Ansprechperson", "Contact Phone": "Telefon Ansprechperson", "Supplier Name": "Lieferantenname", "Supplier Group": "Lieferantengruppe", "Item Group": "Artikelgruppe", "Stock UOM": "Lagereinheit", "Standard Rate": "Standardpreis", "Warehouse Name": "Lagername", "Company Name": "Firmenname" }, pi = { items: "Positionen", taxes: "Steuern", references: "Zahlungsreferenzen", accounts: "Kontobuchungen", payments: "Zahlungen", plans: "Planpositionen", monthly_distribution: "Monatliche Verteilung" }, hi = { "Create Sales Order": "Kundenauftrag erstellen", "Create Sales Invoice": "Ausgangsrechnung erstellen", "Create Delivery Note": "Lieferschein erstellen", "Create Purchase Invoice": "Eingangsrechnung erstellen", "Create Purchase Receipt": "Wareneingang erstellen", "Create Credit Note": "Gutschrift erstellen", "Create Debit Note": "Lastschrift erstellen", "Create Return": "Retoure erstellen" }, gi = { totalRevenue: "Gesamtumsatz", outstandingReceivable: "Offene Forderungen", outstandingPayable: "Offene Verbindlichkeiten", totalStockValue: "Gesamter Lagerwert", recentDocuments: "Letzte Dokumente", noRecentDocuments: "Keine aktuellen Dokumente" }, yi = { title: "Lambda ERP Chat", subtitle: "Bitten Sie mich, Dokumente zu erstellen, Daten abzurufen oder Berichte auszuführen.", s1: "Welche Kunden haben wir?", s2: "Zeig mir die Rohbilanz", s3: "Erstelle ein Angebot für 10 Bolt Pack M8", s4: "Liste alle unbezahlten Rechnungen auf", loadOlder: "Ältere Nachrichten laden", uploading: "Wird hochgeladen...", failed: "Fehlgeschlagen", remove: "Entfernen", placeholderDemo: "Live-Demo läuft...", placeholderType: "Nachricht eingeben...", placeholderConnecting: "Verbindung wird hergestellt...", attachTitle: "Datei anhängen (PDF oder Bild, max. 10 MB)", creating: "Chat wird erstellt...", dropToAttach: "Datei zum Anhängen ablegen (Bilder oder PDF, je max. 10 MB)", demoError: "Demo konnte nicht gestartet werden", voiceStart: "Sprachnachricht aufnehmen", voiceStop: "Aufnahme stoppen", voiceTranscribing: "Wird transkribiert...", micDenied: "Zugriff auf das Mikrofon wurde verweigert.", transcribeFailed: "Transkription fehlgeschlagen. Bitte erneut versuchen." }, fi = /* @__PURE__ */ JSON.parse('{"pageTitle":"Erste Schritte mit Lambda ERP","intro":"Lambda ERP ist ein KI-natives ERP-System, bei dem die gesamte Funktionalität – etwa das Erstellen von Aufträgen, das Prüfen von Beständen und das Erfassen von Zahlungen – über eine Chat-Oberfläche zugänglich ist. Es leitet an, denkt mit und prüft alle Ihre täglichen Geschäftsaufgaben.","openChat":"KI-Chat öffnen","tipLabel":"Tipp:","topTip":"Der KI-Chat kann Ihnen auch direkte Links zu Dokumenten und herunterladbaren PDFs geben. Bitten Sie ihn einfach, ein Dokument zu erstellen oder nachzuschlagen, und er fügt anklickbare Links in seine Antwort ein.","manualIntro":"Wenn Sie genau verstehen möchten, wie die Dinge unter der Haube funktionieren, oder Dinge lieber manuell erledigen, finden Sie hier einen vollständigen Geschäftszyklus Schritt für Schritt.","caTitle":"Dynamische Analysen – Chatten Sie sich zu jedem Diagramm","caBadge":"Kernfunktion","caBody":"Brauchen Sie einen Bericht, den die Vorlagen nicht liefern? Beschreiben Sie ihn einfach im Chat. Der Assistent ruft ein Code-Spezialmodell auf, das den Bericht für Sie schreibt, ihn live über Ihre ERP-Daten ausführt und einen teilbaren Link zurückgibt. Das Diagramm oder die Tabelle wird in Sekunden gerendert und als Entwurf unter „Eigene Analysen“ in der Seitenleiste gespeichert – Sie können ihn erneut öffnen, die URL mit Kollegen teilen oder den Assistenten bitten, ihn zu verfeinern.","caTryAsking":"Versuchen Sie zu fragen (zum Vorausfüllen im Chat klicken):","caPrompt1":"Zeig mir die Top 10 Kunden nach Umsatz dieses Jahr als Balkendiagramm","caPrompt2":"Monatlicher Einkaufstrend nach Lieferant über alle Monate, x-Achse mit Lieferantennamen beschriften","caPrompt3":"Bestseller-Artikel nach Menge, mit Tabelle und Diagramm","caPrompt4":"Welche Kunden schulden mir gerade am meisten?","caTryInChat":"Im Chat ausprobieren","caOpenWorkspace":"Analyse-Arbeitsbereich öffnen","flowTitle":"Überblick Dokumentenfluss","salesCycle":"Verkaufszyklus","purchaseCycle":"Einkaufszyklus","returns":"Retouren","flowShortcut":"Abkürzung: Das Angebot kann den Kundenauftrag überspringen und direkt zur Ausgangsrechnung oder zum Lieferschein führen","legendStock":"Lagerwirkung","legendGl":"Buchungswirkung","legendCash":"Geldwirkung","legendReversal":"Stornierung","lifecycleTitle":"Dokumenten-Lebenszyklus","lcDraftLabel":"Entwurf:","lcDraftDesc":"Bearbeitbar. Keine finanzielle oder Bestandswirkung.","lcSubmittedLabel":"Gebucht:","lcSubmittedDesc":"Gesperrt. Buchungen und Lagerbuchungen werden erzeugt.","lcCancelledLabel":"Storniert:","lcCancelledDesc":"Alle Buchungen storniert. Das Dokument wird dauerhaft archiviert.","lcNoDelete":"Es gibt kein Löschen. Um einen Entwurf zu verwerfen: buchen und dann stornieren.","lcCorrect":"Um ein gebuchtes Dokument zu korrigieren: stornieren und ein neues erstellen.","readyTitle":"Sie sind startklar","readyBody1":"Sie verstehen jetzt den vollständigen Zyklus. Ein typisches Praxisszenario sieht so aus: Sie erhalten einen Kundenauftrag (Angebot → Kundenauftrag), prüfen den Bestand, kaufen, was Sie brauchen (Bestellung → Wareneingang → Eingangsrechnung → Zahlung), liefern an den Kunden (Lieferschein), stellen ihm die Rechnung (Ausgangsrechnung) und ziehen die Zahlung ein (Zahlung). Kommt etwas zurück, erstellen Sie eine Gutschrift und eine Lieferschein-Retoure, um Finanzen und Bestand umzukehren. Die Rohbilanz bestätigt, dass alles ausgeglichen ist.","readyBody2":"Sie können all dies auch über den KI-Chat per natürlicher Konversation erledigen – beschreiben Sie einfach, was Sie brauchen, und er erstellt die richtigen Dokumente für Sie.","chips":{"Quotation":"Angebot","Sales Order":"Kundenauftrag","Delivery Note":"Lieferschein","Sales Invoice":"Ausgangsrechnung","Payment Entry":"Zahlung","Purchase Order":"Bestellung","Purchase Receipt":"Wareneingang","Purchase Invoice":"Eingangsrechnung","Credit Note":"Gutschrift","DN Return":"Lieferschein-Retoure","Debit Note":"Lastschrift","Draft":"Entwurf","Submitted":"Gebucht","Cancelled":"Storniert"},"links":{"Go to Setup":"Zur Einrichtung","Customers":"Kunden","Suppliers":"Lieferanten","Items":"Artikel","Warehouses":"Lager","New Quotation":"Neues Angebot","View Quotations":"Angebote anzeigen","Stock Balance":"Lagerbestand","New Purchase Order":"Neue Bestellung","Purchase Receipts":"Wareneingänge","Purchase Invoices":"Eingangsrechnungen","Delivery Notes":"Lieferscheine","Sales Invoices":"Ausgangsrechnungen","New Payment Entry":"Neue Zahlung","New Stock Entry":"Neue Lagerbuchung","New Journal Entry":"Neuer Buchungssatz","Profit & Loss":"Gewinn- und Verlustrechnung","Balance Sheet":"Bilanz","AR Aging":"Offene Posten Debitoren","AP Aging":"Offene Posten Kreditoren","Trial Balance":"Rohbilanz","General Ledger":"Hauptbuch","Open AI Chat":"KI-Chat öffnen"},"steps":{"1":{"title":"Unternehmen einrichten","description":"Erstellen Sie ein Unternehmen mit einer Basiswährung. Dadurch wird Ihr Kontenplan generiert (30 Standardkonten in den Bereichen Aktiva, Verbindlichkeiten, Eigenkapital, Erträge und Aufwendungen) sowie eine Standard-Kostenstelle. Sie können außerdem Demodaten mit Beispielkunden, -lieferanten und -artikeln anlegen, um schnell loszulegen."},"2":{"title":"Stammdaten anlegen","description":"Bevor Sie buchen können, benötigen Sie Stammdaten. Legen Sie mindestens einen Kunden, einen Lieferanten, einen Artikel (mit Standardpreis) und ein Lager an. Wenn Sie in Schritt 1 Demodaten angelegt haben, existieren diese bereits.","tip":"Artikel haben einen Standardpreis, der beim Hinzufügen zu Dokumenten automatisch ausgefüllt wird. Sie können den Preis pro Transaktion jederzeit überschreiben."},"3":{"title":"Angebot erstellen","description":"Ein Angebot ist eine unverbindliche Offerte an einen Kunden. Wählen Sie einen Kunden, fügen Sie Positionen mit Mengen und Preisen hinzu, optional Steuerzeilen, und speichern Sie. Angebote haben keine finanzielle Auswirkung – sie erzeugen keine Buchungs- oder Lagerbewegungen. Legen Sie ein Gültigkeitsdatum fest, damit das Angebot automatisch abläuft."},"4":{"title":"Buchen und in Kundenauftrag umwandeln","description":"Öffnen Sie Ihr gespeichertes Angebot und klicken Sie auf Buchen, um es zu bestätigen. Klicken Sie dann auf „Kundenauftrag erstellen“, um es umzuwandeln. Der Kundenauftrag stellt eine bestätigte Zusage des Kunden dar. Er hat weiterhin keine finanzielle Auswirkung, reserviert aber Bestand für die Planung.","tip":"Nur gebuchte Dokumente können in den nächsten Schritt umgewandelt werden. Entwurf → Buchen → Umwandeln ist der Standardablauf. Für schnelle Geschäfte können Sie den Kundenauftrag überspringen und direkt vom Angebot zur Ausgangsrechnung oder zum Lieferschein gehen."},"5":{"title":"Bestand vor der Erfüllung prüfen","description":"Bevor Sie liefern können, prüfen Sie, ob der Artikel tatsächlich auf Lager ist. Öffnen Sie den Bericht Lagerbestand und suchen Sie den Artikel. Wenn Ihr Lager eine Menge von null aufweist, müssen Sie zunächst Bestand beschaffen – entweder über eine Bestellung (Einkauf bei einem Lieferanten) oder eine Lagerbuchung (manueller Eingang).","tip":"Dies ist ein häufiges Szenario aus der Praxis: Sie verkaufen etwas und stellen dann fest, dass Sie es erst einkaufen müssen. Das ERP unterstützt beide Abläufe."},"6":{"title":"Einkaufszyklus: Bestand bei einem Lieferanten kaufen","description":"Wenn Sie Bestand einkaufen müssen, haben Sie zwei gültige Wege. Der Standardweg ist Bestellung → Wareneingang → Eingangsrechnung: Nutzen Sie ihn, wenn die Ware vor oder getrennt von der Lieferantenrechnung eintrifft. Treffen Rechnung und Wareneingang gleichzeitig ein, können Sie die Eingangsrechnung direkt erstellen und „Lager aktualisieren“ aktivieren, sodass dasselbe Dokument sowohl den Bestand vereinnahmt als auch die Verbindlichkeit erfasst.","tip":"Verwenden Sie zuerst den Wareneingang, wenn Sie Waren getrennt erhalten. Verwenden Sie die Eingangsrechnung mit „Lager aktualisieren“, wenn ein Schritt sowohl den Bestand vereinnahmen als auch die Lieferantenrechnung buchen soll. Setzen Sie in diesem direkten Weg ein Lager in jeder Bestandszeile."},"7":{"title":"Lieferschein erstellen","description":"Nachdem Sie nun Bestand haben, kehren Sie zu Ihrem gebuchten Kundenauftrag zurück und klicken Sie auf „Lieferschein erstellen“. Setzen Sie in jeder Position das Lager (von dem die Ware versendet wird) und buchen Sie. Dadurch wird Bestand aus dem Lager ausgebucht – Ihr Lagerbestand sinkt.","tip":"Der Lieferschein ist das Versanddokument. Er reduziert den Bestand, erzeugt aber keine Rechnung. Sie können Lieferung und Rechnungsstellung getrennt vornehmen."},"8":{"title":"Ausgangsrechnung erstellen und buchen","description":"Erstellen Sie aus dem gebuchten Kundenauftrag eine Ausgangsrechnung. Beim Buchen der Rechnung werden Buchungen erzeugt: Forderungen aus Lieferungen und Leistungen werden im Soll gebucht (der Kunde schuldet Ihnen Geld) und Umsatzerlöse im Haben (erzielter Ertrag). Sind Steuern konfiguriert, wird auch die Steuerverbindlichkeit im Haben gebucht. Der offene Betrag zeigt, was der Kunde noch schuldet."},"9":{"title":"Kundenzahlungen erfassen","description":"Erstellen Sie eine Zahlung, um vom Kunden erhaltenes Geld zu erfassen. Setzen Sie die Zahlungsart auf „Receive“ (Erhalten), wählen Sie den Kunden, geben Sie den Betrag an und ordnen Sie ihn der Ausgangsrechnung zu. Sie können Teilzahlungen vornehmen – der offene Betrag der Rechnung aktualisiert sich entsprechend. Erstellen Sie weitere Zahlungen, bis die Rechnung vollständig beglichen ist.","tip":"Teilzahlungen sind üblich. Eine Rechnung über 10.000 kann jetzt mit 3.000 und später mit 7.000 bezahlt werden. Jede Zahlung reduziert den offenen Betrag."},"10":{"title":"Lagerbuchungen (manuelle Bestandsführung)","description":"Verwenden Sie Lagerbuchungen für Bestandsbewegungen, die nicht mit Ein- oder Verkäufen verbunden sind. „Material Receipt“ fügt Bestand hinzu (Eröffnungsbestände, Korrekturen). „Material Issue“ bucht Bestand aus (Abschreibungen, interner Verbrauch). „Material Transfer“ verschiebt Bestand zwischen Lägern. Jede Buchung aktualisiert das Lagerbuch mit gleitender Durchschnittsbewertung.","tip":"Verwenden Sie für eingekaufte Waren Wareneingänge statt Lagerbuchungen – sie sind mit der Bestellung verknüpft und bieten einen sauberen Prüfpfad."},"11":{"title":"Buchungssätze","description":"Buchungssätze sind manuelle buchhalterische Anpassungen – Aufwandsabgrenzungen, Korrekturen, Umgliederungen, Eröffnungsbestände. Jeder Satz muss ausgeglichene Soll- und Haben-Beträge haben (Summe Soll = Summe Haben). Verwenden Sie sie, wenn kein anderer Dokumenttyp passt."},"12":{"title":"Gehaltszahlungen","description":"Lambda ERP wickelt Gehälter über die vorhandenen Buchhaltungswerkzeuge ab. Grenzen Sie zunächst den Gehaltsaufwand ab: Erstellen Sie einen Buchungssatz, der Gehaltsaufwand im Soll und Gehaltsverbindlichkeiten im Haben für den gesamten Lohnbetrag bucht. Bezahlen Sie dann die Mitarbeiter: Erstellen Sie einen weiteren Buchungssatz (oder eine Zahlung), der Gehaltsverbindlichkeiten im Soll und Ihr Bankkonto im Haben bucht. Dieser zweistufige Prozess hält Ihre Bücher korrekt – der Aufwand wird in der richtigen Periode erfasst und der Geldabfluss separat nachverfolgt.","tip":"Sie können den KI-Assistenten bitten, dies für Sie zu erledigen: „Grenze 15.000 an Gehältern für April ab“ gefolgt von „Zahle die April-Gehälter von der Bank“. Er erstellt die richtigen Buchungssätze automatisch."},"13":{"title":"Retouren und Gutschriften","description":"Wenn ein Kunde Waren zurückgibt oder Sie eine Gutschrift ausstellen müssen, erstellen Sie eine Retoure. Retouren verwenden denselben Dokumenttyp mit negativen Mengen. Öffnen Sie eine gebuchte Ausgangsrechnung und erstellen Sie eine Gutschrift (Ausgangsrechnungs-Retoure) – dies kehrt die Buchungen um und reduziert den offenen Betrag der ursprünglichen Rechnung. Erstellen Sie für den Bestand eine Lieferschein-Retoure, um Waren zurück ins Lager zu nehmen. Auf der Einkaufsseite erstellen Sie eine Lastschrift (Eingangsrechnungs-Retoure), um eine Lieferantenrechnung umzukehren, oder eine Wareneingangs-Retoure, um Waren zurückzusenden.","tip":"Eine Gutschrift ist einfach eine Ausgangsrechnung mit is_return=1 und negativen Mengen. Dieselbe Buchungslogik läuft – negative Beträge wechseln automatisch auf die richtige Soll-/Haben-Seite. Für eine vollständige Verkaufsretoure benötigen Sie sowohl eine Gutschrift (Finanzen) als auch eine Lieferschein-Retoure (Bestand)."},"14":{"title":"Berichte ausführen","description":"Prüfen Sie Ihre Bücher. Die Gewinn- und Verlustrechnung zeigt Erträge gegenüber Aufwendungen und den Periodengewinn. Die Bilanz zeigt Ihre finanzielle Lage (Aktiva = Verbindlichkeiten + Eigenkapital). Die Offenen Posten Debitoren zeigen, wer Ihnen Geld schuldet und wie überfällig es ist. Die Offenen Posten Kreditoren zeigen, was Sie Lieferanten schulden. Die Rohbilanz überprüft die doppelte Buchführung. Das Hauptbuch zeigt jede einzelne Buchung. Der Lagerbestand zeigt den aktuellen Bestand."},"15":{"title":"Arbeiten in Fremdwährungen","description":"Ihre Bücher werden in einer einzigen Basiswährung geführt (bei der Unternehmenseinrichtung gewählt), aber Sie können in jeder Währung buchen. Setzen Sie eine Währung auf einer Rechnung oder einem Beleg – oder geben Sie einem Kunden oder Lieferanten eine Standardwährung – und der Wechselkurs für dieses Datum wird automatisch ermittelt und auf dem Dokument gespeichert. Das Dokument behält seine Beträge in seiner eigenen Währung, während das Hauptbuch stets in Ihrer Basiswährung bucht. Wenn Sie später zu einem anderen Kurs einnehmen oder zahlen, wird der realisierte Währungsgewinn oder -verlust automatisch auf ein Konto Währungsgewinn/-verlust gebucht. Sie können sogar ein Fremdwährungs-Bankguthaben halten und es später zum Kurs Ihrer Bank umrechnen – die Differenz zum Buchwert wird dann realisiert. Zum Monatsende können Sie offene Fremdwährungssalden zum Stichtagskurs neu bewerten (ein unrealisierter Gewinn/Verlust, der in der nächsten Periode storniert wird), und Sie können jeden Jahresabschluss zur Anzeige in eine andere Währung umgerechnet betrachten.","tip":"Am einfachsten geht das über den KI-Chat – probieren Sie „Erstelle eine Ausgangsrechnung für Lumiere Audio in EUR“, „Zeig mir die Bilanz in EUR“ oder „Wie hoch ist unser unrealisiertes Währungsrisiko zum Monatsende?“. Die Demodaten enthalten bereits einen EUR-Kunden (Lumiere Audio SARL), dessen Rechnung zu einem anderen Kurs eingenommen wurde, sowie eine offene EUR-Lieferantenrechnung – öffnen Sie das Hauptbuch, um die realisierten Währungsbuchungen zu sehen."}}}'), bi = { title: "Formatierungshilfe", intro: "Der Text unter Notizen / Konditionen unterstützt eine einfache Formatierung im PDF:", heading: "fette Überschrift", emphasis: "kursiv / fett", price: "rechtsbündiger Preis neben dem Text darüber (z. B. Monatlich | CHF 380.—)", block: "Trennen Sie Blöcke durch eine Leerzeile." }, xi = {
|
|
6678
|
+
}, ei = { save: "Speichern", saving: "Speichern...", submit: "Buchen", cancel: "Abbrechen", cancelDoc: "Stornieren", cancelDocAbort: "Nicht stornieren", cancelDocConfirmBtn: "Definitiv stornieren", discardDraft: "Entwurf verwerfen", keepDraft: "Behalten", discardDraftConfirm: "Verwerfen", showDiscarded: "Verworfene anzeigen", delete: "Löschen", edit: "Bearbeiten", pdf: "PDF", addRow: "Zeile hinzufügen", loading: "Lädt...", enable: "Aktivieren", disable: "Deaktivieren", refresh: "Aktualisieren", refreshing: "Aktualisiert...", areYouSure: "Sind Sie sicher?", all: "Alle", apply: "Anwenden", new: "Neu", prev: "Zurück", next: "Weiter", perPage: "Pro Seite", page: "Seite", of: "von", showing: "Zeige", total: "Gesamt", totals: "Summen", errorOccurred: "Ein Fehler ist aufgetreten" }, ti = { title: "Sprache", help: "Wählen Sie die Sprache der Oberfläche. Ihre Auswahl wird in diesem Browser gespeichert.", label: "Sprache" }, ni = { logout: "Abmelden", openMenu: "Menü öffnen", closeMenu: "Menü schließen", new: "Neu: {{label}}" }, ai = { dashboard: "Dashboard", setup: "Unternehmenseinrichtung", tutorial: "Erste Schritte", chat: "Chat", reports: "Berichte", "trial-balance": "Rohbilanz", "general-ledger": "Hauptbuch", "stock-balance": "Lagerbestand", "profit-and-loss": "Gewinn- und Verlustrechnung", "balance-sheet": "Bilanz", "ar-aging": "Offene Posten Debitoren", "ap-aging": "Offene Posten Kreditoren", analytics: "Analysen" }, ri = { quotation: { one: "Angebot", other: "Angebote" }, proposal: { one: "Sammelofferte", other: "Sammelofferten" }, "sales-order": { one: "Kundenauftrag", other: "Kundenaufträge" }, "sales-invoice": { one: "Ausgangsrechnung", other: "Ausgangsrechnungen" }, "pos-invoice": { one: "Kassenbeleg", other: "Kassenbelege" }, "purchase-order": { one: "Bestellung", other: "Bestellungen" }, "purchase-invoice": { one: "Eingangsrechnung", other: "Eingangsrechnungen" }, "payment-entry": { one: "Zahlung", other: "Zahlungen" }, "journal-entry": { one: "Buchungssatz", other: "Buchungssätze" }, "bank-transaction": { one: "Banktransaktion", other: "Banktransaktionen" }, budget: { one: "Budget", other: "Budgets" }, subscription: { one: "Abonnement", other: "Abonnements" }, "stock-entry": { one: "Lagerbuchung", other: "Lagerbuchungen" }, "delivery-note": { one: "Lieferschein", other: "Lieferscheine" }, "purchase-receipt": { one: "Wareneingang", other: "Wareneingänge" }, "pricing-rule": { one: "Preisregel", other: "Preisregeln" } }, si = { company: { one: "Unternehmen", other: "Unternehmen" }, customer: { one: "Kunde", other: "Kunden" }, supplier: { one: "Lieferant", other: "Lieferanten" }, item: { one: "Artikel", other: "Artikel" }, warehouse: { one: "Lager", other: "Lager" } }, ii = { chats: "Chats", newChat: "Neuer Chat", deleteChat: "Chat löschen", customAnalytics: "Eigene Analysen", newAnalytics: "Neue Analyse", deleteReport: "Bericht löschen", groups: { Introduction: "Einführung", Selling: "Verkauf", Buying: "Einkauf", Accounting: "Buchhaltung", Stock: "Lager", Reports: "Berichte", Masters: "Stammdaten", Settings: "Einstellungen" }, items: { "Getting Started": "Erste Schritte", "Company Setup": "Unternehmenseinrichtung", "Opening Balances": "Eröffnungsbilanzen", Quotation: "Angebot", Proposal: "Sammelofferte", "Sales Order": "Kundenauftrag", "Sales Invoice": "Ausgangsrechnung", "POS Invoice": "Kassenbeleg", "Purchase Order": "Bestellung", "Purchase Invoice": "Eingangsrechnung", "Payment Entry": "Zahlung", "Journal Entry": "Buchungssatz", "Bank Transaction": "Banktransaktion", Budget: "Budget", Subscription: "Abonnement", "Stock Entry": "Lagerbuchung", "Delivery Note": "Lieferschein", "Purchase Receipt": "Wareneingang", "Trial Balance": "Rohbilanz", "Profit & Loss": "Gewinn- und Verlustrechnung", "Balance Sheet": "Bilanz", "General Ledger": "Hauptbuch", "AR Aging": "Offene Posten Debitoren", "AP Aging": "Offene Posten Kreditoren", Analytics: "Analysen", "Stock Balance": "Lagerbestand", Company: "Unternehmen", Customer: "Kunde", Supplier: "Lieferant", Item: "Artikel", Warehouse: "Lager", General: "Allgemein", "Pricing Rule": "Preisregel", "Users & Team": "Benutzer & Team" } }, oi = { taglineFirstRun: "Erstellen Sie Ihr Administratorkonto, um zu beginnen", taglineRegister: "Erstellen Sie Ihr Konto", taglineSignIn: "Melden Sie sich bei Ihrem Konto an", demoBanner: "Der Demomodus ist aktiv. Melden Sie sich mit einem Administratorkonto an, um Einstellungen zu verwalten oder den öffentlichen Zugriff zu deaktivieren.", fullName: "Vollständiger Name", email: "E-Mail", password: "Passwort", confirmPassword: "Passwort bestätigen", createAdmin: "Administratorkonto erstellen", register: "Registrieren", signIn: "Anmelden", browsingTitle: "Nur am Stöbern?", browsingBody: "Starten Sie eine neue Chat-Sitzung und sehen Sie sich die Live-Demo an.", enterDemo: "Live-Demo starten", haveInvite: "Haben Sie eine Einladung?", noAccountPrompt: "Noch kein Konto?", registerLink: "Registrieren", alreadyHaveAccount: "Haben Sie bereits ein Konto?", signInLink: "Anmelden", passwordsNoMatch: "Passwörter stimmen nicht überein", passwordTooShort: "Das Passwort muss mindestens 6 Zeichen lang sein", registrationFailed: "Registrierung fehlgeschlagen", loginFailed: "Anmeldung fehlgeschlagen" }, li = { pdfTitle: "PDF & Druck", pageSize: "Seitengröße", pdfHelp: "A4 ist international Standard (210 x 297 mm). Letter ist Standard in den USA (8,5 x 11 Zoll).", passwordTitle: "Passwort ändern", currentPassword: "Aktuelles Passwort", newPassword: "Neues Passwort", confirmNewPassword: "Neues Passwort bestätigen", changePassword: "Passwort ändern", changingPassword: "Wird geändert...", passwordChanged: "Passwort geändert.", openingTitle: "Eröffnungsbilanzen", openingBody: "Auf der Seite Eröffnungsbilanzen können Kontensalden, Lagerbestände und offene Rechnungen aus einem früheren System importiert werden.", openingEnabled: "Derzeit aktiviert — erreichbar unter Einführung > Eröffnungsbilanzen.", openingDisabled: "Derzeit deaktiviert — die Seite ist in der Seitenleiste ausgeblendet.", signupTitle: "Öffentliche Registrierung", signupBody: "Erlauben Sie es jedem, ohne Einladung ein eigenes Konto (als Betrachter) zu erstellen. Wenn deaktiviert, können neue Benutzer nur über einen Einladungslink beitreten.", signupEnabled: "Derzeit aktiviert — jeder mit der URL kann sich als Betrachter registrieren.", signupDisabled: "Derzeit deaktiviert — die Registrierung erfolgt nur per Einladung.", publicTitle: "Öffentlicher Zugriff (Demomodus)", publicActive: "Aktiv", publicActiveBody: "Der öffentliche Zugriff ist aktiviert. Jeder kann die Anwendung ohne Anmeldung nutzen. Alle Besucher erhalten Manager-Rechte.", disablePublic: "Öffentlichen Zugriff deaktivieren", disabling: "Wird deaktiviert...", publicInactiveBody: "Aktivieren Sie den öffentlichen Zugriff, damit jeder die Anwendung ohne Konto nutzen kann. Nützlich für Demos und Präsentationen. Alle Besucher erhalten Manager-Rechte und teilen sich dieselbe Identität.", enablePublic: "Öffentlichen Zugriff aktivieren", enableWarning: "Dadurch kann jeder ohne Anmeldung auf die Anwendung zugreifen. Besucher können Dokumente erstellen, bearbeiten und buchen. Ihr Administratorkonto erfordert weiterhin eine Anmeldung.", yesEnable: "Ja, aktivieren", enabling: "Wird aktiviert...", tokenSpendTitle: "Token-Ausgaben" }, ci = { Draft: "Entwurf", Open: "Offen", Submitted: "Gebucht", "To Deliver and Bill": "Zu liefern und abzurechnen", "To Deliver": "Zu liefern", "To Bill": "Abzurechnen", Completed: "Abgeschlossen", Ordered: "Bestellt", Paid: "Bezahlt", Unpaid: "Unbezahlt", Cancelled: "Storniert", Discarded: "Verworfen", Overdue: "Überfällig", Return: "Retoure", Closed: "Geschlossen" }, di = { balanced: "AUSGEGLICHEN", imbalanced: "NICHT AUSGEGLICHEN", income: "Erträge", expenses: "Aufwendungen", totalIncome: "Summe Erträge", totalExpenses: "Summe Aufwendungen", netProfit: "Gewinn", netLoss: "Verlust", assets: "Aktiva", liabilities: "Verbindlichkeiten", equity: "Eigenkapital", totalAssets: "Summe Aktiva", totalLiabilities: "Summe Verbindlichkeiten", totalEquity: "Summe Eigenkapital", totalLiabilitiesEquity: "Summe Verbindlichkeiten + Eigenkapital", current: "Laufend", noData: "Keine Daten gefunden", noEntries: "Keine Buchungen gefunden", noStockData: "Keine Lagerdaten gefunden", noReceivables: "Keine offenen Forderungen", noPayables: "Keine offenen Verbindlichkeiten", noDocuments: "Keine Dokumente gefunden" }, ui = { required: "Erforderlich: {{fields}}", deleteConfirm: "Diesen Datensatz löschen: {{label}}?", disabledNotice: "Dieser Datensatz ({{label}}) ist deaktiviert. Er verbleibt im System, weil andere Datensätze noch darauf verweisen.", disabledOnDelete: "{{label}} {{name}} wurde deaktiviert statt gelöscht, da er von {{reason}} referenziert wird." }, mi = { Account: "Konto", Amount: "Betrag", Balance: "Saldo", Credit: "Haben", Debit: "Soll", Date: "Datum", Party: "Partner", "Party Type": "Partnertyp", "Voucher Type": "Belegart", "Voucher No": "Belegnr.", Invoice: "Rechnung", Customer: "Kunde", Supplier: "Lieferant", "Due Date": "Fälligkeitsdatum", Outstanding: "Offen", "Outstanding Amount": "Offener Betrag", "Item Code": "Artikelnr.", "Item Name": "Artikelname", Item: "Artikel", Warehouse: "Lager", Qty: "Menge", "Valuation Rate": "Bewertungspreis", "Stock Value": "Lagerwert", Name: "Name", Status: "Status", Company: "Unternehmen", "From Date": "Von Datum", "To Date": "Bis Datum", "As of Date": "Stichtag", "Valid Till": "Gültig bis", "Net Total": "Nettobetrag", Tax: "Steuer", "Grand Total": "Gesamtbetrag", Frequency: "Frequenz", "Notes / Terms": "Notizen / Bedingungen", "Posting Date": "Buchungsdatum", "Transaction Date": "Belegdatum", "Delivery Date": "Lieferdatum", "% Delivered": "% geliefert", "% Billed": "% abgerechnet", "Update Stock": "Lager aktualisieren", "Payment Type": "Zahlungsart", "Paid From": "Bezahlt von", "Paid To": "Bezahlt an", "Paid Amount": "Zahlbetrag", Type: "Art", Total: "Gesamt", Allocated: "Zugeordnet", Unallocated: "Nicht zugeordnet", Remark: "Bemerkung", "Total Debit": "Summe Soll", "Total Credit": "Summe Haben", "Cost Center": "Kostenstelle", "Source Warehouse": "Quelllager", "Target Warehouse": "Ziellager", Source: "Quelle", Target: "Ziel", "Incoming Value": "Eingangswert", "Outgoing Value": "Ausgangswert", Rate: "Preis", "Income Account": "Ertragskonto", "Expense Account": "Aufwandskonto", Description: "Beschreibung", "Rate (%)": "Satz (%)", Mode: "Art", Change: "Rückgeld", Currency: "Währung", Title: "Titel", Selling: "Verkauf", Buying: "Einkauf", "Discount %": "Rabatt %", "Discount Amt": "Rabattbetrag", "Min Qty": "Mindestmenge", "Valid From": "Gültig ab", "Valid Upto": "Gültig bis", Priority: "Priorität", Enabled: "Aktiviert", "Fiscal Year": "Geschäftsjahr", "Budget Amount": "Budgetbetrag", "If Exceeded": "Bei Überschreitung", Month: "Monat", "Bank Account": "Bankkonto", Deposit: "Einzahlung", Withdrawal: "Auszahlung", "Reference No": "Referenznr.", "Matched Type": "Zugeordnete Art", "Matched Doc": "Zugeordneter Beleg", "Start Date": "Startdatum", "End Date": "Enddatum", "Billing Interval": "Abrechnungsintervall", "Current Period Start": "Aktueller Periodenbeginn", "Current Period End": "Aktuelles Periodenende", "Plan Items": "Planpositionen", "Total Amount": "Gesamtbetrag", "Stock Entry Type": "Lagerbuchungsart", "Rate Or Discount": "Preis oder Rabatt", "Discount Percentage": "Rabattprozentsatz", ID: "ID", "Customer Name": "Kundenname", "Customer Group": "Kundengruppe", Territory: "Region", "Credit Limit": "Kreditlimit", Email: "E-Mail", Phone: "Telefon", Address: "Adresse", City: "Stadt", "Zip Code": "PLZ", Country: "Land", "Tax ID": "Steuernummer", "Contact Person": "Ansprechperson", "Contact Email": "E-Mail Ansprechperson", "Contact Phone": "Telefon Ansprechperson", "Supplier Name": "Lieferantenname", "Supplier Group": "Lieferantengruppe", "Item Group": "Artikelgruppe", "Stock UOM": "Lagereinheit", "Standard Rate": "Standardpreis", "Warehouse Name": "Lagername", "Company Name": "Firmenname" }, pi = { items: "Positionen", taxes: "Steuern", references: "Zahlungsreferenzen", accounts: "Kontobuchungen", payments: "Zahlungen", plans: "Planpositionen", monthly_distribution: "Monatliche Verteilung" }, hi = { "Create Sales Order": "Kundenauftrag erstellen", "Create Sales Invoice": "Ausgangsrechnung erstellen", "Create Delivery Note": "Lieferschein erstellen", "Create Purchase Invoice": "Eingangsrechnung erstellen", "Create Purchase Receipt": "Wareneingang erstellen", "Create Credit Note": "Gutschrift erstellen", "Create Debit Note": "Lastschrift erstellen", "Create Return": "Retoure erstellen" }, gi = { totalRevenue: "Gesamtumsatz", outstandingReceivable: "Offene Forderungen", outstandingPayable: "Offene Verbindlichkeiten", totalStockValue: "Gesamter Lagerwert", recentDocuments: "Letzte Dokumente", noRecentDocuments: "Keine aktuellen Dokumente" }, yi = { title: "Lambda ERP Chat", subtitle: "Bitten Sie mich, Dokumente zu erstellen, Daten abzurufen oder Berichte auszuführen.", s1: "Welche Kunden haben wir?", s2: "Zeig mir die Rohbilanz", s3: "Erstelle ein Angebot für 10 Bolt Pack M8", s4: "Liste alle unbezahlten Rechnungen auf", loadOlder: "Ältere Nachrichten laden", uploading: "Wird hochgeladen...", failed: "Fehlgeschlagen", remove: "Entfernen", placeholderDemo: "Live-Demo läuft...", placeholderType: "Nachricht eingeben...", placeholderConnecting: "Verbindung wird hergestellt...", attachTitle: "Datei anhängen (PDF oder Bild, max. 10 MB)", creating: "Chat wird erstellt...", dropToAttach: "Datei zum Anhängen ablegen (Bilder oder PDF, je max. 10 MB)", demoError: "Demo konnte nicht gestartet werden", voiceStart: "Sprachnachricht aufnehmen", voiceStop: "Aufnahme stoppen", voiceTranscribing: "Wird transkribiert...", micDenied: "Zugriff auf das Mikrofon wurde verweigert.", transcribeFailed: "Transkription fehlgeschlagen. Bitte erneut versuchen." }, fi = /* @__PURE__ */ JSON.parse('{"pageTitle":"Erste Schritte mit Lambda ERP","intro":"Lambda ERP ist ein KI-natives ERP-System, bei dem die gesamte Funktionalität – etwa das Erstellen von Aufträgen, das Prüfen von Beständen und das Erfassen von Zahlungen – über eine Chat-Oberfläche zugänglich ist. Es leitet an, denkt mit und prüft alle Ihre täglichen Geschäftsaufgaben.","openChat":"KI-Chat öffnen","tipLabel":"Tipp:","topTip":"Der KI-Chat kann Ihnen auch direkte Links zu Dokumenten und herunterladbaren PDFs geben. Bitten Sie ihn einfach, ein Dokument zu erstellen oder nachzuschlagen, und er fügt anklickbare Links in seine Antwort ein.","manualIntro":"Wenn Sie genau verstehen möchten, wie die Dinge unter der Haube funktionieren, oder Dinge lieber manuell erledigen, finden Sie hier einen vollständigen Geschäftszyklus Schritt für Schritt.","caTitle":"Dynamische Analysen – Chatten Sie sich zu jedem Diagramm","caBadge":"Kernfunktion","caBody":"Brauchen Sie einen Bericht, den die Vorlagen nicht liefern? Beschreiben Sie ihn einfach im Chat. Der Assistent ruft ein Code-Spezialmodell auf, das den Bericht für Sie schreibt, ihn live über Ihre ERP-Daten ausführt und einen teilbaren Link zurückgibt. Das Diagramm oder die Tabelle wird in Sekunden gerendert und als Entwurf unter „Eigene Analysen“ in der Seitenleiste gespeichert – Sie können ihn erneut öffnen, die URL mit Kollegen teilen oder den Assistenten bitten, ihn zu verfeinern.","caTryAsking":"Versuchen Sie zu fragen (zum Vorausfüllen im Chat klicken):","caPrompt1":"Zeig mir die Top 10 Kunden nach Umsatz dieses Jahr als Balkendiagramm","caPrompt2":"Monatlicher Einkaufstrend nach Lieferant über alle Monate, x-Achse mit Lieferantennamen beschriften","caPrompt3":"Bestseller-Artikel nach Menge, mit Tabelle und Diagramm","caPrompt4":"Welche Kunden schulden mir gerade am meisten?","caTryInChat":"Im Chat ausprobieren","caOpenWorkspace":"Analyse-Arbeitsbereich öffnen","flowTitle":"Überblick Dokumentenfluss","salesCycle":"Verkaufszyklus","purchaseCycle":"Einkaufszyklus","returns":"Retouren","flowShortcut":"Abkürzung: Das Angebot kann den Kundenauftrag überspringen und direkt zur Ausgangsrechnung oder zum Lieferschein führen","legendStock":"Lagerwirkung","legendGl":"Buchungswirkung","legendCash":"Geldwirkung","legendReversal":"Stornierung","lifecycleTitle":"Dokumenten-Lebenszyklus","lcDraftLabel":"Entwurf:","lcDraftDesc":"Bearbeitbar. Keine finanzielle oder Bestandswirkung.","lcSubmittedLabel":"Gebucht:","lcSubmittedDesc":"Gesperrt. Buchungen und Lagerbuchungen werden erzeugt.","lcCancelledLabel":"Storniert:","lcCancelledDesc":"Alle Buchungen storniert. Das Dokument wird dauerhaft archiviert.","lcNoDelete":"Es gibt kein Löschen. Um einen Entwurf zu verwerfen: buchen und dann stornieren.","lcCorrect":"Um ein gebuchtes Dokument zu korrigieren: stornieren und ein neues erstellen.","readyTitle":"Sie sind startklar","readyBody1":"Sie verstehen jetzt den vollständigen Zyklus. Ein typisches Praxisszenario sieht so aus: Sie erhalten einen Kundenauftrag (Angebot → Kundenauftrag), prüfen den Bestand, kaufen, was Sie brauchen (Bestellung → Wareneingang → Eingangsrechnung → Zahlung), liefern an den Kunden (Lieferschein), stellen ihm die Rechnung (Ausgangsrechnung) und ziehen die Zahlung ein (Zahlung). Kommt etwas zurück, erstellen Sie eine Gutschrift und eine Lieferschein-Retoure, um Finanzen und Bestand umzukehren. Die Rohbilanz bestätigt, dass alles ausgeglichen ist.","readyBody2":"Sie können all dies auch über den KI-Chat per natürlicher Konversation erledigen – beschreiben Sie einfach, was Sie brauchen, und er erstellt die richtigen Dokumente für Sie.","chips":{"Quotation":"Angebot","Sales Order":"Kundenauftrag","Delivery Note":"Lieferschein","Sales Invoice":"Ausgangsrechnung","Payment Entry":"Zahlung","Purchase Order":"Bestellung","Purchase Receipt":"Wareneingang","Purchase Invoice":"Eingangsrechnung","Credit Note":"Gutschrift","DN Return":"Lieferschein-Retoure","Debit Note":"Lastschrift","Draft":"Entwurf","Submitted":"Gebucht","Cancelled":"Storniert"},"links":{"Go to Setup":"Zur Einrichtung","Customers":"Kunden","Suppliers":"Lieferanten","Items":"Artikel","Warehouses":"Lager","New Quotation":"Neues Angebot","View Quotations":"Angebote anzeigen","Stock Balance":"Lagerbestand","New Purchase Order":"Neue Bestellung","Purchase Receipts":"Wareneingänge","Purchase Invoices":"Eingangsrechnungen","Delivery Notes":"Lieferscheine","Sales Invoices":"Ausgangsrechnungen","New Payment Entry":"Neue Zahlung","New Stock Entry":"Neue Lagerbuchung","New Journal Entry":"Neuer Buchungssatz","Profit & Loss":"Gewinn- und Verlustrechnung","Balance Sheet":"Bilanz","AR Aging":"Offene Posten Debitoren","AP Aging":"Offene Posten Kreditoren","Trial Balance":"Rohbilanz","General Ledger":"Hauptbuch","Open AI Chat":"KI-Chat öffnen"},"steps":{"1":{"title":"Unternehmen einrichten","description":"Erstellen Sie ein Unternehmen mit einer Basiswährung. Dadurch wird Ihr Kontenplan generiert (30 Standardkonten in den Bereichen Aktiva, Verbindlichkeiten, Eigenkapital, Erträge und Aufwendungen) sowie eine Standard-Kostenstelle. Sie können außerdem Demodaten mit Beispielkunden, -lieferanten und -artikeln anlegen, um schnell loszulegen."},"2":{"title":"Stammdaten anlegen","description":"Bevor Sie buchen können, benötigen Sie Stammdaten. Legen Sie mindestens einen Kunden, einen Lieferanten, einen Artikel (mit Standardpreis) und ein Lager an. Wenn Sie in Schritt 1 Demodaten angelegt haben, existieren diese bereits.","tip":"Artikel haben einen Standardpreis, der beim Hinzufügen zu Dokumenten automatisch ausgefüllt wird. Sie können den Preis pro Transaktion jederzeit überschreiben."},"3":{"title":"Angebot erstellen","description":"Ein Angebot ist eine unverbindliche Offerte an einen Kunden. Wählen Sie einen Kunden, fügen Sie Positionen mit Mengen und Preisen hinzu, optional Steuerzeilen, und speichern Sie. Angebote haben keine finanzielle Auswirkung – sie erzeugen keine Buchungs- oder Lagerbewegungen. Legen Sie ein Gültigkeitsdatum fest, damit das Angebot automatisch abläuft."},"4":{"title":"Buchen und in Kundenauftrag umwandeln","description":"Öffnen Sie Ihr gespeichertes Angebot und klicken Sie auf Buchen, um es zu bestätigen. Klicken Sie dann auf „Kundenauftrag erstellen“, um es umzuwandeln. Der Kundenauftrag stellt eine bestätigte Zusage des Kunden dar. Er hat weiterhin keine finanzielle Auswirkung, reserviert aber Bestand für die Planung.","tip":"Nur gebuchte Dokumente können in den nächsten Schritt umgewandelt werden. Entwurf → Buchen → Umwandeln ist der Standardablauf. Für schnelle Geschäfte können Sie den Kundenauftrag überspringen und direkt vom Angebot zur Ausgangsrechnung oder zum Lieferschein gehen."},"5":{"title":"Bestand vor der Erfüllung prüfen","description":"Bevor Sie liefern können, prüfen Sie, ob der Artikel tatsächlich auf Lager ist. Öffnen Sie den Bericht Lagerbestand und suchen Sie den Artikel. Wenn Ihr Lager eine Menge von null aufweist, müssen Sie zunächst Bestand beschaffen – entweder über eine Bestellung (Einkauf bei einem Lieferanten) oder eine Lagerbuchung (manueller Eingang).","tip":"Dies ist ein häufiges Szenario aus der Praxis: Sie verkaufen etwas und stellen dann fest, dass Sie es erst einkaufen müssen. Das ERP unterstützt beide Abläufe."},"6":{"title":"Einkaufszyklus: Bestand bei einem Lieferanten kaufen","description":"Wenn Sie Bestand einkaufen müssen, haben Sie zwei gültige Wege. Der Standardweg ist Bestellung → Wareneingang → Eingangsrechnung: Nutzen Sie ihn, wenn die Ware vor oder getrennt von der Lieferantenrechnung eintrifft. Treffen Rechnung und Wareneingang gleichzeitig ein, können Sie die Eingangsrechnung direkt erstellen und „Lager aktualisieren“ aktivieren, sodass dasselbe Dokument sowohl den Bestand vereinnahmt als auch die Verbindlichkeit erfasst.","tip":"Verwenden Sie zuerst den Wareneingang, wenn Sie Waren getrennt erhalten. Verwenden Sie die Eingangsrechnung mit „Lager aktualisieren“, wenn ein Schritt sowohl den Bestand vereinnahmen als auch die Lieferantenrechnung buchen soll. Setzen Sie in diesem direkten Weg ein Lager in jeder Bestandszeile."},"7":{"title":"Lieferschein erstellen","description":"Nachdem Sie nun Bestand haben, kehren Sie zu Ihrem gebuchten Kundenauftrag zurück und klicken Sie auf „Lieferschein erstellen“. Setzen Sie in jeder Position das Lager (von dem die Ware versendet wird) und buchen Sie. Dadurch wird Bestand aus dem Lager ausgebucht – Ihr Lagerbestand sinkt.","tip":"Der Lieferschein ist das Versanddokument. Er reduziert den Bestand, erzeugt aber keine Rechnung. Sie können Lieferung und Rechnungsstellung getrennt vornehmen."},"8":{"title":"Ausgangsrechnung erstellen und buchen","description":"Erstellen Sie aus dem gebuchten Kundenauftrag eine Ausgangsrechnung. Beim Buchen der Rechnung werden Buchungen erzeugt: Forderungen aus Lieferungen und Leistungen werden im Soll gebucht (der Kunde schuldet Ihnen Geld) und Umsatzerlöse im Haben (erzielter Ertrag). Sind Steuern konfiguriert, wird auch die Steuerverbindlichkeit im Haben gebucht. Der offene Betrag zeigt, was der Kunde noch schuldet."},"9":{"title":"Kundenzahlungen erfassen","description":"Erstellen Sie eine Zahlung, um vom Kunden erhaltenes Geld zu erfassen. Setzen Sie die Zahlungsart auf „Receive“ (Erhalten), wählen Sie den Kunden, geben Sie den Betrag an und ordnen Sie ihn der Ausgangsrechnung zu. Sie können Teilzahlungen vornehmen – der offene Betrag der Rechnung aktualisiert sich entsprechend. Erstellen Sie weitere Zahlungen, bis die Rechnung vollständig beglichen ist.","tip":"Teilzahlungen sind üblich. Eine Rechnung über 10.000 kann jetzt mit 3.000 und später mit 7.000 bezahlt werden. Jede Zahlung reduziert den offenen Betrag."},"10":{"title":"Lagerbuchungen (manuelle Bestandsführung)","description":"Verwenden Sie Lagerbuchungen für Bestandsbewegungen, die nicht mit Ein- oder Verkäufen verbunden sind. „Material Receipt“ fügt Bestand hinzu (Eröffnungsbestände, Korrekturen). „Material Issue“ bucht Bestand aus (Abschreibungen, interner Verbrauch). „Material Transfer“ verschiebt Bestand zwischen Lägern. Jede Buchung aktualisiert das Lagerbuch mit gleitender Durchschnittsbewertung.","tip":"Verwenden Sie für eingekaufte Waren Wareneingänge statt Lagerbuchungen – sie sind mit der Bestellung verknüpft und bieten einen sauberen Prüfpfad."},"11":{"title":"Buchungssätze","description":"Buchungssätze sind manuelle buchhalterische Anpassungen – Aufwandsabgrenzungen, Korrekturen, Umgliederungen, Eröffnungsbestände. Jeder Satz muss ausgeglichene Soll- und Haben-Beträge haben (Summe Soll = Summe Haben). Verwenden Sie sie, wenn kein anderer Dokumenttyp passt."},"12":{"title":"Gehaltszahlungen","description":"Lambda ERP wickelt Gehälter über die vorhandenen Buchhaltungswerkzeuge ab. Grenzen Sie zunächst den Gehaltsaufwand ab: Erstellen Sie einen Buchungssatz, der Gehaltsaufwand im Soll und Gehaltsverbindlichkeiten im Haben für den gesamten Lohnbetrag bucht. Bezahlen Sie dann die Mitarbeiter: Erstellen Sie einen weiteren Buchungssatz (oder eine Zahlung), der Gehaltsverbindlichkeiten im Soll und Ihr Bankkonto im Haben bucht. Dieser zweistufige Prozess hält Ihre Bücher korrekt – der Aufwand wird in der richtigen Periode erfasst und der Geldabfluss separat nachverfolgt.","tip":"Sie können den KI-Assistenten bitten, dies für Sie zu erledigen: „Grenze 15.000 an Gehältern für April ab“ gefolgt von „Zahle die April-Gehälter von der Bank“. Er erstellt die richtigen Buchungssätze automatisch."},"13":{"title":"Retouren und Gutschriften","description":"Wenn ein Kunde Waren zurückgibt oder Sie eine Gutschrift ausstellen müssen, erstellen Sie eine Retoure. Retouren verwenden denselben Dokumenttyp mit negativen Mengen. Öffnen Sie eine gebuchte Ausgangsrechnung und erstellen Sie eine Gutschrift (Ausgangsrechnungs-Retoure) – dies kehrt die Buchungen um und reduziert den offenen Betrag der ursprünglichen Rechnung. Erstellen Sie für den Bestand eine Lieferschein-Retoure, um Waren zurück ins Lager zu nehmen. Auf der Einkaufsseite erstellen Sie eine Lastschrift (Eingangsrechnungs-Retoure), um eine Lieferantenrechnung umzukehren, oder eine Wareneingangs-Retoure, um Waren zurückzusenden.","tip":"Eine Gutschrift ist einfach eine Ausgangsrechnung mit is_return=1 und negativen Mengen. Dieselbe Buchungslogik läuft – negative Beträge wechseln automatisch auf die richtige Soll-/Haben-Seite. Für eine vollständige Verkaufsretoure benötigen Sie sowohl eine Gutschrift (Finanzen) als auch eine Lieferschein-Retoure (Bestand)."},"14":{"title":"Berichte ausführen","description":"Prüfen Sie Ihre Bücher. Die Gewinn- und Verlustrechnung zeigt Erträge gegenüber Aufwendungen und den Periodengewinn. Die Bilanz zeigt Ihre finanzielle Lage (Aktiva = Verbindlichkeiten + Eigenkapital). Die Offenen Posten Debitoren zeigen, wer Ihnen Geld schuldet und wie überfällig es ist. Die Offenen Posten Kreditoren zeigen, was Sie Lieferanten schulden. Die Rohbilanz überprüft die doppelte Buchführung. Das Hauptbuch zeigt jede einzelne Buchung. Der Lagerbestand zeigt den aktuellen Bestand."},"15":{"title":"Arbeiten in Fremdwährungen","description":"Ihre Bücher werden in einer einzigen Basiswährung geführt (bei der Unternehmenseinrichtung gewählt), aber Sie können in jeder Währung buchen. Setzen Sie eine Währung auf einer Rechnung oder einem Beleg – oder geben Sie einem Kunden oder Lieferanten eine Standardwährung – und der Wechselkurs für dieses Datum wird automatisch ermittelt und auf dem Dokument gespeichert. Das Dokument behält seine Beträge in seiner eigenen Währung, während das Hauptbuch stets in Ihrer Basiswährung bucht. Wenn Sie später zu einem anderen Kurs einnehmen oder zahlen, wird der realisierte Währungsgewinn oder -verlust automatisch auf ein Konto Währungsgewinn/-verlust gebucht. Sie können sogar ein Fremdwährungs-Bankguthaben halten und es später zum Kurs Ihrer Bank umrechnen – die Differenz zum Buchwert wird dann realisiert. Zum Monatsende können Sie offene Fremdwährungssalden zum Stichtagskurs neu bewerten (ein unrealisierter Gewinn/Verlust, der in der nächsten Periode storniert wird), und Sie können jeden Jahresabschluss zur Anzeige in eine andere Währung umgerechnet betrachten.","tip":"Am einfachsten geht das über den KI-Chat – probieren Sie „Erstelle eine Ausgangsrechnung für Lumiere Audio in EUR“, „Zeig mir die Bilanz in EUR“ oder „Wie hoch ist unser unrealisiertes Währungsrisiko zum Monatsende?“. Die Demodaten enthalten bereits einen EUR-Kunden (Lumiere Audio SARL), dessen Rechnung zu einem anderen Kurs eingenommen wurde, sowie eine offene EUR-Lieferantenrechnung – öffnen Sie das Hauptbuch, um die realisierten Währungsbuchungen zu sehen."}}}'), bi = { title: "Formatierungshilfe", intro: "Der Text unter Notizen / Konditionen unterstützt eine einfache Formatierung im PDF:", heading: "fette Überschrift", emphasis: "kursiv / fett", rule: "horizontale Trennlinie", price: "rechtsbündiger Preis neben dem Text darüber (z. B. Monatlich | CHF 380.—)", block: "Trennen Sie Blöcke durch eine Leerzeile." }, xi = {
|
|
6656
6679
|
common: ei,
|
|
6657
6680
|
language: ti,
|
|
6658
6681
|
header: ni,
|
|
@@ -6672,7 +6695,7 @@ const Bs = { save: "Save", saving: "Saving...", submit: "Submit", cancel: "Cance
|
|
|
6672
6695
|
chat: yi,
|
|
6673
6696
|
tutorial: fi,
|
|
6674
6697
|
notesMarkup: bi
|
|
6675
|
-
}, vi = { save: "Enregistrer", saving: "Enregistrement...", submit: "Valider", cancel: "Annuler", cancelDoc: "Annuler", cancelDocAbort: "Ne pas annuler", cancelDocConfirmBtn: "Annuler définitivement", discardDraft: "Supprimer le brouillon", keepDraft: "Conserver", discardDraftConfirm: "Supprimer", showDiscarded: "Afficher les supprimés", delete: "Supprimer", edit: "Modifier", pdf: "PDF", addRow: "Ajouter une ligne", loading: "Chargement...", enable: "Activer", disable: "Désactiver", refresh: "Actualiser", refreshing: "Actualisation", areYouSure: "Êtes-vous sûr ?", all: "Tous", apply: "Appliquer", new: "Nouveau", prev: "Précédent", next: "Suivant", perPage: "Par page", page: "Page", of: "sur", showing: "Affichage", total: "Total", totals: "Totaux", errorOccurred: "Une erreur s'est produite" }, Ni = { title: "Langue", help: "Choisissez la langue de l'interface. Votre choix est enregistré dans ce navigateur.", label: "Langue" }, wi = { logout: "Déconnexion", openMenu: "Ouvrir le menu", closeMenu: "Fermer le menu", new: "Nouveau : {{label}}" }, ki = { dashboard: "Tableau de bord", setup: "Configuration de l'entreprise", tutorial: "Premiers pas", chat: "Chat", reports: "Rapports", "trial-balance": "Balance comptable", "general-ledger": "Grand livre", "stock-balance": "Solde de stock", "profit-and-loss": "Compte de résultat", "balance-sheet": "Bilan", "ar-aging": "Balance âgée clients", "ap-aging": "Balance âgée fournisseurs", analytics: "Analyses" }, Si = { quotation: { one: "Devis", other: "Devis" }, proposal: { one: "Offre groupée", other: "Offres groupées" }, "sales-order": { one: "Commande client", other: "Commandes client" }, "sales-invoice": { one: "Facture de vente", other: "Factures de vente" }, "pos-invoice": { one: "Ticket de caisse", other: "Tickets de caisse" }, "purchase-order": { one: "Bon de commande", other: "Bons de commande" }, "purchase-invoice": { one: "Facture d'achat", other: "Factures d'achat" }, "payment-entry": { one: "Paiement", other: "Paiements" }, "journal-entry": { one: "Écriture comptable", other: "Écritures comptables" }, "bank-transaction": { one: "Transaction bancaire", other: "Transactions bancaires" }, budget: { one: "Budget", other: "Budgets" }, subscription: { one: "Abonnement", other: "Abonnements" }, "stock-entry": { one: "Mouvement de stock", other: "Mouvements de stock" }, "delivery-note": { one: "Bon de livraison", other: "Bons de livraison" }, "purchase-receipt": { one: "Bon de réception", other: "Bons de réception" }, "pricing-rule": { one: "Règle de prix", other: "Règles de prix" } }, Ci = { company: { one: "Société", other: "Sociétés" }, customer: { one: "Client", other: "Clients" }, supplier: { one: "Fournisseur", other: "Fournisseurs" }, item: { one: "Article", other: "Articles" }, warehouse: { one: "Entrepôt", other: "Entrepôts" } }, Di = { chats: "Discussions", newChat: "Nouvelle discussion", deleteChat: "Supprimer la discussion", customAnalytics: "Analyses personnalisées", newAnalytics: "Nouvelle analyse", deleteReport: "Supprimer le rapport", groups: { Introduction: "Introduction", Selling: "Ventes", Buying: "Achats", Accounting: "Comptabilité", Stock: "Stock", Reports: "Rapports", Masters: "Données de base", Settings: "Paramètres" }, items: { "Getting Started": "Premiers pas", "Company Setup": "Configuration de l'entreprise", "Opening Balances": "Soldes d'ouverture", Quotation: "Devis", Proposal: "Offre groupée", "Sales Order": "Commande client", "Sales Invoice": "Facture de vente", "POS Invoice": "Ticket de caisse", "Purchase Order": "Bon de commande", "Purchase Invoice": "Facture d'achat", "Payment Entry": "Paiement", "Journal Entry": "Écriture comptable", "Bank Transaction": "Transaction bancaire", Budget: "Budget", Subscription: "Abonnement", "Stock Entry": "Mouvement de stock", "Delivery Note": "Bon de livraison", "Purchase Receipt": "Bon de réception", "Trial Balance": "Balance comptable", "Profit & Loss": "Compte de résultat", "Balance Sheet": "Bilan", "General Ledger": "Grand livre", "AR Aging": "Balance âgée clients", "AP Aging": "Balance âgée fournisseurs", Analytics: "Analyses", "Stock Balance": "Solde de stock", Company: "Société", Customer: "Client", Supplier: "Fournisseur", Item: "Article", Warehouse: "Entrepôt", General: "Général", "Pricing Rule": "Règle de prix", "Users & Team": "Utilisateurs et équipe" } }, _i = { taglineFirstRun: "Créez votre compte administrateur pour commencer", taglineRegister: "Créez votre compte", taglineSignIn: "Connectez-vous à votre compte", demoBanner: "Le mode démo est actif. Connectez-vous avec un compte administrateur pour gérer les paramètres ou désactiver l'accès public.", fullName: "Nom complet", email: "E-mail", password: "Mot de passe", confirmPassword: "Confirmer le mot de passe", createAdmin: "Créer un compte administrateur", register: "S'inscrire", signIn: "Se connecter", browsingTitle: "Simple visite ?", browsingBody: "Démarrez une nouvelle session de chat et regardez la démo en direct.", enterDemo: "Lancer la démo", haveInvite: "Vous avez une invitation ?", noAccountPrompt: "Besoin d'un compte ?", registerLink: "S'inscrire", alreadyHaveAccount: "Vous avez déjà un compte ?", signInLink: "Se connecter", passwordsNoMatch: "Les mots de passe ne correspondent pas", passwordTooShort: "Le mot de passe doit comporter au moins 6 caractères", registrationFailed: "Échec de l'inscription", loginFailed: "Échec de la connexion" }, Pi = { pdfTitle: "PDF et impression", pageSize: "Format de page", pdfHelp: "A4 est la norme internationale (210 x 297 mm). Letter est la norme aux États-Unis (8,5 x 11 po).", passwordTitle: "Changer le mot de passe", currentPassword: "Mot de passe actuel", newPassword: "Nouveau mot de passe", confirmNewPassword: "Confirmer le nouveau mot de passe", changePassword: "Changer le mot de passe", changingPassword: "Modification...", passwordChanged: "Mot de passe modifié.", openingTitle: "Soldes d'ouverture", openingBody: "La page Soldes d'ouverture permet d'importer les soldes des comptes, le stock et les factures impayées d'un système précédent.", openingEnabled: "Actuellement activé — accessible sous Introduction > Soldes d'ouverture.", openingDisabled: "Actuellement désactivé — la page est masquée dans la barre latérale.", signupTitle: "Inscription publique", signupBody: "Permettre à quiconque de créer son propre compte (en tant que lecteur) sans invitation. Lorsque désactivé, les nouveaux utilisateurs ne peuvent rejoindre que via un lien d'invitation.", signupEnabled: "Actuellement activé — toute personne disposant de l'URL peut s'inscrire en tant que lecteur.", signupDisabled: "Actuellement désactivé — l'inscription se fait uniquement sur invitation.", publicTitle: "Accès public (mode démo)", publicActive: "Actif", publicActiveBody: "L'accès public est activé. N'importe qui peut utiliser l'application sans se connecter. Tous les visiteurs obtiennent des autorisations de niveau gestionnaire.", disablePublic: "Désactiver l'accès public", disabling: "Désactivation...", publicInactiveBody: "Activez l'accès public pour permettre à quiconque d'utiliser l'application sans compte. Utile pour les démos et présentations. Tous les visiteurs obtiennent des autorisations de niveau gestionnaire et partagent la même identité.", enablePublic: "Activer l'accès public", enableWarning: "Cela permettra à quiconque d'accéder à l'application sans se connecter. Ils pourront créer, modifier et valider des documents. Votre compte administrateur nécessite toujours une connexion.", yesEnable: "Oui, activer", enabling: "Activation...", tokenSpendTitle: "Dépenses de jetons" }, Ti = { Draft: "Brouillon", Open: "Ouvert", Submitted: "Validé", "To Deliver and Bill": "À livrer et facturer", "To Deliver": "À livrer", "To Bill": "À facturer", Completed: "Terminé", Ordered: "Commandé", Paid: "Payé", Unpaid: "Impayé", Cancelled: "Annulé", Discarded: "Supprimé", Overdue: "En retard", Return: "Retour", Closed: "Clôturé" }, Ai = { balanced: "ÉQUILIBRÉ", imbalanced: "DÉSÉQUILIBRÉ", income: "Produits", expenses: "Charges", totalIncome: "Total des produits", totalExpenses: "Total des charges", netProfit: "Bénéfice", netLoss: "Perte", assets: "Actif", liabilities: "Passif", equity: "Capitaux propres", totalAssets: "Total de l'actif", totalLiabilities: "Total du passif", totalEquity: "Total des capitaux propres", totalLiabilitiesEquity: "Total passif + capitaux propres", current: "Non échu", noData: "Aucune donnée trouvée", noEntries: "Aucune écriture trouvée", noStockData: "Aucune donnée de stock trouvée", noReceivables: "Aucune créance en cours", noPayables: "Aucune dette en cours", noDocuments: "Aucun document trouvé" }, Ri = { required: "Requis : {{fields}}", deleteConfirm: "Supprimer ce {{label}} ?", disabledNotice: "Ce {{label}} est désactivé. Il reste dans le système car d'autres enregistrements y font référence.", disabledOnDelete: "{{label}} {{name}} a été désactivé au lieu d'être supprimé car il est référencé par {{reason}}." }, Ii = { Account: "Compte", Amount: "Montant", Balance: "Solde", Credit: "Crédit", Debit: "Débit", Date: "Date", Party: "Tiers", "Party Type": "Type de tiers", "Voucher Type": "Type de pièce", "Voucher No": "N° de pièce", Invoice: "Facture", Customer: "Client", Supplier: "Fournisseur", "Due Date": "Date d'échéance", Outstanding: "Encours", "Outstanding Amount": "Montant dû", "Item Code": "Code article", "Item Name": "Nom de l'article", Item: "Article", Warehouse: "Entrepôt", Qty: "Qté", "Valuation Rate": "Coût unitaire", "Stock Value": "Valeur du stock", Name: "Nom", Status: "Statut", Company: "Société", "From Date": "Date de début", "To Date": "Date de fin", "As of Date": "À la date", "Valid Till": "Valable jusqu'au", "Net Total": "Total net", Tax: "Taxe", "Grand Total": "Total TTC", Frequency: "Fréquence", "Notes / Terms": "Notes / Conditions", "Posting Date": "Date de comptabilisation", "Transaction Date": "Date de transaction", "Delivery Date": "Date de livraison", "% Delivered": "% livré", "% Billed": "% facturé", "Update Stock": "Mettre à jour le stock", "Payment Type": "Type de paiement", "Paid From": "Payé depuis", "Paid To": "Payé à", "Paid Amount": "Montant payé", Type: "Type", Total: "Total", Allocated: "Affecté", Unallocated: "Non affecté", Remark: "Remarque", "Total Debit": "Total débit", "Total Credit": "Total crédit", "Cost Center": "Centre de coûts", "Source Warehouse": "Entrepôt source", "Target Warehouse": "Entrepôt cible", Source: "Source", Target: "Cible", "Incoming Value": "Valeur entrante", "Outgoing Value": "Valeur sortante", Rate: "Prix unitaire", "Income Account": "Compte de produits", "Expense Account": "Compte de charges", Description: "Description", "Rate (%)": "Taux (%)", Mode: "Mode", Change: "Monnaie rendue", Currency: "Devise", Title: "Titre", Selling: "Vente", Buying: "Achat", "Discount %": "Remise %", "Discount Amt": "Montant remise", "Min Qty": "Qté min", "Valid From": "Valable à partir du", "Valid Upto": "Valable jusqu'au", Priority: "Priorité", Enabled: "Activé", "Fiscal Year": "Exercice", "Budget Amount": "Montant du budget", "If Exceeded": "Si dépassé", Month: "Mois", "Bank Account": "Compte bancaire", Deposit: "Dépôt", Withdrawal: "Retrait", "Reference No": "N° de référence", "Matched Type": "Type rapproché", "Matched Doc": "Pièce rapprochée", "Start Date": "Date de début", "End Date": "Date de fin", "Billing Interval": "Intervalle de facturation", "Current Period Start": "Début période actuelle", "Current Period End": "Fin période actuelle", "Plan Items": "Articles du plan", "Total Amount": "Montant total", "Stock Entry Type": "Type de mouvement de stock", "Rate Or Discount": "Prix ou remise", "Discount Percentage": "Pourcentage de remise", ID: "ID", "Customer Name": "Nom du client", "Customer Group": "Groupe de clients", Territory: "Territoire", "Credit Limit": "Limite de crédit", Email: "E-mail", Phone: "Téléphone", Address: "Adresse", City: "Ville", "Zip Code": "Code postal", Country: "Pays", "Tax ID": "N° de TVA", "Contact Person": "Personne de contact", "Contact Email": "E-mail du contact", "Contact Phone": "Téléphone du contact", "Supplier Name": "Nom du fournisseur", "Supplier Group": "Groupe de fournisseurs", "Item Group": "Groupe d'articles", "Stock UOM": "Unité de stock", "Standard Rate": "Prix standard", "Warehouse Name": "Nom de l'entrepôt", "Company Name": "Nom de la société" }, Li = { items: "Lignes", taxes: "Taxes", references: "Références de paiement", accounts: "Écritures de compte", payments: "Paiements", plans: "Articles du plan", monthly_distribution: "Répartition mensuelle" }, Bi = { "Create Sales Order": "Créer une commande client", "Create Sales Invoice": "Créer une facture de vente", "Create Delivery Note": "Créer un bon de livraison", "Create Purchase Invoice": "Créer une facture d'achat", "Create Purchase Receipt": "Créer un bon de réception", "Create Credit Note": "Créer un avoir", "Create Debit Note": "Créer une note de débit", "Create Return": "Créer un retour" }, Ei = { totalRevenue: "Chiffre d'affaires total", outstandingReceivable: "Créances en cours", outstandingPayable: "Dettes en cours", totalStockValue: "Valeur totale du stock", recentDocuments: "Documents récents", noRecentDocuments: "Aucun document récent" }, Oi = { title: "Chat Lambda ERP", subtitle: "Demandez-moi de créer des documents, de consulter des données ou d'exécuter des rapports.", s1: "Quels clients avons-nous ?", s2: "Affiche la balance comptable", s3: "Crée un devis pour 10 Bolt Pack M8", s4: "Liste toutes les factures impayées", loadOlder: "Charger les messages plus anciens", uploading: "Téléversement...", failed: "Échec", remove: "Supprimer", placeholderDemo: "Démo en direct en cours...", placeholderType: "Tapez un message...", placeholderConnecting: "Connexion...", attachTitle: "Joindre un fichier (PDF ou image, max 10 Mo)", creating: "Création du chat...", dropToAttach: "Déposez un fichier à joindre (images ou PDF, max 10 Mo chacun)", demoError: "Impossible de démarrer la démo", voiceStart: "Enregistrer un message vocal", voiceStop: "Arrêter l'enregistrement", voiceTranscribing: "Transcription...", micDenied: "L'accès au microphone a été refusé.", transcribeFailed: "Échec de la transcription. Veuillez réessayer." }, qi = /* @__PURE__ */ JSON.parse(`{"pageTitle":"Premiers pas avec Lambda ERP","intro":"Lambda ERP est un système ERP nativement IA, où toutes les fonctionnalités – comme créer des commandes, vérifier l'inventaire ou enregistrer des paiements – sont accessibles via une interface de chat. Il guide, raisonne et vérifie toutes vos tâches quotidiennes.","openChat":"Ouvrir le chat IA","tipLabel":"Astuce :","topTip":"Le chat IA peut aussi vous donner des liens directs vers des documents et des PDF téléchargeables. Demandez-lui simplement de créer ou de rechercher un document et il inclura des liens cliquables dans sa réponse.","manualIntro":"Si vous souhaitez comprendre pleinement le fonctionnement interne, ou préférez procéder manuellement, voici un cycle commercial complet étape par étape.","caTitle":"Analyses dynamiques – discutez pour obtenir n'importe quel graphique","caBadge":"Fonctionnalité phare","caBody":"Besoin d'un rapport que les modèles prédéfinis ne fournissent pas ? Décrivez-le simplement dans le chat. L'assistant appelle un modèle spécialiste du code qui écrit le rapport pour vous, l'exécute en direct sur vos données ERP et renvoie un lien partageable. Le graphique ou le tableau s'affiche en quelques secondes et est enregistré comme brouillon sous « Analyses personnalisées » dans la barre latérale – vous pouvez le rouvrir, partager l'URL avec vos collègues ou demander à l'assistant de l'affiner.","caTryAsking":"Essayez de demander (cliquez pour préremplir dans le chat) :","caPrompt1":"Montre-moi les 10 meilleurs clients par chiffre d'affaires cette année en diagramme à barres","caPrompt2":"Tendance mensuelle des achats par fournisseur sur tous les mois, étiquette l'axe des x avec le nom du fournisseur","caPrompt3":"Articles les plus vendus par quantité, avec un tableau et un graphique","caPrompt4":"Quels clients me doivent le plus en ce moment ?","caTryInChat":"Essayer dans le chat","caOpenWorkspace":"Ouvrir l'espace d'analyse","flowTitle":"Aperçu du flux des documents","salesCycle":"Cycle de vente","purchaseCycle":"Cycle d'achat","returns":"Retours","flowShortcut":"Raccourci : le devis peut ignorer la commande client et aller directement à la facture de vente ou au bon de livraison","legendStock":"impact stock","legendGl":"impact comptable","legendCash":"impact trésorerie","legendReversal":"annulation","lifecycleTitle":"Cycle de vie du document","lcDraftLabel":"Brouillon :","lcDraftDesc":"Modifiable. Aucun impact financier ni sur le stock.","lcSubmittedLabel":"Validé :","lcSubmittedDesc":"Verrouillé. Les écritures comptables et de stock sont générées.","lcCancelledLabel":"Annulé :","lcCancelledDesc":"Toutes les écritures sont inversées. Le document est archivé définitivement.","lcNoDelete":"Il n'y a pas de suppression. Pour annuler un brouillon : validez-le, puis annulez-le.","lcCorrect":"Pour corriger un document validé : annulez-le et créez-en un nouveau.","readyTitle":"Vous êtes prêt","readyBody1":"Vous comprenez maintenant le cycle complet. Un scénario réel typique ressemble à ceci : vous recevez une commande client (Devis → Commande client), vérifiez le stock, achetez ce dont vous avez besoin (Bon de commande → Bon de réception → Facture d'achat → Paiement), livrez au client (Bon de livraison), facturez-le (Facture de vente) et encaissez le paiement (Paiement). Si quelque chose revient, créez un avoir et un retour de bon de livraison pour inverser les finances et le stock. La Balance comptable confirme que tout est équilibré.","readyBody2":"Vous pouvez aussi tout faire via le chat IA en conversation naturelle – décrivez simplement ce dont vous avez besoin et il créera les bons documents pour vous.","chips":{"Quotation":"Devis","Sales Order":"Commande client","Delivery Note":"Bon de livraison","Sales Invoice":"Facture de vente","Payment Entry":"Paiement","Purchase Order":"Bon de commande","Purchase Receipt":"Bon de réception","Purchase Invoice":"Facture d'achat","Credit Note":"Avoir","DN Return":"Retour BL","Debit Note":"Note de débit","Draft":"Brouillon","Submitted":"Validé","Cancelled":"Annulé"},"links":{"Go to Setup":"Aller à la configuration","Customers":"Clients","Suppliers":"Fournisseurs","Items":"Articles","Warehouses":"Entrepôts","New Quotation":"Nouveau devis","View Quotations":"Voir les devis","Stock Balance":"Solde de stock","New Purchase Order":"Nouveau bon de commande","Purchase Receipts":"Bons de réception","Purchase Invoices":"Factures d'achat","Delivery Notes":"Bons de livraison","Sales Invoices":"Factures de vente","New Payment Entry":"Nouveau paiement","New Stock Entry":"Nouveau mouvement de stock","New Journal Entry":"Nouvelle écriture de journal","Profit & Loss":"Compte de résultat","Balance Sheet":"Bilan","AR Aging":"Balance âgée clients","AP Aging":"Balance âgée fournisseurs","Trial Balance":"Balance comptable","General Ledger":"Grand livre","Open AI Chat":"Ouvrir le chat IA"},"steps":{"1":{"title":"Configurer votre société","description":"Créez une société avec une devise de base. Cela génère votre plan comptable (30 comptes standard répartis entre Actif, Passif, Capitaux propres, Produits et Charges) ainsi qu'un centre de coûts par défaut. Vous pouvez aussi charger des données de démonstration avec des clients, fournisseurs et articles d'exemple pour démarrer rapidement."},"2":{"title":"Créer les données de base","description":"Avant de pouvoir effectuer des transactions, vous avez besoin de fiches de base. Créez au moins un client, un fournisseur, un article (avec un prix standard) et un entrepôt. Si vous avez chargé les données de démonstration à l'étape 1, elles existent déjà.","tip":"Les articles ont un prix standard qui se remplit automatiquement lorsque vous les ajoutez à des documents. Vous pouvez toujours modifier le prix par transaction."},"3":{"title":"Créer un devis","description":"Un devis est une offre non contraignante adressée à un client. Sélectionnez un client, ajoutez des lignes avec quantités et prix, éventuellement des lignes de taxe, puis enregistrez. Les devis n'ont aucun impact financier – ils ne créent ni écritures comptables ni mouvements de stock. Définissez une date de validité pour que l'offre expire automatiquement."},"4":{"title":"Valider et convertir en commande client","description":"Ouvrez votre devis enregistré et cliquez sur Valider pour le confirmer. Cliquez ensuite sur « Créer une commande client » pour le convertir. La commande client représente un engagement confirmé du client. Elle n'a toujours aucun impact financier, mais réserve du stock à des fins de planification.","tip":"Seuls les documents validés peuvent être convertis à l'étape suivante. Brouillon → Valider → Convertir est le flux standard. Pour les affaires rapides, vous pouvez ignorer la commande client et passer directement du devis à la facture de vente ou au bon de livraison."},"5":{"title":"Vérifier le stock avant l'exécution","description":"Avant de pouvoir livrer, vérifiez si vous avez réellement l'article en stock. Ouvrez le rapport Solde de stock et recherchez l'article. Si votre entrepôt affiche une quantité nulle, vous devrez d'abord approvisionner le stock – soit par un bon de commande (achat auprès d'un fournisseur), soit par un mouvement de stock (réception manuelle).","tip":"C'est un scénario courant dans la pratique : vous vendez quelque chose, puis réalisez que vous devez d'abord l'acheter. L'ERP gère les deux flux."},"6":{"title":"Cycle d'achat : acheter du stock à un fournisseur","description":"Si vous devez acheter du stock, vous avez deux chemins valides. Le chemin standard est Bon de commande → Bon de réception → Facture d'achat : utilisez-le lorsque les marchandises arrivent avant ou séparément de la facture du fournisseur. Si la facture et la réception arrivent ensemble, vous pouvez créer directement la facture d'achat et activer « Mettre à jour le stock » afin que le même document réceptionne le stock et enregistre la dette fournisseur.","tip":"Utilisez d'abord le bon de réception lorsque vous recevez les marchandises séparément. Utilisez la facture d'achat avec « Mettre à jour le stock » lorsqu'une seule étape doit à la fois réceptionner le stock et comptabiliser la facture fournisseur. Dans ce chemin direct, indiquez un entrepôt sur chaque ligne d'article en stock."},"7":{"title":"Créer un bon de livraison","description":"Maintenant que vous avez du stock, revenez à votre commande client validée et cliquez sur « Créer un bon de livraison ». Indiquez l'entrepôt sur chaque ligne d'article (d'où partent les marchandises), puis validez. Cela sort le stock de l'entrepôt – votre solde de stock diminue.","tip":"Le bon de livraison est le document d'expédition. Il réduit le stock mais ne crée pas de facture. Vous pouvez livrer et facturer séparément."},"8":{"title":"Créer et valider la facture de vente","description":"À partir de la commande client validée, créez une facture de vente. Lorsque vous validez la facture, des écritures comptables sont générées : les Clients (créances) sont débités (le client vous doit de l'argent) et les Produits des ventes crédités (revenu acquis). Si des taxes sont configurées, la TVA collectée est également créditée. Le montant dû indique ce que le client doit encore."},"9":{"title":"Enregistrer les paiements clients","description":"Créez un paiement pour enregistrer l'argent reçu du client. Définissez le type de paiement sur « Receive » (Recevoir), sélectionnez le client, indiquez le montant et affectez-le à la facture de vente. Vous pouvez effectuer des paiements partiels – le montant dû de la facture se met à jour en conséquence. Créez des paiements supplémentaires jusqu'à ce que la facture soit entièrement réglée.","tip":"Les paiements partiels sont courants. Une facture de 10 000 peut être payée 3 000 maintenant et 7 000 plus tard. Chaque paiement réduit le montant dû."},"10":{"title":"Mouvements de stock (inventaire manuel)","description":"Utilisez les mouvements de stock pour les mouvements d'inventaire non liés aux achats ou aux ventes. « Material Receipt » ajoute du stock (soldes d'ouverture, ajustements). « Material Issue » sort du stock (pertes, consommation interne). « Material Transfer » déplace du stock entre entrepôts. Chaque mouvement met à jour le livre de stock avec une valorisation au coût moyen pondéré.","tip":"Pour les marchandises achetées, utilisez des bons de réception plutôt que des mouvements de stock – ils sont liés au bon de commande et offrent une piste d'audit appropriée."},"11":{"title":"Écritures de journal","description":"Les écritures de journal sont des ajustements comptables manuels – charges à payer, corrections, reclassements, soldes d'ouverture. Chaque écriture doit avoir des débits et crédits équilibrés (total débit = total crédit). Utilisez-les lorsqu'aucun autre type de document ne convient."},"12":{"title":"Paiements des salaires","description":"Lambda ERP gère les salaires à l'aide des outils comptables existants. Comptabilisez d'abord la charge salariale : créez une écriture de journal qui débite la Charge salariale et crédite les Salaires à payer pour le montant total de la paie. Payez ensuite les employés : créez une autre écriture de journal (ou un paiement) qui débite les Salaires à payer et crédite votre compte bancaire. Ce processus en deux étapes garde vos comptes exacts – la charge est enregistrée dans la bonne période et la sortie de trésorerie est suivie séparément.","tip":"Vous pouvez demander à l'assistant IA de le faire pour vous : « Comptabilise 15 000 de salaires pour avril » suivi de « Paie les salaires d'avril depuis la banque ». Il créera automatiquement les bonnes écritures de journal."},"13":{"title":"Retours et avoirs","description":"Lorsqu'un client retourne des marchandises ou que vous devez émettre un avoir, créez un retour. Les retours utilisent le même type de document avec des quantités négatives. Ouvrez une facture de vente validée et créez un avoir (retour de facture de vente) – cela inverse les écritures comptables et réduit le montant dû de la facture d'origine. Pour le stock, créez un retour de bon de livraison pour réintégrer les marchandises en entrepôt. Côté achats, créez une note de débit (retour de facture d'achat) pour inverser une facture fournisseur, ou un retour de bon de réception pour renvoyer des marchandises.","tip":"Un avoir est simplement une facture de vente avec is_return=1 et des quantités négatives. La même logique comptable s'applique – les montants négatifs basculent automatiquement du bon côté débit/crédit. Pour un retour de vente complet, vous avez besoin à la fois d'un avoir (financier) et d'un retour de bon de livraison (stock)."},"14":{"title":"Exécuter les rapports","description":"Vérifiez vos comptes. Le Compte de résultat montre les produits face aux charges et le résultat net d'une période. Le Bilan montre votre situation financière (actif = passif + capitaux propres). La Balance âgée clients montre qui vous doit de l'argent et le retard. La Balance âgée fournisseurs montre ce que vous devez aux fournisseurs. La Balance comptable vérifie l'intégrité de la partie double. Le Grand livre montre chaque écriture individuelle. Le Solde de stock montre l'inventaire actuel."},"15":{"title":"Travailler en devises étrangères","description":"Vos comptes sont tenus dans une seule devise de base (choisie à la configuration de la société), mais vous pouvez effectuer des transactions dans n'importe quelle devise. Définissez une devise sur une facture ou un effet – ou attribuez une devise par défaut à un client ou un fournisseur – et le taux de change de cette date est recherché automatiquement et enregistré sur le document. Le document conserve ses montants dans sa propre devise, tandis que le Grand livre comptabilise toujours dans votre devise de base. Lorsque vous encaissez ou payez ultérieurement à un taux différent, le gain ou la perte de change réalisé est comptabilisé automatiquement sur un compte Gain/Perte de change. Vous pouvez même détenir un solde bancaire en devise étrangère et le convertir plus tard au taux de votre banque – l'écart par rapport à sa valeur comptable est alors réalisé. En fin de mois, vous pouvez réévaluer les soldes en devises ouverts au taux de clôture (un gain/perte latent qui s'inverse à la période suivante), et vous pouvez consulter n'importe quel état financier converti dans une autre devise pour l'affichage.","tip":"Le plus simple est de passer par le chat IA – essayez « Crée une facture de vente pour Lumiere Audio en EUR », « Montre-moi le bilan en EUR » ou « Quelle est notre exposition de change latente en fin de mois ? ». Les données de démonstration incluent déjà un client EUR (Lumiere Audio SARL) dont la facture a été encaissée à un taux différent, ainsi qu'une facture fournisseur EUR ouverte – ouvrez le Grand livre pour voir les écritures de change réalisées."}}}`), Fi = { title: "Aide au formatage", intro: "Le texte des Notes / Conditions prend en charge une mise en forme légère sur le PDF :", heading: "titre en gras", emphasis: "italique / gras", price: "prix aligné à droite à côté du texte ci-dessus (p. ex. Mensuel | CHF 380.—)", block: "Séparez les blocs par une ligne vide." }, Mi = {
|
|
6698
|
+
}, vi = { save: "Enregistrer", saving: "Enregistrement...", submit: "Valider", cancel: "Annuler", cancelDoc: "Annuler", cancelDocAbort: "Ne pas annuler", cancelDocConfirmBtn: "Annuler définitivement", discardDraft: "Supprimer le brouillon", keepDraft: "Conserver", discardDraftConfirm: "Supprimer", showDiscarded: "Afficher les supprimés", delete: "Supprimer", edit: "Modifier", pdf: "PDF", addRow: "Ajouter une ligne", loading: "Chargement...", enable: "Activer", disable: "Désactiver", refresh: "Actualiser", refreshing: "Actualisation", areYouSure: "Êtes-vous sûr ?", all: "Tous", apply: "Appliquer", new: "Nouveau", prev: "Précédent", next: "Suivant", perPage: "Par page", page: "Page", of: "sur", showing: "Affichage", total: "Total", totals: "Totaux", errorOccurred: "Une erreur s'est produite" }, Ni = { title: "Langue", help: "Choisissez la langue de l'interface. Votre choix est enregistré dans ce navigateur.", label: "Langue" }, wi = { logout: "Déconnexion", openMenu: "Ouvrir le menu", closeMenu: "Fermer le menu", new: "Nouveau : {{label}}" }, ki = { dashboard: "Tableau de bord", setup: "Configuration de l'entreprise", tutorial: "Premiers pas", chat: "Chat", reports: "Rapports", "trial-balance": "Balance comptable", "general-ledger": "Grand livre", "stock-balance": "Solde de stock", "profit-and-loss": "Compte de résultat", "balance-sheet": "Bilan", "ar-aging": "Balance âgée clients", "ap-aging": "Balance âgée fournisseurs", analytics: "Analyses" }, Si = { quotation: { one: "Devis", other: "Devis" }, proposal: { one: "Offre groupée", other: "Offres groupées" }, "sales-order": { one: "Commande client", other: "Commandes client" }, "sales-invoice": { one: "Facture de vente", other: "Factures de vente" }, "pos-invoice": { one: "Ticket de caisse", other: "Tickets de caisse" }, "purchase-order": { one: "Bon de commande", other: "Bons de commande" }, "purchase-invoice": { one: "Facture d'achat", other: "Factures d'achat" }, "payment-entry": { one: "Paiement", other: "Paiements" }, "journal-entry": { one: "Écriture comptable", other: "Écritures comptables" }, "bank-transaction": { one: "Transaction bancaire", other: "Transactions bancaires" }, budget: { one: "Budget", other: "Budgets" }, subscription: { one: "Abonnement", other: "Abonnements" }, "stock-entry": { one: "Mouvement de stock", other: "Mouvements de stock" }, "delivery-note": { one: "Bon de livraison", other: "Bons de livraison" }, "purchase-receipt": { one: "Bon de réception", other: "Bons de réception" }, "pricing-rule": { one: "Règle de prix", other: "Règles de prix" } }, Ci = { company: { one: "Société", other: "Sociétés" }, customer: { one: "Client", other: "Clients" }, supplier: { one: "Fournisseur", other: "Fournisseurs" }, item: { one: "Article", other: "Articles" }, warehouse: { one: "Entrepôt", other: "Entrepôts" } }, Di = { chats: "Discussions", newChat: "Nouvelle discussion", deleteChat: "Supprimer la discussion", customAnalytics: "Analyses personnalisées", newAnalytics: "Nouvelle analyse", deleteReport: "Supprimer le rapport", groups: { Introduction: "Introduction", Selling: "Ventes", Buying: "Achats", Accounting: "Comptabilité", Stock: "Stock", Reports: "Rapports", Masters: "Données de base", Settings: "Paramètres" }, items: { "Getting Started": "Premiers pas", "Company Setup": "Configuration de l'entreprise", "Opening Balances": "Soldes d'ouverture", Quotation: "Devis", Proposal: "Offre groupée", "Sales Order": "Commande client", "Sales Invoice": "Facture de vente", "POS Invoice": "Ticket de caisse", "Purchase Order": "Bon de commande", "Purchase Invoice": "Facture d'achat", "Payment Entry": "Paiement", "Journal Entry": "Écriture comptable", "Bank Transaction": "Transaction bancaire", Budget: "Budget", Subscription: "Abonnement", "Stock Entry": "Mouvement de stock", "Delivery Note": "Bon de livraison", "Purchase Receipt": "Bon de réception", "Trial Balance": "Balance comptable", "Profit & Loss": "Compte de résultat", "Balance Sheet": "Bilan", "General Ledger": "Grand livre", "AR Aging": "Balance âgée clients", "AP Aging": "Balance âgée fournisseurs", Analytics: "Analyses", "Stock Balance": "Solde de stock", Company: "Société", Customer: "Client", Supplier: "Fournisseur", Item: "Article", Warehouse: "Entrepôt", General: "Général", "Pricing Rule": "Règle de prix", "Users & Team": "Utilisateurs et équipe" } }, _i = { taglineFirstRun: "Créez votre compte administrateur pour commencer", taglineRegister: "Créez votre compte", taglineSignIn: "Connectez-vous à votre compte", demoBanner: "Le mode démo est actif. Connectez-vous avec un compte administrateur pour gérer les paramètres ou désactiver l'accès public.", fullName: "Nom complet", email: "E-mail", password: "Mot de passe", confirmPassword: "Confirmer le mot de passe", createAdmin: "Créer un compte administrateur", register: "S'inscrire", signIn: "Se connecter", browsingTitle: "Simple visite ?", browsingBody: "Démarrez une nouvelle session de chat et regardez la démo en direct.", enterDemo: "Lancer la démo", haveInvite: "Vous avez une invitation ?", noAccountPrompt: "Besoin d'un compte ?", registerLink: "S'inscrire", alreadyHaveAccount: "Vous avez déjà un compte ?", signInLink: "Se connecter", passwordsNoMatch: "Les mots de passe ne correspondent pas", passwordTooShort: "Le mot de passe doit comporter au moins 6 caractères", registrationFailed: "Échec de l'inscription", loginFailed: "Échec de la connexion" }, Pi = { pdfTitle: "PDF et impression", pageSize: "Format de page", pdfHelp: "A4 est la norme internationale (210 x 297 mm). Letter est la norme aux États-Unis (8,5 x 11 po).", passwordTitle: "Changer le mot de passe", currentPassword: "Mot de passe actuel", newPassword: "Nouveau mot de passe", confirmNewPassword: "Confirmer le nouveau mot de passe", changePassword: "Changer le mot de passe", changingPassword: "Modification...", passwordChanged: "Mot de passe modifié.", openingTitle: "Soldes d'ouverture", openingBody: "La page Soldes d'ouverture permet d'importer les soldes des comptes, le stock et les factures impayées d'un système précédent.", openingEnabled: "Actuellement activé — accessible sous Introduction > Soldes d'ouverture.", openingDisabled: "Actuellement désactivé — la page est masquée dans la barre latérale.", signupTitle: "Inscription publique", signupBody: "Permettre à quiconque de créer son propre compte (en tant que lecteur) sans invitation. Lorsque désactivé, les nouveaux utilisateurs ne peuvent rejoindre que via un lien d'invitation.", signupEnabled: "Actuellement activé — toute personne disposant de l'URL peut s'inscrire en tant que lecteur.", signupDisabled: "Actuellement désactivé — l'inscription se fait uniquement sur invitation.", publicTitle: "Accès public (mode démo)", publicActive: "Actif", publicActiveBody: "L'accès public est activé. N'importe qui peut utiliser l'application sans se connecter. Tous les visiteurs obtiennent des autorisations de niveau gestionnaire.", disablePublic: "Désactiver l'accès public", disabling: "Désactivation...", publicInactiveBody: "Activez l'accès public pour permettre à quiconque d'utiliser l'application sans compte. Utile pour les démos et présentations. Tous les visiteurs obtiennent des autorisations de niveau gestionnaire et partagent la même identité.", enablePublic: "Activer l'accès public", enableWarning: "Cela permettra à quiconque d'accéder à l'application sans se connecter. Ils pourront créer, modifier et valider des documents. Votre compte administrateur nécessite toujours une connexion.", yesEnable: "Oui, activer", enabling: "Activation...", tokenSpendTitle: "Dépenses de jetons" }, Ti = { Draft: "Brouillon", Open: "Ouvert", Submitted: "Validé", "To Deliver and Bill": "À livrer et facturer", "To Deliver": "À livrer", "To Bill": "À facturer", Completed: "Terminé", Ordered: "Commandé", Paid: "Payé", Unpaid: "Impayé", Cancelled: "Annulé", Discarded: "Supprimé", Overdue: "En retard", Return: "Retour", Closed: "Clôturé" }, Ai = { balanced: "ÉQUILIBRÉ", imbalanced: "DÉSÉQUILIBRÉ", income: "Produits", expenses: "Charges", totalIncome: "Total des produits", totalExpenses: "Total des charges", netProfit: "Bénéfice", netLoss: "Perte", assets: "Actif", liabilities: "Passif", equity: "Capitaux propres", totalAssets: "Total de l'actif", totalLiabilities: "Total du passif", totalEquity: "Total des capitaux propres", totalLiabilitiesEquity: "Total passif + capitaux propres", current: "Non échu", noData: "Aucune donnée trouvée", noEntries: "Aucune écriture trouvée", noStockData: "Aucune donnée de stock trouvée", noReceivables: "Aucune créance en cours", noPayables: "Aucune dette en cours", noDocuments: "Aucun document trouvé" }, Ri = { required: "Requis : {{fields}}", deleteConfirm: "Supprimer ce {{label}} ?", disabledNotice: "Ce {{label}} est désactivé. Il reste dans le système car d'autres enregistrements y font référence.", disabledOnDelete: "{{label}} {{name}} a été désactivé au lieu d'être supprimé car il est référencé par {{reason}}." }, Ii = { Account: "Compte", Amount: "Montant", Balance: "Solde", Credit: "Crédit", Debit: "Débit", Date: "Date", Party: "Tiers", "Party Type": "Type de tiers", "Voucher Type": "Type de pièce", "Voucher No": "N° de pièce", Invoice: "Facture", Customer: "Client", Supplier: "Fournisseur", "Due Date": "Date d'échéance", Outstanding: "Encours", "Outstanding Amount": "Montant dû", "Item Code": "Code article", "Item Name": "Nom de l'article", Item: "Article", Warehouse: "Entrepôt", Qty: "Qté", "Valuation Rate": "Coût unitaire", "Stock Value": "Valeur du stock", Name: "Nom", Status: "Statut", Company: "Société", "From Date": "Date de début", "To Date": "Date de fin", "As of Date": "À la date", "Valid Till": "Valable jusqu'au", "Net Total": "Total net", Tax: "Taxe", "Grand Total": "Total TTC", Frequency: "Fréquence", "Notes / Terms": "Notes / Conditions", "Posting Date": "Date de comptabilisation", "Transaction Date": "Date de transaction", "Delivery Date": "Date de livraison", "% Delivered": "% livré", "% Billed": "% facturé", "Update Stock": "Mettre à jour le stock", "Payment Type": "Type de paiement", "Paid From": "Payé depuis", "Paid To": "Payé à", "Paid Amount": "Montant payé", Type: "Type", Total: "Total", Allocated: "Affecté", Unallocated: "Non affecté", Remark: "Remarque", "Total Debit": "Total débit", "Total Credit": "Total crédit", "Cost Center": "Centre de coûts", "Source Warehouse": "Entrepôt source", "Target Warehouse": "Entrepôt cible", Source: "Source", Target: "Cible", "Incoming Value": "Valeur entrante", "Outgoing Value": "Valeur sortante", Rate: "Prix unitaire", "Income Account": "Compte de produits", "Expense Account": "Compte de charges", Description: "Description", "Rate (%)": "Taux (%)", Mode: "Mode", Change: "Monnaie rendue", Currency: "Devise", Title: "Titre", Selling: "Vente", Buying: "Achat", "Discount %": "Remise %", "Discount Amt": "Montant remise", "Min Qty": "Qté min", "Valid From": "Valable à partir du", "Valid Upto": "Valable jusqu'au", Priority: "Priorité", Enabled: "Activé", "Fiscal Year": "Exercice", "Budget Amount": "Montant du budget", "If Exceeded": "Si dépassé", Month: "Mois", "Bank Account": "Compte bancaire", Deposit: "Dépôt", Withdrawal: "Retrait", "Reference No": "N° de référence", "Matched Type": "Type rapproché", "Matched Doc": "Pièce rapprochée", "Start Date": "Date de début", "End Date": "Date de fin", "Billing Interval": "Intervalle de facturation", "Current Period Start": "Début période actuelle", "Current Period End": "Fin période actuelle", "Plan Items": "Articles du plan", "Total Amount": "Montant total", "Stock Entry Type": "Type de mouvement de stock", "Rate Or Discount": "Prix ou remise", "Discount Percentage": "Pourcentage de remise", ID: "ID", "Customer Name": "Nom du client", "Customer Group": "Groupe de clients", Territory: "Territoire", "Credit Limit": "Limite de crédit", Email: "E-mail", Phone: "Téléphone", Address: "Adresse", City: "Ville", "Zip Code": "Code postal", Country: "Pays", "Tax ID": "N° de TVA", "Contact Person": "Personne de contact", "Contact Email": "E-mail du contact", "Contact Phone": "Téléphone du contact", "Supplier Name": "Nom du fournisseur", "Supplier Group": "Groupe de fournisseurs", "Item Group": "Groupe d'articles", "Stock UOM": "Unité de stock", "Standard Rate": "Prix standard", "Warehouse Name": "Nom de l'entrepôt", "Company Name": "Nom de la société" }, Li = { items: "Lignes", taxes: "Taxes", references: "Références de paiement", accounts: "Écritures de compte", payments: "Paiements", plans: "Articles du plan", monthly_distribution: "Répartition mensuelle" }, Bi = { "Create Sales Order": "Créer une commande client", "Create Sales Invoice": "Créer une facture de vente", "Create Delivery Note": "Créer un bon de livraison", "Create Purchase Invoice": "Créer une facture d'achat", "Create Purchase Receipt": "Créer un bon de réception", "Create Credit Note": "Créer un avoir", "Create Debit Note": "Créer une note de débit", "Create Return": "Créer un retour" }, Ei = { totalRevenue: "Chiffre d'affaires total", outstandingReceivable: "Créances en cours", outstandingPayable: "Dettes en cours", totalStockValue: "Valeur totale du stock", recentDocuments: "Documents récents", noRecentDocuments: "Aucun document récent" }, Oi = { title: "Chat Lambda ERP", subtitle: "Demandez-moi de créer des documents, de consulter des données ou d'exécuter des rapports.", s1: "Quels clients avons-nous ?", s2: "Affiche la balance comptable", s3: "Crée un devis pour 10 Bolt Pack M8", s4: "Liste toutes les factures impayées", loadOlder: "Charger les messages plus anciens", uploading: "Téléversement...", failed: "Échec", remove: "Supprimer", placeholderDemo: "Démo en direct en cours...", placeholderType: "Tapez un message...", placeholderConnecting: "Connexion...", attachTitle: "Joindre un fichier (PDF ou image, max 10 Mo)", creating: "Création du chat...", dropToAttach: "Déposez un fichier à joindre (images ou PDF, max 10 Mo chacun)", demoError: "Impossible de démarrer la démo", voiceStart: "Enregistrer un message vocal", voiceStop: "Arrêter l'enregistrement", voiceTranscribing: "Transcription...", micDenied: "L'accès au microphone a été refusé.", transcribeFailed: "Échec de la transcription. Veuillez réessayer." }, qi = /* @__PURE__ */ JSON.parse(`{"pageTitle":"Premiers pas avec Lambda ERP","intro":"Lambda ERP est un système ERP nativement IA, où toutes les fonctionnalités – comme créer des commandes, vérifier l'inventaire ou enregistrer des paiements – sont accessibles via une interface de chat. Il guide, raisonne et vérifie toutes vos tâches quotidiennes.","openChat":"Ouvrir le chat IA","tipLabel":"Astuce :","topTip":"Le chat IA peut aussi vous donner des liens directs vers des documents et des PDF téléchargeables. Demandez-lui simplement de créer ou de rechercher un document et il inclura des liens cliquables dans sa réponse.","manualIntro":"Si vous souhaitez comprendre pleinement le fonctionnement interne, ou préférez procéder manuellement, voici un cycle commercial complet étape par étape.","caTitle":"Analyses dynamiques – discutez pour obtenir n'importe quel graphique","caBadge":"Fonctionnalité phare","caBody":"Besoin d'un rapport que les modèles prédéfinis ne fournissent pas ? Décrivez-le simplement dans le chat. L'assistant appelle un modèle spécialiste du code qui écrit le rapport pour vous, l'exécute en direct sur vos données ERP et renvoie un lien partageable. Le graphique ou le tableau s'affiche en quelques secondes et est enregistré comme brouillon sous « Analyses personnalisées » dans la barre latérale – vous pouvez le rouvrir, partager l'URL avec vos collègues ou demander à l'assistant de l'affiner.","caTryAsking":"Essayez de demander (cliquez pour préremplir dans le chat) :","caPrompt1":"Montre-moi les 10 meilleurs clients par chiffre d'affaires cette année en diagramme à barres","caPrompt2":"Tendance mensuelle des achats par fournisseur sur tous les mois, étiquette l'axe des x avec le nom du fournisseur","caPrompt3":"Articles les plus vendus par quantité, avec un tableau et un graphique","caPrompt4":"Quels clients me doivent le plus en ce moment ?","caTryInChat":"Essayer dans le chat","caOpenWorkspace":"Ouvrir l'espace d'analyse","flowTitle":"Aperçu du flux des documents","salesCycle":"Cycle de vente","purchaseCycle":"Cycle d'achat","returns":"Retours","flowShortcut":"Raccourci : le devis peut ignorer la commande client et aller directement à la facture de vente ou au bon de livraison","legendStock":"impact stock","legendGl":"impact comptable","legendCash":"impact trésorerie","legendReversal":"annulation","lifecycleTitle":"Cycle de vie du document","lcDraftLabel":"Brouillon :","lcDraftDesc":"Modifiable. Aucun impact financier ni sur le stock.","lcSubmittedLabel":"Validé :","lcSubmittedDesc":"Verrouillé. Les écritures comptables et de stock sont générées.","lcCancelledLabel":"Annulé :","lcCancelledDesc":"Toutes les écritures sont inversées. Le document est archivé définitivement.","lcNoDelete":"Il n'y a pas de suppression. Pour annuler un brouillon : validez-le, puis annulez-le.","lcCorrect":"Pour corriger un document validé : annulez-le et créez-en un nouveau.","readyTitle":"Vous êtes prêt","readyBody1":"Vous comprenez maintenant le cycle complet. Un scénario réel typique ressemble à ceci : vous recevez une commande client (Devis → Commande client), vérifiez le stock, achetez ce dont vous avez besoin (Bon de commande → Bon de réception → Facture d'achat → Paiement), livrez au client (Bon de livraison), facturez-le (Facture de vente) et encaissez le paiement (Paiement). Si quelque chose revient, créez un avoir et un retour de bon de livraison pour inverser les finances et le stock. La Balance comptable confirme que tout est équilibré.","readyBody2":"Vous pouvez aussi tout faire via le chat IA en conversation naturelle – décrivez simplement ce dont vous avez besoin et il créera les bons documents pour vous.","chips":{"Quotation":"Devis","Sales Order":"Commande client","Delivery Note":"Bon de livraison","Sales Invoice":"Facture de vente","Payment Entry":"Paiement","Purchase Order":"Bon de commande","Purchase Receipt":"Bon de réception","Purchase Invoice":"Facture d'achat","Credit Note":"Avoir","DN Return":"Retour BL","Debit Note":"Note de débit","Draft":"Brouillon","Submitted":"Validé","Cancelled":"Annulé"},"links":{"Go to Setup":"Aller à la configuration","Customers":"Clients","Suppliers":"Fournisseurs","Items":"Articles","Warehouses":"Entrepôts","New Quotation":"Nouveau devis","View Quotations":"Voir les devis","Stock Balance":"Solde de stock","New Purchase Order":"Nouveau bon de commande","Purchase Receipts":"Bons de réception","Purchase Invoices":"Factures d'achat","Delivery Notes":"Bons de livraison","Sales Invoices":"Factures de vente","New Payment Entry":"Nouveau paiement","New Stock Entry":"Nouveau mouvement de stock","New Journal Entry":"Nouvelle écriture de journal","Profit & Loss":"Compte de résultat","Balance Sheet":"Bilan","AR Aging":"Balance âgée clients","AP Aging":"Balance âgée fournisseurs","Trial Balance":"Balance comptable","General Ledger":"Grand livre","Open AI Chat":"Ouvrir le chat IA"},"steps":{"1":{"title":"Configurer votre société","description":"Créez une société avec une devise de base. Cela génère votre plan comptable (30 comptes standard répartis entre Actif, Passif, Capitaux propres, Produits et Charges) ainsi qu'un centre de coûts par défaut. Vous pouvez aussi charger des données de démonstration avec des clients, fournisseurs et articles d'exemple pour démarrer rapidement."},"2":{"title":"Créer les données de base","description":"Avant de pouvoir effectuer des transactions, vous avez besoin de fiches de base. Créez au moins un client, un fournisseur, un article (avec un prix standard) et un entrepôt. Si vous avez chargé les données de démonstration à l'étape 1, elles existent déjà.","tip":"Les articles ont un prix standard qui se remplit automatiquement lorsque vous les ajoutez à des documents. Vous pouvez toujours modifier le prix par transaction."},"3":{"title":"Créer un devis","description":"Un devis est une offre non contraignante adressée à un client. Sélectionnez un client, ajoutez des lignes avec quantités et prix, éventuellement des lignes de taxe, puis enregistrez. Les devis n'ont aucun impact financier – ils ne créent ni écritures comptables ni mouvements de stock. Définissez une date de validité pour que l'offre expire automatiquement."},"4":{"title":"Valider et convertir en commande client","description":"Ouvrez votre devis enregistré et cliquez sur Valider pour le confirmer. Cliquez ensuite sur « Créer une commande client » pour le convertir. La commande client représente un engagement confirmé du client. Elle n'a toujours aucun impact financier, mais réserve du stock à des fins de planification.","tip":"Seuls les documents validés peuvent être convertis à l'étape suivante. Brouillon → Valider → Convertir est le flux standard. Pour les affaires rapides, vous pouvez ignorer la commande client et passer directement du devis à la facture de vente ou au bon de livraison."},"5":{"title":"Vérifier le stock avant l'exécution","description":"Avant de pouvoir livrer, vérifiez si vous avez réellement l'article en stock. Ouvrez le rapport Solde de stock et recherchez l'article. Si votre entrepôt affiche une quantité nulle, vous devrez d'abord approvisionner le stock – soit par un bon de commande (achat auprès d'un fournisseur), soit par un mouvement de stock (réception manuelle).","tip":"C'est un scénario courant dans la pratique : vous vendez quelque chose, puis réalisez que vous devez d'abord l'acheter. L'ERP gère les deux flux."},"6":{"title":"Cycle d'achat : acheter du stock à un fournisseur","description":"Si vous devez acheter du stock, vous avez deux chemins valides. Le chemin standard est Bon de commande → Bon de réception → Facture d'achat : utilisez-le lorsque les marchandises arrivent avant ou séparément de la facture du fournisseur. Si la facture et la réception arrivent ensemble, vous pouvez créer directement la facture d'achat et activer « Mettre à jour le stock » afin que le même document réceptionne le stock et enregistre la dette fournisseur.","tip":"Utilisez d'abord le bon de réception lorsque vous recevez les marchandises séparément. Utilisez la facture d'achat avec « Mettre à jour le stock » lorsqu'une seule étape doit à la fois réceptionner le stock et comptabiliser la facture fournisseur. Dans ce chemin direct, indiquez un entrepôt sur chaque ligne d'article en stock."},"7":{"title":"Créer un bon de livraison","description":"Maintenant que vous avez du stock, revenez à votre commande client validée et cliquez sur « Créer un bon de livraison ». Indiquez l'entrepôt sur chaque ligne d'article (d'où partent les marchandises), puis validez. Cela sort le stock de l'entrepôt – votre solde de stock diminue.","tip":"Le bon de livraison est le document d'expédition. Il réduit le stock mais ne crée pas de facture. Vous pouvez livrer et facturer séparément."},"8":{"title":"Créer et valider la facture de vente","description":"À partir de la commande client validée, créez une facture de vente. Lorsque vous validez la facture, des écritures comptables sont générées : les Clients (créances) sont débités (le client vous doit de l'argent) et les Produits des ventes crédités (revenu acquis). Si des taxes sont configurées, la TVA collectée est également créditée. Le montant dû indique ce que le client doit encore."},"9":{"title":"Enregistrer les paiements clients","description":"Créez un paiement pour enregistrer l'argent reçu du client. Définissez le type de paiement sur « Receive » (Recevoir), sélectionnez le client, indiquez le montant et affectez-le à la facture de vente. Vous pouvez effectuer des paiements partiels – le montant dû de la facture se met à jour en conséquence. Créez des paiements supplémentaires jusqu'à ce que la facture soit entièrement réglée.","tip":"Les paiements partiels sont courants. Une facture de 10 000 peut être payée 3 000 maintenant et 7 000 plus tard. Chaque paiement réduit le montant dû."},"10":{"title":"Mouvements de stock (inventaire manuel)","description":"Utilisez les mouvements de stock pour les mouvements d'inventaire non liés aux achats ou aux ventes. « Material Receipt » ajoute du stock (soldes d'ouverture, ajustements). « Material Issue » sort du stock (pertes, consommation interne). « Material Transfer » déplace du stock entre entrepôts. Chaque mouvement met à jour le livre de stock avec une valorisation au coût moyen pondéré.","tip":"Pour les marchandises achetées, utilisez des bons de réception plutôt que des mouvements de stock – ils sont liés au bon de commande et offrent une piste d'audit appropriée."},"11":{"title":"Écritures de journal","description":"Les écritures de journal sont des ajustements comptables manuels – charges à payer, corrections, reclassements, soldes d'ouverture. Chaque écriture doit avoir des débits et crédits équilibrés (total débit = total crédit). Utilisez-les lorsqu'aucun autre type de document ne convient."},"12":{"title":"Paiements des salaires","description":"Lambda ERP gère les salaires à l'aide des outils comptables existants. Comptabilisez d'abord la charge salariale : créez une écriture de journal qui débite la Charge salariale et crédite les Salaires à payer pour le montant total de la paie. Payez ensuite les employés : créez une autre écriture de journal (ou un paiement) qui débite les Salaires à payer et crédite votre compte bancaire. Ce processus en deux étapes garde vos comptes exacts – la charge est enregistrée dans la bonne période et la sortie de trésorerie est suivie séparément.","tip":"Vous pouvez demander à l'assistant IA de le faire pour vous : « Comptabilise 15 000 de salaires pour avril » suivi de « Paie les salaires d'avril depuis la banque ». Il créera automatiquement les bonnes écritures de journal."},"13":{"title":"Retours et avoirs","description":"Lorsqu'un client retourne des marchandises ou que vous devez émettre un avoir, créez un retour. Les retours utilisent le même type de document avec des quantités négatives. Ouvrez une facture de vente validée et créez un avoir (retour de facture de vente) – cela inverse les écritures comptables et réduit le montant dû de la facture d'origine. Pour le stock, créez un retour de bon de livraison pour réintégrer les marchandises en entrepôt. Côté achats, créez une note de débit (retour de facture d'achat) pour inverser une facture fournisseur, ou un retour de bon de réception pour renvoyer des marchandises.","tip":"Un avoir est simplement une facture de vente avec is_return=1 et des quantités négatives. La même logique comptable s'applique – les montants négatifs basculent automatiquement du bon côté débit/crédit. Pour un retour de vente complet, vous avez besoin à la fois d'un avoir (financier) et d'un retour de bon de livraison (stock)."},"14":{"title":"Exécuter les rapports","description":"Vérifiez vos comptes. Le Compte de résultat montre les produits face aux charges et le résultat net d'une période. Le Bilan montre votre situation financière (actif = passif + capitaux propres). La Balance âgée clients montre qui vous doit de l'argent et le retard. La Balance âgée fournisseurs montre ce que vous devez aux fournisseurs. La Balance comptable vérifie l'intégrité de la partie double. Le Grand livre montre chaque écriture individuelle. Le Solde de stock montre l'inventaire actuel."},"15":{"title":"Travailler en devises étrangères","description":"Vos comptes sont tenus dans une seule devise de base (choisie à la configuration de la société), mais vous pouvez effectuer des transactions dans n'importe quelle devise. Définissez une devise sur une facture ou un effet – ou attribuez une devise par défaut à un client ou un fournisseur – et le taux de change de cette date est recherché automatiquement et enregistré sur le document. Le document conserve ses montants dans sa propre devise, tandis que le Grand livre comptabilise toujours dans votre devise de base. Lorsque vous encaissez ou payez ultérieurement à un taux différent, le gain ou la perte de change réalisé est comptabilisé automatiquement sur un compte Gain/Perte de change. Vous pouvez même détenir un solde bancaire en devise étrangère et le convertir plus tard au taux de votre banque – l'écart par rapport à sa valeur comptable est alors réalisé. En fin de mois, vous pouvez réévaluer les soldes en devises ouverts au taux de clôture (un gain/perte latent qui s'inverse à la période suivante), et vous pouvez consulter n'importe quel état financier converti dans une autre devise pour l'affichage.","tip":"Le plus simple est de passer par le chat IA – essayez « Crée une facture de vente pour Lumiere Audio en EUR », « Montre-moi le bilan en EUR » ou « Quelle est notre exposition de change latente en fin de mois ? ». Les données de démonstration incluent déjà un client EUR (Lumiere Audio SARL) dont la facture a été encaissée à un taux différent, ainsi qu'une facture fournisseur EUR ouverte – ouvrez le Grand livre pour voir les écritures de change réalisées."}}}`), Fi = { title: "Aide au formatage", intro: "Le texte des Notes / Conditions prend en charge une mise en forme légère sur le PDF :", heading: "titre en gras", emphasis: "italique / gras", rule: "ligne de séparation horizontale", price: "prix aligné à droite à côté du texte ci-dessus (p. ex. Mensuel | CHF 380.—)", block: "Séparez les blocs par une ligne vide." }, Mi = {
|
|
6676
6699
|
common: vi,
|
|
6677
6700
|
language: Ni,
|
|
6678
6701
|
header: wi,
|
|
@@ -6692,17 +6715,17 @@ const Bs = { save: "Save", saving: "Saving...", submit: "Submit", cancel: "Cance
|
|
|
6692
6715
|
chat: Oi,
|
|
6693
6716
|
tutorial: qi,
|
|
6694
6717
|
notesMarkup: Fi
|
|
6695
|
-
},
|
|
6718
|
+
}, da = [
|
|
6696
6719
|
{ code: "en", label: "English" },
|
|
6697
6720
|
{ code: "de", label: "Deutsch" },
|
|
6698
6721
|
{ code: "fr", label: "Français" }
|
|
6699
|
-
],
|
|
6722
|
+
], ua = "lambda-erp:language";
|
|
6700
6723
|
function zi(t) {
|
|
6701
|
-
return !!t &&
|
|
6724
|
+
return !!t && da.some((n) => n.code === t);
|
|
6702
6725
|
}
|
|
6703
6726
|
function $i() {
|
|
6704
6727
|
try {
|
|
6705
|
-
const t = localStorage.getItem(
|
|
6728
|
+
const t = localStorage.getItem(ua);
|
|
6706
6729
|
if (zi(t)) return t;
|
|
6707
6730
|
} catch {
|
|
6708
6731
|
}
|
|
@@ -6710,11 +6733,11 @@ function $i() {
|
|
|
6710
6733
|
}
|
|
6711
6734
|
function Ui(t) {
|
|
6712
6735
|
try {
|
|
6713
|
-
localStorage.setItem(
|
|
6736
|
+
localStorage.setItem(ua, t);
|
|
6714
6737
|
} catch {
|
|
6715
6738
|
}
|
|
6716
6739
|
}
|
|
6717
|
-
|
|
6740
|
+
Yn.use(Da).init({
|
|
6718
6741
|
resources: {
|
|
6719
6742
|
en: { translation: Xs },
|
|
6720
6743
|
de: { translation: xi },
|
|
@@ -6728,7 +6751,7 @@ Jn.use(Ca).init({
|
|
|
6728
6751
|
react: { useSuspense: !1 }
|
|
6729
6752
|
// resources are bundled synchronously — no Suspense needed
|
|
6730
6753
|
});
|
|
6731
|
-
|
|
6754
|
+
Yn.on("languageChanged", Ui);
|
|
6732
6755
|
function Vi({ label: t }) {
|
|
6733
6756
|
var o;
|
|
6734
6757
|
const { t: n, i18n: a } = ae(), s = ((o = a.language) == null ? void 0 : o.split("-")[0]) ?? "en";
|
|
@@ -6736,7 +6759,7 @@ function Vi({ label: t }) {
|
|
|
6736
6759
|
rt,
|
|
6737
6760
|
{
|
|
6738
6761
|
label: t === null ? void 0 : t ?? n("language.label"),
|
|
6739
|
-
options:
|
|
6762
|
+
options: da.map((i) => ({ value: i.code, label: i.label })),
|
|
6740
6763
|
value: s,
|
|
6741
6764
|
onChange: (i) => a.changeLanguage(i.target.value)
|
|
6742
6765
|
}
|
|
@@ -6755,12 +6778,12 @@ function je(t) {
|
|
|
6755
6778
|
}
|
|
6756
6779
|
function ji({ demoActive: t }) {
|
|
6757
6780
|
var D, T;
|
|
6758
|
-
const { t: n } = ae(), [a, s] = v("1h"), { data: o, isLoading: i, isFetching: c, error: l, refetch:
|
|
6781
|
+
const { t: n } = ae(), [a, s] = v("1h"), { data: o, isLoading: i, isFetching: c, error: l, refetch: y, dataUpdatedAt: d } = le({
|
|
6759
6782
|
queryKey: ["demo-spend"],
|
|
6760
6783
|
queryFn: () => L.getDemoSpend(),
|
|
6761
6784
|
// Refresh once a minute — demo spend changes slowly; no need to poll harder.
|
|
6762
6785
|
refetchInterval: 6e4
|
|
6763
|
-
}), p = Fn.find((u) => u.value === a), m = (D = o == null ? void 0 : o.windows) == null ? void 0 : D[a], f = ((T = o == null ? void 0 : o.caps) == null ? void 0 : T.global_hourly_usd) ?? 0,
|
|
6786
|
+
}), p = Fn.find((u) => u.value === a), m = (D = o == null ? void 0 : o.windows) == null ? void 0 : D[a], f = ((T = o == null ? void 0 : o.caps) == null ? void 0 : T.global_hourly_usd) ?? 0, w = m ? m.demo_usd / p.hours : 0, b = m ? m.total_usd / p.hours : 0, g = f > 0 ? Math.min(100, w / f * 100) : 0, P = g >= 90 ? "bg-red-500" : g >= 60 ? "bg-amber-500" : "bg-emerald-500";
|
|
6764
6787
|
return /* @__PURE__ */ r(U, { title: n("settings.tokenSpendTitle"), children: [
|
|
6765
6788
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end justify-between gap-4", children: [
|
|
6766
6789
|
/* @__PURE__ */ r("div", { className: "max-w-lg text-sm text-gray-600", children: [
|
|
@@ -6788,7 +6811,7 @@ function ji({ demoActive: t }) {
|
|
|
6788
6811
|
"button",
|
|
6789
6812
|
{
|
|
6790
6813
|
type: "button",
|
|
6791
|
-
onClick: () =>
|
|
6814
|
+
onClick: () => y(),
|
|
6792
6815
|
disabled: c,
|
|
6793
6816
|
title: d ? `Last updated ${new Date(d).toLocaleTimeString()}` : "Refresh now",
|
|
6794
6817
|
className: "inline-flex h-[38px] items-center gap-1.5 rounded-md border border-gray-300 bg-white px-3 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-60",
|
|
@@ -6833,7 +6856,7 @@ function ji({ demoActive: t }) {
|
|
|
6833
6856
|
")"
|
|
6834
6857
|
] }),
|
|
6835
6858
|
/* @__PURE__ */ r("div", { className: "mt-1 text-2xl font-semibold text-gray-900", children: [
|
|
6836
|
-
je(
|
|
6859
|
+
je(w),
|
|
6837
6860
|
/* @__PURE__ */ r("span", { className: "ml-2 text-sm font-normal text-gray-500", children: [
|
|
6838
6861
|
"/ ",
|
|
6839
6862
|
je(f),
|
|
@@ -6847,17 +6870,17 @@ function ji({ demoActive: t }) {
|
|
|
6847
6870
|
je(m.total_usd),
|
|
6848
6871
|
/* @__PURE__ */ r("span", { className: "ml-1 text-xs font-normal text-gray-500", children: [
|
|
6849
6872
|
"(",
|
|
6850
|
-
je(
|
|
6873
|
+
je(b),
|
|
6851
6874
|
"/hr)"
|
|
6852
6875
|
] })
|
|
6853
6876
|
] })
|
|
6854
6877
|
] })
|
|
6855
6878
|
] }),
|
|
6856
|
-
/* @__PURE__ */ e("div", { className: "mt-2 h-2 w-full overflow-hidden rounded-full bg-gray-100", children: /* @__PURE__ */ e("div", { className: `h-full ${P} transition-all`, style: { width: `${
|
|
6879
|
+
/* @__PURE__ */ e("div", { className: "mt-2 h-2 w-full overflow-hidden rounded-full bg-gray-100", children: /* @__PURE__ */ e("div", { className: `h-full ${P} transition-all`, style: { width: `${g}%` } }) }),
|
|
6857
6880
|
/* @__PURE__ */ r("div", { className: "mt-1 text-xs text-gray-400", children: [
|
|
6858
|
-
|
|
6881
|
+
g.toFixed(0),
|
|
6859
6882
|
"% of the hourly cap",
|
|
6860
|
-
|
|
6883
|
+
g >= 100 && " — demo visitors are currently blocked"
|
|
6861
6884
|
] })
|
|
6862
6885
|
] })
|
|
6863
6886
|
) : (
|
|
@@ -6869,7 +6892,7 @@ function ji({ demoActive: t }) {
|
|
|
6869
6892
|
")"
|
|
6870
6893
|
] }),
|
|
6871
6894
|
/* @__PURE__ */ r("div", { className: "mt-1 text-2xl font-semibold text-gray-900", children: [
|
|
6872
|
-
je(
|
|
6895
|
+
je(b),
|
|
6873
6896
|
/* @__PURE__ */ r("span", { className: "ml-2 text-sm font-normal text-gray-500", children: [
|
|
6874
6897
|
"(",
|
|
6875
6898
|
je(m.total_usd),
|
|
@@ -6938,14 +6961,14 @@ function St({ label: t, value: n }) {
|
|
|
6938
6961
|
] });
|
|
6939
6962
|
}
|
|
6940
6963
|
function Gi() {
|
|
6941
|
-
const { t } = ae(), { user: n } = bt(), [a, s] = v(""), [o, i] = v(""), [c, l] = v(""), [
|
|
6964
|
+
const { t } = ae(), { user: n } = bt(), [a, s] = v(""), [o, i] = v(""), [c, l] = v(""), [y, d] = v(""), [p, m] = v(!1), f = oe({
|
|
6942
6965
|
mutationFn: () => L.authChangePassword(a, o),
|
|
6943
6966
|
onSuccess: () => {
|
|
6944
6967
|
m(!0), d(""), s(""), i(""), l(""), setTimeout(() => m(!1), 4e3);
|
|
6945
6968
|
},
|
|
6946
|
-
onError: (
|
|
6947
|
-
}),
|
|
6948
|
-
if (
|
|
6969
|
+
onError: (b) => d(b instanceof Ge ? b.message : t("login.registrationFailed"))
|
|
6970
|
+
}), w = (b) => {
|
|
6971
|
+
if (b.preventDefault(), d(""), m(!1), o !== c) {
|
|
6949
6972
|
d(t("login.passwordsNoMatch"));
|
|
6950
6973
|
return;
|
|
6951
6974
|
}
|
|
@@ -6955,7 +6978,7 @@ function Gi() {
|
|
|
6955
6978
|
}
|
|
6956
6979
|
f.mutate();
|
|
6957
6980
|
};
|
|
6958
|
-
return /* @__PURE__ */ e(U, { title: t("settings.passwordTitle"), children: /* @__PURE__ */ r("form", { onSubmit:
|
|
6981
|
+
return /* @__PURE__ */ e(U, { title: t("settings.passwordTitle"), children: /* @__PURE__ */ r("form", { onSubmit: w, className: "max-w-sm space-y-3", children: [
|
|
6959
6982
|
/* @__PURE__ */ e(
|
|
6960
6983
|
"input",
|
|
6961
6984
|
{
|
|
@@ -6971,7 +6994,7 @@ function Gi() {
|
|
|
6971
6994
|
}
|
|
6972
6995
|
),
|
|
6973
6996
|
/* @__PURE__ */ e(
|
|
6974
|
-
|
|
6997
|
+
ee,
|
|
6975
6998
|
{
|
|
6976
6999
|
label: t("settings.currentPassword"),
|
|
6977
7000
|
id: "current-password",
|
|
@@ -6979,12 +7002,12 @@ function Gi() {
|
|
|
6979
7002
|
type: "password",
|
|
6980
7003
|
autoComplete: "current-password",
|
|
6981
7004
|
value: a,
|
|
6982
|
-
onChange: (
|
|
7005
|
+
onChange: (b) => s(b.target.value),
|
|
6983
7006
|
required: !0
|
|
6984
7007
|
}
|
|
6985
7008
|
),
|
|
6986
7009
|
/* @__PURE__ */ e(
|
|
6987
|
-
|
|
7010
|
+
ee,
|
|
6988
7011
|
{
|
|
6989
7012
|
label: t("settings.newPassword"),
|
|
6990
7013
|
id: "new-password",
|
|
@@ -6992,12 +7015,12 @@ function Gi() {
|
|
|
6992
7015
|
type: "password",
|
|
6993
7016
|
autoComplete: "new-password",
|
|
6994
7017
|
value: o,
|
|
6995
|
-
onChange: (
|
|
7018
|
+
onChange: (b) => i(b.target.value),
|
|
6996
7019
|
required: !0
|
|
6997
7020
|
}
|
|
6998
7021
|
),
|
|
6999
7022
|
/* @__PURE__ */ e(
|
|
7000
|
-
|
|
7023
|
+
ee,
|
|
7001
7024
|
{
|
|
7002
7025
|
label: t("settings.confirmNewPassword"),
|
|
7003
7026
|
id: "confirm-password",
|
|
@@ -7005,11 +7028,11 @@ function Gi() {
|
|
|
7005
7028
|
type: "password",
|
|
7006
7029
|
autoComplete: "new-password",
|
|
7007
7030
|
value: c,
|
|
7008
|
-
onChange: (
|
|
7031
|
+
onChange: (b) => l(b.target.value),
|
|
7009
7032
|
required: !0
|
|
7010
7033
|
}
|
|
7011
7034
|
),
|
|
7012
|
-
|
|
7035
|
+
y && /* @__PURE__ */ e("p", { className: "text-sm text-red-600", children: y }),
|
|
7013
7036
|
p && /* @__PURE__ */ e("p", { className: "text-sm text-green-700", children: t("settings.passwordChanged") }),
|
|
7014
7037
|
/* @__PURE__ */ e(J, { type: "submit", disabled: f.isPending || !a || !o || !c, children: f.isPending ? t("settings.changingPassword") : t("settings.changePassword") })
|
|
7015
7038
|
] }) });
|
|
@@ -7024,7 +7047,7 @@ function Ki() {
|
|
|
7024
7047
|
}), { data: l } = le({
|
|
7025
7048
|
queryKey: ["public-manager"],
|
|
7026
7049
|
queryFn: () => L.getPublicManagerStatus()
|
|
7027
|
-
}), [
|
|
7050
|
+
}), [y, d] = v(!1), p = oe({
|
|
7028
7051
|
mutationFn: () => L.createPublicManager(),
|
|
7029
7052
|
onSuccess: () => {
|
|
7030
7053
|
a.invalidateQueries({ queryKey: ["public-manager"] }), d(!1);
|
|
@@ -7104,7 +7127,7 @@ function Ki() {
|
|
|
7104
7127
|
)
|
|
7105
7128
|
] }) : /* @__PURE__ */ r("div", { children: [
|
|
7106
7129
|
/* @__PURE__ */ e("p", { className: "text-sm text-gray-600", children: n("settings.publicInactiveBody") }),
|
|
7107
|
-
|
|
7130
|
+
y ? /* @__PURE__ */ r("div", { className: "mt-3 rounded-lg border border-red-200 bg-red-50 p-4", children: [
|
|
7108
7131
|
/* @__PURE__ */ e("p", { className: "text-sm font-medium text-red-800", children: n("common.areYouSure") }),
|
|
7109
7132
|
/* @__PURE__ */ e("p", { className: "mt-1 text-xs text-red-600", children: n("settings.enableWarning") }),
|
|
7110
7133
|
/* @__PURE__ */ r("div", { className: "mt-3 flex gap-2", children: [
|
|
@@ -7137,12 +7160,12 @@ function Ki() {
|
|
|
7137
7160
|
] }) })
|
|
7138
7161
|
] });
|
|
7139
7162
|
}
|
|
7140
|
-
const
|
|
7163
|
+
const ma = {};
|
|
7141
7164
|
function fo(t, n) {
|
|
7142
|
-
|
|
7165
|
+
ma[t] = n;
|
|
7143
7166
|
}
|
|
7144
7167
|
function Wi(t, n) {
|
|
7145
|
-
return
|
|
7168
|
+
return ma[t] ?? n;
|
|
7146
7169
|
}
|
|
7147
7170
|
function Hi() {
|
|
7148
7171
|
const t = Wi("Dashboard", hr);
|
|
@@ -7183,9 +7206,9 @@ const Qi = [
|
|
|
7183
7206
|
// Admin
|
|
7184
7207
|
{ path: "admin/users", element: /* @__PURE__ */ e(Ls, {}) },
|
|
7185
7208
|
{ path: "admin/settings", element: /* @__PURE__ */ e(Ki, {}) }
|
|
7186
|
-
],
|
|
7209
|
+
], pa = [], ha = [];
|
|
7187
7210
|
function bo(t, n) {
|
|
7188
|
-
(n == null ? void 0 : n.area) === "top" ?
|
|
7211
|
+
(n == null ? void 0 : n.area) === "top" ? pa.push(t) : ha.push(t);
|
|
7189
7212
|
}
|
|
7190
7213
|
const Mn = (t) => t.index ? "__index__" : t.path ?? "";
|
|
7191
7214
|
function zn(t, n) {
|
|
@@ -7198,16 +7221,16 @@ function zn(t, n) {
|
|
|
7198
7221
|
}
|
|
7199
7222
|
function Yi() {
|
|
7200
7223
|
return [
|
|
7201
|
-
...zn(Qi,
|
|
7224
|
+
...zn(Qi, pa),
|
|
7202
7225
|
{
|
|
7203
7226
|
path: "/",
|
|
7204
7227
|
element: /* @__PURE__ */ e(lr, { children: /* @__PURE__ */ e(ir, {}) }),
|
|
7205
|
-
children: zn(Ji,
|
|
7228
|
+
children: zn(Ji, ha)
|
|
7206
7229
|
}
|
|
7207
7230
|
];
|
|
7208
7231
|
}
|
|
7209
7232
|
function Zi() {
|
|
7210
|
-
return new
|
|
7233
|
+
return new Na({
|
|
7211
7234
|
defaultOptions: {
|
|
7212
7235
|
queries: { retry: 1, refetchOnWindowFocus: !1 }
|
|
7213
7236
|
}
|
|
@@ -7217,16 +7240,16 @@ function xo(t = {}) {
|
|
|
7217
7240
|
const n = t.rootElement ?? document.getElementById("root");
|
|
7218
7241
|
if (!n)
|
|
7219
7242
|
throw new Error('bootstrap: no mount element (pass rootElement or add <div id="root">)');
|
|
7220
|
-
const a = t.queryClient ?? Zi(), s =
|
|
7221
|
-
|
|
7222
|
-
/* @__PURE__ */ e(
|
|
7243
|
+
const a = t.queryClient ?? Zi(), s = Sa(Yi());
|
|
7244
|
+
xa(n).render(
|
|
7245
|
+
/* @__PURE__ */ e(ba, { children: /* @__PURE__ */ e(va, { client: a, children: /* @__PURE__ */ e(Ha, { children: /* @__PURE__ */ e(Ca, { router: s }) }) }) })
|
|
7223
7246
|
);
|
|
7224
7247
|
}
|
|
7225
7248
|
export {
|
|
7226
7249
|
Ge as ApiError,
|
|
7227
7250
|
ir as AppShell,
|
|
7228
7251
|
Ha as AuthProvider,
|
|
7229
|
-
|
|
7252
|
+
da as SUPPORTED_LANGUAGES,
|
|
7230
7253
|
L as api,
|
|
7231
7254
|
xo as bootstrap,
|
|
7232
7255
|
Yi as buildRoutes,
|
|
@@ -7236,7 +7259,7 @@ export {
|
|
|
7236
7259
|
yo as getAllDoctypeConfigs,
|
|
7237
7260
|
Xa as getBranding,
|
|
7238
7261
|
Wi as getComponent,
|
|
7239
|
-
|
|
7262
|
+
ra as getDoctypeConfig,
|
|
7240
7263
|
Za as getNavGroups,
|
|
7241
7264
|
$i as getStoredLanguage,
|
|
7242
7265
|
wo as i18n,
|