@lambda-development/erp-core 0.1.23 → 0.1.25
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/index.js +666 -649
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as e, jsxs as r, Fragment as Se } from "react/jsx-runtime";
|
|
2
|
-
import { useState as N, useEffect as se, useCallback as Pe, useContext as Mn, createContext as $n, useRef as
|
|
2
|
+
import { useState as N, useEffect as se, useCallback as Pe, useContext as Mn, createContext as $n, useRef as ee, useMemo as Re, useLayoutEffect as cn, StrictMode as ya } from "react";
|
|
3
3
|
import { createRoot as fa } from "react-dom/client";
|
|
4
|
-
import { useQueryClient as
|
|
4
|
+
import { useQueryClient as Ke, useQuery as le, useMutation as oe, QueryClientProvider as ba, QueryClient as xa } from "@tanstack/react-query";
|
|
5
5
|
import { NavLink as Bt, useLocation as Ct, useNavigate as Ee, Outlet as va, Navigate as Na, Link as ve, useSearchParams as Et, useParams as ft, createBrowserRouter as wa, RouterProvider as ka } from "react-router-dom";
|
|
6
|
-
import { useTranslation as
|
|
6
|
+
import { useTranslation as ne, initReactI18next as Sa } from "react-i18next";
|
|
7
7
|
import { BookOpen as Ca, ShoppingCart as Un, CreditCard as Da, FileText as Zt, Package as Vn, BarChart3 as _a, Database as Pa, Settings as Ta, MessageCircle as Aa, ChevronDown as Xt, ChevronRight as en, Plus as jn, Trash2 as Gn, LineChart as Ra, TrendingUp as Ia, ArrowDownRight as La, ArrowUpRight as Ba, Wallet as Ea, Receipt as dn } from "lucide-react";
|
|
8
|
-
import { createColumnHelper as
|
|
8
|
+
import { createColumnHelper as Kn, useReactTable as Wn, getCoreRowModel as Qn, flexRender as At } from "@tanstack/react-table";
|
|
9
9
|
import { createPortal as Oa } from "react-dom";
|
|
10
10
|
import { ResponsiveContainer as qa, LineChart as Fa, CartesianGrid as un, XAxis as mn, YAxis as pn, Tooltip as zt, Line as za, PieChart as Ma, Pie as $a, Cell as Ua, BarChart as Va, Bar as ja } from "recharts";
|
|
11
11
|
import Hn from "i18next";
|
|
@@ -203,7 +203,7 @@ const L = {
|
|
|
203
203
|
updateSettings: (t) => O("/auth/settings", { method: "PUT", body: JSON.stringify(t) }),
|
|
204
204
|
getDemoSpend: () => O("/admin/demo-spend")
|
|
205
205
|
}, Jn = $n(null);
|
|
206
|
-
function
|
|
206
|
+
function Ka({ children: t }) {
|
|
207
207
|
const [n, a] = N(null), [s, o] = N(!0);
|
|
208
208
|
se(() => {
|
|
209
209
|
L.authMe().then((g) => a(g)).catch(() => a(null)).finally(() => o(!1));
|
|
@@ -254,7 +254,7 @@ const Yn = $n(null), hn = {
|
|
|
254
254
|
function Mt(t) {
|
|
255
255
|
return typeof t != "string" ? null : t.trim().toLowerCase().replace(/\s+/g, "-");
|
|
256
256
|
}
|
|
257
|
-
function
|
|
257
|
+
function Wa(t, n) {
|
|
258
258
|
if (t === "create_custom_analytics_report" || t === "update_custom_analytics_report")
|
|
259
259
|
return { group: "Custom Analytics", item: "" };
|
|
260
260
|
if (!n) return null;
|
|
@@ -313,70 +313,70 @@ function et(t) {
|
|
|
313
313
|
return Number.isNaN(a) ? 0 : a;
|
|
314
314
|
}
|
|
315
315
|
function Ha({ children: t }) {
|
|
316
|
-
const n =
|
|
317
|
-
function
|
|
318
|
-
for (const
|
|
319
|
-
|
|
316
|
+
const n = Ke(), [a, s] = N([]), [o, i] = N({}), [c, l] = N({}), [g, d] = N({}), [p, m] = N({}), [f, S] = N({}), [x, y] = N({}), [P, D] = N({}), [T, u] = N(null), [h, A] = N("connecting"), [R, k] = N(0), H = ee(null), $ = ee(null), M = ee(/* @__PURE__ */ new Map()), w = ee(null), K = ee({}), v = ee({}), B = ee(null);
|
|
317
|
+
function C(_) {
|
|
318
|
+
for (const V of M.current.values())
|
|
319
|
+
V.reject(new Error(_));
|
|
320
320
|
M.current.clear();
|
|
321
321
|
}
|
|
322
|
-
function
|
|
323
|
-
i((
|
|
324
|
-
...
|
|
325
|
-
[_]:
|
|
322
|
+
function F(_, V) {
|
|
323
|
+
i((W) => ({
|
|
324
|
+
...W,
|
|
325
|
+
[_]: V(W[_] ?? [])
|
|
326
326
|
}));
|
|
327
327
|
}
|
|
328
|
-
function
|
|
329
|
-
S((
|
|
328
|
+
function Z(_, V) {
|
|
329
|
+
S((W) => ({ ...W, [_]: V }));
|
|
330
330
|
}
|
|
331
|
-
function
|
|
332
|
-
y((
|
|
331
|
+
function ae(_, V) {
|
|
332
|
+
y((W) => ({ ...W, [_]: V }));
|
|
333
333
|
}
|
|
334
|
-
function he(_,
|
|
335
|
-
|
|
334
|
+
function he(_, V) {
|
|
335
|
+
D((W) => ({ ...W, [_]: V }));
|
|
336
336
|
}
|
|
337
|
-
function ye(_,
|
|
338
|
-
|
|
339
|
-
u((
|
|
337
|
+
function ye(_, V) {
|
|
338
|
+
B.current !== null && window.clearTimeout(B.current), u({ group: _, item: V, key: Date.now() }), B.current = window.setTimeout(() => {
|
|
339
|
+
u((W) => (W == null ? void 0 : W.group) === _ && (W == null ? void 0 : W.item) === V ? null : W), B.current = null;
|
|
340
340
|
}, 1100);
|
|
341
341
|
}
|
|
342
342
|
function Ce(_) {
|
|
343
|
-
return [..._].sort((
|
|
344
|
-
const fe = et(
|
|
345
|
-
return (et(
|
|
343
|
+
return [..._].sort((V, W) => {
|
|
344
|
+
const fe = et(K.current[V.id]) || et(V.last_message_at || void 0) || et(V.created_at);
|
|
345
|
+
return (et(K.current[W.id]) || et(W.last_message_at || void 0) || et(W.created_at)) - fe;
|
|
346
346
|
});
|
|
347
347
|
}
|
|
348
348
|
function me(_) {
|
|
349
|
-
s((
|
|
349
|
+
s((V) => Ce(_(V)));
|
|
350
350
|
}
|
|
351
|
-
function I(_,
|
|
352
|
-
const
|
|
353
|
-
et(
|
|
354
|
-
...
|
|
355
|
-
[_]:
|
|
351
|
+
function I(_, V) {
|
|
352
|
+
const W = V || (/* @__PURE__ */ new Date()).toISOString(), fe = K.current[_];
|
|
353
|
+
et(W) >= et(fe) && (K.current = {
|
|
354
|
+
...K.current,
|
|
355
|
+
[_]: W
|
|
356
356
|
});
|
|
357
357
|
}
|
|
358
358
|
function ie(_) {
|
|
359
|
-
const
|
|
360
|
-
for (const
|
|
361
|
-
|
|
362
|
-
|
|
359
|
+
const V = { ...K.current };
|
|
360
|
+
for (const W of _)
|
|
361
|
+
W.last_message_at && !V[W.id] && (V[W.id] = W.last_message_at);
|
|
362
|
+
K.current = V;
|
|
363
363
|
}
|
|
364
364
|
function Te(_) {
|
|
365
|
-
const
|
|
366
|
-
if (!
|
|
365
|
+
const V = H.current;
|
|
366
|
+
if (!V || V.readyState !== WebSocket.OPEN)
|
|
367
367
|
throw new Error("Chat is disconnected.");
|
|
368
|
-
|
|
368
|
+
V.send(JSON.stringify(_));
|
|
369
369
|
}
|
|
370
|
-
function Ne(_,
|
|
370
|
+
function Ne(_, V, W) {
|
|
371
371
|
return new Promise((fe, be) => {
|
|
372
372
|
const De = Qa();
|
|
373
373
|
M.current.set(De, {
|
|
374
|
-
expectedType:
|
|
374
|
+
expectedType: W,
|
|
375
375
|
resolve: fe,
|
|
376
376
|
reject: be
|
|
377
377
|
});
|
|
378
378
|
try {
|
|
379
|
-
Te({ type: _, request_id: De, ...
|
|
379
|
+
Te({ type: _, request_id: De, ...V });
|
|
380
380
|
} catch (it) {
|
|
381
381
|
M.current.delete(De), be(it instanceof Error ? it : new Error("Chat request failed."));
|
|
382
382
|
}
|
|
@@ -384,7 +384,7 @@ function Ha({ children: t }) {
|
|
|
384
384
|
}
|
|
385
385
|
se(() => {
|
|
386
386
|
let _ = !1;
|
|
387
|
-
function
|
|
387
|
+
function V() {
|
|
388
388
|
if (_) return;
|
|
389
389
|
A("connecting");
|
|
390
390
|
const fe = `${window.location.protocol === "https:" ? "wss:" : "ws:"}//${window.location.host}/ws/chat`, be = new WebSocket(fe);
|
|
@@ -397,19 +397,19 @@ function Ha({ children: t }) {
|
|
|
397
397
|
}, be.onmessage = (De) => {
|
|
398
398
|
var it;
|
|
399
399
|
try {
|
|
400
|
-
const
|
|
400
|
+
const j = JSON.parse(De.data), Ye = typeof j.request_id == "string" ? j.request_id : null, ue = typeof j.type == "string" ? j.type : null, E = typeof j.session_id == "string" ? j.session_id : null;
|
|
401
401
|
if (Ye) {
|
|
402
402
|
const q = M.current.get(Ye);
|
|
403
|
-
q && (ue === "error" ? (M.current.delete(Ye), q.reject(new Error(String(
|
|
403
|
+
q && (ue === "error" ? (M.current.delete(Ye), q.reject(new Error(String(j.content || "Request failed.")))) : ue === q.expectedType && (M.current.delete(Ye), q.resolve(j)));
|
|
404
404
|
}
|
|
405
405
|
if (ue === "sessions_list") {
|
|
406
|
-
const q = Array.isArray(
|
|
406
|
+
const q = Array.isArray(j.sessions) ? j.sessions : [];
|
|
407
407
|
ie(q), s(
|
|
408
408
|
Ce(
|
|
409
409
|
q
|
|
410
410
|
)
|
|
411
411
|
);
|
|
412
|
-
const
|
|
412
|
+
const G = new Set(q.map((xe) => xe.id)), Be = [...tn()].filter((xe) => !G.has(xe));
|
|
413
413
|
Be.length > 0 && Promise.all(
|
|
414
414
|
Be.map(async (xe) => {
|
|
415
415
|
try {
|
|
@@ -429,42 +429,42 @@ function Ha({ children: t }) {
|
|
|
429
429
|
return;
|
|
430
430
|
}
|
|
431
431
|
if (ue === "session_created") {
|
|
432
|
-
const q =
|
|
432
|
+
const q = j.session;
|
|
433
433
|
if (!q) return;
|
|
434
|
-
ea(q.id), ie([q]), me((
|
|
434
|
+
ea(q.id), ie([q]), me((G) => [q, ...G.filter((Q) => Q.id !== q.id)]);
|
|
435
435
|
return;
|
|
436
436
|
}
|
|
437
437
|
if (ue === "session_deleted" && E) {
|
|
438
|
-
fn(E), me((
|
|
439
|
-
const Q = { ...
|
|
438
|
+
fn(E), me((G) => G.filter((Q) => Q.id !== E)), i((G) => {
|
|
439
|
+
const Q = { ...G };
|
|
440
440
|
return delete Q[E], Q;
|
|
441
|
-
}), S((
|
|
442
|
-
const Q = { ...
|
|
441
|
+
}), S((G) => {
|
|
442
|
+
const Q = { ...G };
|
|
443
443
|
return delete Q[E], Q;
|
|
444
|
-
}), y((
|
|
445
|
-
const Q = { ...
|
|
444
|
+
}), y((G) => {
|
|
445
|
+
const Q = { ...G };
|
|
446
446
|
return delete Q[E], Q;
|
|
447
|
-
}),
|
|
448
|
-
const Q = { ...
|
|
447
|
+
}), D((G) => {
|
|
448
|
+
const Q = { ...G };
|
|
449
449
|
return delete Q[E], Q;
|
|
450
|
-
}), l((
|
|
451
|
-
const Q = { ...
|
|
450
|
+
}), l((G) => {
|
|
451
|
+
const Q = { ...G };
|
|
452
452
|
return delete Q[E], Q;
|
|
453
|
-
}), d((
|
|
454
|
-
const Q = { ...
|
|
453
|
+
}), d((G) => {
|
|
454
|
+
const Q = { ...G };
|
|
455
455
|
return delete Q[E], Q;
|
|
456
|
-
}), m((
|
|
457
|
-
const Q = { ...
|
|
456
|
+
}), m((G) => {
|
|
457
|
+
const Q = { ...G };
|
|
458
458
|
return delete Q[E], Q;
|
|
459
459
|
});
|
|
460
|
-
const q = { ...
|
|
461
|
-
delete q[E],
|
|
460
|
+
const q = { ...K.current };
|
|
461
|
+
delete q[E], K.current = q;
|
|
462
462
|
return;
|
|
463
463
|
}
|
|
464
464
|
if (ue === "history_loaded" && E) {
|
|
465
|
-
const q = Array.isArray(
|
|
465
|
+
const q = Array.isArray(j.messages) ? j.messages.map(yn) : [], G = j.before_id != null, Q = !!j.has_more, Be = typeof j.oldest_id == "number" ? j.oldest_id : null;
|
|
466
466
|
i((re) => {
|
|
467
|
-
if (
|
|
467
|
+
if (G) {
|
|
468
468
|
const de = re[E] ?? [], pt = new Set(
|
|
469
469
|
de.map((Ze) => Ze.id).filter((Ze) => typeof Ze == "number")
|
|
470
470
|
), vt = q.filter(
|
|
@@ -474,77 +474,77 @@ function Ha({ children: t }) {
|
|
|
474
474
|
}
|
|
475
475
|
return { ...re, [E]: q };
|
|
476
476
|
}), l((re) => ({ ...re, [E]: Q })), d((re) => ({ ...re, [E]: Be })), m((re) => ({ ...re, [E]: !1 }));
|
|
477
|
-
const xe = typeof
|
|
477
|
+
const xe = typeof j.title == "string" ? j.title : null;
|
|
478
478
|
if (xe && me(
|
|
479
479
|
(re) => re.map((de) => de.id === E ? { ...de, title: xe } : de)
|
|
480
|
-
), !
|
|
480
|
+
), !G) {
|
|
481
481
|
const re = q[q.length - 1];
|
|
482
482
|
re != null && re.timestamp && (I(E, re.timestamp), me((de) => de));
|
|
483
483
|
}
|
|
484
484
|
return;
|
|
485
485
|
}
|
|
486
486
|
if (ue === "history_cleared" && E) {
|
|
487
|
-
i((q) => ({ ...q, [E]: [] })), l((q) => ({ ...q, [E]: !1 })), d((q) => ({ ...q, [E]: null })), m((q) => ({ ...q, [E]: !1 })),
|
|
487
|
+
i((q) => ({ ...q, [E]: [] })), l((q) => ({ ...q, [E]: !1 })), d((q) => ({ ...q, [E]: null })), m((q) => ({ ...q, [E]: !1 })), Z(E, !1), ae(E, "idle"), he(E, null);
|
|
488
488
|
return;
|
|
489
489
|
}
|
|
490
490
|
if (ue === "message_added" && E) {
|
|
491
|
-
const q =
|
|
491
|
+
const q = j.message;
|
|
492
492
|
if (!q) return;
|
|
493
|
-
I(E, q.created_at), q.role === "user" && he(E, null),
|
|
494
|
-
...
|
|
493
|
+
I(E, q.created_at), q.role === "user" && he(E, null), F(E, (G) => [
|
|
494
|
+
...G.filter((Q) => Q.type !== "thinking"),
|
|
495
495
|
yn(q)
|
|
496
|
-
]), me((
|
|
496
|
+
]), me((G) => G);
|
|
497
497
|
return;
|
|
498
498
|
}
|
|
499
499
|
if (ue === "demo_started" && E) {
|
|
500
|
-
|
|
500
|
+
ae(E, "running"), he(E, null);
|
|
501
501
|
return;
|
|
502
502
|
}
|
|
503
503
|
if (ue === "demo_typing" && E) {
|
|
504
|
-
|
|
505
|
-
content: String(
|
|
506
|
-
seq: Math.max(0, Number(
|
|
507
|
-
typingMs: Math.max(0, Number(
|
|
504
|
+
ae(E, "running"), he(E, {
|
|
505
|
+
content: String(j.content || ""),
|
|
506
|
+
seq: Math.max(0, Number(j.seq || 0)),
|
|
507
|
+
typingMs: Math.max(0, Number(j.typing_ms || 0))
|
|
508
508
|
});
|
|
509
509
|
return;
|
|
510
510
|
}
|
|
511
511
|
if (ue === "demo_replay_complete" && E) {
|
|
512
|
-
|
|
512
|
+
ae(E, "complete"), he(E, null);
|
|
513
513
|
return;
|
|
514
514
|
}
|
|
515
515
|
if (ue === "navigation_flash") {
|
|
516
|
-
const q = typeof
|
|
517
|
-
q && ye(q,
|
|
516
|
+
const q = typeof j.group == "string" ? j.group : "", G = typeof j.item == "string" ? j.item : void 0;
|
|
517
|
+
q && ye(q, G);
|
|
518
518
|
return;
|
|
519
519
|
}
|
|
520
520
|
if (ue === "session_title_updated" && E) {
|
|
521
|
-
const q = typeof
|
|
521
|
+
const q = typeof j.title == "string" ? j.title : "";
|
|
522
522
|
me(
|
|
523
|
-
(
|
|
523
|
+
(G) => G.map((Q) => Q.id === E ? { ...Q, title: q } : Q)
|
|
524
524
|
);
|
|
525
525
|
return;
|
|
526
526
|
}
|
|
527
527
|
if (ue === "thinking" && E) {
|
|
528
|
-
|
|
529
|
-
const
|
|
528
|
+
Z(E, !0), F(E, (q) => {
|
|
529
|
+
const G = q.find((Q) => Q.type === "thinking");
|
|
530
530
|
return [
|
|
531
531
|
...q.filter((Q) => Q.type !== "thinking"),
|
|
532
532
|
{
|
|
533
533
|
type: "thinking",
|
|
534
|
-
content: `Thinking (step ${
|
|
535
|
-
provider:
|
|
536
|
-
model:
|
|
534
|
+
content: `Thinking (step ${j.iteration})...`,
|
|
535
|
+
provider: G == null ? void 0 : G.provider,
|
|
536
|
+
model: G == null ? void 0 : G.model
|
|
537
537
|
}
|
|
538
538
|
];
|
|
539
539
|
});
|
|
540
540
|
return;
|
|
541
541
|
}
|
|
542
542
|
if (ue === "llm_provider" && E) {
|
|
543
|
-
const q = typeof
|
|
544
|
-
|
|
543
|
+
const q = typeof j.provider == "string" ? j.provider : void 0, G = typeof j.model == "string" ? j.model : void 0, Be = (typeof j.role == "string" ? j.role : void 0) === "code_specialist" ? "Delegating to code specialist..." : void 0;
|
|
544
|
+
Z(E, !0), F(E, (xe) => xe.some((de) => de.type === "thinking") ? xe.map((de) => de.type === "thinking" ? {
|
|
545
545
|
...de,
|
|
546
546
|
provider: q,
|
|
547
|
-
model:
|
|
547
|
+
model: G,
|
|
548
548
|
...Be ? { content: Be } : {}
|
|
549
549
|
} : de) : [
|
|
550
550
|
...xe,
|
|
@@ -552,63 +552,63 @@ function Ha({ children: t }) {
|
|
|
552
552
|
type: "thinking",
|
|
553
553
|
content: Be ?? "Thinking...",
|
|
554
554
|
provider: q,
|
|
555
|
-
model:
|
|
555
|
+
model: G
|
|
556
556
|
}
|
|
557
557
|
]);
|
|
558
558
|
return;
|
|
559
559
|
}
|
|
560
560
|
if (ue === "tool_call" && E) {
|
|
561
|
-
|
|
562
|
-
...
|
|
561
|
+
v.current = {
|
|
562
|
+
...v.current,
|
|
563
563
|
[E]: {
|
|
564
|
-
tool: String(
|
|
565
|
-
args:
|
|
564
|
+
tool: String(j.tool || ""),
|
|
565
|
+
args: j.args
|
|
566
566
|
}
|
|
567
|
-
},
|
|
568
|
-
...q.filter((
|
|
567
|
+
}, F(E, (q) => [
|
|
568
|
+
...q.filter((G) => G.type !== "thinking"),
|
|
569
569
|
{
|
|
570
570
|
type: "tool_call",
|
|
571
|
-
content: `Calling ${
|
|
572
|
-
tool:
|
|
573
|
-
args:
|
|
571
|
+
content: `Calling ${j.tool}...`,
|
|
572
|
+
tool: j.tool,
|
|
573
|
+
args: j.args
|
|
574
574
|
}
|
|
575
575
|
]);
|
|
576
576
|
return;
|
|
577
577
|
}
|
|
578
578
|
if (ue === "tool_result" && E) {
|
|
579
|
-
const q =
|
|
580
|
-
if (q && q.tool === String(
|
|
579
|
+
const q = v.current[E];
|
|
580
|
+
if (q && q.tool === String(j.tool || "") && j.success)
|
|
581
581
|
if (q.tool === "create_custom_analytics_report" || q.tool === "update_custom_analytics_report") {
|
|
582
|
-
const Q = typeof
|
|
582
|
+
const Q = typeof j.report_id == "string" ? j.report_id : void 0, Be = typeof ((it = q.args) == null ? void 0 : it.report_id) == "string" ? q.args.report_id : void 0;
|
|
583
583
|
ye("Custom Analytics", Q || Be || ""), n.invalidateQueries({ queryKey: ["runtime-drafts"] });
|
|
584
584
|
} else {
|
|
585
|
-
const Q =
|
|
585
|
+
const Q = Wa(q.tool, q.args);
|
|
586
586
|
Q && ye(Q.group, Q.item);
|
|
587
587
|
}
|
|
588
|
-
|
|
589
|
-
...
|
|
588
|
+
v.current = {
|
|
589
|
+
...v.current,
|
|
590
590
|
[E]: null
|
|
591
|
-
},
|
|
592
|
-
...
|
|
591
|
+
}, F(E, (G) => [
|
|
592
|
+
...G,
|
|
593
593
|
{
|
|
594
594
|
type: "tool_result",
|
|
595
|
-
content: String(
|
|
596
|
-
tool:
|
|
597
|
-
success: !!
|
|
595
|
+
content: String(j.summary || ""),
|
|
596
|
+
tool: j.tool,
|
|
597
|
+
success: !!j.success
|
|
598
598
|
}
|
|
599
599
|
]);
|
|
600
600
|
return;
|
|
601
601
|
}
|
|
602
602
|
if (ue === "complete" && E) {
|
|
603
|
-
|
|
603
|
+
Z(E, !1), F(E, (q) => q.filter((G) => G.type !== "thinking"));
|
|
604
604
|
return;
|
|
605
605
|
}
|
|
606
606
|
if (ue === "error") {
|
|
607
607
|
if (Ye)
|
|
608
608
|
return;
|
|
609
|
-
E && (
|
|
610
|
-
...q.filter((
|
|
611
|
-
{ type: "error", content: String(
|
|
609
|
+
E && (Z(E, !1), F(E, (q) => [
|
|
610
|
+
...q.filter((G) => G.type !== "thinking"),
|
|
611
|
+
{ type: "error", content: String(j.content || "Chat error.") }
|
|
612
612
|
]));
|
|
613
613
|
}
|
|
614
614
|
} catch {
|
|
@@ -616,41 +616,41 @@ function Ha({ children: t }) {
|
|
|
616
616
|
}, be.onerror = () => {
|
|
617
617
|
be.close();
|
|
618
618
|
}, be.onclose = (De) => {
|
|
619
|
-
if (H.current === be && (H.current = null),
|
|
619
|
+
if (H.current === be && (H.current = null), C("Chat disconnected."), A("disconnected"), !_) {
|
|
620
620
|
if (De.code === 4001 || De.code === 4003) {
|
|
621
621
|
window.location.href = "/login";
|
|
622
622
|
return;
|
|
623
623
|
}
|
|
624
|
-
|
|
624
|
+
$.current = window.setTimeout(V, 3e3);
|
|
625
625
|
}
|
|
626
626
|
};
|
|
627
627
|
}
|
|
628
|
-
return
|
|
629
|
-
if (_ = !0,
|
|
630
|
-
const
|
|
631
|
-
H.current = null,
|
|
628
|
+
return V(), () => {
|
|
629
|
+
if (_ = !0, $.current !== null && window.clearTimeout($.current), B.current !== null && window.clearTimeout(B.current), C("Chat disconnected."), H.current) {
|
|
630
|
+
const W = H.current;
|
|
631
|
+
H.current = null, W.close();
|
|
632
632
|
}
|
|
633
633
|
};
|
|
634
634
|
}, []);
|
|
635
635
|
async function He() {
|
|
636
636
|
if (w.current)
|
|
637
637
|
return w.current;
|
|
638
|
-
const _ = Ne("create_session", {}, "session_created").then((
|
|
638
|
+
const _ = Ne("create_session", {}, "session_created").then((V) => V.session).finally(() => {
|
|
639
639
|
w.current === _ && (w.current = null);
|
|
640
640
|
});
|
|
641
641
|
return w.current = _, _;
|
|
642
642
|
}
|
|
643
643
|
async function qe(_) {
|
|
644
|
-
|
|
644
|
+
ae(_, "running"), he(_, null);
|
|
645
645
|
try {
|
|
646
646
|
await Ne("start_demo", { session_id: _ }, "demo_started");
|
|
647
|
-
} catch (
|
|
648
|
-
throw
|
|
647
|
+
} catch (V) {
|
|
648
|
+
throw ae(_, "idle"), V;
|
|
649
649
|
}
|
|
650
650
|
}
|
|
651
|
-
function Me(_,
|
|
651
|
+
function Me(_, V) {
|
|
652
652
|
try {
|
|
653
|
-
Te({ type: "demo_typing_done", session_id: _, seq:
|
|
653
|
+
Te({ type: "demo_typing_done", session_id: _, seq: V });
|
|
654
654
|
} catch {
|
|
655
655
|
}
|
|
656
656
|
}
|
|
@@ -662,42 +662,42 @@ function Ha({ children: t }) {
|
|
|
662
662
|
}
|
|
663
663
|
async function dt(_) {
|
|
664
664
|
if (p[_]) return;
|
|
665
|
-
const
|
|
666
|
-
if (
|
|
667
|
-
m((
|
|
665
|
+
const V = g[_];
|
|
666
|
+
if (V != null && c[_]) {
|
|
667
|
+
m((W) => ({ ...W, [_]: !0 }));
|
|
668
668
|
try {
|
|
669
669
|
await Ne(
|
|
670
670
|
"load_history",
|
|
671
|
-
{ session_id: _, before_id:
|
|
671
|
+
{ session_id: _, before_id: V },
|
|
672
672
|
"history_loaded"
|
|
673
673
|
);
|
|
674
|
-
} catch (
|
|
675
|
-
throw m((fe) => ({ ...fe, [_]: !1 })),
|
|
674
|
+
} catch (W) {
|
|
675
|
+
throw m((fe) => ({ ...fe, [_]: !1 })), W;
|
|
676
676
|
}
|
|
677
677
|
}
|
|
678
678
|
}
|
|
679
679
|
async function Je(_) {
|
|
680
680
|
await Ne("clear_history", { session_id: _ }, "history_cleared");
|
|
681
681
|
}
|
|
682
|
-
function we(_,
|
|
683
|
-
const fe =
|
|
682
|
+
function we(_, V, W) {
|
|
683
|
+
const fe = V.trim(), be = ((W == null ? void 0 : W.length) ?? 0) > 0;
|
|
684
684
|
if (!fe && !be) return !1;
|
|
685
685
|
try {
|
|
686
|
-
|
|
686
|
+
Z(_, !0);
|
|
687
687
|
const De = {
|
|
688
688
|
type: "send_message",
|
|
689
689
|
session_id: _,
|
|
690
690
|
content: fe
|
|
691
691
|
};
|
|
692
|
-
return be && (De.attachment_ids =
|
|
692
|
+
return be && (De.attachment_ids = W), Te(De), !0;
|
|
693
693
|
} catch {
|
|
694
|
-
return
|
|
694
|
+
return Z(_, !1), !1;
|
|
695
695
|
}
|
|
696
696
|
}
|
|
697
|
-
async function _e(_,
|
|
697
|
+
async function _e(_, V, W) {
|
|
698
698
|
const fe = await Ne(
|
|
699
699
|
"transcribe",
|
|
700
|
-
{ audio_data: _, audio_format:
|
|
700
|
+
{ audio_data: _, audio_format: V, session_id: W },
|
|
701
701
|
"transcription_result"
|
|
702
702
|
);
|
|
703
703
|
if (!fe.success)
|
|
@@ -855,16 +855,16 @@ function io(t, n) {
|
|
|
855
855
|
const a = lt.find((s) => s.label === t);
|
|
856
856
|
a ? a.items.push(n) : lt.push({ label: t, icon: null, items: [n] });
|
|
857
857
|
}
|
|
858
|
-
let
|
|
858
|
+
let Kt = { appName: "Lambda ERP" };
|
|
859
859
|
function oo(t) {
|
|
860
|
-
if (
|
|
860
|
+
if (Kt = { ...Kt, ...t }, !(typeof document > "u") && (t.appName && (document.title = t.appName), t.tokens)) {
|
|
861
861
|
const n = document.documentElement;
|
|
862
862
|
for (const [a, s] of Object.entries(t.tokens))
|
|
863
863
|
n.style.setProperty(a.startsWith("--") ? a : `--${a}`, s);
|
|
864
864
|
}
|
|
865
865
|
}
|
|
866
866
|
function Ya() {
|
|
867
|
-
return
|
|
867
|
+
return Kt;
|
|
868
868
|
}
|
|
869
869
|
function Ie(...t) {
|
|
870
870
|
return t.filter(Boolean).join(" ");
|
|
@@ -876,7 +876,7 @@ function Oe(t, n = "USD") {
|
|
|
876
876
|
minimumFractionDigits: 2
|
|
877
877
|
}).format(t ?? 0);
|
|
878
878
|
}
|
|
879
|
-
function
|
|
879
|
+
function Wt(t, n = 2) {
|
|
880
880
|
return new Intl.NumberFormat("en-US", {
|
|
881
881
|
minimumFractionDigits: n,
|
|
882
882
|
maximumFractionDigits: n
|
|
@@ -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 Za() {
|
|
935
|
-
const [t, n] = nn("chats"), a = Ct(), s = Ee(), { t: o } =
|
|
935
|
+
const [t, n] = nn("chats"), a = Ct(), s = Ee(), { t: o } = ne(), { sessions: i, createSession: c, deleteSession: l } = ct(), g = async () => {
|
|
936
936
|
try {
|
|
937
937
|
const p = await c();
|
|
938
938
|
s(`/chat/${p.id}`);
|
|
@@ -1010,7 +1010,7 @@ function rn() {
|
|
|
1010
1010
|
);
|
|
1011
1011
|
}
|
|
1012
1012
|
function Xa() {
|
|
1013
|
-
const [t, n, a] = nn("custom-analytics"), s = Ct(), o = Ee(), i =
|
|
1013
|
+
const [t, n, a] = nn("custom-analytics"), s = Ct(), o = Ee(), i = Ke(), { t: c } = ne(), { navigationFlash: l, sessions: g, 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
|
|
@@ -1018,16 +1018,16 @@ function Xa() {
|
|
|
1018
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 x =
|
|
1022
|
-
mutationFn: (
|
|
1023
|
-
onSuccess: (
|
|
1021
|
+
const x = oe({
|
|
1022
|
+
mutationFn: (D) => L.deleteRuntimeDraft(D),
|
|
1023
|
+
onSuccess: (D, T) => {
|
|
1024
1024
|
i.invalidateQueries({ queryKey: ["runtime-drafts"] }), s.search.includes(`report_id=${T}`) && o("/reports/analytics");
|
|
1025
1025
|
}
|
|
1026
|
-
}), y = async (
|
|
1027
|
-
|
|
1026
|
+
}), y = async (D, T) => {
|
|
1027
|
+
D.preventDefault(), D.stopPropagation(), x.mutate(T);
|
|
1028
1028
|
}, P = async () => {
|
|
1029
1029
|
var u;
|
|
1030
|
-
const
|
|
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
1031
|
let T = ((u = g[0]) == null ? void 0 : u.id) || "";
|
|
1032
1032
|
if (!T)
|
|
1033
1033
|
try {
|
|
@@ -1036,7 +1036,7 @@ function Xa() {
|
|
|
1036
1036
|
o("/reports/analytics");
|
|
1037
1037
|
return;
|
|
1038
1038
|
}
|
|
1039
|
-
o(`/chat/${T}`, { state: { prefillMessage:
|
|
1039
|
+
o(`/chat/${T}`, { state: { prefillMessage: D } });
|
|
1040
1040
|
};
|
|
1041
1041
|
return /* @__PURE__ */ r("div", { children: [
|
|
1042
1042
|
/* @__PURE__ */ r(
|
|
@@ -1067,8 +1067,8 @@ function Xa() {
|
|
|
1067
1067
|
]
|
|
1068
1068
|
}
|
|
1069
1069
|
) }),
|
|
1070
|
-
S.map((
|
|
1071
|
-
const T = `/reports/analytics?report_id=${
|
|
1070
|
+
S.map((D) => {
|
|
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(
|
|
1074
1074
|
Bt,
|
|
@@ -1080,27 +1080,27 @@ function Xa() {
|
|
|
1080
1080
|
u && "bg-surface-subtle font-medium text-fg",
|
|
1081
1081
|
h && m
|
|
1082
1082
|
),
|
|
1083
|
-
title:
|
|
1084
|
-
children:
|
|
1083
|
+
title: D.title,
|
|
1084
|
+
children: D.title
|
|
1085
1085
|
}
|
|
1086
1086
|
),
|
|
1087
1087
|
u && /* @__PURE__ */ e(rn, {}),
|
|
1088
1088
|
/* @__PURE__ */ e(
|
|
1089
1089
|
"button",
|
|
1090
1090
|
{
|
|
1091
|
-
onClick: (A) => y(A,
|
|
1091
|
+
onClick: (A) => y(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(Gn, { className: "h-3.5 w-3.5" })
|
|
1095
1095
|
}
|
|
1096
1096
|
)
|
|
1097
|
-
] },
|
|
1097
|
+
] }, D.id);
|
|
1098
1098
|
})
|
|
1099
1099
|
] })
|
|
1100
1100
|
] });
|
|
1101
1101
|
}
|
|
1102
1102
|
function er({ group: t }) {
|
|
1103
|
-
const [n, a] = nn(t.label), { t: s } =
|
|
1103
|
+
const [n, a] = nn(t.label), { t: s } = ne(), { navigationFlash: o } = ct(), i = (o == null ? void 0 : o.group) === t.label, c = an[t.label] ?? "bg-blue-300 text-blue-950 ring-2 ring-inset ring-blue-100";
|
|
1104
1104
|
return /* @__PURE__ */ r("div", { children: [
|
|
1105
1105
|
/* @__PURE__ */ r(
|
|
1106
1106
|
"button",
|
|
@@ -1147,11 +1147,11 @@ const tr = {
|
|
|
1147
1147
|
};
|
|
1148
1148
|
function nr({ isMobileOpen: t = !1, onClose: n }) {
|
|
1149
1149
|
var l;
|
|
1150
|
-
const { data: a } =
|
|
1150
|
+
const { data: a } = le({
|
|
1151
1151
|
queryKey: ["settings"],
|
|
1152
1152
|
queryFn: () => L.getSettings(),
|
|
1153
1153
|
staleTime: 6e4
|
|
1154
|
-
}), { data: s } =
|
|
1154
|
+
}), { data: s } = le({
|
|
1155
1155
|
queryKey: ["setup-status"],
|
|
1156
1156
|
queryFn: () => L.setupStatus(),
|
|
1157
1157
|
staleTime: 6e4
|
|
@@ -1238,7 +1238,7 @@ function rr() {
|
|
|
1238
1238
|
return /* @__PURE__ */ e(Ha, { children: /* @__PURE__ */ e(sr, {}) });
|
|
1239
1239
|
}
|
|
1240
1240
|
function sr() {
|
|
1241
|
-
const { pathname: t } = Ct(), { user: n, logout: a } = bt(), { navigationFlash: s } = ct(), { t: o } =
|
|
1241
|
+
const { pathname: t } = Ct(), { user: n, logout: a } = bt(), { navigationFlash: s } = ct(), { t: o } = ne(), i = ar(t, o), [c, l] = N(!1);
|
|
1242
1242
|
se(() => {
|
|
1243
1243
|
l(!1);
|
|
1244
1244
|
}, [t]);
|
|
@@ -1293,7 +1293,7 @@ function ir({ children: t }) {
|
|
|
1293
1293
|
const { user: n, loading: a } = bt();
|
|
1294
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(Na, { to: "/login", replace: !0 });
|
|
1295
1295
|
}
|
|
1296
|
-
function
|
|
1296
|
+
function U({ title: t, children: n, className: a, interactive: s }) {
|
|
1297
1297
|
return /* @__PURE__ */ r(
|
|
1298
1298
|
"div",
|
|
1299
1299
|
{
|
|
@@ -1352,12 +1352,12 @@ const cr = {
|
|
|
1352
1352
|
Overdue: "danger"
|
|
1353
1353
|
};
|
|
1354
1354
|
function sn({ status: t }) {
|
|
1355
|
-
const { t: n } =
|
|
1355
|
+
const { t: n } = ne(), a = cr[t] ?? "secondary";
|
|
1356
1356
|
return /* @__PURE__ */ e(lr, { variant: a, children: n(`status.${t}`, { defaultValue: t }) });
|
|
1357
1357
|
}
|
|
1358
|
-
function
|
|
1358
|
+
function We(t) {
|
|
1359
1359
|
var s;
|
|
1360
|
-
const { data: n } =
|
|
1360
|
+
const { data: n } = le({
|
|
1361
1361
|
queryKey: ["setup-status"],
|
|
1362
1362
|
queryFn: () => L.setupStatus(),
|
|
1363
1363
|
staleTime: 3e5
|
|
@@ -1371,8 +1371,8 @@ function Ke(t) {
|
|
|
1371
1371
|
return ((s = a[0]) == null ? void 0 : s.default_currency) || "USD";
|
|
1372
1372
|
}
|
|
1373
1373
|
function _t({ title: t, value: n, icon: a, tone: s }) {
|
|
1374
|
-
const o = s ?? "text-brand bg-brand/10", i =
|
|
1375
|
-
return /* @__PURE__ */ e(
|
|
1374
|
+
const o = s ?? "text-brand bg-brand/10", i = We();
|
|
1375
|
+
return /* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "flex items-start justify-between gap-4", children: [
|
|
1376
1376
|
/* @__PURE__ */ r("div", { className: "min-w-0", children: [
|
|
1377
1377
|
/* @__PURE__ */ e("p", { className: "text-sm font-medium text-fg-muted", children: t }),
|
|
1378
1378
|
/* @__PURE__ */ e("p", { className: "mt-1.5 text-2xl font-semibold tracking-tight tabular-nums text-fg", children: ((l) => Oe(l, i))(n ?? 0) })
|
|
@@ -1381,7 +1381,7 @@ function _t({ title: t, value: n, icon: a, tone: s }) {
|
|
|
1381
1381
|
] }) });
|
|
1382
1382
|
}
|
|
1383
1383
|
function Pt() {
|
|
1384
|
-
return /* @__PURE__ */ e(
|
|
1384
|
+
return /* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "flex items-start justify-between gap-4", children: [
|
|
1385
1385
|
/* @__PURE__ */ r("div", { className: "min-w-0 flex-1", children: [
|
|
1386
1386
|
/* @__PURE__ */ e("div", { className: "h-4 w-24 animate-pulse rounded bg-surface-subtle" }),
|
|
1387
1387
|
/* @__PURE__ */ e("div", { className: "mt-2.5 h-7 w-32 animate-pulse rounded bg-surface-subtle" })
|
|
@@ -1397,7 +1397,7 @@ const dr = {
|
|
|
1397
1397
|
Quotation: Zt
|
|
1398
1398
|
};
|
|
1399
1399
|
function ur({ doc: t }) {
|
|
1400
|
-
const { t: n } =
|
|
1400
|
+
const { t: n } = ne(), a = t.doctype ?? t.type ?? "Document", s = t.creation ?? t.date, o = dr[a] ?? Zt, c = `/app/${a.toLowerCase().replace(/\s+/g, "-")}/${encodeURIComponent(t.name)}`;
|
|
1401
1401
|
return /* @__PURE__ */ r(
|
|
1402
1402
|
ve,
|
|
1403
1403
|
{
|
|
@@ -1427,7 +1427,7 @@ function wt() {
|
|
|
1427
1427
|
] });
|
|
1428
1428
|
}
|
|
1429
1429
|
function mr() {
|
|
1430
|
-
const { t } =
|
|
1430
|
+
const { t } = ne(), { data: n, isLoading: a } = le({
|
|
1431
1431
|
queryKey: ["dashboard-summary"],
|
|
1432
1432
|
queryFn: () => L.dashboardSummary()
|
|
1433
1433
|
});
|
|
@@ -1475,7 +1475,7 @@ function mr() {
|
|
|
1475
1475
|
}
|
|
1476
1476
|
)
|
|
1477
1477
|
] }) }),
|
|
1478
|
-
/* @__PURE__ */ e(
|
|
1478
|
+
/* @__PURE__ */ e(U, { title: t("dashboard.recentDocuments"), children: /* @__PURE__ */ e("div", { className: "-mx-3 space-y-0.5", children: a ? /* @__PURE__ */ r(Se, { children: [
|
|
1479
1479
|
/* @__PURE__ */ e(wt, {}),
|
|
1480
1480
|
/* @__PURE__ */ e(wt, {}),
|
|
1481
1481
|
/* @__PURE__ */ e(wt, {}),
|
|
@@ -1485,7 +1485,7 @@ function mr() {
|
|
|
1485
1485
|
] });
|
|
1486
1486
|
}
|
|
1487
1487
|
function pr(t, n) {
|
|
1488
|
-
const { data: a, isLoading: s, error: o, refetch: i } =
|
|
1488
|
+
const { data: a, isLoading: s, error: o, refetch: i } = le({
|
|
1489
1489
|
queryKey: ["documents", t, n],
|
|
1490
1490
|
queryFn: () => L.listDocuments(t, n),
|
|
1491
1491
|
enabled: !!t
|
|
@@ -1509,7 +1509,7 @@ function Qe() {
|
|
|
1509
1509
|
[t]
|
|
1510
1510
|
);
|
|
1511
1511
|
}
|
|
1512
|
-
function
|
|
1512
|
+
function te(t, n) {
|
|
1513
1513
|
const [a, s] = Et(), o = a.get(t);
|
|
1514
1514
|
let i;
|
|
1515
1515
|
if (o === null)
|
|
@@ -2217,7 +2217,7 @@ function J({
|
|
|
2217
2217
|
}
|
|
2218
2218
|
);
|
|
2219
2219
|
}
|
|
2220
|
-
function
|
|
2220
|
+
function X({ label: t, hint: n, error: a, className: s, id: o, ...i }) {
|
|
2221
2221
|
const c = o || (t ? t.toLowerCase().replace(/\s+/g, "-") : void 0);
|
|
2222
2222
|
return /* @__PURE__ */ r("div", { children: [
|
|
2223
2223
|
t && /* @__PURE__ */ e(
|
|
@@ -2326,7 +2326,7 @@ function fr({ text: t }) {
|
|
|
2326
2326
|
] });
|
|
2327
2327
|
}
|
|
2328
2328
|
function br(t, n = !0) {
|
|
2329
|
-
const { data: a } =
|
|
2329
|
+
const { data: a } = le({
|
|
2330
2330
|
queryKey: ["currencies", ""],
|
|
2331
2331
|
queryFn: () => L.currencies(t),
|
|
2332
2332
|
enabled: n,
|
|
@@ -2356,7 +2356,7 @@ function Nr({
|
|
|
2356
2356
|
disabled: s,
|
|
2357
2357
|
hideLabel: o
|
|
2358
2358
|
}) {
|
|
2359
|
-
const [i, c] = N(n ?? ""), [l, g] = N(!1), { data: d } =
|
|
2359
|
+
const [i, c] = N(n ?? ""), [l, g] = N(!1), { data: d } = le({
|
|
2360
2360
|
queryKey: ["link-search", t.linkDoctype, i],
|
|
2361
2361
|
queryFn: () => L.searchLink(t.linkDoctype, i),
|
|
2362
2362
|
enabled: !!t.linkDoctype && l
|
|
@@ -2368,7 +2368,7 @@ function Nr({
|
|
|
2368
2368
|
/* @__PURE__ */ e("p", { className: "py-2 text-sm text-fg", children: n || "-" })
|
|
2369
2369
|
] }) : /* @__PURE__ */ r("div", { className: "relative", children: [
|
|
2370
2370
|
/* @__PURE__ */ e(
|
|
2371
|
-
|
|
2371
|
+
X,
|
|
2372
2372
|
{
|
|
2373
2373
|
label: o ? void 0 : t.label,
|
|
2374
2374
|
value: i,
|
|
@@ -2402,7 +2402,7 @@ function Ht({
|
|
|
2402
2402
|
currency: c = "USD"
|
|
2403
2403
|
}) {
|
|
2404
2404
|
var S;
|
|
2405
|
-
const { t: l } =
|
|
2405
|
+
const { t: l } = ne(), g = s || !!t.readOnly, d = () => i ? null : /* @__PURE__ */ e(vr, { label: l(`fields.${t.label}`, { defaultValue: t.label }), hint: t.hint }), p = t.type === "select" && t.optionsSource === "currency", m = br(void 0, p);
|
|
2406
2406
|
if (g) {
|
|
2407
2407
|
if (t.type === "link" && n) {
|
|
2408
2408
|
const y = t.linkDoctypeField && o ? String(o[t.linkDoctypeField] ?? "").toLowerCase().replace(/\s+/g, "-") : t.linkDoctype, P = Qt(y, String(n));
|
|
@@ -2472,7 +2472,7 @@ function Ht({
|
|
|
2472
2472
|
return /* @__PURE__ */ r("div", { children: [
|
|
2473
2473
|
/* @__PURE__ */ e(d, {}),
|
|
2474
2474
|
/* @__PURE__ */ e(
|
|
2475
|
-
|
|
2475
|
+
X,
|
|
2476
2476
|
{
|
|
2477
2477
|
type: f,
|
|
2478
2478
|
step: t.type === "currency" ? "0.01" : void 0,
|
|
@@ -2491,7 +2491,7 @@ function wr({
|
|
|
2491
2491
|
readOnly: s,
|
|
2492
2492
|
currency: o = "USD"
|
|
2493
2493
|
}) {
|
|
2494
|
-
const { t: i } =
|
|
2494
|
+
const { t: i } = ne(), c = (d, p, m) => {
|
|
2495
2495
|
const f = n.map(
|
|
2496
2496
|
(S, x) => x === d ? { ...S, [p]: m } : S
|
|
2497
2497
|
);
|
|
@@ -2504,7 +2504,7 @@ function wr({
|
|
|
2504
2504
|
}, g = (d) => {
|
|
2505
2505
|
a(n.filter((p, m) => m !== d));
|
|
2506
2506
|
};
|
|
2507
|
-
return /* @__PURE__ */ r(
|
|
2507
|
+
return /* @__PURE__ */ r(U, { title: i(`tables.${t.key}`, { defaultValue: t.label }), children: [
|
|
2508
2508
|
/* @__PURE__ */ e("div", { className: "-mx-6 overflow-x-auto px-6", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-line text-sm", children: [
|
|
2509
2509
|
/* @__PURE__ */ e("thead", { children: /* @__PURE__ */ r("tr", { children: [
|
|
2510
2510
|
/* @__PURE__ */ e("th", { className: "px-2 py-2 text-left text-xs font-medium uppercase tracking-wide text-fg-muted", children: "#" }),
|
|
@@ -2560,11 +2560,11 @@ function kr({
|
|
|
2560
2560
|
onConvert: p,
|
|
2561
2561
|
onDiscard: m
|
|
2562
2562
|
}) {
|
|
2563
|
-
const { t: f } =
|
|
2563
|
+
const { t: f } = ne(), [S, x] = N(!1), [y, P] = N(!1);
|
|
2564
2564
|
if (!c) return null;
|
|
2565
|
-
const
|
|
2565
|
+
const D = !t && n && a ? `/api/documents/${n}/${encodeURIComponent(a)}/pdf` : null, T = !t && c.canCancel && s === 1;
|
|
2566
2566
|
return /* @__PURE__ */ r("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2567
|
-
|
|
2567
|
+
D && /* @__PURE__ */ e(J, { variant: "secondary", onClick: () => window.open(D, "_blank"), children: f("common.pdf") }),
|
|
2568
2568
|
s < 1 && !o && /* @__PURE__ */ e(J, { onClick: l, disabled: i, children: f(i ? "common.saving" : "common.save") }),
|
|
2569
2569
|
!t && c.canSubmit && s === 0 && !o && /* @__PURE__ */ e(J, { variant: "secondary", onClick: g, children: f("common.submit") }),
|
|
2570
2570
|
!t && c.canSubmit && s === 0 && !o && (y ? /* @__PURE__ */ r(Se, { children: [
|
|
@@ -2627,14 +2627,14 @@ function vn(t, n) {
|
|
|
2627
2627
|
}
|
|
2628
2628
|
function Nn() {
|
|
2629
2629
|
var me;
|
|
2630
|
-
const { doctype: t, name: n } = ft(), a = Ee(), s =
|
|
2630
|
+
const { doctype: t, name: n } = ft(), a = Ee(), s = Ke(), { t: o } = ne(), i = na(t ?? ""), c = !n, [l, g] = N({}), [d, p] = N(!1), { data: m, isLoading: f } = le({
|
|
2631
2631
|
queryKey: ["document", t, n],
|
|
2632
2632
|
queryFn: () => L.getDocument(t, n),
|
|
2633
2633
|
enabled: !!t && !!n && !c
|
|
2634
2634
|
}), S = Re(
|
|
2635
2635
|
() => !!(i != null && i.fields.some((I) => I.name === "currency")),
|
|
2636
2636
|
[i]
|
|
2637
|
-
), x = i == null ? void 0 : i.partyField, y = x ? l[x] : void 0, P =
|
|
2637
|
+
), x = i == null ? void 0 : i.partyField, y = x ? l[x] : void 0, P = We(l.company), { data: D } = le({
|
|
2638
2638
|
queryKey: ["master", x, y],
|
|
2639
2639
|
queryFn: () => L.getMaster(x, y),
|
|
2640
2640
|
enabled: c && S && !!x && !!y,
|
|
@@ -2644,8 +2644,8 @@ function Nn() {
|
|
|
2644
2644
|
if (!c || !S || d) return;
|
|
2645
2645
|
let I;
|
|
2646
2646
|
if (y) {
|
|
2647
|
-
if (!
|
|
2648
|
-
I =
|
|
2647
|
+
if (!D) return;
|
|
2648
|
+
I = D.default_currency || P;
|
|
2649
2649
|
} else
|
|
2650
2650
|
I = P;
|
|
2651
2651
|
I && I !== l.currency && g((ie) => ({ ...ie, currency: I }));
|
|
@@ -2654,7 +2654,7 @@ function Nn() {
|
|
|
2654
2654
|
S,
|
|
2655
2655
|
d,
|
|
2656
2656
|
y,
|
|
2657
|
-
|
|
2657
|
+
D,
|
|
2658
2658
|
P,
|
|
2659
2659
|
l.currency
|
|
2660
2660
|
]), se(() => {
|
|
@@ -2667,32 +2667,32 @@ function Nn() {
|
|
|
2667
2667
|
}), I.docstatus = 0, g(I);
|
|
2668
2668
|
} else m && g(m);
|
|
2669
2669
|
}, [c, m, i]);
|
|
2670
|
-
const T =
|
|
2670
|
+
const T = oe({
|
|
2671
2671
|
mutationFn: (I) => L.createDocument(t, I),
|
|
2672
2672
|
onSuccess: (I) => {
|
|
2673
2673
|
s.invalidateQueries({ queryKey: ["documents", t] }), a(`/app/${t}/${I.name}`, { replace: !0 });
|
|
2674
2674
|
}
|
|
2675
|
-
}), u =
|
|
2675
|
+
}), u = oe({
|
|
2676
2676
|
mutationFn: (I) => L.updateDocument(t, n, I),
|
|
2677
2677
|
onSuccess: (I) => {
|
|
2678
2678
|
s.invalidateQueries({ queryKey: ["document", t, n] }), s.invalidateQueries({ queryKey: ["documents", t] }), g(I);
|
|
2679
2679
|
}
|
|
2680
|
-
}), h =
|
|
2680
|
+
}), h = oe({
|
|
2681
2681
|
mutationFn: () => L.submitDocument(t, n),
|
|
2682
2682
|
onSuccess: (I) => {
|
|
2683
2683
|
g(I), s.invalidateQueries({ queryKey: ["document", t, n] }), s.invalidateQueries({ queryKey: ["documents", t] });
|
|
2684
2684
|
}
|
|
2685
|
-
}), A =
|
|
2685
|
+
}), A = oe({
|
|
2686
2686
|
mutationFn: () => L.cancelDocument(t, n),
|
|
2687
2687
|
onSuccess: (I) => {
|
|
2688
2688
|
g(I), s.invalidateQueries({ queryKey: ["document", t, n] }), s.invalidateQueries({ queryKey: ["documents", t] });
|
|
2689
2689
|
}
|
|
2690
|
-
}), R =
|
|
2690
|
+
}), R = oe({
|
|
2691
2691
|
mutationFn: () => L.discardDocument(t, n),
|
|
2692
2692
|
onSuccess: () => {
|
|
2693
2693
|
s.invalidateQueries({ queryKey: ["documents", t] }), a(`/app/${t}`, { replace: !0 });
|
|
2694
2694
|
}
|
|
2695
|
-
}), k =
|
|
2695
|
+
}), k = oe({
|
|
2696
2696
|
mutationFn: (I) => L.convertDocument(t, n, I),
|
|
2697
2697
|
onSuccess: (I, ie) => {
|
|
2698
2698
|
const Te = ie.toLowerCase().replace(/\s+/g, "-");
|
|
@@ -2706,7 +2706,7 @@ function Nn() {
|
|
|
2706
2706
|
});
|
|
2707
2707
|
},
|
|
2708
2708
|
[i]
|
|
2709
|
-
),
|
|
2709
|
+
), $ = Pe(
|
|
2710
2710
|
(I, ie) => {
|
|
2711
2711
|
g((Te) => {
|
|
2712
2712
|
const Ne = { ...Te, [I]: ie };
|
|
@@ -2718,11 +2718,11 @@ function Nn() {
|
|
|
2718
2718
|
c ? T.mutate(l) : u.mutate(l);
|
|
2719
2719
|
}, w = () => {
|
|
2720
2720
|
h.mutate();
|
|
2721
|
-
},
|
|
2721
|
+
}, K = () => {
|
|
2722
2722
|
A.mutate();
|
|
2723
|
-
},
|
|
2723
|
+
}, v = (I) => {
|
|
2724
2724
|
k.mutate(I);
|
|
2725
|
-
},
|
|
2725
|
+
}, B = () => {
|
|
2726
2726
|
R.mutate();
|
|
2727
2727
|
};
|
|
2728
2728
|
if (!i)
|
|
@@ -2732,7 +2732,7 @@ function Nn() {
|
|
|
2732
2732
|
] });
|
|
2733
2733
|
if (!c && f)
|
|
2734
2734
|
return /* @__PURE__ */ e("p", { className: "text-fg-muted", children: o("common.loading") });
|
|
2735
|
-
const
|
|
2735
|
+
const C = l.docstatus ?? 0, F = !!l.discarded, Z = C >= 1 || F, ae = l.currency || "USD", he = ze(l.conversion_rate ?? 1), ye = i.fields.filter((I) => !I.readOnly), Ce = i.fields.filter((I) => I.readOnly);
|
|
2736
2736
|
return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
2737
2737
|
/* @__PURE__ */ r("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
2738
2738
|
/* @__PURE__ */ r("div", { className: "flex items-center gap-3", children: [
|
|
@@ -2741,9 +2741,9 @@ function Nn() {
|
|
|
2741
2741
|
"span",
|
|
2742
2742
|
{
|
|
2743
2743
|
className: "inline-flex items-center gap-1 rounded-full bg-surface-subtle px-2.5 py-0.5 text-xs font-medium text-fg-muted ring-1 ring-line",
|
|
2744
|
-
title: he !== 1 ? `1 ${
|
|
2744
|
+
title: he !== 1 ? `1 ${ae} = ${he} base currency` : void 0,
|
|
2745
2745
|
children: [
|
|
2746
|
-
|
|
2746
|
+
ae,
|
|
2747
2747
|
he !== 1 && /* @__PURE__ */ r("span", { className: "text-fg-muted/70", children: [
|
|
2748
2748
|
"@ ",
|
|
2749
2749
|
he
|
|
@@ -2758,28 +2758,28 @@ function Nn() {
|
|
|
2758
2758
|
isNew: c,
|
|
2759
2759
|
doctype: t,
|
|
2760
2760
|
name: n,
|
|
2761
|
-
docstatus:
|
|
2761
|
+
docstatus: C,
|
|
2762
2762
|
saving: T.isPending || u.isPending,
|
|
2763
2763
|
config: i,
|
|
2764
|
-
discarded:
|
|
2764
|
+
discarded: F,
|
|
2765
2765
|
onSave: M,
|
|
2766
2766
|
onSubmit: w,
|
|
2767
|
-
onCancel:
|
|
2768
|
-
onConvert:
|
|
2769
|
-
onDiscard:
|
|
2767
|
+
onCancel: K,
|
|
2768
|
+
onConvert: v,
|
|
2769
|
+
onDiscard: B
|
|
2770
2770
|
}
|
|
2771
2771
|
)
|
|
2772
2772
|
] }),
|
|
2773
2773
|
(T.error || u.error || h.error || A.error) && /* @__PURE__ */ e("div", { className: "rounded-lg bg-rose-50 p-4 text-sm text-rose-700 ring-1 ring-rose-200", children: ((me = T.error ?? u.error ?? h.error ?? A.error) == null ? void 0 : me.message) ?? o("common.errorOccurred") }),
|
|
2774
|
-
/* @__PURE__ */ e(
|
|
2774
|
+
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: ye.map((I) => /* @__PURE__ */ e(
|
|
2775
2775
|
Ht,
|
|
2776
2776
|
{
|
|
2777
2777
|
field: I,
|
|
2778
2778
|
value: l[I.name],
|
|
2779
2779
|
onChange: (ie) => H(I.name, ie),
|
|
2780
|
-
readOnly:
|
|
2780
|
+
readOnly: Z,
|
|
2781
2781
|
rowData: l,
|
|
2782
|
-
currency:
|
|
2782
|
+
currency: ae
|
|
2783
2783
|
},
|
|
2784
2784
|
I.name
|
|
2785
2785
|
)) }) }),
|
|
@@ -2788,13 +2788,13 @@ function Nn() {
|
|
|
2788
2788
|
{
|
|
2789
2789
|
tableDef: I,
|
|
2790
2790
|
rows: l[I.key] ?? [],
|
|
2791
|
-
onChange: (ie) =>
|
|
2792
|
-
readOnly:
|
|
2793
|
-
currency:
|
|
2791
|
+
onChange: (ie) => $(I.key, ie),
|
|
2792
|
+
readOnly: Z,
|
|
2793
|
+
currency: ae
|
|
2794
2794
|
},
|
|
2795
2795
|
I.key
|
|
2796
2796
|
)),
|
|
2797
|
-
Ce.length > 0 && /* @__PURE__ */ e(
|
|
2797
|
+
Ce.length > 0 && /* @__PURE__ */ e(U, { title: o("common.totals"), children: /* @__PURE__ */ e("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-3", children: Ce.map((I) => /* @__PURE__ */ e(
|
|
2798
2798
|
Ht,
|
|
2799
2799
|
{
|
|
2800
2800
|
field: I,
|
|
@@ -2802,7 +2802,7 @@ function Nn() {
|
|
|
2802
2802
|
onChange: () => {
|
|
2803
2803
|
},
|
|
2804
2804
|
readOnly: !0,
|
|
2805
|
-
currency:
|
|
2805
|
+
currency: ae
|
|
2806
2806
|
},
|
|
2807
2807
|
I.name
|
|
2808
2808
|
)) }) })
|
|
@@ -2953,89 +2953,89 @@ function Tr(t) {
|
|
|
2953
2953
|
}
|
|
2954
2954
|
const Ar = ["25", "50", "100", "200"];
|
|
2955
2955
|
function Rr() {
|
|
2956
|
-
const { t } =
|
|
2956
|
+
const { t } = ne(), { doctype: n } = ft(), a = na(n ?? ""), [s] = te("status", "All"), [o] = te("from", ""), [i] = te("to", ""), [c] = te("discarded", ""), [l] = te("per_page", 50), [g] = te("page", 1), d = g - 1, p = Qe(), m = (w) => p({ page: w === 0 ? null : w + 1 }), f = (w) => p({ status: w === "All" ? null : w, page: null }), S = (w) => p({ from: w || null, page: null }), x = (w) => p({ to: w || null, page: null }), y = (w) => p({ discarded: w ? "1" : null, page: null }), P = (w) => p({ per_page: w, page: null }), D = Re(() => {
|
|
2957
2957
|
const w = {};
|
|
2958
2958
|
return s !== "All" && (w.status = s), o && (w.from_date = o), i && (w.to_date = i), c && (w.include_discarded = "true"), w.limit = l, w.offset = d * l, w;
|
|
2959
|
-
}, [s, o, i, c, l, d]), { data: T, isLoading: u } = pr(n ?? "",
|
|
2959
|
+
}, [s, o, i, c, l, d]), { data: T, isLoading: u } = pr(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)), k = A === 0 ? 0 : d * l + 1, H = Math.min(A, (d + 1) * l), $ = Re(() => {
|
|
2960
2960
|
if (!a) return [];
|
|
2961
|
-
const w =
|
|
2962
|
-
const
|
|
2963
|
-
return t(`fields.${
|
|
2961
|
+
const w = Kn(), K = (v) => {
|
|
2962
|
+
const B = v.split("_").map((C) => C.charAt(0).toUpperCase() + C.slice(1)).join(" ");
|
|
2963
|
+
return t(`fields.${B}`, { defaultValue: B });
|
|
2964
2964
|
};
|
|
2965
|
-
return a.listColumns.map((
|
|
2966
|
-
if (
|
|
2965
|
+
return a.listColumns.map((v) => {
|
|
2966
|
+
if (v === "name")
|
|
2967
2967
|
return w.accessor("name", {
|
|
2968
2968
|
header: t("fields.Name", { defaultValue: "Name" }),
|
|
2969
|
-
cell: (
|
|
2969
|
+
cell: (B) => /* @__PURE__ */ e(
|
|
2970
2970
|
ve,
|
|
2971
2971
|
{
|
|
2972
|
-
to: `/app/${a.slug}/${
|
|
2972
|
+
to: `/app/${a.slug}/${B.getValue()}`,
|
|
2973
2973
|
className: "font-medium text-brand transition-colors hover:text-brand/80",
|
|
2974
|
-
children:
|
|
2974
|
+
children: B.getValue()
|
|
2975
2975
|
}
|
|
2976
2976
|
)
|
|
2977
2977
|
});
|
|
2978
|
-
if (
|
|
2978
|
+
if (v === "status")
|
|
2979
2979
|
return w.accessor("status", {
|
|
2980
2980
|
header: t("fields.Status", { defaultValue: "Status" }),
|
|
2981
|
-
cell: (
|
|
2981
|
+
cell: (B) => /* @__PURE__ */ e(sn, { status: B.getValue() })
|
|
2982
2982
|
});
|
|
2983
|
-
if (_r.has(
|
|
2984
|
-
return w.accessor(
|
|
2985
|
-
header: v
|
|
2986
|
-
cell: (
|
|
2987
|
-
var
|
|
2988
|
-
return Oe(
|
|
2983
|
+
if (_r.has(v))
|
|
2984
|
+
return w.accessor(v, {
|
|
2985
|
+
header: K(v),
|
|
2986
|
+
cell: (B) => {
|
|
2987
|
+
var C;
|
|
2988
|
+
return Oe(B.getValue(), ((C = B.row.original) == null ? void 0 : C.currency) || "USD");
|
|
2989
2989
|
}
|
|
2990
2990
|
});
|
|
2991
|
-
if (
|
|
2991
|
+
if (v === "party")
|
|
2992
2992
|
return w.accessor("party", {
|
|
2993
2993
|
header: t("fields.Party", { defaultValue: "Party" }),
|
|
2994
|
-
cell: (
|
|
2995
|
-
const
|
|
2996
|
-
if (!
|
|
2997
|
-
const
|
|
2998
|
-
return
|
|
2994
|
+
cell: (B) => {
|
|
2995
|
+
const C = B.getValue();
|
|
2996
|
+
if (!C) return "-";
|
|
2997
|
+
const F = Tr(B.row.original.party_type), Z = F ? Qt(F, String(C)) : null;
|
|
2998
|
+
return Z ? /* @__PURE__ */ e(
|
|
2999
2999
|
ve,
|
|
3000
3000
|
{
|
|
3001
|
-
to:
|
|
3002
|
-
onClick: (
|
|
3001
|
+
to: Z,
|
|
3002
|
+
onClick: (ae) => ae.stopPropagation(),
|
|
3003
3003
|
className: "text-brand transition-colors hover:text-brand/80 hover:underline",
|
|
3004
|
-
children:
|
|
3004
|
+
children: C
|
|
3005
3005
|
}
|
|
3006
|
-
) : String(
|
|
3006
|
+
) : String(C);
|
|
3007
3007
|
}
|
|
3008
3008
|
});
|
|
3009
|
-
if (Sn[
|
|
3010
|
-
const
|
|
3011
|
-
return w.accessor(
|
|
3012
|
-
header: v
|
|
3013
|
-
cell: (
|
|
3014
|
-
const
|
|
3015
|
-
if (!
|
|
3016
|
-
const
|
|
3017
|
-
return
|
|
3009
|
+
if (Sn[v]) {
|
|
3010
|
+
const B = Sn[v];
|
|
3011
|
+
return w.accessor(v, {
|
|
3012
|
+
header: K(v),
|
|
3013
|
+
cell: (C) => {
|
|
3014
|
+
const F = C.getValue();
|
|
3015
|
+
if (!F) return "-";
|
|
3016
|
+
const Z = Qt(B, String(F));
|
|
3017
|
+
return Z ? /* @__PURE__ */ e(
|
|
3018
3018
|
ve,
|
|
3019
3019
|
{
|
|
3020
|
-
to:
|
|
3021
|
-
onClick: (
|
|
3020
|
+
to: Z,
|
|
3021
|
+
onClick: (ae) => ae.stopPropagation(),
|
|
3022
3022
|
className: "text-brand transition-colors hover:text-brand/80 hover:underline",
|
|
3023
|
-
children:
|
|
3023
|
+
children: F
|
|
3024
3024
|
}
|
|
3025
|
-
) : String(
|
|
3025
|
+
) : String(F);
|
|
3026
3026
|
}
|
|
3027
3027
|
});
|
|
3028
3028
|
}
|
|
3029
|
-
return Pr.has(
|
|
3030
|
-
header: v
|
|
3031
|
-
cell: (
|
|
3032
|
-
}) : w.accessor(
|
|
3033
|
-
header: v
|
|
3029
|
+
return Pr.has(v) ? w.accessor(v, {
|
|
3030
|
+
header: K(v),
|
|
3031
|
+
cell: (B) => Ot(B.getValue())
|
|
3032
|
+
}) : w.accessor(v, {
|
|
3033
|
+
header: K(v)
|
|
3034
3034
|
});
|
|
3035
3035
|
});
|
|
3036
|
-
}, [a, t]), M =
|
|
3036
|
+
}, [a, t]), M = Wn({
|
|
3037
3037
|
data: h,
|
|
3038
|
-
columns:
|
|
3038
|
+
columns: $,
|
|
3039
3039
|
getCoreRowModel: Qn()
|
|
3040
3040
|
});
|
|
3041
3041
|
return a ? /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
@@ -3054,7 +3054,7 @@ function Rr() {
|
|
|
3054
3054
|
}
|
|
3055
3055
|
),
|
|
3056
3056
|
/* @__PURE__ */ e(
|
|
3057
|
-
|
|
3057
|
+
X,
|
|
3058
3058
|
{
|
|
3059
3059
|
label: t("fields.From Date", { defaultValue: "From Date" }),
|
|
3060
3060
|
type: "date",
|
|
@@ -3063,7 +3063,7 @@ function Rr() {
|
|
|
3063
3063
|
}
|
|
3064
3064
|
),
|
|
3065
3065
|
/* @__PURE__ */ e(
|
|
3066
|
-
|
|
3066
|
+
X,
|
|
3067
3067
|
{
|
|
3068
3068
|
label: t("fields.To Date", { defaultValue: "To Date" }),
|
|
3069
3069
|
type: "date",
|
|
@@ -3084,24 +3084,24 @@ function Rr() {
|
|
|
3084
3084
|
t("common.showDiscarded")
|
|
3085
3085
|
] })
|
|
3086
3086
|
] }),
|
|
3087
|
-
/* @__PURE__ */ e(qt, { onSelect: (w,
|
|
3087
|
+
/* @__PURE__ */ e(qt, { onSelect: (w, K) => p({ from: w, to: K, page: null }) }),
|
|
3088
3088
|
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: [
|
|
3089
3089
|
/* @__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: [
|
|
3090
|
-
/* @__PURE__ */ e("thead", { className: "bg-surface-subtle", children: M.getHeaderGroups().map((w) => /* @__PURE__ */ e("tr", { children: w.headers.map((
|
|
3090
|
+
/* @__PURE__ */ e("thead", { className: "bg-surface-subtle", children: M.getHeaderGroups().map((w) => /* @__PURE__ */ e("tr", { children: w.headers.map((K) => /* @__PURE__ */ e(
|
|
3091
3091
|
"th",
|
|
3092
3092
|
{
|
|
3093
3093
|
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted",
|
|
3094
|
-
children:
|
|
3095
|
-
|
|
3096
|
-
|
|
3094
|
+
children: K.isPlaceholder ? null : At(
|
|
3095
|
+
K.column.columnDef.header,
|
|
3096
|
+
K.getContext()
|
|
3097
3097
|
)
|
|
3098
3098
|
},
|
|
3099
|
-
|
|
3099
|
+
K.id
|
|
3100
3100
|
)) }, w.id)) }),
|
|
3101
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-line", children: M.getRowModel().rows.map((w) => /* @__PURE__ */ e("tr", { className: "transition-colors hover:bg-surface-subtle", children: w.getVisibleCells().map((
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
) },
|
|
3101
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-line", children: M.getRowModel().rows.map((w) => /* @__PURE__ */ e("tr", { className: "transition-colors hover:bg-surface-subtle", children: w.getVisibleCells().map((K) => /* @__PURE__ */ e("td", { className: "px-4 py-2.5 text-fg", children: At(
|
|
3102
|
+
K.column.columnDef.cell,
|
|
3103
|
+
K.getContext()
|
|
3104
|
+
) }, K.id)) }, w.id)) })
|
|
3105
3105
|
] }) }),
|
|
3106
3106
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-center justify-between gap-3 text-sm text-fg-muted", children: [
|
|
3107
3107
|
/* @__PURE__ */ r("div", { children: [
|
|
@@ -3172,27 +3172,27 @@ function ke({
|
|
|
3172
3172
|
linkDoctype: s,
|
|
3173
3173
|
readOnly: o
|
|
3174
3174
|
}) {
|
|
3175
|
-
const [i, c] = N(n ?? ""), [l, g] = N([]), [d, p] = N(!1), [m, f] = N(!1), [S, x] = N({}), y =
|
|
3175
|
+
const [i, c] = N(n ?? ""), [l, g] = N([]), [d, p] = N(!1), [m, f] = N(!1), [S, x] = N({}), y = ee(null), P = ee(null), D = ee(null), T = ee(null), u = ee(!1);
|
|
3176
3176
|
se(() => {
|
|
3177
3177
|
c(n ?? "");
|
|
3178
3178
|
}, [n]);
|
|
3179
3179
|
const h = Pe(() => {
|
|
3180
3180
|
if (T.current) {
|
|
3181
|
-
const
|
|
3181
|
+
const $ = T.current.getBoundingClientRect();
|
|
3182
3182
|
x({
|
|
3183
3183
|
position: "fixed",
|
|
3184
|
-
top:
|
|
3185
|
-
left:
|
|
3186
|
-
width:
|
|
3184
|
+
top: $.bottom + 4,
|
|
3185
|
+
left: $.left,
|
|
3186
|
+
width: $.width,
|
|
3187
3187
|
zIndex: 9999
|
|
3188
3188
|
});
|
|
3189
3189
|
}
|
|
3190
3190
|
}, []), A = Pe(
|
|
3191
|
-
(
|
|
3191
|
+
($) => {
|
|
3192
3192
|
y.current && clearTimeout(y.current), y.current = setTimeout(async () => {
|
|
3193
3193
|
f(!0);
|
|
3194
3194
|
try {
|
|
3195
|
-
const M = await L.searchLink(s,
|
|
3195
|
+
const M = await L.searchLink(s, $);
|
|
3196
3196
|
g(M), p(!0);
|
|
3197
3197
|
} catch {
|
|
3198
3198
|
g([]);
|
|
@@ -3202,11 +3202,11 @@ function ke({
|
|
|
3202
3202
|
}, 300);
|
|
3203
3203
|
},
|
|
3204
3204
|
[s]
|
|
3205
|
-
), R = (
|
|
3206
|
-
const M =
|
|
3205
|
+
), R = ($) => {
|
|
3206
|
+
const M = $.target.value;
|
|
3207
3207
|
c(M), A(M);
|
|
3208
|
-
}, k = (
|
|
3209
|
-
const M =
|
|
3208
|
+
}, k = ($) => {
|
|
3209
|
+
const M = $.name ?? $.id ?? String($);
|
|
3210
3210
|
c(M), a(M), p(!1), g([]);
|
|
3211
3211
|
}, H = () => {
|
|
3212
3212
|
setTimeout(() => {
|
|
@@ -3218,12 +3218,12 @@ function ke({
|
|
|
3218
3218
|
}, 150);
|
|
3219
3219
|
};
|
|
3220
3220
|
return se(() => {
|
|
3221
|
-
const
|
|
3222
|
-
var
|
|
3221
|
+
const $ = (M) => {
|
|
3222
|
+
var K, v;
|
|
3223
3223
|
const w = M.target;
|
|
3224
|
-
(
|
|
3224
|
+
(K = P.current) != null && K.contains(w) || (v = D.current) != null && v.contains(w) || p(!1);
|
|
3225
3225
|
};
|
|
3226
|
-
return document.addEventListener("mousedown",
|
|
3226
|
+
return document.addEventListener("mousedown", $), () => document.removeEventListener("mousedown", $);
|
|
3227
3227
|
}, []), o ? /* @__PURE__ */ r("div", { children: [
|
|
3228
3228
|
t && /* @__PURE__ */ e("span", { className: "mb-1.5 block text-sm font-medium text-fg", children: t }),
|
|
3229
3229
|
/* @__PURE__ */ e("span", { className: "text-sm text-fg", children: n || "—" })
|
|
@@ -3248,8 +3248,8 @@ function ke({
|
|
|
3248
3248
|
}
|
|
3249
3249
|
),
|
|
3250
3250
|
d && l.length > 0 && Oa(
|
|
3251
|
-
/* @__PURE__ */ e("div", { ref:
|
|
3252
|
-
const w =
|
|
3251
|
+
/* @__PURE__ */ e("div", { ref: D, style: S, className: "max-h-48 overflow-y-auto rounded-lg bg-surface ring-1 ring-line shadow-card-hover", children: l.map(($, M) => {
|
|
3252
|
+
const w = $.name ?? $.id ?? String($);
|
|
3253
3253
|
return /* @__PURE__ */ e(
|
|
3254
3254
|
"button",
|
|
3255
3255
|
{
|
|
@@ -3257,7 +3257,7 @@ function ke({
|
|
|
3257
3257
|
onMouseDown: () => {
|
|
3258
3258
|
u.current = !0;
|
|
3259
3259
|
},
|
|
3260
|
-
onClick: () => k(
|
|
3260
|
+
onClick: () => k($),
|
|
3261
3261
|
className: "block w-full px-3 py-1.5 text-left text-sm text-fg transition-colors hover:bg-surface-subtle",
|
|
3262
3262
|
children: w
|
|
3263
3263
|
},
|
|
@@ -3275,7 +3275,7 @@ const Tt = () => ({
|
|
|
3275
3275
|
is_recommended: 0
|
|
3276
3276
|
}), Ir = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
3277
3277
|
function Cn() {
|
|
3278
|
-
const { name: t } = ft(), n = !t, a = Ee(), s =
|
|
3278
|
+
const { name: t } = ft(), n = !t, a = Ee(), s = Ke(), { t: o } = ne(), i = (v, B) => o(v, { defaultValue: B }), [c, l] = N({
|
|
3279
3279
|
title: "Offerte",
|
|
3280
3280
|
customer: "",
|
|
3281
3281
|
company: "",
|
|
@@ -3283,7 +3283,7 @@ function Cn() {
|
|
|
3283
3283
|
partner_name: "",
|
|
3284
3284
|
partner_email: "",
|
|
3285
3285
|
cover_letter: ""
|
|
3286
|
-
}), [g, d] = N([Tt()]), [p, m] = N(null), [f, S] = N(!1), [x, y] = N(null), P =
|
|
3286
|
+
}), [g, d] = N([Tt()]), [p, m] = N(null), [f, S] = N(!1), [x, y] = N(null), P = ee(null), D = (v, B) => l((C) => ({ ...C, [v]: B })), { data: T } = le({
|
|
3287
3287
|
queryKey: ["document", "proposal", t],
|
|
3288
3288
|
queryFn: () => L.getDocument("proposal", t),
|
|
3289
3289
|
enabled: !n
|
|
@@ -3305,7 +3305,7 @@ function Cn() {
|
|
|
3305
3305
|
const u = async () => {
|
|
3306
3306
|
try {
|
|
3307
3307
|
const { cover_letter: v } = await L.getProposalCoverDefault(c.company, c.customer);
|
|
3308
|
-
v &&
|
|
3308
|
+
v && D("cover_letter", v);
|
|
3309
3309
|
} catch {
|
|
3310
3310
|
}
|
|
3311
3311
|
};
|
|
@@ -3315,32 +3315,38 @@ function Cn() {
|
|
|
3315
3315
|
const h = () => ({
|
|
3316
3316
|
...c,
|
|
3317
3317
|
quotations: g.filter((v) => v.quotation).map((v, B) => ({ ...v, idx: B + 1, is_recommended: v.is_recommended ? 1 : 0 }))
|
|
3318
|
-
}), A =
|
|
3318
|
+
}), A = oe({
|
|
3319
3319
|
mutationFn: async () => n ? L.createDocument("proposal", h()) : L.updateDocument("proposal", t, h()),
|
|
3320
3320
|
onSuccess: (v) => {
|
|
3321
3321
|
y(null), s.invalidateQueries({ queryKey: ["documents", "proposal"] }), s.invalidateQueries({ queryKey: ["document", "proposal", v.name] }), n && a(`/app/proposal/${encodeURIComponent(v.name)}`);
|
|
3322
3322
|
},
|
|
3323
3323
|
onError: (v) => y((v == null ? void 0 : v.message) ?? "Save failed")
|
|
3324
|
-
}), R = (
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
const
|
|
3324
|
+
}), R = oe({
|
|
3325
|
+
mutationFn: () => L.discardDocument("proposal", t),
|
|
3326
|
+
onSuccess: () => {
|
|
3327
|
+
s.invalidateQueries({ queryKey: ["documents", "proposal"] }), a("/app/proposal");
|
|
3328
|
+
},
|
|
3329
|
+
onError: (v) => y((v == null ? void 0 : v.message) ?? "Discard failed")
|
|
3330
|
+
}), k = (v, B) => d((C) => C.map((F, Z) => Z === v ? { ...F, ...B } : F)), H = () => d((v) => [...v, Tt()]), $ = (v) => d((B) => B.length > 1 ? B.filter((C, F) => F !== v) : B), M = (v, B) => d((C) => {
|
|
3331
|
+
const F = v + B;
|
|
3332
|
+
if (F < 0 || F >= C.length) return C;
|
|
3333
|
+
const Z = [...C];
|
|
3334
|
+
return [Z[v], Z[F]] = [Z[F], Z[v]], Z;
|
|
3335
|
+
}), w = async (v) => {
|
|
3336
|
+
var C;
|
|
3337
|
+
const B = (C = v.target.files) == null ? void 0 : C[0];
|
|
3332
3338
|
if (v.target.value = "", !(!B || n)) {
|
|
3333
3339
|
S(!0), y(null);
|
|
3334
3340
|
try {
|
|
3335
|
-
const
|
|
3336
|
-
m(
|
|
3337
|
-
} catch (
|
|
3338
|
-
y((
|
|
3341
|
+
const F = await L.uploadProposalAppendix(t, B);
|
|
3342
|
+
m(F.appendix_filename), s.invalidateQueries({ queryKey: ["document", "proposal", t] });
|
|
3343
|
+
} catch (F) {
|
|
3344
|
+
y((F == null ? void 0 : F.message) ?? "Upload failed");
|
|
3339
3345
|
} finally {
|
|
3340
3346
|
S(!1);
|
|
3341
3347
|
}
|
|
3342
3348
|
}
|
|
3343
|
-
},
|
|
3349
|
+
}, K = async () => {
|
|
3344
3350
|
if (!n) {
|
|
3345
3351
|
S(!0);
|
|
3346
3352
|
try {
|
|
@@ -3359,19 +3365,30 @@ function Cn() {
|
|
|
3359
3365
|
!n && /* @__PURE__ */ e("p", { className: "text-sm text-fg-muted", children: t })
|
|
3360
3366
|
] }),
|
|
3361
3367
|
/* @__PURE__ */ r("div", { className: "flex gap-2", children: [
|
|
3368
|
+
!n && /* @__PURE__ */ e(
|
|
3369
|
+
J,
|
|
3370
|
+
{
|
|
3371
|
+
variant: "danger",
|
|
3372
|
+
disabled: R.isPending,
|
|
3373
|
+
onClick: () => {
|
|
3374
|
+
window.confirm(i("proposal.discardConfirm", "Discard this proposal? It will be hidden from the list.")) && R.mutate();
|
|
3375
|
+
},
|
|
3376
|
+
children: R.isPending ? i("common.discarding", "Discarding…") : i("common.discard", "Discard")
|
|
3377
|
+
}
|
|
3378
|
+
),
|
|
3362
3379
|
!n && /* @__PURE__ */ e(J, { variant: "secondary", onClick: () => window.open(L.proposalPdfUrl(t), "_blank"), children: i("common.pdf", "PDF") }),
|
|
3363
3380
|
/* @__PURE__ */ e(J, { onClick: () => A.mutate(), disabled: A.isPending, children: A.isPending ? i("common.saving", "Saving…") : i("common.save", "Save") })
|
|
3364
3381
|
] })
|
|
3365
3382
|
] }),
|
|
3366
3383
|
x && /* @__PURE__ */ e("div", { className: "rounded-lg bg-red-50 px-4 py-2 text-sm text-red-700 ring-1 ring-red-200", children: x }),
|
|
3367
|
-
/* @__PURE__ */ r(
|
|
3384
|
+
/* @__PURE__ */ r(U, { className: "space-y-4 p-5", children: [
|
|
3368
3385
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
3369
|
-
/* @__PURE__ */ e(
|
|
3370
|
-
/* @__PURE__ */ e(
|
|
3371
|
-
/* @__PURE__ */ e(ke, { label: i("fields.Customer", "Customer"), value: c.customer, onChange: (v) =>
|
|
3372
|
-
/* @__PURE__ */ e(ke, { label: i("fields.Company", "Company"), value: c.company, onChange: (v) =>
|
|
3373
|
-
/* @__PURE__ */ e(
|
|
3374
|
-
/* @__PURE__ */ e(
|
|
3386
|
+
/* @__PURE__ */ e(X, { label: i("fields.Title", "Title"), value: c.title, onChange: (v) => D("title", v.target.value) }),
|
|
3387
|
+
/* @__PURE__ */ e(X, { label: i("fields.Date", "Date"), type: "date", value: c.proposal_date, onChange: (v) => D("proposal_date", v.target.value) }),
|
|
3388
|
+
/* @__PURE__ */ e(ke, { label: i("fields.Customer", "Customer"), value: c.customer, onChange: (v) => D("customer", v), linkDoctype: "customer", readOnly: !1 }),
|
|
3389
|
+
/* @__PURE__ */ e(ke, { label: i("fields.Company", "Company"), value: c.company, onChange: (v) => D("company", v), linkDoctype: "company", readOnly: !1 }),
|
|
3390
|
+
/* @__PURE__ */ e(X, { label: i("fields.Partner", "Account Manager"), value: c.partner_name, onChange: (v) => D("partner_name", v.target.value) }),
|
|
3391
|
+
/* @__PURE__ */ e(X, { label: i("fields.Partner Email", "Account Manager Email"), value: c.partner_email, onChange: (v) => D("partner_email", v.target.value) })
|
|
3375
3392
|
] }),
|
|
3376
3393
|
/* @__PURE__ */ r("div", { children: [
|
|
3377
3394
|
/* @__PURE__ */ r("div", { className: "mb-1.5 flex items-center justify-between", children: [
|
|
@@ -3382,46 +3399,46 @@ function Cn() {
|
|
|
3382
3399
|
"textarea",
|
|
3383
3400
|
{
|
|
3384
3401
|
value: c.cover_letter,
|
|
3385
|
-
onChange: (v) =>
|
|
3402
|
+
onChange: (v) => D("cover_letter", v.target.value),
|
|
3386
3403
|
rows: 5,
|
|
3387
3404
|
className: "block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line focus:outline-none focus:ring-2 focus:ring-brand/30"
|
|
3388
3405
|
}
|
|
3389
3406
|
)
|
|
3390
3407
|
] })
|
|
3391
3408
|
] }),
|
|
3392
|
-
/* @__PURE__ */ r(
|
|
3409
|
+
/* @__PURE__ */ r(U, { className: "space-y-4 p-5", children: [
|
|
3393
3410
|
/* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
|
|
3394
3411
|
/* @__PURE__ */ e("h2", { className: "font-semibold text-fg", children: i("proposal.offers", "Offers") }),
|
|
3395
|
-
/* @__PURE__ */ e(J, { size: "sm", variant: "secondary", onClick:
|
|
3412
|
+
/* @__PURE__ */ e(J, { size: "sm", variant: "secondary", onClick: H, children: i("proposal.addOffer", "Add offer") })
|
|
3396
3413
|
] }),
|
|
3397
3414
|
g.map((v, B) => /* @__PURE__ */ r("div", { className: "rounded-lg p-3 ring-1 ring-line", children: [
|
|
3398
3415
|
/* @__PURE__ */ r("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
3399
3416
|
/* @__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: Ir[B] ?? B + 1 }),
|
|
3400
|
-
/* @__PURE__ */ e("div", { className: "flex-1", children: /* @__PURE__ */ e(ke, { label: "", value: v.quotation, onChange: (
|
|
3401
|
-
/* @__PURE__ */ e("button", { type: "button", onClick: () =>
|
|
3402
|
-
/* @__PURE__ */ e("button", { type: "button", onClick: () =>
|
|
3403
|
-
/* @__PURE__ */ e("button", { type: "button", onClick: () =>
|
|
3417
|
+
/* @__PURE__ */ e("div", { className: "flex-1", children: /* @__PURE__ */ e(ke, { label: "", value: v.quotation, onChange: (C) => k(B, { quotation: C }), linkDoctype: "quotation", readOnly: !1 }) }),
|
|
3418
|
+
/* @__PURE__ */ e("button", { type: "button", onClick: () => M(B, -1), disabled: B === 0, className: "px-1 text-fg-muted disabled:opacity-30", children: "↑" }),
|
|
3419
|
+
/* @__PURE__ */ e("button", { type: "button", onClick: () => M(B, 1), disabled: B === g.length - 1, className: "px-1 text-fg-muted disabled:opacity-30", children: "↓" }),
|
|
3420
|
+
/* @__PURE__ */ e("button", { type: "button", onClick: () => $(B), className: "px-1 text-red-500 hover:text-red-700", children: "✕" })
|
|
3404
3421
|
] }),
|
|
3405
3422
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-1 gap-2 pl-8 sm:grid-cols-2", children: [
|
|
3406
|
-
/* @__PURE__ */ e(
|
|
3423
|
+
/* @__PURE__ */ e(X, { label: i("proposal.positionTitle", "Position title"), value: v.position_title, onChange: (C) => k(B, { position_title: C.target.value }), placeholder: i("proposal.positionTitleHint", "defaults to the offer's first item") }),
|
|
3407
3424
|
/* @__PURE__ */ r("label", { className: "flex items-center gap-2 self-end pb-2 text-sm text-fg", children: [
|
|
3408
|
-
/* @__PURE__ */ e("input", { type: "checkbox", checked: !!v.is_recommended, onChange: (
|
|
3425
|
+
/* @__PURE__ */ e("input", { type: "checkbox", checked: !!v.is_recommended, onChange: (C) => k(B, { is_recommended: C.target.checked ? 1 : 0 }) }),
|
|
3409
3426
|
i("proposal.recommended", "Mark as recommendation")
|
|
3410
3427
|
] }),
|
|
3411
|
-
/* @__PURE__ */ e("div", { className: "sm:col-span-2", children: /* @__PURE__ */ e(
|
|
3428
|
+
/* @__PURE__ */ e("div", { className: "sm:col-span-2", children: /* @__PURE__ */ e(X, { label: i("proposal.blurb", "Description"), value: v.position_blurb, onChange: (C) => k(B, { position_blurb: C.target.value }), placeholder: i("proposal.blurbHint", "defaults to the offer's notes") }) })
|
|
3412
3429
|
] })
|
|
3413
3430
|
] }, B))
|
|
3414
3431
|
] }),
|
|
3415
|
-
/* @__PURE__ */ r(
|
|
3432
|
+
/* @__PURE__ */ r(U, { className: "space-y-3 p-5", children: [
|
|
3416
3433
|
/* @__PURE__ */ e("h2", { className: "font-semibold text-fg", children: i("proposal.appendix", "Appendix PDF") }),
|
|
3417
3434
|
n ? /* @__PURE__ */ e("p", { className: "text-sm text-fg-muted", children: i("proposal.saveFirst", "Save the proposal first to attach an appendix.") }) : p ? /* @__PURE__ */ r("div", { className: "flex items-center gap-3 text-sm", children: [
|
|
3418
3435
|
/* @__PURE__ */ r("span", { className: "text-fg", children: [
|
|
3419
3436
|
"📎 ",
|
|
3420
3437
|
p
|
|
3421
3438
|
] }),
|
|
3422
|
-
/* @__PURE__ */ e("button", { type: "button", onClick:
|
|
3439
|
+
/* @__PURE__ */ e("button", { type: "button", onClick: K, disabled: f, className: "text-red-500 hover:underline", children: i("common.remove", "Remove") })
|
|
3423
3440
|
] }) : /* @__PURE__ */ r("div", { children: [
|
|
3424
|
-
/* @__PURE__ */ e("input", { ref: P, type: "file", accept: "application/pdf", onChange:
|
|
3441
|
+
/* @__PURE__ */ e("input", { ref: P, type: "file", accept: "application/pdf", onChange: w, className: "hidden" }),
|
|
3425
3442
|
/* @__PURE__ */ e(J, { size: "sm", variant: "secondary", disabled: f, onClick: () => {
|
|
3426
3443
|
var v;
|
|
3427
3444
|
return (v = P.current) == null ? void 0 : v.click();
|
|
@@ -3434,7 +3451,7 @@ function Cn() {
|
|
|
3434
3451
|
const Lr = ["25", "50", "100", "200"];
|
|
3435
3452
|
function Br() {
|
|
3436
3453
|
var u;
|
|
3437
|
-
const { type: t } = ft(), n = Ee(), s = (u = Ct().state) == null ? void 0 : u.notice, [o] =
|
|
3454
|
+
const { type: t } = ft(), n = Ee(), s = (u = Ct().state) == null ? void 0 : u.notice, [o] = te("per_page", 50), [i] = te("page", 1), c = i - 1, l = Qe(), g = (h) => l({ page: h === 0 ? null : h + 1 }), d = (h) => l({ per_page: h, page: null }), { data: p, isLoading: m } = le({
|
|
3438
3455
|
queryKey: ["masters", t, c, o],
|
|
3439
3456
|
queryFn: () => L.listMasters(t, {
|
|
3440
3457
|
include_disabled: 1,
|
|
@@ -3442,21 +3459,21 @@ function Br() {
|
|
|
3442
3459
|
offset: c * o
|
|
3443
3460
|
}),
|
|
3444
3461
|
enabled: !!t
|
|
3445
|
-
}), f = (p == null ? void 0 : p.rows) ?? [], S = (p == null ? void 0 : p.total) ?? 0, x = Math.max(1, Math.ceil(S / o)), y = S === 0 ? 0 : c * o + 1, P = Math.min(S, (c + 1) * o),
|
|
3462
|
+
}), f = (p == null ? void 0 : p.rows) ?? [], S = (p == null ? void 0 : p.total) ?? 0, x = Math.max(1, Math.ceil(S / o)), y = S === 0 ? 0 : c * o + 1, P = Math.min(S, (c + 1) * o), D = Re(() => {
|
|
3446
3463
|
if (!f || f.length === 0) return [];
|
|
3447
|
-
const h =
|
|
3464
|
+
const h = Kn();
|
|
3448
3465
|
return Object.keys(f[0]).map(
|
|
3449
3466
|
(R) => h.accessor(R, {
|
|
3450
3467
|
header: R.split("_").map((k) => k.charAt(0).toUpperCase() + k.slice(1)).join(" "),
|
|
3451
3468
|
cell: (k) => {
|
|
3452
3469
|
const H = k.getValue();
|
|
3453
3470
|
if (R === "name") {
|
|
3454
|
-
const
|
|
3471
|
+
const $ = k.row.original.disabled === 1;
|
|
3455
3472
|
return /* @__PURE__ */ e(
|
|
3456
3473
|
ve,
|
|
3457
3474
|
{
|
|
3458
3475
|
to: `/masters/${t}/${H}`,
|
|
3459
|
-
className:
|
|
3476
|
+
className: $ ? "font-medium text-fg-muted" : "font-medium text-brand transition-colors hover:text-brand/80",
|
|
3460
3477
|
children: H
|
|
3461
3478
|
}
|
|
3462
3479
|
);
|
|
@@ -3465,9 +3482,9 @@ function Br() {
|
|
|
3465
3482
|
}
|
|
3466
3483
|
})
|
|
3467
3484
|
);
|
|
3468
|
-
}, [f, t]), T =
|
|
3485
|
+
}, [f, t]), T = Wn({
|
|
3469
3486
|
data: f,
|
|
3470
|
-
columns:
|
|
3487
|
+
columns: D,
|
|
3471
3488
|
getCoreRowModel: Qn()
|
|
3472
3489
|
});
|
|
3473
3490
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
@@ -3624,7 +3641,7 @@ const Er = {
|
|
|
3624
3641
|
}, Dn = /* @__PURE__ */ new Set(["customer", "supplier", "item", "warehouse"]);
|
|
3625
3642
|
function _n() {
|
|
3626
3643
|
var R;
|
|
3627
|
-
const { type: t, name: n } = ft(), a = Ee(), s =
|
|
3644
|
+
const { type: t, name: n } = ft(), a = Ee(), s = Ke(), { t: o } = ne(), i = !n || n === "new", c = Or[t ?? ""] ?? t ?? "", l = o(`masters.${t}.one`, { defaultValue: c }), g = Er[t ?? ""] ?? [], d = (k) => o(`fields.${k.label}`, { defaultValue: k.label }), [p, m] = N({}), { data: f, isLoading: S } = le({
|
|
3628
3645
|
queryKey: ["master", t, n],
|
|
3629
3646
|
queryFn: () => L.getMaster(t, n),
|
|
3630
3647
|
enabled: !!t && !!n && !i
|
|
@@ -3637,17 +3654,17 @@ function _n() {
|
|
|
3637
3654
|
}), m(k);
|
|
3638
3655
|
} else f && m(f);
|
|
3639
3656
|
}, [i, f, g]);
|
|
3640
|
-
const x =
|
|
3657
|
+
const x = oe({
|
|
3641
3658
|
mutationFn: (k) => L.createMaster(t, k),
|
|
3642
3659
|
onSuccess: (k) => {
|
|
3643
3660
|
s.invalidateQueries({ queryKey: ["masters", t] }), a(`/masters/${t}/${k.name}`, { replace: !0 });
|
|
3644
3661
|
}
|
|
3645
|
-
}), y =
|
|
3662
|
+
}), y = oe({
|
|
3646
3663
|
mutationFn: (k) => L.updateMaster(t, n, k),
|
|
3647
3664
|
onSuccess: () => {
|
|
3648
3665
|
s.invalidateQueries({ queryKey: ["master", t, n] }), s.invalidateQueries({ queryKey: ["masters", t] });
|
|
3649
3666
|
}
|
|
3650
|
-
}), P =
|
|
3667
|
+
}), P = oe({
|
|
3651
3668
|
mutationFn: () => L.deleteMaster(t, n),
|
|
3652
3669
|
onSuccess: (k) => {
|
|
3653
3670
|
if (s.invalidateQueries({ queryKey: ["masters", t] }), (k == null ? void 0 : k.status) === "disabled") {
|
|
@@ -3665,14 +3682,14 @@ function _n() {
|
|
|
3665
3682
|
}
|
|
3666
3683
|
a(`/masters/${t}`, { replace: !0 });
|
|
3667
3684
|
}
|
|
3668
|
-
}),
|
|
3685
|
+
}), D = () => {
|
|
3669
3686
|
if (A.length > 0) return;
|
|
3670
3687
|
const k = t === "company" && !p.name ? { ...p, name: p.company_name } : p;
|
|
3671
3688
|
i ? x.mutate(k) : y.mutate(k);
|
|
3672
3689
|
}, T = () => {
|
|
3673
3690
|
window.confirm(o("masterForm.deleteConfirm", { label: l })) && P.mutate();
|
|
3674
3691
|
}, u = (k, H) => {
|
|
3675
|
-
m((
|
|
3692
|
+
m(($) => ({ ...$, [k]: H }));
|
|
3676
3693
|
};
|
|
3677
3694
|
if (!i && S)
|
|
3678
3695
|
return /* @__PURE__ */ e("p", { className: "text-fg-muted", children: o("common.loading") });
|
|
@@ -3683,7 +3700,7 @@ function _n() {
|
|
|
3683
3700
|
});
|
|
3684
3701
|
return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
3685
3702
|
/* @__PURE__ */ e("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ r("div", { className: "flex gap-2", children: [
|
|
3686
|
-
/* @__PURE__ */ e(J, { onClick:
|
|
3703
|
+
/* @__PURE__ */ e(J, { onClick: D, disabled: h || A.length > 0, children: o(h ? "common.saving" : "common.save") }),
|
|
3687
3704
|
!i && /* @__PURE__ */ e(
|
|
3688
3705
|
J,
|
|
3689
3706
|
{
|
|
@@ -3697,8 +3714,8 @@ function _n() {
|
|
|
3697
3714
|
(x.error || y.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 = x.error ?? y.error ?? P.error) == null ? void 0 : R.message) ?? o("common.errorOccurred") }),
|
|
3698
3715
|
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(", ") }) }),
|
|
3699
3716
|
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 }) }),
|
|
3700
|
-
/* @__PURE__ */ e(
|
|
3701
|
-
const
|
|
3717
|
+
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: g.map((k) => {
|
|
3718
|
+
const $ = k.name === "name" && !i || k.readOnly, M = k.required && !(i && k.name === "name" && Dn.has(t ?? ""));
|
|
3702
3719
|
if (k.type === "select" && k.options)
|
|
3703
3720
|
return /* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
|
|
3704
3721
|
rt,
|
|
@@ -3707,8 +3724,8 @@ function _n() {
|
|
|
3707
3724
|
options: k.options,
|
|
3708
3725
|
value: p[k.name] ?? "",
|
|
3709
3726
|
required: M,
|
|
3710
|
-
disabled:
|
|
3711
|
-
onChange: (
|
|
3727
|
+
disabled: $,
|
|
3728
|
+
onChange: (K) => u(k.name, K.target.value)
|
|
3712
3729
|
}
|
|
3713
3730
|
) }, k.name);
|
|
3714
3731
|
if (k.type === "textarea")
|
|
@@ -3721,26 +3738,26 @@ function _n() {
|
|
|
3721
3738
|
rows: 3,
|
|
3722
3739
|
value: p[k.name] ?? "",
|
|
3723
3740
|
required: M,
|
|
3724
|
-
readOnly:
|
|
3725
|
-
disabled:
|
|
3726
|
-
onChange: (
|
|
3741
|
+
readOnly: $,
|
|
3742
|
+
disabled: $,
|
|
3743
|
+
onChange: (K) => u(k.name, K.target.value)
|
|
3727
3744
|
}
|
|
3728
3745
|
)
|
|
3729
3746
|
] }, k.name);
|
|
3730
3747
|
const w = k.type === "number" || k.type === "currency" ? "number" : k.type === "date" ? "date" : "text";
|
|
3731
3748
|
return /* @__PURE__ */ e(
|
|
3732
|
-
|
|
3749
|
+
X,
|
|
3733
3750
|
{
|
|
3734
3751
|
label: d(k),
|
|
3735
3752
|
type: w,
|
|
3736
3753
|
step: k.type === "currency" ? "0.01" : void 0,
|
|
3737
3754
|
required: M,
|
|
3738
|
-
readOnly:
|
|
3739
|
-
disabled:
|
|
3755
|
+
readOnly: $,
|
|
3756
|
+
disabled: $,
|
|
3740
3757
|
value: p[k.name] ?? "",
|
|
3741
|
-
onChange: (
|
|
3758
|
+
onChange: (K) => u(
|
|
3742
3759
|
k.name,
|
|
3743
|
-
w === "number" ? parseFloat(
|
|
3760
|
+
w === "number" ? parseFloat(K.target.value) || 0 : K.target.value
|
|
3744
3761
|
)
|
|
3745
3762
|
},
|
|
3746
3763
|
k.name
|
|
@@ -3749,59 +3766,59 @@ function _n() {
|
|
|
3749
3766
|
] });
|
|
3750
3767
|
}
|
|
3751
3768
|
function qr(t) {
|
|
3752
|
-
const { data: n, isLoading: a, error: s, refetch: o } =
|
|
3769
|
+
const { data: n, isLoading: a, error: s, refetch: o } = le({
|
|
3753
3770
|
queryKey: ["report", "trial-balance", t],
|
|
3754
3771
|
queryFn: () => L.trialBalance(t)
|
|
3755
3772
|
});
|
|
3756
3773
|
return { data: n, isLoading: a, error: s, refetch: o };
|
|
3757
3774
|
}
|
|
3758
3775
|
function Fr(t) {
|
|
3759
|
-
const { data: n, isLoading: a, error: s, refetch: o } =
|
|
3776
|
+
const { data: n, isLoading: a, error: s, refetch: o } = le({
|
|
3760
3777
|
queryKey: ["report", "general-ledger", t],
|
|
3761
3778
|
queryFn: () => L.generalLedger(t)
|
|
3762
3779
|
});
|
|
3763
3780
|
return { data: n, isLoading: a, error: s, refetch: o };
|
|
3764
3781
|
}
|
|
3765
3782
|
function zr(t) {
|
|
3766
|
-
const { data: n, isLoading: a, error: s, refetch: o } =
|
|
3783
|
+
const { data: n, isLoading: a, error: s, refetch: o } = le({
|
|
3767
3784
|
queryKey: ["report", "stock-balance", t],
|
|
3768
3785
|
queryFn: () => L.stockBalance(t)
|
|
3769
3786
|
});
|
|
3770
3787
|
return { data: n, isLoading: a, error: s, refetch: o };
|
|
3771
3788
|
}
|
|
3772
3789
|
function Mr(t) {
|
|
3773
|
-
const { data: n, isLoading: a, error: s, refetch: o } =
|
|
3790
|
+
const { data: n, isLoading: a, error: s, refetch: o } = le({
|
|
3774
3791
|
queryKey: ["report", "profit-and-loss", t],
|
|
3775
3792
|
queryFn: () => L.profitAndLoss(t)
|
|
3776
3793
|
});
|
|
3777
3794
|
return { data: n, isLoading: a, error: s, refetch: o };
|
|
3778
3795
|
}
|
|
3779
3796
|
function $r(t) {
|
|
3780
|
-
const { data: n, isLoading: a, error: s, refetch: o } =
|
|
3797
|
+
const { data: n, isLoading: a, error: s, refetch: o } = le({
|
|
3781
3798
|
queryKey: ["report", "balance-sheet", t],
|
|
3782
3799
|
queryFn: () => L.balanceSheet(t)
|
|
3783
3800
|
});
|
|
3784
3801
|
return { data: n, isLoading: a, error: s, refetch: o };
|
|
3785
3802
|
}
|
|
3786
3803
|
function Ur(t) {
|
|
3787
|
-
const { data: n, isLoading: a, error: s, refetch: o } =
|
|
3804
|
+
const { data: n, isLoading: a, error: s, refetch: o } = le({
|
|
3788
3805
|
queryKey: ["report", "ar-aging", t],
|
|
3789
3806
|
queryFn: () => L.arAging(t)
|
|
3790
3807
|
});
|
|
3791
3808
|
return { data: n, isLoading: a, error: s, refetch: o };
|
|
3792
3809
|
}
|
|
3793
3810
|
function Vr(t) {
|
|
3794
|
-
const { data: n, isLoading: a, error: s, refetch: o } =
|
|
3811
|
+
const { data: n, isLoading: a, error: s, refetch: o } = le({
|
|
3795
3812
|
queryKey: ["report", "ap-aging", t],
|
|
3796
3813
|
queryFn: () => L.apAging(t)
|
|
3797
3814
|
});
|
|
3798
3815
|
return { data: n, isLoading: a, error: s, refetch: o };
|
|
3799
3816
|
}
|
|
3800
3817
|
function jr() {
|
|
3801
|
-
const { t } =
|
|
3818
|
+
const { t } = ne(), [n] = te("company", ""), [a] = te("from", ""), [s] = te("to", ""), o = Qe(), [i, c] = N(n), [l, g] = N(a), [d, p] = N(s), m = We(i), f = (u) => Oe(u, m), S = Re(() => {
|
|
3802
3819
|
const u = {};
|
|
3803
3820
|
return n && (u.company = n), a && (u.from_date = a), s && (u.to_date = s), u;
|
|
3804
|
-
}, [n, a, s]), { data: x, isLoading: y, refetch: P } = qr(S),
|
|
3821
|
+
}, [n, a, s]), { data: x, isLoading: y, refetch: P } = qr(S), D = () => {
|
|
3805
3822
|
o({
|
|
3806
3823
|
company: i || null,
|
|
3807
3824
|
from: l || null,
|
|
@@ -3821,7 +3838,7 @@ function jr() {
|
|
|
3821
3838
|
}
|
|
3822
3839
|
),
|
|
3823
3840
|
/* @__PURE__ */ e(
|
|
3824
|
-
|
|
3841
|
+
X,
|
|
3825
3842
|
{
|
|
3826
3843
|
label: t("fields.From Date", { defaultValue: "From Date" }),
|
|
3827
3844
|
type: "date",
|
|
@@ -3830,7 +3847,7 @@ function jr() {
|
|
|
3830
3847
|
}
|
|
3831
3848
|
),
|
|
3832
3849
|
/* @__PURE__ */ e(
|
|
3833
|
-
|
|
3850
|
+
X,
|
|
3834
3851
|
{
|
|
3835
3852
|
label: t("fields.To Date", { defaultValue: "To Date" }),
|
|
3836
3853
|
type: "date",
|
|
@@ -3838,12 +3855,12 @@ function jr() {
|
|
|
3838
3855
|
onChange: (u) => p(u.target.value)
|
|
3839
3856
|
}
|
|
3840
3857
|
),
|
|
3841
|
-
/* @__PURE__ */ e(J, { onClick:
|
|
3858
|
+
/* @__PURE__ */ e(J, { onClick: D, children: t("common.apply") })
|
|
3842
3859
|
] }),
|
|
3843
3860
|
/* @__PURE__ */ e(qt, { onSelect: (u, h) => {
|
|
3844
3861
|
g(u), p(h), o({ from: u, to: h });
|
|
3845
3862
|
} }),
|
|
3846
|
-
y ? /* @__PURE__ */ e("p", { className: "text-fg-muted", children: t("common.loading") }) : !x || !x.rows || x.rows.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-fg-muted", children: t("reports.noData") }) : /* @__PURE__ */ r(
|
|
3863
|
+
y ? /* @__PURE__ */ e("p", { className: "text-fg-muted", children: t("common.loading") }) : !x || !x.rows || x.rows.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-fg-muted", children: t("reports.noData") }) : /* @__PURE__ */ r(U, { children: [
|
|
3847
3864
|
/* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-line text-sm", children: [
|
|
3848
3865
|
/* @__PURE__ */ e("thead", { className: "bg-surface-subtle", children: /* @__PURE__ */ r("tr", { children: [
|
|
3849
3866
|
/* @__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" }) }),
|
|
@@ -3877,17 +3894,17 @@ function jr() {
|
|
|
3877
3894
|
function Gr(t) {
|
|
3878
3895
|
return t.toLowerCase().replace(/\s+/g, "-");
|
|
3879
3896
|
}
|
|
3880
|
-
const
|
|
3881
|
-
function
|
|
3882
|
-
const { t } =
|
|
3883
|
-
const
|
|
3884
|
-
return n && (
|
|
3885
|
-
}, [n, a, s, o, i, l]), { data: R, isLoading: k, refetch: H } = Fr(A),
|
|
3897
|
+
const Kr = ["25", "50", "100", "200"];
|
|
3898
|
+
function Wr() {
|
|
3899
|
+
const { t } = ne(), [n] = te("account", ""), [a] = te("party", ""), [s] = te("from", ""), [o] = te("to", ""), [i] = te("per_page", 50), [c] = te("page", 1), l = c - 1, g = Qe(), d = (C) => g({ page: C === 0 ? null : C + 1 }), p = (C) => g({ per_page: C, page: null }), [m, f] = N(n), [S, x] = N(a), [y, P] = N(s), [D, T] = N(o), u = We(), h = (C) => Oe(C, u), A = Re(() => {
|
|
3900
|
+
const C = {};
|
|
3901
|
+
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;
|
|
3902
|
+
}, [n, a, s, o, i, l]), { data: R, isLoading: k, refetch: H } = Fr(A), $ = (R == null ? void 0 : R.rows) ?? [], M = (R == null ? void 0 : R.total) ?? 0, w = Math.max(1, Math.ceil(M / i)), K = M === 0 ? 0 : l * i + 1, v = Math.min(M, (l + 1) * i), B = () => {
|
|
3886
3903
|
g({
|
|
3887
3904
|
account: m || null,
|
|
3888
3905
|
party: S || null,
|
|
3889
3906
|
from: y || null,
|
|
3890
|
-
to:
|
|
3907
|
+
to: D || null,
|
|
3891
3908
|
page: null
|
|
3892
3909
|
}), H();
|
|
3893
3910
|
};
|
|
@@ -3914,30 +3931,30 @@ function Kr() {
|
|
|
3914
3931
|
}
|
|
3915
3932
|
),
|
|
3916
3933
|
/* @__PURE__ */ e(
|
|
3917
|
-
|
|
3934
|
+
X,
|
|
3918
3935
|
{
|
|
3919
3936
|
label: t("fields.From Date", { defaultValue: "From Date" }),
|
|
3920
3937
|
type: "date",
|
|
3921
3938
|
value: y,
|
|
3922
|
-
onChange: (
|
|
3939
|
+
onChange: (C) => P(C.target.value)
|
|
3923
3940
|
}
|
|
3924
3941
|
),
|
|
3925
3942
|
/* @__PURE__ */ e(
|
|
3926
|
-
|
|
3943
|
+
X,
|
|
3927
3944
|
{
|
|
3928
3945
|
label: t("fields.To Date", { defaultValue: "To Date" }),
|
|
3929
3946
|
type: "date",
|
|
3930
|
-
value:
|
|
3931
|
-
onChange: (
|
|
3947
|
+
value: D,
|
|
3948
|
+
onChange: (C) => T(C.target.value)
|
|
3932
3949
|
}
|
|
3933
3950
|
),
|
|
3934
|
-
/* @__PURE__ */ e(J, { onClick:
|
|
3951
|
+
/* @__PURE__ */ e(J, { onClick: B, children: t("common.apply") })
|
|
3935
3952
|
] }),
|
|
3936
|
-
/* @__PURE__ */ e(qt, { onSelect: (
|
|
3937
|
-
P(
|
|
3953
|
+
/* @__PURE__ */ e(qt, { onSelect: (C, F) => {
|
|
3954
|
+
P(C), T(F), g({ from: C, to: F, page: null });
|
|
3938
3955
|
} }),
|
|
3939
|
-
k ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) :
|
|
3940
|
-
/* @__PURE__ */ e(
|
|
3956
|
+
k ? /* @__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: [
|
|
3957
|
+
/* @__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: [
|
|
3941
3958
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
3942
3959
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Date", { defaultValue: "Date" }) }),
|
|
3943
3960
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Account", { defaultValue: "Account" }) }),
|
|
@@ -3948,32 +3965,32 @@ function Kr() {
|
|
|
3948
3965
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Voucher Type", { defaultValue: "Voucher Type" }) }),
|
|
3949
3966
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Voucher No", { defaultValue: "Voucher No" }) })
|
|
3950
3967
|
] }) }),
|
|
3951
|
-
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children:
|
|
3952
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-500", children: Ot(
|
|
3953
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-900", children:
|
|
3954
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children:
|
|
3955
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: h(
|
|
3956
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: h(
|
|
3957
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right font-medium", children: h(
|
|
3958
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children:
|
|
3959
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2", children:
|
|
3968
|
+
/* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: $.map((C, F) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
|
|
3969
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-500", children: Ot(C.posting_date ?? C.date) }),
|
|
3970
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-900", children: C.account }),
|
|
3971
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: C.party ?? "-" }),
|
|
3972
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: h(C.debit) }),
|
|
3973
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: h(C.credit) }),
|
|
3974
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right font-medium", children: h(C.balance) }),
|
|
3975
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: C.voucher_type ?? "-" }),
|
|
3976
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2", children: C.voucher_type && C.voucher_no ? /* @__PURE__ */ e(
|
|
3960
3977
|
ve,
|
|
3961
3978
|
{
|
|
3962
|
-
to: `/app/${Gr(
|
|
3979
|
+
to: `/app/${Gr(C.voucher_type)}/${C.voucher_no}`,
|
|
3963
3980
|
className: "font-medium text-blue-600 hover:text-blue-800",
|
|
3964
|
-
children:
|
|
3981
|
+
children: C.voucher_no
|
|
3965
3982
|
}
|
|
3966
|
-
) :
|
|
3967
|
-
] },
|
|
3983
|
+
) : C.voucher_no ?? "-" })
|
|
3984
|
+
] }, F)) })
|
|
3968
3985
|
] }) }) }),
|
|
3969
3986
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-center justify-between gap-3 text-sm text-gray-600", children: [
|
|
3970
3987
|
/* @__PURE__ */ r("div", { children: [
|
|
3971
3988
|
t("common.showing"),
|
|
3972
3989
|
" ",
|
|
3973
3990
|
/* @__PURE__ */ r("span", { className: "font-medium text-gray-900", children: [
|
|
3974
|
-
|
|
3991
|
+
K,
|
|
3975
3992
|
"–",
|
|
3976
|
-
|
|
3993
|
+
v
|
|
3977
3994
|
] }),
|
|
3978
3995
|
" ",
|
|
3979
3996
|
t("common.of"),
|
|
@@ -3987,9 +4004,9 @@ function Kr() {
|
|
|
3987
4004
|
"select",
|
|
3988
4005
|
{
|
|
3989
4006
|
value: i,
|
|
3990
|
-
onChange: (
|
|
4007
|
+
onChange: (C) => p(Number(C.target.value)),
|
|
3991
4008
|
className: "rounded border border-gray-300 bg-white px-2 py-1 text-sm",
|
|
3992
|
-
children:
|
|
4009
|
+
children: Kr.map((C) => /* @__PURE__ */ e("option", { value: C, children: C }, C))
|
|
3993
4010
|
}
|
|
3994
4011
|
)
|
|
3995
4012
|
] }),
|
|
@@ -4026,7 +4043,7 @@ function Kr() {
|
|
|
4026
4043
|
] });
|
|
4027
4044
|
}
|
|
4028
4045
|
function Qr() {
|
|
4029
|
-
const { t } =
|
|
4046
|
+
const { t } = ne(), [n] = te("item_code", ""), [a] = te("warehouse", ""), s = Qe(), [o, i] = N(n), [c, l] = N(a), g = We(), d = (y) => Oe(y, g), p = Re(() => {
|
|
4030
4047
|
const y = {};
|
|
4031
4048
|
return n && (y.item_code = n), a && (y.warehouse = a), y;
|
|
4032
4049
|
}, [n, a]), { data: m, isLoading: f, refetch: S } = zr(p), x = () => {
|
|
@@ -4059,7 +4076,7 @@ function Qr() {
|
|
|
4059
4076
|
),
|
|
4060
4077
|
/* @__PURE__ */ e(J, { onClick: x, children: t("common.apply") })
|
|
4061
4078
|
] }),
|
|
4062
|
-
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(
|
|
4079
|
+
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: [
|
|
4063
4080
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
4064
4081
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Item Code", { defaultValue: "Item Code" }) }),
|
|
4065
4082
|
/* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Item Name", { defaultValue: "Item Name" }) }),
|
|
@@ -4072,7 +4089,7 @@ function Qr() {
|
|
|
4072
4089
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 font-medium text-gray-900", children: y.item_code }),
|
|
4073
4090
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: y.item_name }),
|
|
4074
4091
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: y.warehouse }),
|
|
4075
|
-
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children:
|
|
4092
|
+
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: Wt(y.actual_qty) }),
|
|
4076
4093
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: d(y.valuation_rate) }),
|
|
4077
4094
|
/* @__PURE__ */ e("td", { className: "px-4 py-2 text-right font-medium", children: d(y.stock_value) })
|
|
4078
4095
|
] }, P)) })
|
|
@@ -4080,10 +4097,10 @@ function Qr() {
|
|
|
4080
4097
|
] });
|
|
4081
4098
|
}
|
|
4082
4099
|
function Hr() {
|
|
4083
|
-
const { t } =
|
|
4100
|
+
const { t } = ne(), [n] = te("company", ""), [a] = te("from", ""), [s] = te("to", ""), o = Qe(), [i, c] = N(n), l = We(i), g = (u) => Oe(u, l), [d, p] = N(a), [m, f] = N(s), S = Re(() => {
|
|
4084
4101
|
const u = {};
|
|
4085
4102
|
return n && (u.company = n), a && (u.from_date = a), s && (u.to_date = s), u;
|
|
4086
|
-
}, [n, a, s]), { data: x, isLoading: y, refetch: P } = Mr(S),
|
|
4103
|
+
}, [n, a, s]), { data: x, isLoading: y, refetch: P } = Mr(S), D = () => {
|
|
4087
4104
|
o({
|
|
4088
4105
|
company: i || null,
|
|
4089
4106
|
from: d || null,
|
|
@@ -4093,15 +4110,15 @@ function Hr() {
|
|
|
4093
4110
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4094
4111
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
4095
4112
|
/* @__PURE__ */ e(ke, { label: t("fields.Company", { defaultValue: "Company" }), value: i, onChange: c, linkDoctype: "company", readOnly: !1 }),
|
|
4096
|
-
/* @__PURE__ */ e(
|
|
4097
|
-
/* @__PURE__ */ e(
|
|
4098
|
-
/* @__PURE__ */ e(J, { onClick:
|
|
4113
|
+
/* @__PURE__ */ e(X, { label: t("fields.From Date", { defaultValue: "From Date" }), type: "date", value: d, onChange: (u) => p(u.target.value) }),
|
|
4114
|
+
/* @__PURE__ */ e(X, { label: t("fields.To Date", { defaultValue: "To Date" }), type: "date", value: m, onChange: (u) => f(u.target.value) }),
|
|
4115
|
+
/* @__PURE__ */ e(J, { onClick: D, children: t("common.apply") })
|
|
4099
4116
|
] }),
|
|
4100
4117
|
/* @__PURE__ */ e(qt, { onSelect: (u, h) => {
|
|
4101
4118
|
p(u), f(h), o({ from: u, to: h });
|
|
4102
4119
|
} }),
|
|
4103
4120
|
y ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) : T ? /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4104
|
-
/* @__PURE__ */ r(
|
|
4121
|
+
/* @__PURE__ */ r(U, { children: [
|
|
4105
4122
|
/* @__PURE__ */ e("h3", { className: "mb-3 text-base font-semibold text-gray-800", children: t("reports.income") }),
|
|
4106
4123
|
/* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
4107
4124
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
@@ -4118,7 +4135,7 @@ function Hr() {
|
|
|
4118
4135
|
] }) })
|
|
4119
4136
|
] })
|
|
4120
4137
|
] }),
|
|
4121
|
-
/* @__PURE__ */ r(
|
|
4138
|
+
/* @__PURE__ */ r(U, { children: [
|
|
4122
4139
|
/* @__PURE__ */ e("h3", { className: "mb-3 text-base font-semibold text-gray-800", children: t("reports.expenses") }),
|
|
4123
4140
|
/* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
4124
4141
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
@@ -4144,8 +4161,8 @@ function Hr() {
|
|
|
4144
4161
|
] });
|
|
4145
4162
|
}
|
|
4146
4163
|
function Ut({ title: t, rows: n, total: a, totalLabel: s, currency: o }) {
|
|
4147
|
-
const { t: i } =
|
|
4148
|
-
return /* @__PURE__ */ r(
|
|
4164
|
+
const { t: i } = ne(), c = (l) => Oe(l, o);
|
|
4165
|
+
return /* @__PURE__ */ r(U, { children: [
|
|
4149
4166
|
/* @__PURE__ */ e("h3", { className: "mb-3 text-base font-semibold text-gray-800", children: t }),
|
|
4150
4167
|
/* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
4151
4168
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
@@ -4164,17 +4181,17 @@ function Ut({ title: t, rows: n, total: a, totalLabel: s, currency: o }) {
|
|
|
4164
4181
|
] });
|
|
4165
4182
|
}
|
|
4166
4183
|
function Jr() {
|
|
4167
|
-
var
|
|
4168
|
-
const { t } =
|
|
4184
|
+
var D, T, u;
|
|
4185
|
+
const { t } = ne(), [n] = te("company", ""), [a] = te("as_of_date", ""), s = Qe(), [o, i] = N(n), [c, l] = N(a), g = We(o), d = (h) => Oe(h, g), p = Re(() => {
|
|
4169
4186
|
const h = {};
|
|
4170
4187
|
return n && (h.company = n), a && (h.as_of_date = a), h;
|
|
4171
4188
|
}, [n, a]), { data: m, isLoading: f, refetch: S } = $r(p), x = () => {
|
|
4172
4189
|
s({ company: o || null, as_of_date: c || null }), S();
|
|
4173
|
-
}, y = m && (((
|
|
4190
|
+
}, y = 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;
|
|
4174
4191
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4175
4192
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
4176
4193
|
/* @__PURE__ */ e(ke, { label: t("fields.Company", { defaultValue: "Company" }), value: o, onChange: i, linkDoctype: "company", readOnly: !1 }),
|
|
4177
|
-
/* @__PURE__ */ e(
|
|
4194
|
+
/* @__PURE__ */ e(X, { label: t("fields.As of Date", { defaultValue: "As of Date" }), type: "date", value: c, onChange: (h) => l(h.target.value) }),
|
|
4178
4195
|
/* @__PURE__ */ e(J, { onClick: x, children: t("common.apply") })
|
|
4179
4196
|
] }),
|
|
4180
4197
|
/* @__PURE__ */ e(ln, { onSelect: (h) => {
|
|
@@ -4184,7 +4201,7 @@ function Jr() {
|
|
|
4184
4201
|
/* @__PURE__ */ e(Ut, { title: t("reports.assets"), rows: m.assets || [], total: m.total_assets, totalLabel: t("reports.totalAssets"), currency: g }),
|
|
4185
4202
|
/* @__PURE__ */ e(Ut, { title: t("reports.liabilities"), rows: m.liabilities || [], total: m.total_liabilities, totalLabel: t("reports.totalLiabilities"), currency: g }),
|
|
4186
4203
|
/* @__PURE__ */ e(Ut, { title: t("reports.equity"), rows: m.equity || [], total: m.total_equity, totalLabel: t("reports.totalEquity"), currency: g }),
|
|
4187
|
-
/* @__PURE__ */ e(
|
|
4204
|
+
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
|
|
4188
4205
|
/* @__PURE__ */ r("div", { className: "text-sm", children: [
|
|
4189
4206
|
/* @__PURE__ */ r("div", { className: "text-gray-500", children: [
|
|
4190
4207
|
t("reports.totalAssets"),
|
|
@@ -4203,7 +4220,7 @@ function Jr() {
|
|
|
4203
4220
|
] });
|
|
4204
4221
|
}
|
|
4205
4222
|
function Yr() {
|
|
4206
|
-
const { t } =
|
|
4223
|
+
const { t } = ne(), [n] = te("company", ""), [a] = te("as_of_date", ""), s = Qe(), [o, i] = N(n), [c, l] = N(a), g = We(o), d = (y) => Oe(y, g), p = Re(() => {
|
|
4207
4224
|
const y = {};
|
|
4208
4225
|
return n && (y.company = n), a && (y.as_of_date = a), y;
|
|
4209
4226
|
}, [n, a]), { data: m, isLoading: f, refetch: S } = Ur(p), x = () => {
|
|
@@ -4212,13 +4229,13 @@ function Yr() {
|
|
|
4212
4229
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4213
4230
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
4214
4231
|
/* @__PURE__ */ e(ke, { label: t("fields.Company", { defaultValue: "Company" }), value: o, onChange: i, linkDoctype: "company", readOnly: !1 }),
|
|
4215
|
-
/* @__PURE__ */ e(
|
|
4232
|
+
/* @__PURE__ */ e(X, { label: t("fields.As of Date", { defaultValue: "As of Date" }), type: "date", value: c, onChange: (y) => l(y.target.value) }),
|
|
4216
4233
|
/* @__PURE__ */ e(J, { onClick: x, children: t("common.apply") })
|
|
4217
4234
|
] }),
|
|
4218
4235
|
/* @__PURE__ */ e(ln, { onSelect: (y) => {
|
|
4219
4236
|
l(y), s({ as_of_date: y });
|
|
4220
4237
|
} }),
|
|
4221
|
-
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(
|
|
4238
|
+
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: [
|
|
4222
4239
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
4223
4240
|
/* @__PURE__ */ e("th", { className: "px-3 py-3 text-left font-medium text-gray-500", children: t("fields.Invoice", { defaultValue: "Invoice" }) }),
|
|
4224
4241
|
/* @__PURE__ */ e("th", { className: "px-3 py-3 text-left font-medium text-gray-500", children: t("fields.Customer", { defaultValue: "Customer" }) }),
|
|
@@ -4261,7 +4278,7 @@ function Yr() {
|
|
|
4261
4278
|
] });
|
|
4262
4279
|
}
|
|
4263
4280
|
function Zr() {
|
|
4264
|
-
const { t } =
|
|
4281
|
+
const { t } = ne(), [n] = te("company", ""), [a] = te("as_of_date", ""), s = Qe(), [o, i] = N(n), [c, l] = N(a), g = We(o), d = (y) => Oe(y, g), p = Re(() => {
|
|
4265
4282
|
const y = {};
|
|
4266
4283
|
return n && (y.company = n), a && (y.as_of_date = a), y;
|
|
4267
4284
|
}, [n, a]), { data: m, isLoading: f, refetch: S } = Vr(p), x = () => {
|
|
@@ -4270,13 +4287,13 @@ function Zr() {
|
|
|
4270
4287
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4271
4288
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
4272
4289
|
/* @__PURE__ */ e(ke, { label: t("fields.Company", { defaultValue: "Company" }), value: o, onChange: i, linkDoctype: "company", readOnly: !1 }),
|
|
4273
|
-
/* @__PURE__ */ e(
|
|
4290
|
+
/* @__PURE__ */ e(X, { label: t("fields.As of Date", { defaultValue: "As of Date" }), type: "date", value: c, onChange: (y) => l(y.target.value) }),
|
|
4274
4291
|
/* @__PURE__ */ e(J, { onClick: x, children: t("common.apply") })
|
|
4275
4292
|
] }),
|
|
4276
4293
|
/* @__PURE__ */ e(ln, { onSelect: (y) => {
|
|
4277
4294
|
l(y), s({ as_of_date: y });
|
|
4278
4295
|
} }),
|
|
4279
|
-
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(
|
|
4296
|
+
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: [
|
|
4280
4297
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
4281
4298
|
/* @__PURE__ */ e("th", { className: "px-3 py-3 text-left font-medium text-gray-500", children: t("fields.Invoice", { defaultValue: "Invoice" }) }),
|
|
4282
4299
|
/* @__PURE__ */ e("th", { className: "px-3 py-3 text-left font-medium text-gray-500", children: t("fields.Supplier", { defaultValue: "Supplier" }) }),
|
|
@@ -4413,19 +4430,19 @@ return {
|
|
|
4413
4430
|
}
|
|
4414
4431
|
const sa = es();
|
|
4415
4432
|
function ts() {
|
|
4416
|
-
const t = Ee(), { sessions: n, createSession: a } = ct(), [s] =
|
|
4433
|
+
const t = Ee(), { sessions: n, createSession: a } = ct(), [s] = te("report_id", ""), [o] = te("metric", ""), [i] = te("group_by", ""), [c] = te("from", ""), [l] = te("to", ""), [g] = te("company", ""), [d, p] = N(sa), [m, f] = N([]), [S, x] = N(null), [y, P] = N(""), [D, T] = N(!1), [u, h] = N(!1), [A, R] = N(""), k = ee(null), H = ee(""), $ = ee(""), M = ee(0), w = Re(() => !o || !i ? "" : JSON.stringify(ss({
|
|
4417
4434
|
metric: o,
|
|
4418
4435
|
groupBy: i,
|
|
4419
4436
|
fromDate: c || void 0,
|
|
4420
4437
|
toDate: l || void 0,
|
|
4421
4438
|
company: g || void 0
|
|
4422
|
-
}), null, 2), [o, i, c, l, g]),
|
|
4439
|
+
}), null, 2), [o, i, c, l, g]), K = async (F) => {
|
|
4423
4440
|
var he;
|
|
4424
|
-
const
|
|
4441
|
+
const Z = ++M.current, ae = () => M.current === Z;
|
|
4425
4442
|
P(""), T(!0);
|
|
4426
4443
|
try {
|
|
4427
|
-
const Ce = JSON.parse(
|
|
4428
|
-
if (!
|
|
4444
|
+
const Ce = JSON.parse(F ?? d), me = await L.runtimeData({ requests: Ce.data_requests || [] });
|
|
4445
|
+
if (!ae()) return;
|
|
4429
4446
|
f(me.datasets), (he = k.current) == null || he.terminate();
|
|
4430
4447
|
const I = new Xr();
|
|
4431
4448
|
k.current = I;
|
|
@@ -4442,34 +4459,34 @@ function ts() {
|
|
|
4442
4459
|
transformJs: Ce.transform_js || "return {};"
|
|
4443
4460
|
});
|
|
4444
4461
|
});
|
|
4445
|
-
if (!
|
|
4462
|
+
if (!ae()) return;
|
|
4446
4463
|
x(ie);
|
|
4447
4464
|
} catch (ye) {
|
|
4448
|
-
if (!
|
|
4465
|
+
if (!ae()) return;
|
|
4449
4466
|
x(null), P(ye instanceof Error ? ye.message : String(ye));
|
|
4450
4467
|
} finally {
|
|
4451
|
-
|
|
4468
|
+
ae() && T(!1);
|
|
4452
4469
|
}
|
|
4453
4470
|
};
|
|
4454
4471
|
se(() => {
|
|
4455
|
-
let
|
|
4456
|
-
return s ? H.current === s ? void 0 : (h(!0), P(""), L.getRuntimeDraft(s).then((
|
|
4457
|
-
if (
|
|
4458
|
-
const
|
|
4459
|
-
return H.current = s,
|
|
4460
|
-
}).catch((
|
|
4461
|
-
|
|
4472
|
+
let F = !1;
|
|
4473
|
+
return s ? H.current === s ? void 0 : (h(!0), P(""), L.getRuntimeDraft(s).then((Z) => {
|
|
4474
|
+
if (F) return;
|
|
4475
|
+
const ae = JSON.stringify(Z.definition, null, 2);
|
|
4476
|
+
return H.current = s, $.current = ae, R(Z.source_chat_session_id || ""), p(ae), K(ae);
|
|
4477
|
+
}).catch((Z) => {
|
|
4478
|
+
F || (x(null), P(Z instanceof Error ? Z.message : String(Z)));
|
|
4462
4479
|
}).finally(() => {
|
|
4463
|
-
|
|
4480
|
+
F || h(!1);
|
|
4464
4481
|
}), () => {
|
|
4465
|
-
|
|
4466
|
-
}) : (H.current = "",
|
|
4467
|
-
|
|
4482
|
+
F = !0;
|
|
4483
|
+
}) : (H.current = "", $.current = "", R(""), w && ($.current = w, p(w), K(w)), () => {
|
|
4484
|
+
F = !0;
|
|
4468
4485
|
});
|
|
4469
4486
|
}, [s, w]);
|
|
4470
|
-
const
|
|
4487
|
+
const v = !!(!s && w), B = Re(() => rs(S), [S]), C = async () => {
|
|
4471
4488
|
var me;
|
|
4472
|
-
const
|
|
4489
|
+
const F = d.trim() !== $.current.trim(), Z = s || "unsaved-runtime-report", ae = m.map((I) => ({
|
|
4473
4490
|
name: I.name,
|
|
4474
4491
|
dataset: I.dataset,
|
|
4475
4492
|
row_count: I.row_count,
|
|
@@ -4477,13 +4494,13 @@ function ts() {
|
|
|
4477
4494
|
})), he = [
|
|
4478
4495
|
"This custom analytics report does not work yet. Please repair the existing report draft instead of creating a new one.",
|
|
4479
4496
|
"",
|
|
4480
|
-
`Report ID: ${
|
|
4497
|
+
`Report ID: ${Z}`,
|
|
4481
4498
|
"",
|
|
4482
4499
|
"Current issue summary:",
|
|
4483
|
-
y ||
|
|
4500
|
+
y || B.join(`
|
|
4484
4501
|
`) || "No runtime error captured; please review and improve the report definition."
|
|
4485
4502
|
];
|
|
4486
|
-
|
|
4503
|
+
F ? he.push(
|
|
4487
4504
|
"",
|
|
4488
4505
|
"The analytics editor contains unsaved local changes. Use this JSON as the source of truth when repairing the draft:",
|
|
4489
4506
|
"```json",
|
|
@@ -4492,11 +4509,11 @@ function ts() {
|
|
|
4492
4509
|
) : he.push(
|
|
4493
4510
|
"",
|
|
4494
4511
|
"Load the current saved draft with `get_custom_analytics_report` before making changes."
|
|
4495
|
-
),
|
|
4512
|
+
), ae.length > 0 && he.push(
|
|
4496
4513
|
"",
|
|
4497
4514
|
"Fetched dataset preview:",
|
|
4498
4515
|
"```json",
|
|
4499
|
-
JSON.stringify(
|
|
4516
|
+
JSON.stringify(ae, null, 2),
|
|
4500
4517
|
"```"
|
|
4501
4518
|
);
|
|
4502
4519
|
const ye = he.join(`
|
|
@@ -4505,7 +4522,7 @@ function ts() {
|
|
|
4505
4522
|
Ce || (Ce = ((me = n[0]) == null ? void 0 : me.id) || ""), Ce || (Ce = (await a()).id), t(`/chat/${Ce}`, { state: { prefillMessage: ye } });
|
|
4506
4523
|
};
|
|
4507
4524
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4508
|
-
/* @__PURE__ */ e(
|
|
4525
|
+
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
|
|
4509
4526
|
/* @__PURE__ */ r("div", { children: [
|
|
4510
4527
|
/* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-gray-900", children: "Analytics" }),
|
|
4511
4528
|
/* @__PURE__ */ e("p", { className: "text-sm text-gray-600", children: "All analytics now run through the custom runtime and semantic datasets." })
|
|
@@ -4514,34 +4531,34 @@ function ts() {
|
|
|
4514
4531
|
s ? /* @__PURE__ */ r("div", { className: "text-xs text-gray-500", children: [
|
|
4515
4532
|
"Loaded draft: ",
|
|
4516
4533
|
s
|
|
4517
|
-
] }) :
|
|
4518
|
-
s ? /* @__PURE__ */ e(J, { variant: "secondary", onClick: () => void
|
|
4519
|
-
/* @__PURE__ */ e(J, { onClick: () => void
|
|
4534
|
+
] }) : v ? /* @__PURE__ */ e("div", { className: "text-xs text-gray-500", children: "Loaded runtime report from legacy URL filters." }) : null,
|
|
4535
|
+
s ? /* @__PURE__ */ e(J, { variant: "secondary", onClick: () => void C(), children: "Fix In Chat" }) : null,
|
|
4536
|
+
/* @__PURE__ */ e(J, { onClick: () => void K(), disabled: D, children: D ? "Running..." : "Run Report" })
|
|
4520
4537
|
] })
|
|
4521
4538
|
] }) }),
|
|
4522
|
-
u ? /* @__PURE__ */ e(
|
|
4523
|
-
m.length > 0 && /* @__PURE__ */ e(
|
|
4539
|
+
u ? /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("p", { className: "text-sm text-gray-600", children: "Loading draft..." }) }) : y ? /* @__PURE__ */ e(U, { children: /* @__PURE__ */ e("p", { className: "text-sm text-red-600", children: y }) }) : S ? /* @__PURE__ */ e(ns, { output: S }) : /* @__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." }) }),
|
|
4540
|
+
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: [
|
|
4524
4541
|
/* @__PURE__ */ r("div", { className: "flex items-baseline justify-between gap-4", children: [
|
|
4525
4542
|
/* @__PURE__ */ r("div", { children: [
|
|
4526
|
-
/* @__PURE__ */ e("div", { className: "font-medium text-gray-900", children:
|
|
4527
|
-
/* @__PURE__ */ e("div", { className: "text-xs text-gray-500", children:
|
|
4543
|
+
/* @__PURE__ */ e("div", { className: "font-medium text-gray-900", children: F.name }),
|
|
4544
|
+
/* @__PURE__ */ e("div", { className: "text-xs text-gray-500", children: F.dataset })
|
|
4528
4545
|
] }),
|
|
4529
4546
|
/* @__PURE__ */ r("div", { className: "text-xs text-gray-500", children: [
|
|
4530
|
-
|
|
4547
|
+
F.row_count,
|
|
4531
4548
|
" rows",
|
|
4532
|
-
|
|
4549
|
+
F.truncated ? ` (truncated at ${F.limit})` : ""
|
|
4533
4550
|
] })
|
|
4534
4551
|
] }),
|
|
4535
|
-
/* @__PURE__ */ e("pre", { className: "mt-3 overflow-x-auto rounded bg-gray-50 p-3 text-xs text-gray-700", children: JSON.stringify(
|
|
4536
|
-
] },
|
|
4537
|
-
/* @__PURE__ */ r(
|
|
4552
|
+
/* @__PURE__ */ e("pre", { className: "mt-3 overflow-x-auto rounded bg-gray-50 p-3 text-xs text-gray-700", children: JSON.stringify(F.rows.slice(0, 5), null, 2) })
|
|
4553
|
+
] }, F.name)) }) }),
|
|
4554
|
+
/* @__PURE__ */ r(U, { children: [
|
|
4538
4555
|
/* @__PURE__ */ e("label", { className: "mb-2 block text-sm font-medium text-gray-700", children: "Report Definition JSON" }),
|
|
4539
4556
|
/* @__PURE__ */ e(
|
|
4540
4557
|
"textarea",
|
|
4541
4558
|
{
|
|
4542
4559
|
className: "min-h-[520px] w-full rounded-md border border-gray-300 p-3 font-mono text-xs text-gray-900 outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500",
|
|
4543
4560
|
value: d,
|
|
4544
|
-
onChange: (
|
|
4561
|
+
onChange: (F) => p(F.target.value),
|
|
4545
4562
|
spellCheck: !1
|
|
4546
4563
|
}
|
|
4547
4564
|
)
|
|
@@ -4555,7 +4572,7 @@ function ns({ output: t }) {
|
|
|
4555
4572
|
id: i.id || `table_${c + 1}`
|
|
4556
4573
|
})), a = ia(n);
|
|
4557
4574
|
return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4558
|
-
/* @__PURE__ */ r(
|
|
4575
|
+
/* @__PURE__ */ r(U, { children: [
|
|
4559
4576
|
/* @__PURE__ */ e("div", { className: "flex items-baseline justify-between gap-4", children: /* @__PURE__ */ r("div", { children: [
|
|
4560
4577
|
/* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-gray-900", children: t.title || "Custom Report" }),
|
|
4561
4578
|
t.summary && /* @__PURE__ */ e("p", { className: "mt-1 text-sm text-gray-600", children: t.summary })
|
|
@@ -4568,9 +4585,9 @@ function ns({ output: t }) {
|
|
|
4568
4585
|
(o = t.charts) == null ? void 0 : o.map((i, c) => {
|
|
4569
4586
|
const l = i.dataTable ? a.get(i.dataTable) : void 0, g = i.data ?? (l == null ? void 0 : l.rows) ?? [];
|
|
4570
4587
|
if (!g.length)
|
|
4571
|
-
return /* @__PURE__ */ e(
|
|
4588
|
+
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}`);
|
|
4572
4589
|
const d = i.type === "pie" ? [] : g.map((f) => String(f[i.x] ?? "")), p = cs(d), m = Math.max(320, 200 + p.axisHeight);
|
|
4573
|
-
return /* @__PURE__ */ r(
|
|
4590
|
+
return /* @__PURE__ */ r(U, { children: [
|
|
4574
4591
|
/* @__PURE__ */ e("div", { className: "pb-3 text-sm font-semibold text-gray-700", children: i.title }),
|
|
4575
4592
|
/* @__PURE__ */ e("div", { style: { height: m }, className: "w-full", children: /* @__PURE__ */ e(qa, { width: "100%", height: "100%", children: i.type === "line" ? /* @__PURE__ */ r(Fa, { data: g, margin: { top: 10, right: 20, left: 0, bottom: 0 }, children: [
|
|
4576
4593
|
/* @__PURE__ */ e(un, { strokeDasharray: "3 3", stroke: "#f3f4f6" }),
|
|
@@ -4610,7 +4627,7 @@ function ns({ output: t }) {
|
|
|
4610
4627
|
] }) }) })
|
|
4611
4628
|
] }, i.id || `chart_${c + 1}`);
|
|
4612
4629
|
}),
|
|
4613
|
-
n.map((i) => /* @__PURE__ */ e(
|
|
4630
|
+
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: [
|
|
4614
4631
|
/* @__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)) }) }),
|
|
4615
4632
|
/* @__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((g) => /* @__PURE__ */ e("td", { className: "px-4 py-1.5 text-gray-900", children: kt(c[g.key], g.type) }, g.key)) }, l)) })
|
|
4616
4633
|
] }) }) }, i.id))
|
|
@@ -4818,7 +4835,7 @@ function Vt(t, n) {
|
|
|
4818
4835
|
return ((a = t == null ? void 0 : t.columns.find((o) => o.key === n)) == null ? void 0 : a.type) || ((s = t == null ? void 0 : t.columns.find((o) => o.key === n)) == null ? void 0 : s.format);
|
|
4819
4836
|
}
|
|
4820
4837
|
function kt(t, n) {
|
|
4821
|
-
return n === "currency" ? Oe(ze(t)) : n === "percent" ? `${(ze(t) * 100).toFixed(1)}%` : n === "number" ?
|
|
4838
|
+
return n === "currency" ? Oe(ze(t)) : n === "percent" ? `${(ze(t) * 100).toFixed(1)}%` : n === "number" ? Wt(ze(t)) : n === "date" ? Ot(String(t ?? "")) : typeof t == "number" ? Wt(t) : String(t ?? "");
|
|
4822
4839
|
}
|
|
4823
4840
|
function Tn(t) {
|
|
4824
4841
|
const n = Math.abs(t);
|
|
@@ -4842,7 +4859,7 @@ function cs(t) {
|
|
|
4842
4859
|
}
|
|
4843
4860
|
const ds = ["USD", "EUR", "GBP", "CHF", "JPY", "CAD", "AUD", "CNY", "INR"];
|
|
4844
4861
|
function us() {
|
|
4845
|
-
const t =
|
|
4862
|
+
const t = Ke(), { data: n, isLoading: a } = le({
|
|
4846
4863
|
queryKey: ["setup-status"],
|
|
4847
4864
|
queryFn: () => L.setupStatus()
|
|
4848
4865
|
}), [s, o] = N(""), [i, c] = N("USD"), [l, g] = N({
|
|
@@ -4853,11 +4870,11 @@ function us() {
|
|
|
4853
4870
|
email: "",
|
|
4854
4871
|
phone: "",
|
|
4855
4872
|
tax_id: ""
|
|
4856
|
-
}), d = (R) => (k) => g((H) => ({ ...H, [R]: k.target.value })), [p, m] = N("quick"), [f, S] = N(!1), [x, y] = N(null), P =
|
|
4873
|
+
}), d = (R) => (k) => g((H) => ({ ...H, [R]: k.target.value })), [p, m] = N("quick"), [f, S] = N(!1), [x, y] = N(null), P = oe({
|
|
4857
4874
|
mutationFn: () => L.createCompany({ name: s, currency: i, ...l })
|
|
4858
|
-
}),
|
|
4875
|
+
}), D = oe({
|
|
4859
4876
|
mutationFn: () => L.seedDemo()
|
|
4860
|
-
}), T =
|
|
4877
|
+
}), T = oe({
|
|
4861
4878
|
mutationFn: () => L.seedHistory()
|
|
4862
4879
|
}), u = async () => {
|
|
4863
4880
|
if (s.trim())
|
|
@@ -4865,7 +4882,7 @@ function us() {
|
|
|
4865
4882
|
if (await P.mutateAsync(), p === "history") {
|
|
4866
4883
|
const R = await T.mutateAsync();
|
|
4867
4884
|
y(R.stats);
|
|
4868
|
-
} else p === "quick" && await
|
|
4885
|
+
} else p === "quick" && await D.mutateAsync();
|
|
4869
4886
|
t.invalidateQueries({ queryKey: ["setup-status"] }), S(!0);
|
|
4870
4887
|
} catch {
|
|
4871
4888
|
}
|
|
@@ -4874,11 +4891,11 @@ function us() {
|
|
|
4874
4891
|
return /* @__PURE__ */ e("p", { className: "text-gray-500", children: "Loading..." });
|
|
4875
4892
|
if (n != null && n.setup_complete && !f)
|
|
4876
4893
|
return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
4877
|
-
/* @__PURE__ */ e(
|
|
4894
|
+
/* @__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, k) => /* @__PURE__ */ e("li", { className: "py-3", children: /* @__PURE__ */ e(ms, { company: R }) }, k)) }) : /* @__PURE__ */ e("p", { className: "text-gray-400", children: "No companies found" }) }),
|
|
4878
4895
|
/* @__PURE__ */ e(ve, { to: "/", className: "text-blue-600 hover:text-blue-800 text-sm font-medium", children: "Go to Dashboard" })
|
|
4879
4896
|
] });
|
|
4880
4897
|
if (f)
|
|
4881
|
-
return /* @__PURE__ */ e("div", { className: "space-y-6", children: /* @__PURE__ */ e(
|
|
4898
|
+
return /* @__PURE__ */ e("div", { className: "space-y-6", children: /* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "py-8 text-center", children: [
|
|
4882
4899
|
/* @__PURE__ */ e("p", { className: "text-lg font-semibold text-green-700", children: "Setup complete!" }),
|
|
4883
4900
|
/* @__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." }),
|
|
4884
4901
|
x && /* @__PURE__ */ r("div", { className: "mx-auto mt-6 max-w-sm text-left", children: [
|
|
@@ -4890,13 +4907,13 @@ function us() {
|
|
|
4890
4907
|
] }),
|
|
4891
4908
|
/* @__PURE__ */ e("div", { className: "mt-6", children: /* @__PURE__ */ e(ve, { to: "/", children: /* @__PURE__ */ e(J, { children: "Go to Dashboard" }) }) })
|
|
4892
4909
|
] }) }) });
|
|
4893
|
-
const h = P.isPending ||
|
|
4910
|
+
const h = P.isPending || D.isPending || T.isPending, A = P.error ?? D.error ?? T.error;
|
|
4894
4911
|
return /* @__PURE__ */ r("div", { className: "mx-auto max-w-lg space-y-6", children: [
|
|
4895
4912
|
/* @__PURE__ */ e("p", { className: "text-sm text-gray-500", children: "Set up your first company to get started." }),
|
|
4896
4913
|
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" }),
|
|
4897
|
-
/* @__PURE__ */ e(
|
|
4914
|
+
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "space-y-4", children: [
|
|
4898
4915
|
/* @__PURE__ */ e(
|
|
4899
|
-
|
|
4916
|
+
X,
|
|
4900
4917
|
{
|
|
4901
4918
|
label: "Company Name",
|
|
4902
4919
|
value: s,
|
|
@@ -4918,7 +4935,7 @@ function us() {
|
|
|
4918
4935
|
/* @__PURE__ */ e("legend", { className: "mb-1 text-sm font-medium text-gray-700", children: "Company details" }),
|
|
4919
4936
|
/* @__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." }),
|
|
4920
4937
|
/* @__PURE__ */ e(
|
|
4921
|
-
|
|
4938
|
+
X,
|
|
4922
4939
|
{
|
|
4923
4940
|
label: "Address",
|
|
4924
4941
|
value: l.address,
|
|
@@ -4927,16 +4944,16 @@ function us() {
|
|
|
4927
4944
|
}
|
|
4928
4945
|
),
|
|
4929
4946
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
4930
|
-
/* @__PURE__ */ e(
|
|
4931
|
-
/* @__PURE__ */ e(
|
|
4947
|
+
/* @__PURE__ */ e(X, { label: "City", value: l.city, onChange: d("city") }),
|
|
4948
|
+
/* @__PURE__ */ e(X, { label: "ZIP / Postal code", value: l.zip_code, onChange: d("zip_code") })
|
|
4932
4949
|
] }),
|
|
4933
4950
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
4934
|
-
/* @__PURE__ */ e(
|
|
4935
|
-
/* @__PURE__ */ e(
|
|
4951
|
+
/* @__PURE__ */ e(X, { label: "Country", value: l.country, onChange: d("country") }),
|
|
4952
|
+
/* @__PURE__ */ e(X, { label: "Tax ID / VAT", value: l.tax_id, onChange: d("tax_id") })
|
|
4936
4953
|
] }),
|
|
4937
4954
|
/* @__PURE__ */ r("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
4938
|
-
/* @__PURE__ */ e(
|
|
4939
|
-
/* @__PURE__ */ e(
|
|
4955
|
+
/* @__PURE__ */ e(X, { label: "Email", value: l.email, onChange: d("email") }),
|
|
4956
|
+
/* @__PURE__ */ e(X, { label: "Phone", value: l.phone, onChange: d("phone") })
|
|
4940
4957
|
] })
|
|
4941
4958
|
] }),
|
|
4942
4959
|
/* @__PURE__ */ r("fieldset", { className: "space-y-2", children: [
|
|
@@ -5183,7 +5200,7 @@ const ps = [
|
|
|
5183
5200
|
}
|
|
5184
5201
|
];
|
|
5185
5202
|
function hs() {
|
|
5186
|
-
const t = Ee(), { t: n } =
|
|
5203
|
+
const t = Ee(), { t: n } = ne(), { sessions: a, createSession: s } = ct(), o = async (c) => {
|
|
5187
5204
|
var g;
|
|
5188
5205
|
let l = ((g = a[0]) == null ? void 0 : g.id) || "";
|
|
5189
5206
|
if (!l)
|
|
@@ -5200,7 +5217,7 @@ function hs() {
|
|
|
5200
5217
|
n("tutorial.caPrompt3"),
|
|
5201
5218
|
n("tutorial.caPrompt4")
|
|
5202
5219
|
];
|
|
5203
|
-
return /* @__PURE__ */ e(
|
|
5220
|
+
return /* @__PURE__ */ e(U, { className: "border-indigo-200 bg-gradient-to-br from-indigo-50 to-white", children: /* @__PURE__ */ r("div", { className: "flex flex-col gap-4 md:flex-row md:items-start", children: [
|
|
5204
5221
|
/* @__PURE__ */ e("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-indigo-100 text-lg font-bold text-indigo-700", children: "★" }),
|
|
5205
5222
|
/* @__PURE__ */ r("div", { className: "flex-1 space-y-3", children: [
|
|
5206
5223
|
/* @__PURE__ */ r("div", { children: [
|
|
@@ -5253,8 +5270,8 @@ function hs() {
|
|
|
5253
5270
|
] }) });
|
|
5254
5271
|
}
|
|
5255
5272
|
function gs() {
|
|
5256
|
-
const { t } =
|
|
5257
|
-
return /* @__PURE__ */ r(
|
|
5273
|
+
const { t } = ne(), n = (a) => t(`tutorial.chips.${a}`, { defaultValue: a });
|
|
5274
|
+
return /* @__PURE__ */ r(U, { children: [
|
|
5258
5275
|
/* @__PURE__ */ e("h3", { className: "text-base font-semibold text-gray-900 mb-3", children: t("tutorial.flowTitle") }),
|
|
5259
5276
|
/* @__PURE__ */ r("div", { className: "space-y-4 text-sm text-gray-600", children: [
|
|
5260
5277
|
/* @__PURE__ */ r("div", { children: [
|
|
@@ -5324,8 +5341,8 @@ function gs() {
|
|
|
5324
5341
|
] });
|
|
5325
5342
|
}
|
|
5326
5343
|
function ys() {
|
|
5327
|
-
const { t } =
|
|
5328
|
-
return /* @__PURE__ */ r(
|
|
5344
|
+
const { t } = ne(), n = (a) => t(`tutorial.chips.${a}`, { defaultValue: a });
|
|
5345
|
+
return /* @__PURE__ */ r(U, { children: [
|
|
5329
5346
|
/* @__PURE__ */ e("h3", { className: "text-base font-semibold text-gray-900 mb-3", children: t("tutorial.lifecycleTitle") }),
|
|
5330
5347
|
/* @__PURE__ */ r("div", { className: "space-y-2 text-sm text-gray-600", children: [
|
|
5331
5348
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-center gap-2 font-mono text-xs", children: [
|
|
@@ -5360,7 +5377,7 @@ function ys() {
|
|
|
5360
5377
|
] });
|
|
5361
5378
|
}
|
|
5362
5379
|
function fs() {
|
|
5363
|
-
const { t } =
|
|
5380
|
+
const { t } = ne();
|
|
5364
5381
|
return /* @__PURE__ */ r("div", { className: "mx-auto max-w-3xl space-y-6", children: [
|
|
5365
5382
|
/* @__PURE__ */ r("div", { children: [
|
|
5366
5383
|
/* @__PURE__ */ e("h2", { className: "text-xl font-semibold text-gray-900", children: t("tutorial.pageTitle") }),
|
|
@@ -5388,7 +5405,7 @@ function fs() {
|
|
|
5388
5405
|
/* @__PURE__ */ e(ys, {}),
|
|
5389
5406
|
ps.map((n) => {
|
|
5390
5407
|
var a;
|
|
5391
|
-
return /* @__PURE__ */ e(
|
|
5408
|
+
return /* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "flex gap-4", children: [
|
|
5392
5409
|
/* @__PURE__ */ e("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-blue-100 text-sm font-bold text-blue-700", children: n.number }),
|
|
5393
5410
|
/* @__PURE__ */ r("div", { className: "space-y-2", children: [
|
|
5394
5411
|
/* @__PURE__ */ e("h3", { className: "text-base font-semibold text-gray-900", children: t(`tutorial.steps.${n.number}.title`, { defaultValue: n.title }) }),
|
|
@@ -5426,7 +5443,7 @@ function fs() {
|
|
|
5426
5443
|
] })
|
|
5427
5444
|
] }) }, n.number);
|
|
5428
5445
|
}),
|
|
5429
|
-
/* @__PURE__ */ e(
|
|
5446
|
+
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "flex gap-4", children: [
|
|
5430
5447
|
/* @__PURE__ */ e("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-green-100 text-sm font-bold text-green-700", children: "✓" }),
|
|
5431
5448
|
/* @__PURE__ */ r("div", { className: "space-y-2", children: [
|
|
5432
5449
|
/* @__PURE__ */ e("h3", { className: "text-base font-semibold text-gray-900", children: t("tutorial.readyTitle") }),
|
|
@@ -5487,62 +5504,62 @@ function In(t) {
|
|
|
5487
5504
|
});
|
|
5488
5505
|
}
|
|
5489
5506
|
function Ln() {
|
|
5490
|
-
const { t } =
|
|
5507
|
+
const { t } = ne(), { sessionId: n } = ft(), a = Ee(), s = Ct(), [o] = Et(), i = o.get("demo") === "1", [c, l] = N(""), [g, d] = N(""), [p, m] = N([]), [f, S] = N(""), [x, y] = N(!1), [P, D] = N("idle"), T = ee(null), u = ee(null), h = ee([]), {
|
|
5491
5508
|
connectionStatus: A,
|
|
5492
5509
|
connectionVersion: R,
|
|
5493
5510
|
createSession: k,
|
|
5494
5511
|
startDemo: H,
|
|
5495
|
-
completeDemoTyping:
|
|
5512
|
+
completeDemoTyping: $,
|
|
5496
5513
|
loadHistory: M,
|
|
5497
5514
|
loadMoreHistory: w,
|
|
5498
|
-
sendMessage:
|
|
5499
|
-
transcribeAudio:
|
|
5500
|
-
getMessages:
|
|
5501
|
-
hasMoreHistory:
|
|
5502
|
-
isLoadingOlder:
|
|
5503
|
-
isThinking:
|
|
5504
|
-
getDemoStatus:
|
|
5515
|
+
sendMessage: K,
|
|
5516
|
+
transcribeAudio: v,
|
|
5517
|
+
getMessages: B,
|
|
5518
|
+
hasMoreHistory: C,
|
|
5519
|
+
isLoadingOlder: F,
|
|
5520
|
+
isThinking: Z,
|
|
5521
|
+
getDemoStatus: ae,
|
|
5505
5522
|
getDemoTypingCue: he
|
|
5506
|
-
} = ct(), ye =
|
|
5523
|
+
} = ct(), ye = ee(null), Ce = ee(null), me = ee(null), I = ee(null), [ie, Te] = N(0), Ne = ee(!1), He = ee(null), qe = ee(0), Me = ee(!0), Fe = ee(null), xt = ee(!1), dt = ee(null), Je = B(n), we = A === "connected", _e = Z(n), $e = ae(n), Ge = he(n), Ae = i || $e === "running", ut = C(n), st = F(n), mt = Je[Je.length - 1], _ = mt ? `${mt.type}:${mt.timestamp || ""}:${mt.content}` : "empty", V = Pe(() => {
|
|
5507
5524
|
xt.current = !0, dt.current !== null && window.clearTimeout(dt.current), dt.current = window.setTimeout(() => {
|
|
5508
5525
|
xt.current = !1, dt.current = null;
|
|
5509
5526
|
}, 600);
|
|
5510
|
-
}, []),
|
|
5511
|
-
const
|
|
5512
|
-
if (!
|
|
5513
|
-
|
|
5527
|
+
}, []), W = Pe((b = "smooth") => {
|
|
5528
|
+
const z = ye.current;
|
|
5529
|
+
if (!z) return;
|
|
5530
|
+
V(), z.scrollTo({ top: z.scrollHeight, behavior: b });
|
|
5514
5531
|
const Y = () => {
|
|
5515
|
-
const
|
|
5516
|
-
|
|
5532
|
+
const ce = ye.current;
|
|
5533
|
+
ce && (!Me.current && !Ae && !_e || ce.scrollTop + ce.clientHeight >= ce.scrollHeight - 2 || (V(), ce.scrollTo({ top: ce.scrollHeight, behavior: "auto" })));
|
|
5517
5534
|
};
|
|
5518
5535
|
requestAnimationFrame(Y), window.setTimeout(Y, 120);
|
|
5519
|
-
}, [Ae, _e,
|
|
5536
|
+
}, [Ae, _e, V]);
|
|
5520
5537
|
cn(() => {
|
|
5521
|
-
const b = ye.current,
|
|
5522
|
-
if (!b ||
|
|
5523
|
-
const Y = b.scrollHeight -
|
|
5538
|
+
const b = ye.current, z = Fe.current;
|
|
5539
|
+
if (!b || z === null) return;
|
|
5540
|
+
const Y = b.scrollHeight - z;
|
|
5524
5541
|
Y > 0 && (b.scrollTop = b.scrollTop + Y), Fe.current = null;
|
|
5525
5542
|
}, [Je.length]), se(() => {
|
|
5526
|
-
Fe.current === null && (!Me.current && !Ae && !_e ||
|
|
5527
|
-
}, [_, Ae, _e,
|
|
5543
|
+
Fe.current === null && (!Me.current && !Ae && !_e || W(Ae ? "auto" : "smooth"));
|
|
5544
|
+
}, [_, Ae, _e, W]), se(() => {
|
|
5528
5545
|
const b = ye.current;
|
|
5529
5546
|
if (!b || typeof ResizeObserver > "u") return;
|
|
5530
|
-
let
|
|
5547
|
+
let z = 0;
|
|
5531
5548
|
const Y = new ResizeObserver(() => {
|
|
5532
|
-
Fe.current === null && (!Me.current && !Ae && !_e || (cancelAnimationFrame(
|
|
5549
|
+
Fe.current === null && (!Me.current && !Ae && !_e || (cancelAnimationFrame(z), z = requestAnimationFrame(() => {
|
|
5533
5550
|
const pe = ye.current;
|
|
5534
5551
|
if (!pe) return;
|
|
5535
|
-
pe.scrollHeight - pe.scrollTop - pe.clientHeight <= 120 && (
|
|
5552
|
+
pe.scrollHeight - pe.scrollTop - pe.clientHeight <= 120 && (V(), pe.scrollTo({ top: pe.scrollHeight, behavior: "auto" }));
|
|
5536
5553
|
})));
|
|
5537
|
-
}),
|
|
5538
|
-
return
|
|
5539
|
-
Y.disconnect(), cancelAnimationFrame(
|
|
5554
|
+
}), ce = b.firstElementChild;
|
|
5555
|
+
return ce && Y.observe(ce), Y.observe(b), () => {
|
|
5556
|
+
Y.disconnect(), cancelAnimationFrame(z);
|
|
5540
5557
|
};
|
|
5541
|
-
}, [Ae, _e,
|
|
5558
|
+
}, [Ae, _e, V]), cn(() => {
|
|
5542
5559
|
const b = I.current;
|
|
5543
5560
|
if (!b || (Te(b.offsetHeight), typeof ResizeObserver > "u")) return;
|
|
5544
|
-
const
|
|
5545
|
-
return
|
|
5561
|
+
const z = new ResizeObserver(() => Te(b.offsetHeight));
|
|
5562
|
+
return z.observe(b), () => z.disconnect();
|
|
5546
5563
|
}, []);
|
|
5547
5564
|
const fe = Pe(() => {
|
|
5548
5565
|
if (!n || st || !ut) return;
|
|
@@ -5550,25 +5567,25 @@ function Ln() {
|
|
|
5550
5567
|
Fe.current = b ? b.scrollHeight : null, Me.current = !1, w(n).catch(() => {
|
|
5551
5568
|
Fe.current = null;
|
|
5552
5569
|
});
|
|
5553
|
-
}, [n, st, ut, w]), be =
|
|
5570
|
+
}, [n, st, ut, w]), be = ee(null);
|
|
5554
5571
|
se(() => {
|
|
5555
5572
|
d(""), He.current = null, qe.current += 1, n && ea(n);
|
|
5556
5573
|
const b = s.state;
|
|
5557
5574
|
b != null && b.prefillMessage && be.current !== b ? (be.current = b, l(b.prefillMessage), window.setTimeout(() => {
|
|
5558
|
-
var
|
|
5559
|
-
return (
|
|
5575
|
+
var z;
|
|
5576
|
+
return (z = me.current) == null ? void 0 : z.focus();
|
|
5560
5577
|
}, 50)) : b != null && b.prefillMessage || (be.current = null, l(""));
|
|
5561
5578
|
}, [n, i, s.state]), se(() => {
|
|
5562
5579
|
if (n || !we) return;
|
|
5563
5580
|
let b = !1;
|
|
5564
|
-
return k().then((
|
|
5565
|
-
b || a(`/chat/${
|
|
5581
|
+
return k().then((z) => {
|
|
5582
|
+
b || a(`/chat/${z.id}`, { replace: !0 });
|
|
5566
5583
|
}).catch(() => {
|
|
5567
5584
|
}), () => {
|
|
5568
5585
|
b = !0;
|
|
5569
5586
|
};
|
|
5570
5587
|
}, [n, we, a]);
|
|
5571
|
-
const De =
|
|
5588
|
+
const De = ee(M);
|
|
5572
5589
|
se(() => {
|
|
5573
5590
|
De.current = M;
|
|
5574
5591
|
}, [M]), se(() => {
|
|
@@ -5582,7 +5599,7 @@ function Ln() {
|
|
|
5582
5599
|
}, [_e, we]);
|
|
5583
5600
|
function it(b) {
|
|
5584
5601
|
if (xt.current) return;
|
|
5585
|
-
const
|
|
5602
|
+
const z = b.currentTarget, Y = z.scrollHeight - z.scrollTop - z.clientHeight;
|
|
5586
5603
|
Me.current = Y < 80;
|
|
5587
5604
|
}
|
|
5588
5605
|
se(() => {
|
|
@@ -5592,22 +5609,22 @@ function Ln() {
|
|
|
5592
5609
|
}, [n, we, i, H]), se(() => {
|
|
5593
5610
|
!n || !i || $e !== "complete" || (l(""), a(`/chat/${n}`, { replace: !0 }));
|
|
5594
5611
|
}, [n, i, $e, a]);
|
|
5595
|
-
const
|
|
5612
|
+
const j = ee($);
|
|
5596
5613
|
se(() => {
|
|
5597
|
-
|
|
5598
|
-
}, [
|
|
5599
|
-
const Ye =
|
|
5614
|
+
j.current = $;
|
|
5615
|
+
}, [$]);
|
|
5616
|
+
const Ye = ee(null);
|
|
5600
5617
|
se(() => {
|
|
5601
5618
|
if (!Ge || !n || Ye.current === Ge.seq) return;
|
|
5602
5619
|
Ye.current = Ge.seq;
|
|
5603
|
-
const b = n,
|
|
5620
|
+
const b = n, z = Ge.content, Y = z.length > 0 ? Math.max(8, Ge.typingMs / z.length) : 0, ce = Ge.seq, pe = ++qe.current;
|
|
5604
5621
|
async function Xe() {
|
|
5605
5622
|
l("");
|
|
5606
|
-
for (const ht of
|
|
5623
|
+
for (const ht of z) {
|
|
5607
5624
|
if (pe !== qe.current) return;
|
|
5608
5625
|
l((Ue) => Ue + ht), await vs(Y);
|
|
5609
5626
|
}
|
|
5610
|
-
pe === qe.current &&
|
|
5627
|
+
pe === qe.current && j.current(b, ce);
|
|
5611
5628
|
}
|
|
5612
5629
|
Xe();
|
|
5613
5630
|
}, [Ge, n]), se(() => {
|
|
@@ -5616,11 +5633,11 @@ function Ln() {
|
|
|
5616
5633
|
const ue = Pe((b) => {
|
|
5617
5634
|
if (!n) return;
|
|
5618
5635
|
S("");
|
|
5619
|
-
const
|
|
5636
|
+
const z = Array.from(b);
|
|
5620
5637
|
m((Y) => {
|
|
5621
|
-
const
|
|
5622
|
-
for (const pe of
|
|
5623
|
-
if (
|
|
5638
|
+
const ce = [...Y];
|
|
5639
|
+
for (const pe of z) {
|
|
5640
|
+
if (ce.length >= Gt) {
|
|
5624
5641
|
S(`Maximum ${Gt} attachments per message.`);
|
|
5625
5642
|
break;
|
|
5626
5643
|
}
|
|
@@ -5633,7 +5650,7 @@ function Ln() {
|
|
|
5633
5650
|
continue;
|
|
5634
5651
|
}
|
|
5635
5652
|
const Xe = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, ht = pe.type.startsWith("image/") ? URL.createObjectURL(pe) : void 0, Ue = { localId: Xe, file: pe, previewUrl: ht, uploading: !0 };
|
|
5636
|
-
|
|
5653
|
+
ce.push(Ue), L.uploadChatAttachment(n, pe).then((ot) => {
|
|
5637
5654
|
m(
|
|
5638
5655
|
(Dt) => Dt.map(
|
|
5639
5656
|
(Nt) => Nt.localId === Xe ? { ...Nt, uploading: !1, uploadedId: ot.id } : Nt
|
|
@@ -5648,34 +5665,34 @@ function Ln() {
|
|
|
5648
5665
|
);
|
|
5649
5666
|
});
|
|
5650
5667
|
}
|
|
5651
|
-
return
|
|
5668
|
+
return ce;
|
|
5652
5669
|
});
|
|
5653
5670
|
}, [n]), E = (b) => {
|
|
5654
|
-
m((
|
|
5655
|
-
const Y =
|
|
5656
|
-
return Y != null && Y.previewUrl && URL.revokeObjectURL(Y.previewUrl),
|
|
5671
|
+
m((z) => {
|
|
5672
|
+
const Y = z.find((ce) => ce.localId === b);
|
|
5673
|
+
return Y != null && Y.previewUrl && URL.revokeObjectURL(Y.previewUrl), z.filter((ce) => ce.localId !== b);
|
|
5657
5674
|
});
|
|
5658
5675
|
}, q = (b) => {
|
|
5659
5676
|
b.dataTransfer.types.includes("Files") && (b.preventDefault(), y(!0));
|
|
5660
|
-
},
|
|
5661
|
-
const
|
|
5662
|
-
(!
|
|
5677
|
+
}, G = (b) => {
|
|
5678
|
+
const z = b.relatedTarget;
|
|
5679
|
+
(!z || !b.currentTarget.contains(z)) && y(!1);
|
|
5663
5680
|
}, Q = (b) => {
|
|
5664
5681
|
b.preventDefault(), y(!1), b.dataTransfer.files && b.dataTransfer.files.length > 0 && ue(b.dataTransfer.files);
|
|
5665
5682
|
}, Be = (b) => {
|
|
5666
|
-
const
|
|
5683
|
+
const z = [];
|
|
5667
5684
|
for (const Y of b.clipboardData.items)
|
|
5668
5685
|
if (Y.kind === "file") {
|
|
5669
|
-
const
|
|
5670
|
-
|
|
5686
|
+
const ce = Y.getAsFile();
|
|
5687
|
+
ce && z.push(ce);
|
|
5671
5688
|
}
|
|
5672
|
-
|
|
5689
|
+
z.length > 0 && (b.preventDefault(), ue(z));
|
|
5673
5690
|
}, xe = p.some((b) => b.uploading), re = p.some((b) => b.error), de = p.filter((b) => b.uploadedId && !b.error).map((b) => b.uploadedId);
|
|
5674
5691
|
function pt() {
|
|
5675
5692
|
const b = c.trim();
|
|
5676
|
-
if (n && !(!b && de.length === 0) && !xe &&
|
|
5677
|
-
for (const
|
|
5678
|
-
|
|
5693
|
+
if (n && !(!b && de.length === 0) && !xe && K(n, b, de.length > 0 ? de : void 0)) {
|
|
5694
|
+
for (const z of p)
|
|
5695
|
+
z.previewUrl && URL.revokeObjectURL(z.previewUrl);
|
|
5679
5696
|
m([]), S(""), l("");
|
|
5680
5697
|
}
|
|
5681
5698
|
}
|
|
@@ -5683,8 +5700,8 @@ function Ln() {
|
|
|
5683
5700
|
b.key === "Enter" && !b.shiftKey && (b.preventDefault(), pt());
|
|
5684
5701
|
}
|
|
5685
5702
|
function Ze(b) {
|
|
5686
|
-
const
|
|
5687
|
-
|
|
5703
|
+
const z = b.trim();
|
|
5704
|
+
z && (l((Y) => Y.trim() ? `${Y.trim()} ${z}` : z), window.setTimeout(() => {
|
|
5688
5705
|
const Y = me.current;
|
|
5689
5706
|
Y && (Y.focus(), Y.style.height = "auto", Y.style.height = Math.min(Math.max(Y.scrollHeight, 48), 120) + "px");
|
|
5690
5707
|
}, 0));
|
|
@@ -5699,28 +5716,28 @@ function Ln() {
|
|
|
5699
5716
|
return;
|
|
5700
5717
|
}
|
|
5701
5718
|
S("");
|
|
5702
|
-
const
|
|
5703
|
-
u.current =
|
|
5719
|
+
const z = new MediaRecorder(b);
|
|
5720
|
+
u.current = z, h.current = [], z.ondataavailable = (Y) => {
|
|
5704
5721
|
Y.data.size > 0 && h.current.push(Y.data);
|
|
5705
|
-
},
|
|
5722
|
+
}, z.onstop = async () => {
|
|
5706
5723
|
var ht;
|
|
5707
5724
|
b.getTracks().forEach((Ue) => Ue.stop());
|
|
5708
5725
|
const Y = h.current;
|
|
5709
5726
|
if (h.current = [], u.current = null, Y.length === 0) {
|
|
5710
|
-
|
|
5727
|
+
D("idle");
|
|
5711
5728
|
return;
|
|
5712
5729
|
}
|
|
5713
|
-
const
|
|
5714
|
-
|
|
5730
|
+
const ce = z.mimeType || ((ht = Y[0]) == null ? void 0 : ht.type) || "audio/webm", pe = new Blob(Y, { type: ce }), Xe = (ce.split(";")[0].split("/")[1] || "webm").toLowerCase();
|
|
5731
|
+
D("transcribing");
|
|
5715
5732
|
try {
|
|
5716
|
-
const Ue = await Ns(pe), ot = await
|
|
5733
|
+
const Ue = await Ns(pe), ot = await v(Ue, Xe, n);
|
|
5717
5734
|
Ze(ot);
|
|
5718
5735
|
} catch (Ue) {
|
|
5719
5736
|
S(Ue instanceof Error ? Ue.message : t("chat.transcribeFailed"));
|
|
5720
5737
|
} finally {
|
|
5721
|
-
|
|
5738
|
+
D("idle");
|
|
5722
5739
|
}
|
|
5723
|
-
},
|
|
5740
|
+
}, z.start(), D("recording");
|
|
5724
5741
|
}
|
|
5725
5742
|
function ha() {
|
|
5726
5743
|
const b = u.current;
|
|
@@ -5734,7 +5751,7 @@ function Ln() {
|
|
|
5734
5751
|
{
|
|
5735
5752
|
className: "relative -m-4 h-[calc(100%+2rem)] overflow-hidden md:-m-6 md:h-[calc(100%+3rem)]",
|
|
5736
5753
|
onDragOver: q,
|
|
5737
|
-
onDragLeave:
|
|
5754
|
+
onDragLeave: G,
|
|
5738
5755
|
onDrop: Q,
|
|
5739
5756
|
children: [
|
|
5740
5757
|
x && /* @__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") }),
|
|
@@ -5772,8 +5789,8 @@ function Ln() {
|
|
|
5772
5789
|
"button",
|
|
5773
5790
|
{
|
|
5774
5791
|
onClick: () => {
|
|
5775
|
-
var
|
|
5776
|
-
l(b), (
|
|
5792
|
+
var z;
|
|
5793
|
+
l(b), (z = me.current) == null || z.focus();
|
|
5777
5794
|
},
|
|
5778
5795
|
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",
|
|
5779
5796
|
children: b
|
|
@@ -5781,7 +5798,7 @@ function Ln() {
|
|
|
5781
5798
|
b
|
|
5782
5799
|
)) })
|
|
5783
5800
|
] }),
|
|
5784
|
-
Je.map((b,
|
|
5801
|
+
Je.map((b, z) => /* @__PURE__ */ e(ks, { message: b }, z)),
|
|
5785
5802
|
/* @__PURE__ */ e("div", { ref: Ce })
|
|
5786
5803
|
]
|
|
5787
5804
|
}
|
|
@@ -5846,8 +5863,8 @@ function Ln() {
|
|
|
5846
5863
|
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",
|
|
5847
5864
|
style: { minHeight: "3rem", maxHeight: "120px" },
|
|
5848
5865
|
onInput: (b) => {
|
|
5849
|
-
const
|
|
5850
|
-
|
|
5866
|
+
const z = b.target;
|
|
5867
|
+
z.style.height = "auto", z.style.height = Math.min(Math.max(z.scrollHeight, 48), 120) + "px";
|
|
5851
5868
|
}
|
|
5852
5869
|
}
|
|
5853
5870
|
),
|
|
@@ -6071,7 +6088,7 @@ function Ds(t, n) {
|
|
|
6071
6088
|
return s < t.length && a.push(t.slice(s)), a.length > 0 ? a : [t];
|
|
6072
6089
|
}
|
|
6073
6090
|
function _s() {
|
|
6074
|
-
const t = Ee(), [n] = Et(), { user: a, login: s, register: o } = bt(), { t: i } =
|
|
6091
|
+
const t = Ee(), [n] = Et(), { user: a, login: s, register: o } = bt(), { t: i } = ne(), c = n.get("invite") || "", [l, g] = N(c ? "register" : "login"), [d, p] = N(!1), [m, f] = N(!1), [S, x] = N(!0), [y, P] = N(""), [D, T] = N(""), [u, h] = N(""), [A, R] = N(""), [k, H] = N("");
|
|
6075
6092
|
se(() => {
|
|
6076
6093
|
a && a.role !== "public_manager" && t("/", { replace: !0 });
|
|
6077
6094
|
}, [a, t]), se(() => {
|
|
@@ -6080,7 +6097,7 @@ function _s() {
|
|
|
6080
6097
|
}).catch(() => {
|
|
6081
6098
|
}).finally(() => x(!1));
|
|
6082
6099
|
}, []);
|
|
6083
|
-
const
|
|
6100
|
+
const $ = async (M) => {
|
|
6084
6101
|
if (M.preventDefault(), P(""), l === "register") {
|
|
6085
6102
|
if (A !== k) {
|
|
6086
6103
|
P(i("login.passwordsNoMatch"));
|
|
@@ -6091,13 +6108,13 @@ function _s() {
|
|
|
6091
6108
|
return;
|
|
6092
6109
|
}
|
|
6093
6110
|
try {
|
|
6094
|
-
await o(
|
|
6111
|
+
await o(D, u, A, c || void 0), t("/", { replace: !0 });
|
|
6095
6112
|
} catch (w) {
|
|
6096
6113
|
P(w instanceof je ? w.message : i("login.registrationFailed"));
|
|
6097
6114
|
}
|
|
6098
6115
|
} else
|
|
6099
6116
|
try {
|
|
6100
|
-
await s(
|
|
6117
|
+
await s(D, A), t("/", { replace: !0 });
|
|
6101
6118
|
} catch (w) {
|
|
6102
6119
|
P(w instanceof je ? w.message : i("login.loginFailed"));
|
|
6103
6120
|
}
|
|
@@ -6109,9 +6126,9 @@ function _s() {
|
|
|
6109
6126
|
(a == null ? void 0 : a.role) === "public_manager" && /* @__PURE__ */ e("p", { className: "mt-2 text-xs text-amber-700", children: i("login.demoBanner") })
|
|
6110
6127
|
] }),
|
|
6111
6128
|
y && /* @__PURE__ */ e("div", { className: "rounded-lg bg-rose-50 px-4 py-3 text-sm text-rose-700 ring-1 ring-rose-200", children: y }),
|
|
6112
|
-
/* @__PURE__ */ e(
|
|
6129
|
+
/* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("form", { onSubmit: $, className: "space-y-4", children: [
|
|
6113
6130
|
l === "register" && /* @__PURE__ */ e(
|
|
6114
|
-
|
|
6131
|
+
X,
|
|
6115
6132
|
{
|
|
6116
6133
|
label: i("login.fullName"),
|
|
6117
6134
|
value: u,
|
|
@@ -6120,17 +6137,17 @@ function _s() {
|
|
|
6120
6137
|
}
|
|
6121
6138
|
),
|
|
6122
6139
|
/* @__PURE__ */ e(
|
|
6123
|
-
|
|
6140
|
+
X,
|
|
6124
6141
|
{
|
|
6125
6142
|
label: i("login.email"),
|
|
6126
6143
|
type: "email",
|
|
6127
|
-
value:
|
|
6144
|
+
value: D,
|
|
6128
6145
|
onChange: (M) => T(M.target.value),
|
|
6129
6146
|
required: !0
|
|
6130
6147
|
}
|
|
6131
6148
|
),
|
|
6132
6149
|
/* @__PURE__ */ e(
|
|
6133
|
-
|
|
6150
|
+
X,
|
|
6134
6151
|
{
|
|
6135
6152
|
label: i("login.password"),
|
|
6136
6153
|
type: "password",
|
|
@@ -6140,7 +6157,7 @@ function _s() {
|
|
|
6140
6157
|
}
|
|
6141
6158
|
),
|
|
6142
6159
|
l === "register" && /* @__PURE__ */ e(
|
|
6143
|
-
|
|
6160
|
+
X,
|
|
6144
6161
|
{
|
|
6145
6162
|
label: i("login.confirmPassword"),
|
|
6146
6163
|
type: "password",
|
|
@@ -6151,7 +6168,7 @@ function _s() {
|
|
|
6151
6168
|
),
|
|
6152
6169
|
/* @__PURE__ */ e(J, { type: "submit", className: "w-full", children: i(l === "register" ? m ? "login.createAdmin" : "login.register" : "login.signIn") })
|
|
6153
6170
|
] }) }),
|
|
6154
|
-
(a == null ? void 0 : a.role) === "public_manager" && /* @__PURE__ */ e(
|
|
6171
|
+
(a == null ? void 0 : a.role) === "public_manager" && /* @__PURE__ */ e(U, { children: /* @__PURE__ */ r("div", { className: "space-y-3", children: [
|
|
6155
6172
|
/* @__PURE__ */ r("div", { children: [
|
|
6156
6173
|
/* @__PURE__ */ e("h2", { className: "text-sm font-semibold text-fg", children: i("login.browsingTitle") }),
|
|
6157
6174
|
/* @__PURE__ */ e("p", { className: "mt-1 text-sm text-fg-muted", children: i("login.browsingBody") })
|
|
@@ -6178,7 +6195,7 @@ function _s() {
|
|
|
6178
6195
|
] }) });
|
|
6179
6196
|
}
|
|
6180
6197
|
function Ps() {
|
|
6181
|
-
const t = Ee(), n =
|
|
6198
|
+
const t = Ee(), n = ee(!1), [a, s] = N("");
|
|
6182
6199
|
return se(() => {
|
|
6183
6200
|
n.current || (n.current = !0, L.createChatSession().then((o) => {
|
|
6184
6201
|
t(`/chat/${o.id}?demo=1`, { replace: !0 });
|
|
@@ -6210,7 +6227,7 @@ function On() {
|
|
|
6210
6227
|
return { type: "sales", party: "", amount: "", due_date: "", remarks: "" };
|
|
6211
6228
|
}
|
|
6212
6229
|
function Ts() {
|
|
6213
|
-
const t = Ee(), n =
|
|
6230
|
+
const t = Ee(), n = Ke(), [a, s] = N(""), [o, i] = N((/* @__PURE__ */ new Date()).toISOString().split("T")[0]), [c, l] = N(""), [g, d] = N([Bn()]), [p, m] = N([En()]), [f, S] = N([On()]), [x, y] = N({}), P = oe({
|
|
6214
6231
|
mutationFn: () => L.importAccountBalances({
|
|
6215
6232
|
company: a,
|
|
6216
6233
|
posting_date: o,
|
|
@@ -6223,7 +6240,7 @@ function Ts() {
|
|
|
6223
6240
|
}))
|
|
6224
6241
|
}),
|
|
6225
6242
|
onSuccess: (h) => y((A) => ({ ...A, accounts: h }))
|
|
6226
|
-
}),
|
|
6243
|
+
}), D = oe({
|
|
6227
6244
|
mutationFn: () => L.importStockBalances({
|
|
6228
6245
|
company: a,
|
|
6229
6246
|
posting_date: o,
|
|
@@ -6235,7 +6252,7 @@ function Ts() {
|
|
|
6235
6252
|
}))
|
|
6236
6253
|
}),
|
|
6237
6254
|
onSuccess: (h) => y((A) => ({ ...A, stock: h }))
|
|
6238
|
-
}), T =
|
|
6255
|
+
}), T = oe({
|
|
6239
6256
|
mutationFn: () => L.importOutstandingInvoices({
|
|
6240
6257
|
company: a,
|
|
6241
6258
|
invoices: f.filter((h) => h.party && h.amount).map((h) => ({
|
|
@@ -6250,16 +6267,16 @@ function Ts() {
|
|
|
6250
6267
|
onSuccess: (h) => y((A) => ({ ...A, invoices: h }))
|
|
6251
6268
|
});
|
|
6252
6269
|
function u(h, A, R, k, H) {
|
|
6253
|
-
const
|
|
6254
|
-
|
|
6270
|
+
const $ = [...h];
|
|
6271
|
+
$[R][k] = H, A($);
|
|
6255
6272
|
}
|
|
6256
6273
|
return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
6257
6274
|
/* @__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." }),
|
|
6258
|
-
/* @__PURE__ */ e(
|
|
6275
|
+
/* @__PURE__ */ e(U, { title: "Common Settings", children: /* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
6259
6276
|
/* @__PURE__ */ e(ke, { label: "Company", value: a, onChange: s, linkDoctype: "company", readOnly: !1 }),
|
|
6260
|
-
/* @__PURE__ */ e(
|
|
6277
|
+
/* @__PURE__ */ e(X, { label: "As-of Date", type: "date", value: o, onChange: (h) => i(h.target.value) })
|
|
6261
6278
|
] }) }),
|
|
6262
|
-
/* @__PURE__ */ r(
|
|
6279
|
+
/* @__PURE__ */ r(U, { title: "1. Account Balances", children: [
|
|
6263
6280
|
/* @__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." }),
|
|
6264
6281
|
/* @__PURE__ */ e("div", { children: /* @__PURE__ */ r("table", { className: "min-w-full text-sm", children: [
|
|
6265
6282
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
@@ -6291,7 +6308,7 @@ function Ts() {
|
|
|
6291
6308
|
] })
|
|
6292
6309
|
] })
|
|
6293
6310
|
] }),
|
|
6294
|
-
/* @__PURE__ */ r(
|
|
6311
|
+
/* @__PURE__ */ r(U, { title: "2. Stock Balances", children: [
|
|
6295
6312
|
/* @__PURE__ */ e("p", { className: "mb-3 text-xs text-gray-500", children: "Enter your current inventory. Creates a Stock Entry (Opening Stock) — posts Dr Stock In Hand / Cr Opening Balance Equity so the P&L isn't distorted by day-one inventory." }),
|
|
6296
6313
|
/* @__PURE__ */ e("div", { className: "mb-3", children: /* @__PURE__ */ e(ke, { label: "Warehouse", value: c, onChange: l, linkDoctype: "warehouse", readOnly: !1 }) }),
|
|
6297
6314
|
/* @__PURE__ */ e("div", { children: /* @__PURE__ */ r("table", { className: "min-w-full text-sm", children: [
|
|
@@ -6308,8 +6325,8 @@ function Ts() {
|
|
|
6308
6325
|
] }) }),
|
|
6309
6326
|
/* @__PURE__ */ e("div", { className: "mt-2", children: /* @__PURE__ */ e("button", { onClick: () => m([...p, En()]), className: "text-xs text-blue-600 hover:text-blue-800", children: "+ Add Row" }) }),
|
|
6310
6327
|
/* @__PURE__ */ r("div", { className: "mt-3 flex items-center gap-3", children: [
|
|
6311
|
-
/* @__PURE__ */ e(J, { onClick: () =>
|
|
6312
|
-
|
|
6328
|
+
/* @__PURE__ */ e(J, { onClick: () => D.mutate(), disabled: !a || !c || D.isPending, children: D.isPending ? "Importing..." : "Import Stock Balances" }),
|
|
6329
|
+
D.error && /* @__PURE__ */ e("span", { className: "text-xs text-red-600", children: D.error.message }),
|
|
6313
6330
|
x.stock && /* @__PURE__ */ r("span", { className: "text-xs text-green-600", children: [
|
|
6314
6331
|
"Created ",
|
|
6315
6332
|
x.stock.stock_entry,
|
|
@@ -6319,7 +6336,7 @@ function Ts() {
|
|
|
6319
6336
|
] })
|
|
6320
6337
|
] })
|
|
6321
6338
|
] }),
|
|
6322
|
-
/* @__PURE__ */ r(
|
|
6339
|
+
/* @__PURE__ */ r(U, { title: "3. Outstanding Invoices", children: [
|
|
6323
6340
|
/* @__PURE__ */ e("p", { className: "mb-3 text-xs text-gray-500", children: "Enter unpaid invoices from your old system. Creates submitted Sales or Purchase Invoices with the correct outstanding amounts for AR/AP aging." }),
|
|
6324
6341
|
/* @__PURE__ */ e("div", { children: /* @__PURE__ */ r("table", { className: "min-w-full text-sm", children: [
|
|
6325
6342
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
@@ -6376,35 +6393,35 @@ function Ts() {
|
|
|
6376
6393
|
] });
|
|
6377
6394
|
}
|
|
6378
6395
|
function As() {
|
|
6379
|
-
const { user: t } = bt(), n =
|
|
6396
|
+
const { user: t } = bt(), n = Ke(), { data: a, isLoading: s } = le({
|
|
6380
6397
|
queryKey: ["auth-users"],
|
|
6381
6398
|
queryFn: () => L.authListUsers()
|
|
6382
|
-
}), { data: o } =
|
|
6399
|
+
}), { data: o } = le({
|
|
6383
6400
|
queryKey: ["auth-invites"],
|
|
6384
6401
|
queryFn: () => L.authListInvites()
|
|
6385
|
-
}), [i, c] = N(""), [l, g] = N("viewer"), [d, p] = N(null), m =
|
|
6402
|
+
}), [i, c] = N(""), [l, g] = N("viewer"), [d, p] = N(null), m = oe({
|
|
6386
6403
|
mutationFn: () => L.authInvite(i, l),
|
|
6387
6404
|
onSuccess: (u) => {
|
|
6388
6405
|
p(u), c(""), n.invalidateQueries({ queryKey: ["auth-invites"] });
|
|
6389
6406
|
}
|
|
6390
|
-
}), f =
|
|
6407
|
+
}), f = oe({
|
|
6391
6408
|
mutationFn: ({ name: u, role: h }) => L.authChangeRole(u, h),
|
|
6392
6409
|
onSuccess: () => n.invalidateQueries({ queryKey: ["auth-users"] })
|
|
6393
|
-
}), S =
|
|
6410
|
+
}), S = oe({
|
|
6394
6411
|
mutationFn: (u) => L.authDisableUser(u),
|
|
6395
6412
|
onSuccess: () => n.invalidateQueries({ queryKey: ["auth-users"] })
|
|
6396
|
-
}), x =
|
|
6413
|
+
}), x = oe({
|
|
6397
6414
|
mutationFn: (u) => L.authRevokeInvite(u),
|
|
6398
6415
|
onSuccess: () => n.invalidateQueries({ queryKey: ["auth-invites"] })
|
|
6399
|
-
}), [y, P] = N(null),
|
|
6416
|
+
}), [y, P] = N(null), D = (u) => `${window.location.origin}/login?invite=${u}`, T = async (u) => {
|
|
6400
6417
|
try {
|
|
6401
|
-
await navigator.clipboard.writeText(
|
|
6418
|
+
await navigator.clipboard.writeText(D(u)), P(u), setTimeout(() => P((h) => h === u ? null : h), 2e3);
|
|
6402
6419
|
} catch {
|
|
6403
|
-
window.prompt("Invite link",
|
|
6420
|
+
window.prompt("Invite link", D(u));
|
|
6404
6421
|
}
|
|
6405
6422
|
};
|
|
6406
6423
|
return (t == null ? void 0 : t.role) !== "admin" ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-gray-400", children: "Admin access required" }) : /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
6407
|
-
/* @__PURE__ */ e(
|
|
6424
|
+
/* @__PURE__ */ e(U, { title: "Roles", children: /* @__PURE__ */ r("div", { className: "grid gap-3 text-sm sm:grid-cols-3", children: [
|
|
6408
6425
|
/* @__PURE__ */ r("div", { className: "rounded-lg border border-blue-200 bg-blue-50 p-3", children: [
|
|
6409
6426
|
/* @__PURE__ */ e("div", { className: "font-semibold text-blue-900", children: "Admin" }),
|
|
6410
6427
|
/* @__PURE__ */ e("p", { className: "mt-1 text-blue-700", children: "Full access. Can create and manage documents, masters, company setup, and users. Can invite team members and change roles." })
|
|
@@ -6418,10 +6435,10 @@ function As() {
|
|
|
6418
6435
|
/* @__PURE__ */ e("p", { className: "mt-1 text-gray-600", children: "Read-only access to all documents, masters, and reports. Can use the AI chat. Cannot create or modify any data." })
|
|
6419
6436
|
] })
|
|
6420
6437
|
] }) }),
|
|
6421
|
-
/* @__PURE__ */ r(
|
|
6438
|
+
/* @__PURE__ */ r(U, { title: "Invite User", children: [
|
|
6422
6439
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
|
|
6423
6440
|
/* @__PURE__ */ e(
|
|
6424
|
-
|
|
6441
|
+
X,
|
|
6425
6442
|
{
|
|
6426
6443
|
label: "Email",
|
|
6427
6444
|
type: "email",
|
|
@@ -6461,7 +6478,7 @@ function As() {
|
|
|
6461
6478
|
] })
|
|
6462
6479
|
] })
|
|
6463
6480
|
] }),
|
|
6464
|
-
o && o.filter((u) => !u.used).length > 0 && /* @__PURE__ */ e(
|
|
6481
|
+
o && o.filter((u) => !u.used).length > 0 && /* @__PURE__ */ e(U, { title: "Pending Invites", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
6465
6482
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
6466
6483
|
/* @__PURE__ */ e("th", { className: "px-4 py-2 text-left font-medium text-gray-500", children: "Email" }),
|
|
6467
6484
|
/* @__PURE__ */ e("th", { className: "px-4 py-2 text-left font-medium text-gray-500", children: "Role" }),
|
|
@@ -6498,7 +6515,7 @@ function As() {
|
|
|
6498
6515
|
] }, u.token);
|
|
6499
6516
|
}) })
|
|
6500
6517
|
] }) }),
|
|
6501
|
-
/* @__PURE__ */ e(
|
|
6518
|
+
/* @__PURE__ */ e(U, { title: "Team Members", children: s ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: "Loading..." }) : /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
|
|
6502
6519
|
/* @__PURE__ */ e("thead", { className: "bg-gray-50", children: /* @__PURE__ */ r("tr", { children: [
|
|
6503
6520
|
/* @__PURE__ */ e("th", { className: "px-4 py-2 text-left font-medium text-gray-500", children: "Name" }),
|
|
6504
6521
|
/* @__PURE__ */ e("th", { className: "px-4 py-2 text-left font-medium text-gray-500", children: "Email" }),
|
|
@@ -6536,7 +6553,7 @@ function As() {
|
|
|
6536
6553
|
] }) })
|
|
6537
6554
|
] });
|
|
6538
6555
|
}
|
|
6539
|
-
const Rs = { 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" }, Is = { title: "Language", help: "Choose the language for the interface. Your choice is saved in this browser.", label: "Language" }, Ls = { logout: "Logout", openMenu: "Open menu", closeMenu: "Close menu", new: "New {{label}}" }, Bs = { 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" }, Es = { 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" } }, Os = { 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" } }, qs = { 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" } }, Fs = { 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" }, zs = { 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" }, Ms = { 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" }, $s = { 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" }, Us = { 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}}." }, Vs = { totalRevenue: "Total Revenue", outstandingReceivable: "Outstanding Receivable", outstandingPayable: "Outstanding Payable", totalStockValue: "Total Stock Value", recentDocuments: "Recent Documents", noRecentDocuments: "No recent documents" }, js = { 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." }, Gs = { "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" }, Ws = { "% 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", 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" }, Ks = { accounts: "accounts", items: "items", monthly_distribution: "monthly_distribution", payments: "payments", plans: "plans", references: "references", taxes: "taxes" }, Qs = /* @__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."}`), Hs = {
|
|
6556
|
+
const Rs = { 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" }, Is = { title: "Language", help: "Choose the language for the interface. Your choice is saved in this browser.", label: "Language" }, Ls = { logout: "Logout", openMenu: "Open menu", closeMenu: "Close menu", new: "New {{label}}" }, Bs = { 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" }, Es = { 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" } }, Os = { 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" } }, qs = { 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" } }, Fs = { 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" }, zs = { 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" }, Ms = { 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" }, $s = { 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" }, Us = { 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}}." }, Vs = { totalRevenue: "Total Revenue", outstandingReceivable: "Outstanding Receivable", outstandingPayable: "Outstanding Payable", totalStockValue: "Total Stock Value", recentDocuments: "Recent Documents", noRecentDocuments: "No recent documents" }, js = { 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." }, Gs = { "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" }, Ks = { "% 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", 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" }, Ws = { accounts: "accounts", items: "items", monthly_distribution: "monthly_distribution", payments: "payments", plans: "plans", references: "references", taxes: "taxes" }, Qs = /* @__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."}`), Hs = {
|
|
6540
6557
|
common: Rs,
|
|
6541
6558
|
language: Is,
|
|
6542
6559
|
header: Ls,
|
|
@@ -6552,8 +6569,8 @@ const Rs = { save: "Save", saving: "Saving...", submit: "Submit", cancel: "Cance
|
|
|
6552
6569
|
dashboard: Vs,
|
|
6553
6570
|
chat: js,
|
|
6554
6571
|
conversions: Gs,
|
|
6555
|
-
fields:
|
|
6556
|
-
tables:
|
|
6572
|
+
fields: Ks,
|
|
6573
|
+
tables: Ws,
|
|
6557
6574
|
tutorial: Qs
|
|
6558
6575
|
}, Js = { 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" }, Ys = { title: "Sprache", help: "Wählen Sie die Sprache der Oberfläche. Ihre Auswahl wird in diesem Browser gespeichert.", label: "Sprache" }, Zs = { logout: "Abmelden", openMenu: "Menü öffnen", closeMenu: "Menü schließen", new: "Neu: {{label}}" }, Xs = { 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" }, ei = { 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" } }, ti = { 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" } }, ni = { 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" } }, ai = { 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" }, ri = { 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" }, si = { 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" }, ii = { 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" }, oi = { 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." }, li = { 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", "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" }, ci = { items: "Positionen", taxes: "Steuern", references: "Zahlungsreferenzen", accounts: "Kontobuchungen", payments: "Zahlungen", plans: "Planpositionen", monthly_distribution: "Monatliche Verteilung" }, di = { "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" }, ui = { totalRevenue: "Gesamtumsatz", outstandingReceivable: "Offene Forderungen", outstandingPayable: "Offene Verbindlichkeiten", totalStockValue: "Gesamter Lagerwert", recentDocuments: "Letzte Dokumente", noRecentDocuments: "Keine aktuellen Dokumente" }, mi = { 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." }, pi = /* @__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."}}}'), hi = {
|
|
6559
6576
|
common: Js,
|
|
@@ -6632,7 +6649,7 @@ Hn.use(Sa).init({
|
|
|
6632
6649
|
Hn.on("languageChanged", Oi);
|
|
6633
6650
|
function qi({ label: t }) {
|
|
6634
6651
|
var o;
|
|
6635
|
-
const { t: n, i18n: a } =
|
|
6652
|
+
const { t: n, i18n: a } = ne(), s = ((o = a.language) == null ? void 0 : o.split("-")[0]) ?? "en";
|
|
6636
6653
|
return /* @__PURE__ */ e(
|
|
6637
6654
|
rt,
|
|
6638
6655
|
{
|
|
@@ -6655,14 +6672,14 @@ function Ve(t) {
|
|
|
6655
6672
|
return t === 0 ? "$0.00" : t < 0.01 ? `$${t.toFixed(4)}` : `$${t.toFixed(2)}`;
|
|
6656
6673
|
}
|
|
6657
6674
|
function Fi({ demoActive: t }) {
|
|
6658
|
-
var
|
|
6659
|
-
const { t: n } =
|
|
6675
|
+
var D, T;
|
|
6676
|
+
const { t: n } = ne(), [a, s] = N("1h"), { data: o, isLoading: i, isFetching: c, error: l, refetch: g, dataUpdatedAt: d } = le({
|
|
6660
6677
|
queryKey: ["demo-spend"],
|
|
6661
6678
|
queryFn: () => L.getDemoSpend(),
|
|
6662
6679
|
// Refresh once a minute — demo spend changes slowly; no need to poll harder.
|
|
6663
6680
|
refetchInterval: 6e4
|
|
6664
|
-
}), p = qn.find((u) => u.value === a), m = (
|
|
6665
|
-
return /* @__PURE__ */ r(
|
|
6681
|
+
}), p = qn.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, S = m ? m.demo_usd / p.hours : 0, x = m ? m.total_usd / p.hours : 0, y = f > 0 ? Math.min(100, S / f * 100) : 0, P = y >= 90 ? "bg-red-500" : y >= 60 ? "bg-amber-500" : "bg-emerald-500";
|
|
6682
|
+
return /* @__PURE__ */ r(U, { title: n("settings.tokenSpendTitle"), children: [
|
|
6666
6683
|
/* @__PURE__ */ r("div", { className: "flex flex-wrap items-end justify-between gap-4", children: [
|
|
6667
6684
|
/* @__PURE__ */ r("div", { className: "max-w-lg text-sm text-gray-600", children: [
|
|
6668
6685
|
"Cost and token usage from AI / LLM calls in this deployment, across all providers.",
|
|
@@ -6839,7 +6856,7 @@ function St({ label: t, value: n }) {
|
|
|
6839
6856
|
] });
|
|
6840
6857
|
}
|
|
6841
6858
|
function zi() {
|
|
6842
|
-
const { t } =
|
|
6859
|
+
const { t } = ne(), { user: n } = bt(), [a, s] = N(""), [o, i] = N(""), [c, l] = N(""), [g, d] = N(""), [p, m] = N(!1), f = oe({
|
|
6843
6860
|
mutationFn: () => L.authChangePassword(a, o),
|
|
6844
6861
|
onSuccess: () => {
|
|
6845
6862
|
m(!0), d(""), s(""), i(""), l(""), setTimeout(() => m(!1), 4e3);
|
|
@@ -6856,7 +6873,7 @@ function zi() {
|
|
|
6856
6873
|
}
|
|
6857
6874
|
f.mutate();
|
|
6858
6875
|
};
|
|
6859
|
-
return /* @__PURE__ */ e(
|
|
6876
|
+
return /* @__PURE__ */ e(U, { title: t("settings.passwordTitle"), children: /* @__PURE__ */ r("form", { onSubmit: S, className: "max-w-sm space-y-3", children: [
|
|
6860
6877
|
/* @__PURE__ */ e(
|
|
6861
6878
|
"input",
|
|
6862
6879
|
{
|
|
@@ -6872,7 +6889,7 @@ function zi() {
|
|
|
6872
6889
|
}
|
|
6873
6890
|
),
|
|
6874
6891
|
/* @__PURE__ */ e(
|
|
6875
|
-
|
|
6892
|
+
X,
|
|
6876
6893
|
{
|
|
6877
6894
|
label: t("settings.currentPassword"),
|
|
6878
6895
|
id: "current-password",
|
|
@@ -6885,7 +6902,7 @@ function zi() {
|
|
|
6885
6902
|
}
|
|
6886
6903
|
),
|
|
6887
6904
|
/* @__PURE__ */ e(
|
|
6888
|
-
|
|
6905
|
+
X,
|
|
6889
6906
|
{
|
|
6890
6907
|
label: t("settings.newPassword"),
|
|
6891
6908
|
id: "new-password",
|
|
@@ -6898,7 +6915,7 @@ function zi() {
|
|
|
6898
6915
|
}
|
|
6899
6916
|
),
|
|
6900
6917
|
/* @__PURE__ */ e(
|
|
6901
|
-
|
|
6918
|
+
X,
|
|
6902
6919
|
{
|
|
6903
6920
|
label: t("settings.confirmNewPassword"),
|
|
6904
6921
|
id: "confirm-password",
|
|
@@ -6916,31 +6933,31 @@ function zi() {
|
|
|
6916
6933
|
] }) });
|
|
6917
6934
|
}
|
|
6918
6935
|
function Mi() {
|
|
6919
|
-
const { user: t } = bt(), { t: n } =
|
|
6936
|
+
const { user: t } = bt(), { t: n } = ne(), a = Ke(), s = (t == null ? void 0 : t.role) === "admin", { data: o, isLoading: i } = le({
|
|
6920
6937
|
queryKey: ["settings"],
|
|
6921
6938
|
queryFn: () => L.getSettings()
|
|
6922
|
-
}), c =
|
|
6939
|
+
}), c = oe({
|
|
6923
6940
|
mutationFn: (f) => L.updateSettings(f),
|
|
6924
6941
|
onSuccess: () => a.invalidateQueries({ queryKey: ["settings"] })
|
|
6925
|
-
}), { data: l } =
|
|
6942
|
+
}), { data: l } = le({
|
|
6926
6943
|
queryKey: ["public-manager"],
|
|
6927
6944
|
queryFn: () => L.getPublicManagerStatus()
|
|
6928
|
-
}), [g, d] = N(!1), p =
|
|
6945
|
+
}), [g, d] = N(!1), p = oe({
|
|
6929
6946
|
mutationFn: () => L.createPublicManager(),
|
|
6930
6947
|
onSuccess: () => {
|
|
6931
6948
|
a.invalidateQueries({ queryKey: ["public-manager"] }), d(!1);
|
|
6932
6949
|
}
|
|
6933
|
-
}), m =
|
|
6950
|
+
}), m = oe({
|
|
6934
6951
|
mutationFn: () => L.removePublicManager(),
|
|
6935
6952
|
onSuccess: () => a.invalidateQueries({ queryKey: ["public-manager"] })
|
|
6936
6953
|
});
|
|
6937
6954
|
return i ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: n("common.loading") }) : /* @__PURE__ */ r("div", { className: "space-y-6", children: [
|
|
6938
|
-
/* @__PURE__ */ r(
|
|
6955
|
+
/* @__PURE__ */ r(U, { title: n("language.title"), children: [
|
|
6939
6956
|
/* @__PURE__ */ e("div", { className: "flex flex-wrap items-end gap-4", children: /* @__PURE__ */ e("div", { className: "w-64", children: /* @__PURE__ */ e(qi, {}) }) }),
|
|
6940
6957
|
/* @__PURE__ */ e("p", { className: "mt-2 text-xs text-gray-400", children: n("language.help") })
|
|
6941
6958
|
] }),
|
|
6942
6959
|
(t == null ? void 0 : t.role) !== "public_manager" && /* @__PURE__ */ e(zi, {}),
|
|
6943
|
-
/* @__PURE__ */ r(
|
|
6960
|
+
/* @__PURE__ */ r(U, { title: n("settings.pdfTitle"), children: [
|
|
6944
6961
|
/* @__PURE__ */ e("div", { className: "flex flex-wrap items-end gap-4", children: s ? /* @__PURE__ */ e(
|
|
6945
6962
|
rt,
|
|
6946
6963
|
{
|
|
@@ -6955,7 +6972,7 @@ function Mi() {
|
|
|
6955
6972
|
] }) }),
|
|
6956
6973
|
/* @__PURE__ */ e("p", { className: "mt-2 text-xs text-gray-400", children: n("settings.pdfHelp") })
|
|
6957
6974
|
] }),
|
|
6958
|
-
/* @__PURE__ */ e(
|
|
6975
|
+
/* @__PURE__ */ e(U, { title: n("settings.openingTitle"), children: /* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
|
|
6959
6976
|
/* @__PURE__ */ r("div", { children: [
|
|
6960
6977
|
/* @__PURE__ */ e("p", { className: "text-sm text-gray-700", children: n("settings.openingBody") }),
|
|
6961
6978
|
/* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-400", children: (o == null ? void 0 : o.opening_balances_enabled) === "1" ? n("settings.openingEnabled") : n("settings.openingDisabled") })
|
|
@@ -6971,7 +6988,7 @@ function Mi() {
|
|
|
6971
6988
|
}
|
|
6972
6989
|
)
|
|
6973
6990
|
] }) }),
|
|
6974
|
-
/* @__PURE__ */ e(
|
|
6991
|
+
/* @__PURE__ */ e(U, { title: n("settings.signupTitle"), children: /* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
|
|
6975
6992
|
/* @__PURE__ */ r("div", { children: [
|
|
6976
6993
|
/* @__PURE__ */ e("p", { className: "text-sm text-gray-700", children: n("settings.signupBody") }),
|
|
6977
6994
|
/* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-400", children: (o == null ? void 0 : o.allow_public_signup) === "1" ? n("settings.signupEnabled") : n("settings.signupDisabled") })
|
|
@@ -6988,7 +7005,7 @@ function Mi() {
|
|
|
6988
7005
|
)
|
|
6989
7006
|
] }) }),
|
|
6990
7007
|
s && /* @__PURE__ */ e(Fi, { demoActive: !!(l != null && l.active) }),
|
|
6991
|
-
s && /* @__PURE__ */ e(
|
|
7008
|
+
s && /* @__PURE__ */ e(U, { title: n("settings.publicTitle"), children: l != null && l.active ? /* @__PURE__ */ r("div", { children: [
|
|
6992
7009
|
/* @__PURE__ */ r("div", { className: "flex items-center gap-2", children: [
|
|
6993
7010
|
/* @__PURE__ */ e("span", { className: "inline-block h-2 w-2 rounded-full bg-green-500" }),
|
|
6994
7011
|
/* @__PURE__ */ e("span", { className: "text-sm font-medium text-green-800", children: n("settings.publicActive") })
|
|
@@ -7074,7 +7091,7 @@ const Vi = [
|
|
|
7074
7091
|
{ path: "masters/:type/:name", element: /* @__PURE__ */ e(_n, {}) },
|
|
7075
7092
|
// Reports
|
|
7076
7093
|
{ path: "reports/trial-balance", element: /* @__PURE__ */ e(jr, {}) },
|
|
7077
|
-
{ path: "reports/general-ledger", element: /* @__PURE__ */ e(
|
|
7094
|
+
{ path: "reports/general-ledger", element: /* @__PURE__ */ e(Wr, {}) },
|
|
7078
7095
|
{ path: "reports/stock-balance", element: /* @__PURE__ */ e(Qr, {}) },
|
|
7079
7096
|
{ path: "reports/profit-and-loss", element: /* @__PURE__ */ e(Hr, {}) },
|
|
7080
7097
|
{ path: "reports/balance-sheet", element: /* @__PURE__ */ e(Jr, {}) },
|
|
@@ -7107,7 +7124,7 @@ function Gi() {
|
|
|
7107
7124
|
}
|
|
7108
7125
|
];
|
|
7109
7126
|
}
|
|
7110
|
-
function
|
|
7127
|
+
function Ki() {
|
|
7111
7128
|
return new xa({
|
|
7112
7129
|
defaultOptions: {
|
|
7113
7130
|
queries: { retry: 1, refetchOnWindowFocus: !1 }
|
|
@@ -7118,22 +7135,22 @@ function po(t = {}) {
|
|
|
7118
7135
|
const n = t.rootElement ?? document.getElementById("root");
|
|
7119
7136
|
if (!n)
|
|
7120
7137
|
throw new Error('bootstrap: no mount element (pass rootElement or add <div id="root">)');
|
|
7121
|
-
const a = t.queryClient ??
|
|
7138
|
+
const a = t.queryClient ?? Ki(), s = wa(Gi());
|
|
7122
7139
|
fa(n).render(
|
|
7123
|
-
/* @__PURE__ */ e(ya, { children: /* @__PURE__ */ e(ba, { client: a, children: /* @__PURE__ */ e(
|
|
7140
|
+
/* @__PURE__ */ e(ya, { children: /* @__PURE__ */ e(ba, { client: a, children: /* @__PURE__ */ e(Ka, { children: /* @__PURE__ */ e(ka, { router: s }) }) }) })
|
|
7124
7141
|
);
|
|
7125
7142
|
}
|
|
7126
7143
|
export {
|
|
7127
7144
|
je as ApiError,
|
|
7128
7145
|
rr as AppShell,
|
|
7129
|
-
|
|
7146
|
+
Ka as AuthProvider,
|
|
7130
7147
|
la as SUPPORTED_LANGUAGES,
|
|
7131
7148
|
L as api,
|
|
7132
7149
|
po as bootstrap,
|
|
7133
7150
|
Gi as buildRoutes,
|
|
7134
7151
|
ro as configureApiBase,
|
|
7135
7152
|
oo as configureBranding,
|
|
7136
|
-
|
|
7153
|
+
Ki as createAppQueryClient,
|
|
7137
7154
|
co as getAllDoctypeConfigs,
|
|
7138
7155
|
Ya as getBranding,
|
|
7139
7156
|
$i as getComponent,
|