@lambda-development/erp-core 0.6.2 → 0.6.3

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 CHANGED
@@ -1,17 +1,17 @@
1
1
  import { jsx as e, jsxs as r, Fragment as we } from "react/jsx-runtime";
2
2
  import { useState as S, useEffect as se, useCallback as Pe, useContext as Kn, createContext as jn, useRef as te, useMemo as Ce, useLayoutEffect as un, StrictMode as ka } from "react";
3
3
  import { createRoot as Sa } from "react-dom/client";
4
- import { useQueryClient as We, useQuery as ie, useMutation as oe, QueryClientProvider as Ca, QueryClient as Aa } from "@tanstack/react-query";
5
- import { NavLink as Ot, useLocation as Ct, useNavigate as Le, Outlet as Da, Navigate as Pa, Link as be, useSearchParams as qt, useParams as bt, createBrowserRouter as _a, RouterProvider as Ta } from "react-router-dom";
4
+ import { useQueryClient as We, useQuery as ie, useMutation as oe, QueryClientProvider as Ca, QueryClient as Da } from "@tanstack/react-query";
5
+ import { NavLink as Ot, useLocation as Ct, useNavigate as Le, Outlet as Aa, Navigate as Pa, Link as be, useSearchParams as qt, useParams as ut, createBrowserRouter as _a, RouterProvider as Ta } from "react-router-dom";
6
6
  import { useTranslation as Z, initReactI18next as Ra } from "react-i18next";
7
7
  import { BookOpen as Ia, ShoppingCart as Gn, CreditCard as Ba, FileText as nn, Package as Wn, BarChart3 as Ea, Database as La, Settings as Oa, MessageCircle as qa, ChevronDown as zt, ChevronRight as Mt, Plus as Hn, Trash2 as Qn, LineChart as za, ArrowLeft as Ma, TrendingUp as Fa, ArrowDownRight as $a, ArrowUpRight as Ua, Wallet as Va, Receipt as mn, Info as Ka } from "lucide-react";
8
8
  import { createColumnHelper as Yn, useReactTable as Jn, getCoreRowModel as Zn, flexRender as It } from "@tanstack/react-table";
9
9
  import { createPortal as Xn } from "react-dom";
10
10
  import { ResponsiveContainer as ja, LineChart as Ga, CartesianGrid as pn, XAxis as hn, YAxis as gn, Tooltip as Vt, Line as Wa, PieChart as Ha, Pie as Qa, Cell as Ya, BarChart as Ja, Bar as Za } from "recharts";
11
11
  import ea from "i18next";
12
- import { default as $o } from "i18next";
12
+ import { default as Vo } from "i18next";
13
13
  let ct = "/api";
14
- function To(t) {
14
+ function Bo(t) {
15
15
  ct = t.replace(/\/+$/, "");
16
16
  }
17
17
  function Xa(t) {
@@ -349,8 +349,8 @@ function tt(t) {
349
349
  return Number.isNaN(a) ? 0 : a;
350
350
  }
351
351
  function rr({ children: t }) {
352
- const n = We(), [a, s] = S([]), [o, i] = S({}), [l, c] = S({}), [g, m] = S({}), [p, u] = S({}), [N, v] = S({}), [x, f] = S({}), [R, P] = S({}), [b, d] = S(null), [h, _] = S("connecting"), [y, B] = S(0), A = te(null), O = te(null), G = te(/* @__PURE__ */ new Map()), ee = te(null), C = te({}), w = te({}), q = te(null);
353
- function D(I) {
352
+ const n = We(), [a, s] = S([]), [o, i] = S({}), [l, c] = S({}), [g, m] = S({}), [p, u] = S({}), [N, v] = S({}), [x, f] = S({}), [R, P] = S({}), [b, d] = S(null), [h, _] = S("connecting"), [y, B] = S(0), D = te(null), O = te(null), G = te(/* @__PURE__ */ new Map()), ee = te(null), C = te({}), w = te({}), q = te(null);
353
+ function A(I) {
354
354
  for (const V of G.current.values())
355
355
  V.reject(new Error(I));
356
356
  G.current.clear();
@@ -398,23 +398,23 @@ function rr({ children: t }) {
398
398
  C.current = V;
399
399
  }
400
400
  function E(I) {
401
- const V = A.current;
401
+ const V = D.current;
402
402
  if (!V || V.readyState !== WebSocket.OPEN)
403
403
  throw new Error("Chat is disconnected.");
404
404
  V.send(JSON.stringify(I));
405
405
  }
406
406
  function ne(I, V, W) {
407
407
  return new Promise((ve, xe) => {
408
- const De = ar();
409
- G.current.set(De, {
408
+ const Ae = ar();
409
+ G.current.set(Ae, {
410
410
  expectedType: W,
411
411
  resolve: ve,
412
412
  reject: xe
413
413
  });
414
414
  try {
415
- E({ type: I, request_id: De, ...V });
415
+ E({ type: I, request_id: Ae, ...V });
416
416
  } catch (ot) {
417
- G.current.delete(De), xe(ot instanceof Error ? ot : new Error("Chat request failed."));
417
+ G.current.delete(Ae), xe(ot instanceof Error ? ot : new Error("Chat request failed."));
418
418
  }
419
419
  });
420
420
  }
@@ -424,16 +424,16 @@ function rr({ children: t }) {
424
424
  if (I) return;
425
425
  _("connecting");
426
426
  const ve = `${window.location.protocol === "https:" ? "wss:" : "ws:"}//${window.location.host}/ws/chat`, xe = new WebSocket(ve);
427
- A.current = xe, xe.onopen = () => {
427
+ D.current = xe, xe.onopen = () => {
428
428
  if (I) {
429
429
  xe.close();
430
430
  return;
431
431
  }
432
- _("connected"), B((De) => De + 1);
433
- }, xe.onmessage = (De) => {
432
+ _("connected"), B((Ae) => Ae + 1);
433
+ }, xe.onmessage = (Ae) => {
434
434
  var ot;
435
435
  try {
436
- const K = JSON.parse(De.data), Ze = typeof K.request_id == "string" ? K.request_id : null, me = typeof K.type == "string" ? K.type : null, M = typeof K.session_id == "string" ? K.session_id : null;
436
+ const K = JSON.parse(Ae.data), Ze = typeof K.request_id == "string" ? K.request_id : null, me = typeof K.type == "string" ? K.type : null, M = typeof K.session_id == "string" ? K.session_id : null;
437
437
  if (Ze) {
438
438
  const F = G.current.get(Ze);
439
439
  F && (me === "error" ? (G.current.delete(Ze), F.reject(new Error(String(K.content || "Request failed.")))) : me === F.expectedType && (G.current.delete(Ze), F.resolve(K)));
@@ -458,7 +458,7 @@ function rr({ children: t }) {
458
458
  ).then((Ne) => {
459
459
  const le = Ne.filter((ue) => !!ue);
460
460
  le.length && (Ue(le), pe((ue) => [
461
- ...le.filter((gt) => !ue.some((xt) => xt.id === gt.id)),
461
+ ...le.filter((ft) => !ue.some((xt) => xt.id === ft.id)),
462
462
  ...ue
463
463
  ]));
464
464
  });
@@ -501,10 +501,10 @@ function rr({ children: t }) {
501
501
  const F = Array.isArray(K.messages) ? K.messages.map(bn) : [], j = K.before_id != null, Q = !!K.has_more, ze = typeof K.oldest_id == "number" ? K.oldest_id : null;
502
502
  i((le) => {
503
503
  if (j) {
504
- const ue = le[M] ?? [], gt = new Set(
504
+ const ue = le[M] ?? [], ft = new Set(
505
505
  ue.map((Xe) => Xe.id).filter((Xe) => typeof Xe == "number")
506
506
  ), xt = F.filter(
507
- (Xe) => Xe.id === void 0 || !gt.has(Xe.id)
507
+ (Xe) => Xe.id === void 0 || !ft.has(Xe.id)
508
508
  );
509
509
  return { ...le, [M]: [...xt, ...ue] };
510
510
  }
@@ -651,9 +651,9 @@ function rr({ children: t }) {
651
651
  }
652
652
  }, xe.onerror = () => {
653
653
  xe.close();
654
- }, xe.onclose = (De) => {
655
- if (A.current === xe && (A.current = null), D("Chat disconnected."), _("disconnected"), !I) {
656
- if (De.code === 4001 || De.code === 4003) {
654
+ }, xe.onclose = (Ae) => {
655
+ if (D.current === xe && (D.current = null), A("Chat disconnected."), _("disconnected"), !I) {
656
+ if (Ae.code === 4001 || Ae.code === 4003) {
657
657
  window.location.href = "/login";
658
658
  return;
659
659
  }
@@ -662,9 +662,9 @@ function rr({ children: t }) {
662
662
  };
663
663
  }
664
664
  return V(), () => {
665
- if (I = !0, O.current !== null && window.clearTimeout(O.current), q.current !== null && window.clearTimeout(q.current), D("Chat disconnected."), A.current) {
666
- const W = A.current;
667
- A.current = null, W.close();
665
+ if (I = !0, O.current !== null && window.clearTimeout(O.current), q.current !== null && window.clearTimeout(q.current), A("Chat disconnected."), D.current) {
666
+ const W = D.current;
667
+ D.current = null, W.close();
668
668
  }
669
669
  };
670
670
  }, []);
@@ -676,7 +676,7 @@ function rr({ children: t }) {
676
676
  });
677
677
  return ee.current = I, I;
678
678
  }
679
- async function Ae(I) {
679
+ async function De(I) {
680
680
  re(I, "running"), ce(I, null);
681
681
  try {
682
682
  await ne("start_demo", { session_id: I }, "demo_started");
@@ -696,7 +696,7 @@ function rr({ children: t }) {
696
696
  async function vt(I) {
697
697
  await ne("load_history", { session_id: I }, "history_loaded");
698
698
  }
699
- async function mt(I) {
699
+ async function pt(I) {
700
700
  if (p[I]) return;
701
701
  const V = g[I];
702
702
  if (V != null && l[I]) {
@@ -720,12 +720,12 @@ function rr({ children: t }) {
720
720
  if (!ve && !xe) return !1;
721
721
  try {
722
722
  Y(I, !0);
723
- const De = {
723
+ const Ae = {
724
724
  type: "send_message",
725
725
  session_id: I,
726
726
  content: ve
727
727
  };
728
- return xe && (De.attachment_ids = W), E(De), !0;
728
+ return xe && (Ae.attachment_ids = W), E(Ae), !0;
729
729
  } catch {
730
730
  return Y(I, !1), !1;
731
731
  }
@@ -749,13 +749,13 @@ function rr({ children: t }) {
749
749
  function Ie(I) {
750
750
  return I ? !!l[I] : !1;
751
751
  }
752
- function pt(I) {
752
+ function ht(I) {
753
753
  return I ? !!p[I] : !1;
754
754
  }
755
755
  function it(I) {
756
756
  return I ? x[I] ?? "idle" : "idle";
757
757
  }
758
- function ht(I) {
758
+ function gt(I) {
759
759
  return I ? R[I] ?? null : null;
760
760
  }
761
761
  return /* @__PURE__ */ e(
@@ -767,26 +767,26 @@ function rr({ children: t }) {
767
767
  connectionVersion: y,
768
768
  navigationFlash: b,
769
769
  createSession: Re,
770
- startDemo: Ae,
770
+ startDemo: De,
771
771
  completeDemoTyping: Ve,
772
772
  deleteSession: Me,
773
773
  loadHistory: vt,
774
- loadMoreHistory: mt,
774
+ loadMoreHistory: pt,
775
775
  clearHistory: Je,
776
776
  sendMessage: ke,
777
777
  transcribeAudio: Te,
778
778
  getMessages: Ke,
779
779
  hasMoreHistory: Ie,
780
- isLoadingOlder: pt,
780
+ isLoadingOlder: ht,
781
781
  isThinking: Qe,
782
782
  getDemoStatus: it,
783
- getDemoTypingCue: ht
783
+ getDemoTypingCue: gt
784
784
  },
785
785
  children: t
786
786
  }
787
787
  );
788
788
  }
789
- function ut() {
789
+ function mt() {
790
790
  const t = Kn(na);
791
791
  if (!t)
792
792
  throw new Error("useChat must be used within ChatProvider.");
@@ -880,7 +880,7 @@ const dt = [
880
880
  function sr() {
881
881
  return dt;
882
882
  }
883
- function Ro(t, n) {
883
+ function Eo(t, n) {
884
884
  const a = dt.findIndex((s) => s.label === t.label);
885
885
  if (a >= 0) {
886
886
  dt[a] = t;
@@ -888,12 +888,12 @@ function Ro(t, n) {
888
888
  }
889
889
  (n == null ? void 0 : n.index) != null ? dt.splice(n.index, 0, t) : dt.push(t);
890
890
  }
891
- function Io(t, n) {
891
+ function Lo(t, n) {
892
892
  const a = dt.find((s) => s.label === t);
893
893
  a ? a.items.push(n) : dt.push({ label: t, icon: null, items: [n] });
894
894
  }
895
895
  let Jt = { appName: "Lambda ERP" };
896
- function Bo(t) {
896
+ function Oo(t) {
897
897
  if (Jt = { ...Jt, ...t }, !(typeof document > "u") && (t.appName && (document.title = t.appName), t.tokens)) {
898
898
  const n = document.documentElement;
899
899
  for (const [a, s] of Object.entries(t.tokens))
@@ -969,7 +969,7 @@ const sn = {
969
969
  "Custom Analytics": "bg-indigo-300 text-indigo-950 ring-2 ring-inset ring-indigo-100"
970
970
  };
971
971
  function or() {
972
- const [t, n] = rn("chats"), a = Ct(), s = Le(), { t: o } = Z(), { sessions: i, createSession: l, deleteSession: c } = ut(), g = async () => {
972
+ const [t, n] = rn("chats"), a = Ct(), s = Le(), { t: o } = Z(), { sessions: i, createSession: l, deleteSession: c } = mt(), g = async () => {
973
973
  try {
974
974
  const p = await l();
975
975
  s(`/chat/${p.id}`);
@@ -1047,7 +1047,7 @@ function on() {
1047
1047
  );
1048
1048
  }
1049
1049
  function lr() {
1050
- const [t, n, a] = rn("custom-analytics"), s = Ct(), o = Le(), i = We(), { t: l } = Z(), { navigationFlash: c, sessions: g, createSession: m } = ut(), p = (c == null ? void 0 : c.group) === "Custom Analytics", u = sn["Custom Analytics"], { data: N } = ie({
1050
+ const [t, n, a] = rn("custom-analytics"), s = Ct(), o = Le(), i = We(), { t: l } = Z(), { navigationFlash: c, sessions: g, createSession: m } = mt(), p = (c == null ? void 0 : c.group) === "Custom Analytics", u = sn["Custom Analytics"], { data: N } = ie({
1051
1051
  queryKey: ["runtime-drafts"],
1052
1052
  queryFn: () => T.listRuntimeDrafts(),
1053
1053
  staleTime: 3e4
@@ -1137,7 +1137,7 @@ function lr() {
1137
1137
  ] });
1138
1138
  }
1139
1139
  function cr({ group: t }) {
1140
- const [n, a] = rn(t.label), { t: s } = Z(), { navigationFlash: o } = ut(), i = (o == null ? void 0 : o.group) === t.label, l = sn[t.label] ?? "bg-blue-300 text-blue-950 ring-2 ring-inset ring-blue-100";
1140
+ const [n, a] = rn(t.label), { t: s } = Z(), { navigationFlash: o } = mt(), i = (o == null ? void 0 : o.group) === t.label, l = sn[t.label] ?? "bg-blue-300 text-blue-950 ring-2 ring-inset ring-blue-100";
1141
1141
  return /* @__PURE__ */ r("div", { children: [
1142
1142
  /* @__PURE__ */ r(
1143
1143
  "button",
@@ -1279,7 +1279,7 @@ function hr() {
1279
1279
  return /* @__PURE__ */ e(rr, { children: /* @__PURE__ */ e(gr, {}) });
1280
1280
  }
1281
1281
  function gr() {
1282
- const { pathname: t } = Ct(), n = Le(), { user: a, logout: s } = st(), { navigationFlash: o } = ut(), { t: i } = Z(), l = mr(t, i), c = pr(t), g = () => {
1282
+ const { pathname: t } = Ct(), n = Le(), { user: a, logout: s } = st(), { navigationFlash: o } = mt(), { t: i } = Z(), l = mr(t, i), c = pr(t), g = () => {
1283
1283
  var N;
1284
1284
  c && (((N = window.history.state) == null ? void 0 : N.idx) > 0 ? n(-1) : n(c));
1285
1285
  }, [m, p] = S(!1);
@@ -1338,7 +1338,7 @@ function gr() {
1338
1338
  )
1339
1339
  ] })
1340
1340
  ] }),
1341
- /* @__PURE__ */ e("main", { className: "flex-1 overflow-auto p-4 md:p-6", children: /* @__PURE__ */ e(Da, {}) })
1341
+ /* @__PURE__ */ e("main", { className: "flex-1 overflow-auto p-4 md:p-6", children: /* @__PURE__ */ e(Aa, {}) })
1342
1342
  ] })
1343
1343
  ] });
1344
1344
  }
@@ -1423,7 +1423,7 @@ function qe(t) {
1423
1423
  }
1424
1424
  return ((s = a[0]) == null ? void 0 : s.default_currency) || "USD";
1425
1425
  }
1426
- function Dt({ title: t, value: n, icon: a, tone: s }) {
1426
+ function At({ title: t, value: n, icon: a, tone: s }) {
1427
1427
  const o = s ?? "text-brand bg-brand/10", i = qe();
1428
1428
  return /* @__PURE__ */ e($, { children: /* @__PURE__ */ r("div", { className: "flex items-start justify-between gap-4", children: [
1429
1429
  /* @__PURE__ */ r("div", { className: "min-w-0", children: [
@@ -1492,7 +1492,7 @@ function Nr() {
1492
1492
  /* @__PURE__ */ e(Pt, {})
1493
1493
  ] }) : /* @__PURE__ */ r(we, { children: [
1494
1494
  /* @__PURE__ */ e(
1495
- Dt,
1495
+ At,
1496
1496
  {
1497
1497
  title: t("dashboard.totalRevenue"),
1498
1498
  value: n == null ? void 0 : n.total_revenue,
@@ -1501,7 +1501,7 @@ function Nr() {
1501
1501
  }
1502
1502
  ),
1503
1503
  /* @__PURE__ */ e(
1504
- Dt,
1504
+ At,
1505
1505
  {
1506
1506
  title: t("dashboard.outstandingReceivable"),
1507
1507
  value: n == null ? void 0 : n.outstanding_receivable,
@@ -1510,7 +1510,7 @@ function Nr() {
1510
1510
  }
1511
1511
  ),
1512
1512
  /* @__PURE__ */ e(
1513
- Dt,
1513
+ At,
1514
1514
  {
1515
1515
  title: t("dashboard.outstandingPayable"),
1516
1516
  value: n == null ? void 0 : n.outstanding_payable,
@@ -1519,7 +1519,7 @@ function Nr() {
1519
1519
  }
1520
1520
  ),
1521
1521
  /* @__PURE__ */ e(
1522
- Dt,
1522
+ At,
1523
1523
  {
1524
1524
  title: t("dashboard.totalStockValue"),
1525
1525
  value: n == null ? void 0 : n.total_stock_value,
@@ -2233,10 +2233,10 @@ const rt = [
2233
2233
  function oa(t) {
2234
2234
  return cn[t];
2235
2235
  }
2236
- function Eo(t) {
2236
+ function qo(t) {
2237
2237
  cn[t.slug] = t;
2238
2238
  }
2239
- function Lo() {
2239
+ function zo() {
2240
2240
  return Object.values(cn);
2241
2241
  }
2242
2242
  const Sr = {
@@ -2329,7 +2329,7 @@ function J({ label: t, hint: n, error: a, className: s, id: o, ...i }) {
2329
2329
  )
2330
2330
  ] });
2331
2331
  }
2332
- function Ar(t) {
2332
+ function Dr(t) {
2333
2333
  return typeof t == "string" ? { value: t, label: t } : t;
2334
2334
  }
2335
2335
  function He({ label: t, options: n, value: a, onChange: s, className: o, required: i, disabled: l }) {
@@ -2363,7 +2363,7 @@ function He({ label: t, options: n, value: a, onChange: s, className: o, require
2363
2363
  children: [
2364
2364
  /* @__PURE__ */ e("option", { value: "", children: "Select..." }),
2365
2365
  n.map((g) => {
2366
- const { value: m, label: p } = Ar(g);
2366
+ const { value: m, label: p } = Dr(g);
2367
2367
  return /* @__PURE__ */ e("option", { value: m, children: p }, m);
2368
2368
  })
2369
2369
  ]
@@ -2371,7 +2371,7 @@ function He({ label: t, options: n, value: a, onChange: s, className: o, require
2371
2371
  )
2372
2372
  ] });
2373
2373
  }
2374
- function Dr({ text: t }) {
2374
+ function Ar({ text: t }) {
2375
2375
  const [n, a] = S(!1);
2376
2376
  return /* @__PURE__ */ r("span", { className: "relative ml-1 inline-flex", children: [
2377
2377
  /* @__PURE__ */ e(
@@ -2455,7 +2455,7 @@ function Xt(t, n) {
2455
2455
  function wn({ label: t, hint: n, extra: a }) {
2456
2456
  return /* @__PURE__ */ r("label", { className: "mb-1.5 block text-sm font-medium text-fg", children: [
2457
2457
  t,
2458
- n && /* @__PURE__ */ e(Dr, { text: n }),
2458
+ n && /* @__PURE__ */ e(Ar, { text: n }),
2459
2459
  a
2460
2460
  ] });
2461
2461
  }
@@ -2773,7 +2773,7 @@ function kn(t, n) {
2773
2773
  }
2774
2774
  function Sn() {
2775
2775
  var Ue;
2776
- const { doctype: t, name: n } = bt(), a = Le(), s = We(), { t: o } = Z(), i = oa(t ?? ""), l = !n, [c, g] = S({}), [m, p] = S(!1), { data: u, isLoading: N } = ie({
2776
+ const { doctype: t, name: n } = ut(), a = Le(), s = We(), { t: o } = Z(), i = oa(t ?? ""), l = !n, [c, g] = S({}), [m, p] = S(!1), { data: u, isLoading: N } = ie({
2777
2777
  queryKey: ["document", t, n],
2778
2778
  queryFn: () => T.getDocument(t, n),
2779
2779
  enabled: !!t && !!n && !l
@@ -2844,19 +2844,19 @@ function Sn() {
2844
2844
  const Re = ne.toLowerCase().replace(/\s+/g, "-");
2845
2845
  a(`/app/${Re}/${E.name}`);
2846
2846
  }
2847
- }), A = Pe(
2847
+ }), D = Pe(
2848
2848
  (E, ne) => {
2849
2849
  E === "currency" && p(!0), g((Re) => {
2850
- const Ae = { ...Re, [E]: ne };
2851
- return E === "currency" && (Ae.conversion_rate = 0), kn(Ae, i);
2850
+ const De = { ...Re, [E]: ne };
2851
+ return E === "currency" && (De.conversion_rate = 0), kn(De, i);
2852
2852
  });
2853
2853
  },
2854
2854
  [i]
2855
2855
  ), O = Pe(
2856
2856
  (E, ne) => {
2857
2857
  g((Re) => {
2858
- const Ae = { ...Re, [E]: ne };
2859
- return kn(Ae, i);
2858
+ const De = { ...Re, [E]: ne };
2859
+ return kn(De, i);
2860
2860
  });
2861
2861
  },
2862
2862
  [i]
@@ -2878,7 +2878,7 @@ function Sn() {
2878
2878
  ] });
2879
2879
  if (!l && N)
2880
2880
  return /* @__PURE__ */ e("p", { className: "text-fg-muted", children: o("common.loading") });
2881
- const D = c.docstatus ?? 0, z = !!c.discarded, Y = D >= 1 || z, re = c.currency || R, ce = Fe(c.conversion_rate ?? 1), ge = i.fields.filter((E) => !E.readOnly), _e = ge.filter((E) => E.type !== "textarea"), pe = ge.filter((E) => E.type === "textarea"), fe = i.fields.filter((E) => E.readOnly);
2881
+ const A = c.docstatus ?? 0, z = !!c.discarded, Y = A >= 1 || z, re = c.currency || R, ce = Fe(c.conversion_rate ?? 1), ge = i.fields.filter((E) => !E.readOnly), _e = ge.filter((E) => E.type !== "textarea"), pe = ge.filter((E) => E.type === "textarea"), fe = i.fields.filter((E) => E.readOnly);
2882
2882
  return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
2883
2883
  /* @__PURE__ */ r("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
2884
2884
  /* @__PURE__ */ r("div", { className: "flex items-center gap-3", children: [
@@ -2904,7 +2904,7 @@ function Sn() {
2904
2904
  isNew: l,
2905
2905
  doctype: t,
2906
2906
  name: n,
2907
- docstatus: D,
2907
+ docstatus: A,
2908
2908
  saving: b.isPending || d.isPending,
2909
2909
  config: i,
2910
2910
  discarded: z,
@@ -2923,7 +2923,7 @@ function Sn() {
2923
2923
  {
2924
2924
  field: E,
2925
2925
  value: c[E.name],
2926
- onChange: (ne) => A(E.name, ne),
2926
+ onChange: (ne) => D(E.name, ne),
2927
2927
  readOnly: Y,
2928
2928
  rowData: c,
2929
2929
  currency: re
@@ -2935,7 +2935,7 @@ function Sn() {
2935
2935
  {
2936
2936
  field: E,
2937
2937
  value: c[E.name],
2938
- onChange: (ne) => A(E.name, ne),
2938
+ onChange: (ne) => D(E.name, ne),
2939
2939
  readOnly: Y,
2940
2940
  rowData: c,
2941
2941
  currency: re
@@ -2993,7 +2993,7 @@ function tn(t) {
2993
2993
  const n = en(t);
2994
2994
  return new Date(n.getFullYear(), n.getMonth() + 3, 0);
2995
2995
  }
2996
- function An(t) {
2996
+ function Dn(t) {
2997
2997
  return new Date(t.getFullYear(), 0, 1);
2998
2998
  }
2999
2999
  function Et(t) {
@@ -3021,7 +3021,7 @@ const Lr = [
3021
3021
  },
3022
3022
  {
3023
3023
  label: "This Year",
3024
- range: () => [ye(An(/* @__PURE__ */ new Date())), ye(Et(/* @__PURE__ */ new Date()))]
3024
+ range: () => [ye(Dn(/* @__PURE__ */ new Date())), ye(Et(/* @__PURE__ */ new Date()))]
3025
3025
  },
3026
3026
  {
3027
3027
  label: "Last Month",
@@ -3041,7 +3041,7 @@ const Lr = [
3041
3041
  label: "Last Year",
3042
3042
  range: () => {
3043
3043
  const t = new Date((/* @__PURE__ */ new Date()).getFullYear() - 1, 6, 1);
3044
- return [ye(An(t)), ye(Et(t))];
3044
+ return [ye(Dn(t)), ye(Et(t))];
3045
3045
  }
3046
3046
  }
3047
3047
  ];
@@ -3096,7 +3096,7 @@ const Or = ["All", "Draft", "Submitted", "Cancelled"], qr = /* @__PURE__ */ new
3096
3096
  "delivery_date",
3097
3097
  "valid_till",
3098
3098
  "date"
3099
- ]), Dn = {
3099
+ ]), An = {
3100
3100
  customer: "customer",
3101
3101
  supplier: "supplier",
3102
3102
  item_code: "item",
@@ -3113,48 +3113,48 @@ function Mr(t) {
3113
3113
  }
3114
3114
  const Fr = ["25", "50", "100", "200"];
3115
3115
  function $r() {
3116
- const { t } = Z(), n = qe(), { doctype: a } = bt(), s = oa(a ?? ""), [o] = ae("status", "All"), [i] = ae("from", ""), [l] = ae("to", ""), [c] = ae("discarded", ""), [g] = ae("per_page", 50), [m] = ae("page", 1), p = m - 1, u = Ye(), N = (C) => u({ page: C === 0 ? null : C + 1 }), v = (C) => u({ status: C === "All" ? null : C, page: null }), x = (C) => u({ from: C || null, page: null }), f = (C) => u({ to: C || null, page: null }), R = (C) => u({ discarded: C ? "1" : null, page: null }), P = (C) => u({ per_page: C, page: null }), b = Ce(() => {
3116
+ const { t } = Z(), n = qe(), { doctype: a } = ut(), s = oa(a ?? ""), [o] = ae("status", "All"), [i] = ae("from", ""), [l] = ae("to", ""), [c] = ae("discarded", ""), [g] = ae("per_page", 50), [m] = ae("page", 1), p = m - 1, u = Ye(), N = (C) => u({ page: C === 0 ? null : C + 1 }), v = (C) => u({ status: C === "All" ? null : C, page: null }), x = (C) => u({ from: C || null, page: null }), f = (C) => u({ to: C || null, page: null }), R = (C) => u({ discarded: C ? "1" : null, page: null }), P = (C) => u({ per_page: C, page: null }), b = Ce(() => {
3117
3117
  const C = {};
3118
3118
  return o !== "All" && (C.status = o), i && (C.from_date = i), l && (C.to_date = l), c && (C.include_discarded = "true"), C.limit = g, C.offset = p * g, C;
3119
- }, [o, i, l, c, g, p]), { data: d, isLoading: h } = wr(a ?? "", b), _ = (d == null ? void 0 : d.rows) ?? [], y = (d == null ? void 0 : d.total) ?? 0, B = Math.max(1, Math.ceil(y / g)), A = y === 0 ? 0 : p * g + 1, O = Math.min(y, (p + 1) * g), G = Ce(() => {
3119
+ }, [o, i, l, c, g, p]), { data: d, isLoading: h } = wr(a ?? "", b), _ = (d == null ? void 0 : d.rows) ?? [], y = (d == null ? void 0 : d.total) ?? 0, B = Math.max(1, Math.ceil(y / g)), D = y === 0 ? 0 : p * g + 1, O = Math.min(y, (p + 1) * g), G = Ce(() => {
3120
3120
  if (!s) return [];
3121
3121
  const C = Yn(), w = (q) => {
3122
- const D = q.split("_").map((z) => z.charAt(0).toUpperCase() + z.slice(1)).join(" ");
3123
- return t(`fields.${D}`, { defaultValue: D });
3122
+ const A = q.split("_").map((z) => z.charAt(0).toUpperCase() + z.slice(1)).join(" ");
3123
+ return t(`fields.${A}`, { defaultValue: A });
3124
3124
  };
3125
3125
  return s.listColumns.map((q) => {
3126
3126
  if (q === "name")
3127
3127
  return C.accessor("name", {
3128
3128
  header: t("fields.Name", { defaultValue: "Name" }),
3129
- cell: (D) => /* @__PURE__ */ e(
3129
+ cell: (A) => /* @__PURE__ */ e(
3130
3130
  be,
3131
3131
  {
3132
- to: `/app/${s.slug}/${D.getValue()}`,
3132
+ to: `/app/${s.slug}/${A.getValue()}`,
3133
3133
  className: "font-medium text-brand transition-colors hover:text-brand/80",
3134
- children: D.getValue()
3134
+ children: A.getValue()
3135
3135
  }
3136
3136
  )
3137
3137
  });
3138
3138
  if (q === "status")
3139
3139
  return C.accessor("status", {
3140
3140
  header: t("fields.Status", { defaultValue: "Status" }),
3141
- cell: (D) => /* @__PURE__ */ e(ln, { status: D.getValue() })
3141
+ cell: (A) => /* @__PURE__ */ e(ln, { status: A.getValue() })
3142
3142
  });
3143
3143
  if (qr.has(q))
3144
3144
  return C.accessor(q, {
3145
3145
  header: w(q),
3146
- cell: (D) => {
3146
+ cell: (A) => {
3147
3147
  var z;
3148
- return Oe(D.getValue(), ((z = D.row.original) == null ? void 0 : z.currency) || n);
3148
+ return Oe(A.getValue(), ((z = A.row.original) == null ? void 0 : z.currency) || n);
3149
3149
  }
3150
3150
  });
3151
3151
  if (q === "party")
3152
3152
  return C.accessor("party", {
3153
3153
  header: t("fields.Party", { defaultValue: "Party" }),
3154
- cell: (D) => {
3155
- const z = D.getValue();
3154
+ cell: (A) => {
3155
+ const z = A.getValue();
3156
3156
  if (!z) return "-";
3157
- const Y = Mr(D.row.original.party_type), re = Y ? Xt(Y, String(z)) : null;
3157
+ const Y = Mr(A.row.original.party_type), re = Y ? Xt(Y, String(z)) : null;
3158
3158
  return re ? /* @__PURE__ */ e(
3159
3159
  be,
3160
3160
  {
@@ -3166,14 +3166,14 @@ function $r() {
3166
3166
  ) : String(z);
3167
3167
  }
3168
3168
  });
3169
- if (Dn[q]) {
3170
- const D = Dn[q];
3169
+ if (An[q]) {
3170
+ const A = An[q];
3171
3171
  return C.accessor(q, {
3172
3172
  header: w(q),
3173
3173
  cell: (z) => {
3174
3174
  const Y = z.getValue();
3175
3175
  if (!Y) return "-";
3176
- const re = Xt(D, String(Y));
3176
+ const re = Xt(A, String(Y));
3177
3177
  return re ? /* @__PURE__ */ e(
3178
3178
  be,
3179
3179
  {
@@ -3188,7 +3188,7 @@ function $r() {
3188
3188
  }
3189
3189
  return zr.has(q) ? C.accessor(q, {
3190
3190
  header: w(q),
3191
- cell: (D) => Ft(D.getValue())
3191
+ cell: (A) => Ft(A.getValue())
3192
3192
  }) : C.accessor(q, {
3193
3193
  header: w(q)
3194
3194
  });
@@ -3268,7 +3268,7 @@ function $r() {
3268
3268
  t("common.showing"),
3269
3269
  " ",
3270
3270
  /* @__PURE__ */ r("span", { className: "font-medium text-fg", children: [
3271
- A,
3271
+ D,
3272
3272
  "–",
3273
3273
  O
3274
3274
  ] }),
@@ -3368,7 +3368,7 @@ function Se({
3368
3368
  }, B = (O) => {
3369
3369
  const G = O.name ?? O.id ?? String(O);
3370
3370
  l(G), a(G), p(!1), g([]);
3371
- }, A = () => {
3371
+ }, D = () => {
3372
3372
  setTimeout(() => {
3373
3373
  if (d.current) {
3374
3374
  d.current = !1;
@@ -3399,7 +3399,7 @@ function Se({
3399
3399
  onFocus: () => {
3400
3400
  h(), _(i);
3401
3401
  },
3402
- onBlur: A,
3402
+ onBlur: D,
3403
3403
  placeholder: `Search ${s}...`,
3404
3404
  className: Ee(
3405
3405
  "block h-9 w-full rounded-lg bg-surface px-3 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30",
@@ -3435,7 +3435,7 @@ const _t = () => ({
3435
3435
  is_recommended: 0
3436
3436
  }), Ur = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
3437
3437
  function Pn() {
3438
- const { name: t } = bt(), n = !t, a = Le(), s = We(), { t: o } = Z(), i = (w, q) => o(w, { defaultValue: q }), [l, c] = S({
3438
+ const { name: t } = ut(), n = !t, a = Le(), s = We(), { t: o } = Z(), i = (w, q) => o(w, { defaultValue: q }), [l, c] = S({
3439
3439
  title: "Offerte",
3440
3440
  customer: "",
3441
3441
  company: "",
@@ -3443,7 +3443,7 @@ function Pn() {
3443
3443
  partner_name: "",
3444
3444
  partner_email: "",
3445
3445
  cover_letter: ""
3446
- }), [g, m] = S([_t()]), [p, u] = S(null), [N, v] = S(!1), [x, f] = S(null), R = te(null), P = (w, q) => c((D) => ({ ...D, [w]: q })), { data: b } = ie({
3446
+ }), [g, m] = S([_t()]), [p, u] = S(null), [N, v] = S(!1), [x, f] = S(null), R = te(null), P = (w, q) => c((A) => ({ ...A, [w]: q })), { data: b } = ie({
3447
3447
  queryKey: ["document", "proposal", t],
3448
3448
  queryFn: () => T.getDocument("proposal", t),
3449
3449
  enabled: !n
@@ -3487,14 +3487,14 @@ function Pn() {
3487
3487
  s.invalidateQueries({ queryKey: ["documents", "proposal"] }), a("/app/proposal");
3488
3488
  },
3489
3489
  onError: (w) => f((w == null ? void 0 : w.message) ?? "Discard failed")
3490
- }), B = (w, q) => m((D) => D.map((z, Y) => Y === w ? { ...z, ...q } : z)), A = () => m((w) => [...w, _t()]), O = (w) => m((q) => q.length > 1 ? q.filter((D, z) => z !== w) : q), G = (w, q) => m((D) => {
3490
+ }), B = (w, q) => m((A) => A.map((z, Y) => Y === w ? { ...z, ...q } : z)), D = () => m((w) => [...w, _t()]), O = (w) => m((q) => q.length > 1 ? q.filter((A, z) => z !== w) : q), G = (w, q) => m((A) => {
3491
3491
  const z = w + q;
3492
- if (z < 0 || z >= D.length) return D;
3493
- const Y = [...D];
3492
+ if (z < 0 || z >= A.length) return A;
3493
+ const Y = [...A];
3494
3494
  return [Y[w], Y[z]] = [Y[z], Y[w]], Y;
3495
3495
  }), ee = async (w) => {
3496
- var D;
3497
- const q = (D = w.target.files) == null ? void 0 : D[0];
3496
+ var A;
3497
+ const q = (A = w.target.files) == null ? void 0 : A[0];
3498
3498
  if (w.target.value = "", !(!q || n)) {
3499
3499
  v(!0), f(null);
3500
3500
  try {
@@ -3569,23 +3569,23 @@ function Pn() {
3569
3569
  /* @__PURE__ */ r($, { className: "space-y-4 p-5", children: [
3570
3570
  /* @__PURE__ */ r("div", { className: "flex items-center justify-between", children: [
3571
3571
  /* @__PURE__ */ e("h2", { className: "font-semibold text-fg", children: i("proposal.offers", "Offers") }),
3572
- /* @__PURE__ */ e(H, { size: "sm", variant: "secondary", onClick: A, children: i("proposal.addOffer", "Add offer") })
3572
+ /* @__PURE__ */ e(H, { size: "sm", variant: "secondary", onClick: D, children: i("proposal.addOffer", "Add offer") })
3573
3573
  ] }),
3574
3574
  g.map((w, q) => /* @__PURE__ */ r("div", { className: "rounded-lg p-3 ring-1 ring-line", children: [
3575
3575
  /* @__PURE__ */ r("div", { className: "mb-2 flex items-center gap-2", children: [
3576
3576
  /* @__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: Ur[q] ?? q + 1 }),
3577
- /* @__PURE__ */ e("div", { className: "flex-1", children: /* @__PURE__ */ e(Se, { label: "", value: w.quotation, onChange: (D) => B(q, { quotation: D }), linkDoctype: "quotation", readOnly: !1 }) }),
3577
+ /* @__PURE__ */ e("div", { className: "flex-1", children: /* @__PURE__ */ e(Se, { label: "", value: w.quotation, onChange: (A) => B(q, { quotation: A }), linkDoctype: "quotation", readOnly: !1 }) }),
3578
3578
  /* @__PURE__ */ e("button", { type: "button", onClick: () => G(q, -1), disabled: q === 0, className: "px-1 text-fg-muted disabled:opacity-30", children: "↑" }),
3579
3579
  /* @__PURE__ */ e("button", { type: "button", onClick: () => G(q, 1), disabled: q === g.length - 1, className: "px-1 text-fg-muted disabled:opacity-30", children: "↓" }),
3580
3580
  /* @__PURE__ */ e("button", { type: "button", onClick: () => O(q), className: "px-1 text-red-500 hover:text-red-700", children: "✕" })
3581
3581
  ] }),
3582
3582
  /* @__PURE__ */ r("div", { className: "grid grid-cols-1 gap-2 pl-8 sm:grid-cols-2", children: [
3583
- /* @__PURE__ */ e(J, { label: i("proposal.positionTitle", "Position title"), value: w.position_title, onChange: (D) => B(q, { position_title: D.target.value }), placeholder: i("proposal.positionTitleHint", "defaults to the offer's first item") }),
3583
+ /* @__PURE__ */ e(J, { label: i("proposal.positionTitle", "Position title"), value: w.position_title, onChange: (A) => B(q, { position_title: A.target.value }), placeholder: i("proposal.positionTitleHint", "defaults to the offer's first item") }),
3584
3584
  /* @__PURE__ */ r("label", { className: "flex items-center gap-2 self-end pb-2 text-sm text-fg", children: [
3585
- /* @__PURE__ */ e("input", { type: "checkbox", checked: !!w.is_recommended, onChange: (D) => B(q, { is_recommended: D.target.checked ? 1 : 0 }) }),
3585
+ /* @__PURE__ */ e("input", { type: "checkbox", checked: !!w.is_recommended, onChange: (A) => B(q, { is_recommended: A.target.checked ? 1 : 0 }) }),
3586
3586
  i("proposal.recommended", "Mark as recommendation")
3587
3587
  ] }),
3588
- /* @__PURE__ */ e("div", { className: "sm:col-span-2", children: /* @__PURE__ */ e(J, { label: i("proposal.blurb", "Description"), value: w.position_blurb, onChange: (D) => B(q, { position_blurb: D.target.value }), placeholder: i("proposal.blurbHint", "defaults to the offer's notes") }) })
3588
+ /* @__PURE__ */ e("div", { className: "sm:col-span-2", children: /* @__PURE__ */ e(J, { label: i("proposal.blurb", "Description"), value: w.position_blurb, onChange: (A) => B(q, { position_blurb: A.target.value }), placeholder: i("proposal.blurbHint", "defaults to the offer's notes") }) })
3589
3589
  ] })
3590
3590
  ] }, q))
3591
3591
  ] }),
@@ -3611,7 +3611,7 @@ function Pn() {
3611
3611
  const Vr = ["25", "50", "100", "200"];
3612
3612
  function Kr() {
3613
3613
  var d;
3614
- const { type: t } = bt(), n = Le(), s = (d = Ct().state) == null ? void 0 : d.notice, [o] = ae("per_page", 50), [i] = ae("page", 1), l = i - 1, c = Ye(), g = (h) => c({ page: h === 0 ? null : h + 1 }), m = (h) => c({ per_page: h, page: null }), { data: p, isLoading: u } = ie({
3614
+ const { type: t } = ut(), n = Le(), s = (d = Ct().state) == null ? void 0 : d.notice, [o] = ae("per_page", 50), [i] = ae("page", 1), l = i - 1, c = Ye(), g = (h) => c({ page: h === 0 ? null : h + 1 }), m = (h) => c({ per_page: h, page: null }), { data: p, isLoading: u } = ie({
3615
3615
  queryKey: ["masters", t, l, o],
3616
3616
  queryFn: () => T.listMasters(t, {
3617
3617
  include_disabled: 1,
@@ -3626,19 +3626,19 @@ function Kr() {
3626
3626
  (y) => h.accessor(y, {
3627
3627
  header: y.split("_").map((B) => B.charAt(0).toUpperCase() + B.slice(1)).join(" "),
3628
3628
  cell: (B) => {
3629
- const A = B.getValue();
3629
+ const D = B.getValue();
3630
3630
  if (y === "name") {
3631
3631
  const O = B.row.original.disabled === 1;
3632
3632
  return /* @__PURE__ */ e(
3633
3633
  be,
3634
3634
  {
3635
- to: `/masters/${t}/${A}`,
3635
+ to: `/masters/${t}/${D}`,
3636
3636
  className: O ? "font-medium text-fg-muted" : "font-medium text-brand transition-colors hover:text-brand/80",
3637
- children: A
3637
+ children: D
3638
3638
  }
3639
3639
  );
3640
3640
  }
3641
- return y === "disabled" ? A === 1 ? "Disabled" : "Active" : A ?? "-";
3641
+ return y === "disabled" ? D === 1 ? "Disabled" : "Active" : D ?? "-";
3642
3642
  }
3643
3643
  })
3644
3644
  );
@@ -3803,47 +3803,47 @@ const jr = {
3803
3803
  }, _n = /* @__PURE__ */ new Set(["customer", "supplier", "item", "warehouse"]);
3804
3804
  function Tn() {
3805
3805
  var B;
3806
- const { type: t, name: n } = bt(), a = Le(), s = We(), { t: o } = Z(), i = !n || n === "new", l = Gr[t ?? ""] ?? t ?? "", c = o(`masters.${t}.one`, { defaultValue: l }), g = jr[t ?? ""] ?? [], m = (A) => o(`fields.${A.label}`, { defaultValue: A.label }), [p, u] = S({}), { data: N, isLoading: v } = ie({
3806
+ const { type: t, name: n } = ut(), a = Le(), s = We(), { t: o } = Z(), i = !n || n === "new", l = Gr[t ?? ""] ?? t ?? "", c = o(`masters.${t}.one`, { defaultValue: l }), g = jr[t ?? ""] ?? [], m = (D) => o(`fields.${D.label}`, { defaultValue: D.label }), [p, u] = S({}), { data: N, isLoading: v } = ie({
3807
3807
  queryKey: ["master", t, n],
3808
3808
  queryFn: () => T.getMaster(t, n),
3809
3809
  enabled: !!t && !!n && !i
3810
3810
  });
3811
3811
  se(() => {
3812
3812
  if (i) {
3813
- const A = {};
3813
+ const D = {};
3814
3814
  g.forEach((O) => {
3815
- A[O.name] = O.default ?? "";
3816
- }), u(A);
3815
+ D[O.name] = O.default ?? "";
3816
+ }), u(D);
3817
3817
  } else N && u(N);
3818
3818
  }, [i, N, g]);
3819
3819
  const x = qe();
3820
3820
  se(() => {
3821
- !i || !x || g.some((A) => A.name === "default_currency") && u((A) => {
3822
- const O = A.default_currency;
3823
- return O && O !== "USD" || O === x ? A : { ...A, default_currency: x };
3821
+ !i || !x || g.some((D) => D.name === "default_currency") && u((D) => {
3822
+ const O = D.default_currency;
3823
+ return O && O !== "USD" || O === x ? D : { ...D, default_currency: x };
3824
3824
  });
3825
3825
  }, [i, g, x]);
3826
3826
  const f = oe({
3827
- mutationFn: (A) => T.createMaster(t, A),
3828
- onSuccess: (A) => {
3829
- s.invalidateQueries({ queryKey: ["masters", t] }), a(`/masters/${t}/${A.name}`, { replace: !0 });
3827
+ mutationFn: (D) => T.createMaster(t, D),
3828
+ onSuccess: (D) => {
3829
+ s.invalidateQueries({ queryKey: ["masters", t] }), a(`/masters/${t}/${D.name}`, { replace: !0 });
3830
3830
  }
3831
3831
  }), R = oe({
3832
- mutationFn: (A) => T.updateMaster(t, n, A),
3832
+ mutationFn: (D) => T.updateMaster(t, n, D),
3833
3833
  onSuccess: () => {
3834
3834
  s.invalidateQueries({ queryKey: ["master", t, n] }), s.invalidateQueries({ queryKey: ["masters", t] });
3835
3835
  }
3836
3836
  }), P = oe({
3837
3837
  mutationFn: () => T.deleteMaster(t, n),
3838
- onSuccess: (A) => {
3839
- if (s.invalidateQueries({ queryKey: ["masters", t] }), (A == null ? void 0 : A.status) === "disabled") {
3838
+ onSuccess: (D) => {
3839
+ if (s.invalidateQueries({ queryKey: ["masters", t] }), (D == null ? void 0 : D.status) === "disabled") {
3840
3840
  a(`/masters/${t}`, {
3841
3841
  replace: !0,
3842
3842
  state: {
3843
3843
  notice: o("masterForm.disabledOnDelete", {
3844
3844
  label: c,
3845
3845
  name: n,
3846
- reason: A.reason ?? "other records"
3846
+ reason: D.reason ?? "other records"
3847
3847
  })
3848
3848
  }
3849
3849
  });
@@ -3853,18 +3853,18 @@ function Tn() {
3853
3853
  }
3854
3854
  }), b = () => {
3855
3855
  if (y.length > 0) return;
3856
- const A = t === "company" && !p.name ? { ...p, name: p.company_name } : p;
3857
- i ? f.mutate(A) : R.mutate(A);
3856
+ const D = t === "company" && !p.name ? { ...p, name: p.company_name } : p;
3857
+ i ? f.mutate(D) : R.mutate(D);
3858
3858
  }, d = () => {
3859
3859
  window.confirm(o("masterForm.deleteConfirm", { label: c })) && P.mutate();
3860
- }, h = (A, O) => {
3861
- u((G) => ({ ...G, [A]: O }));
3860
+ }, h = (D, O) => {
3861
+ u((G) => ({ ...G, [D]: O }));
3862
3862
  };
3863
3863
  if (!i && v)
3864
3864
  return /* @__PURE__ */ e("p", { className: "text-fg-muted", children: o("common.loading") });
3865
- const _ = f.isPending || R.isPending, y = g.filter((A) => {
3866
- if (!A.required || A.readOnly || i && A.name === "name" && _n.has(t ?? "")) return !1;
3867
- const O = p[A.name];
3865
+ const _ = f.isPending || R.isPending, y = g.filter((D) => {
3866
+ if (!D.required || D.readOnly || i && D.name === "name" && _n.has(t ?? "")) return !1;
3867
+ const O = p[D.name];
3868
3868
  return O == null || String(O).trim() === "";
3869
3869
  });
3870
3870
  return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
@@ -3883,55 +3883,55 @@ function Tn() {
3883
3883
  (f.error || R.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: ((B = f.error ?? R.error ?? P.error) == null ? void 0 : B.message) ?? o("common.errorOccurred") }),
3884
3884
  y.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: y.map(m).join(", ") }) }),
3885
3885
  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: c }) }),
3886
- /* @__PURE__ */ e($, { children: /* @__PURE__ */ e("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: g.map((A) => {
3887
- const G = A.name === "name" && !i || A.readOnly, ee = A.required && !(i && A.name === "name" && _n.has(t ?? ""));
3888
- if (A.type === "select" && A.options) {
3889
- const w = p[A.name], q = typeof w == "string" && w !== "" && !A.options.includes(w) ? [...A.options, w] : A.options;
3886
+ /* @__PURE__ */ e($, { children: /* @__PURE__ */ e("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: g.map((D) => {
3887
+ const G = D.name === "name" && !i || D.readOnly, ee = D.required && !(i && D.name === "name" && _n.has(t ?? ""));
3888
+ if (D.type === "select" && D.options) {
3889
+ const w = p[D.name], q = typeof w == "string" && w !== "" && !D.options.includes(w) ? [...D.options, w] : D.options;
3890
3890
  return /* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
3891
3891
  He,
3892
3892
  {
3893
- label: m(A),
3893
+ label: m(D),
3894
3894
  options: q,
3895
- value: p[A.name] ?? "",
3895
+ value: p[D.name] ?? "",
3896
3896
  required: ee,
3897
3897
  disabled: G,
3898
- onChange: (D) => h(A.name, D.target.value)
3898
+ onChange: (A) => h(D.name, A.target.value)
3899
3899
  }
3900
- ) }, A.name);
3900
+ ) }, D.name);
3901
3901
  }
3902
- if (A.type === "textarea")
3902
+ if (D.type === "textarea")
3903
3903
  return /* @__PURE__ */ r("div", { className: "sm:col-span-2", children: [
3904
- /* @__PURE__ */ e("label", { className: "mb-1.5 block text-sm font-medium text-fg", children: m(A) }),
3904
+ /* @__PURE__ */ e("label", { className: "mb-1.5 block text-sm font-medium text-fg", children: m(D) }),
3905
3905
  /* @__PURE__ */ e(
3906
3906
  "textarea",
3907
3907
  {
3908
3908
  className: "block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30 disabled:bg-surface-subtle disabled:text-fg-muted",
3909
3909
  rows: 3,
3910
- value: p[A.name] ?? "",
3910
+ value: p[D.name] ?? "",
3911
3911
  required: ee,
3912
3912
  readOnly: G,
3913
3913
  disabled: G,
3914
- onChange: (w) => h(A.name, w.target.value)
3914
+ onChange: (w) => h(D.name, w.target.value)
3915
3915
  }
3916
3916
  )
3917
- ] }, A.name);
3918
- const C = A.type === "number" || A.type === "currency" ? "number" : A.type === "date" ? "date" : "text";
3917
+ ] }, D.name);
3918
+ const C = D.type === "number" || D.type === "currency" ? "number" : D.type === "date" ? "date" : "text";
3919
3919
  return /* @__PURE__ */ e(
3920
3920
  J,
3921
3921
  {
3922
- label: m(A),
3922
+ label: m(D),
3923
3923
  type: C,
3924
- step: A.type === "currency" ? "0.01" : void 0,
3924
+ step: D.type === "currency" ? "0.01" : void 0,
3925
3925
  required: ee,
3926
3926
  readOnly: G,
3927
3927
  disabled: G,
3928
- value: p[A.name] ?? "",
3928
+ value: p[D.name] ?? "",
3929
3929
  onChange: (w) => h(
3930
- A.name,
3930
+ D.name,
3931
3931
  C === "number" ? parseFloat(w.target.value) || 0 : w.target.value
3932
3932
  )
3933
3933
  },
3934
- A.name
3934
+ D.name
3935
3935
  );
3936
3936
  }) }) })
3937
3937
  ] });
@@ -4160,17 +4160,17 @@ function rs(t) {
4160
4160
  }
4161
4161
  const ss = ["25", "50", "100", "200"];
4162
4162
  function is() {
4163
- const { t } = Z(), [n] = ae("account", ""), [a] = ae("party", ""), [s] = ae("from", ""), [o] = ae("to", ""), [i] = ae("per_page", 50), [l] = ae("page", 1), c = l - 1, g = Ye(), m = (D) => g({ page: D === 0 ? null : D + 1 }), p = (D) => g({ per_page: D, page: null }), [u, N] = S(n), [v, x] = S(a), [f, R] = S(s), [P, b] = S(o), d = qe(), h = (D) => Oe(D, d), _ = Ce(() => {
4164
- const D = {};
4165
- return n && (D.account = n), a && (D.party = a), s && (D.from_date = s), o && (D.to_date = o), D.limit = String(i), D.offset = String(c * i), D;
4166
- }, [n, a, s, o, i, c]), { data: y, isLoading: B, refetch: A } = Qr(_), O = (y == null ? void 0 : y.rows) ?? [], G = (y == null ? void 0 : y.total) ?? 0, ee = Math.max(1, Math.ceil(G / i)), C = G === 0 ? 0 : c * i + 1, w = Math.min(G, (c + 1) * i), q = () => {
4163
+ const { t } = Z(), [n] = ae("account", ""), [a] = ae("party", ""), [s] = ae("from", ""), [o] = ae("to", ""), [i] = ae("per_page", 50), [l] = ae("page", 1), c = l - 1, g = Ye(), m = (A) => g({ page: A === 0 ? null : A + 1 }), p = (A) => g({ per_page: A, page: null }), [u, N] = S(n), [v, x] = S(a), [f, R] = S(s), [P, b] = S(o), d = qe(), h = (A) => Oe(A, d), _ = Ce(() => {
4164
+ const A = {};
4165
+ return n && (A.account = n), a && (A.party = a), s && (A.from_date = s), o && (A.to_date = o), A.limit = String(i), A.offset = String(c * i), A;
4166
+ }, [n, a, s, o, i, c]), { data: y, isLoading: B, refetch: D } = Qr(_), O = (y == null ? void 0 : y.rows) ?? [], G = (y == null ? void 0 : y.total) ?? 0, ee = Math.max(1, Math.ceil(G / i)), C = G === 0 ? 0 : c * i + 1, w = Math.min(G, (c + 1) * i), q = () => {
4167
4167
  g({
4168
4168
  account: u || null,
4169
4169
  party: v || null,
4170
4170
  from: f || null,
4171
4171
  to: P || null,
4172
4172
  page: null
4173
- }), A();
4173
+ }), D();
4174
4174
  };
4175
4175
  return /* @__PURE__ */ r("div", { className: "space-y-4", children: [
4176
4176
  /* @__PURE__ */ r("div", { className: "flex flex-wrap items-end gap-4", children: [
@@ -4200,7 +4200,7 @@ function is() {
4200
4200
  label: t("fields.From Date", { defaultValue: "From Date" }),
4201
4201
  type: "date",
4202
4202
  value: f,
4203
- onChange: (D) => R(D.target.value)
4203
+ onChange: (A) => R(A.target.value)
4204
4204
  }
4205
4205
  ),
4206
4206
  /* @__PURE__ */ e(
@@ -4209,13 +4209,13 @@ function is() {
4209
4209
  label: t("fields.To Date", { defaultValue: "To Date" }),
4210
4210
  type: "date",
4211
4211
  value: P,
4212
- onChange: (D) => b(D.target.value)
4212
+ onChange: (A) => b(A.target.value)
4213
4213
  }
4214
4214
  ),
4215
4215
  /* @__PURE__ */ e(H, { onClick: q, children: t("common.apply") })
4216
4216
  ] }),
4217
- /* @__PURE__ */ e($t, { onSelect: (D, z) => {
4218
- R(D), b(z), g({ from: D, to: z, page: null });
4217
+ /* @__PURE__ */ e($t, { onSelect: (A, z) => {
4218
+ R(A), b(z), g({ from: A, to: z, page: null });
4219
4219
  } }),
4220
4220
  B ? /* @__PURE__ */ e("p", { className: "text-gray-500", children: t("common.loading") }) : O.length === 0 ? /* @__PURE__ */ e("p", { className: "py-8 text-center text-gray-400", children: t("reports.noEntries") }) : /* @__PURE__ */ r(we, { children: [
4221
4221
  /* @__PURE__ */ e($, { children: /* @__PURE__ */ e("div", { className: "overflow-x-auto", children: /* @__PURE__ */ r("table", { className: "min-w-full divide-y divide-gray-200 text-sm", children: [
@@ -4229,22 +4229,22 @@ function is() {
4229
4229
  /* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Voucher Type", { defaultValue: "Voucher Type" }) }),
4230
4230
  /* @__PURE__ */ e("th", { className: "px-4 py-3 text-left font-medium text-gray-500", children: t("fields.Voucher No", { defaultValue: "Voucher No" }) })
4231
4231
  ] }) }),
4232
- /* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: O.map((D, z) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
4233
- /* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-500", children: Ft(D.posting_date ?? D.date) }),
4234
- /* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-900", children: D.account }),
4235
- /* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: D.party ?? "-" }),
4236
- /* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: h(D.debit) }),
4237
- /* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: h(D.credit) }),
4238
- /* @__PURE__ */ e("td", { className: "px-4 py-2 text-right font-medium", children: h(D.balance) }),
4239
- /* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: D.voucher_type ?? "-" }),
4240
- /* @__PURE__ */ e("td", { className: "px-4 py-2", children: D.voucher_type && D.voucher_no ? /* @__PURE__ */ e(
4232
+ /* @__PURE__ */ e("tbody", { className: "divide-y divide-gray-100", children: O.map((A, z) => /* @__PURE__ */ r("tr", { className: "hover:bg-gray-50", children: [
4233
+ /* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-500", children: Ft(A.posting_date ?? A.date) }),
4234
+ /* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-900", children: A.account }),
4235
+ /* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: A.party ?? "-" }),
4236
+ /* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: h(A.debit) }),
4237
+ /* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: h(A.credit) }),
4238
+ /* @__PURE__ */ e("td", { className: "px-4 py-2 text-right font-medium", children: h(A.balance) }),
4239
+ /* @__PURE__ */ e("td", { className: "px-4 py-2 text-gray-700", children: A.voucher_type ?? "-" }),
4240
+ /* @__PURE__ */ e("td", { className: "px-4 py-2", children: A.voucher_type && A.voucher_no ? /* @__PURE__ */ e(
4241
4241
  be,
4242
4242
  {
4243
- to: `/app/${rs(D.voucher_type)}/${D.voucher_no}`,
4243
+ to: `/app/${rs(A.voucher_type)}/${A.voucher_no}`,
4244
4244
  className: "font-medium text-blue-600 hover:text-blue-800",
4245
- children: D.voucher_no
4245
+ children: A.voucher_no
4246
4246
  }
4247
- ) : D.voucher_no ?? "-" })
4247
+ ) : A.voucher_no ?? "-" })
4248
4248
  ] }, z)) })
4249
4249
  ] }) }) }),
4250
4250
  /* @__PURE__ */ r("div", { className: "flex flex-wrap items-center justify-between gap-3 text-sm text-gray-600", children: [
@@ -4268,9 +4268,9 @@ function is() {
4268
4268
  "select",
4269
4269
  {
4270
4270
  value: i,
4271
- onChange: (D) => p(Number(D.target.value)),
4271
+ onChange: (A) => p(Number(A.target.value)),
4272
4272
  className: "rounded border border-gray-300 bg-white px-2 py-1 text-sm",
4273
- children: ss.map((D) => /* @__PURE__ */ e("option", { value: D, children: D }, D))
4273
+ children: ss.map((A) => /* @__PURE__ */ e("option", { value: A, children: A }, A))
4274
4274
  }
4275
4275
  )
4276
4276
  ] }),
@@ -4694,7 +4694,7 @@ return {
4694
4694
  }
4695
4695
  const da = ps();
4696
4696
  function hs() {
4697
- const t = Le(), { sessions: n, createSession: a } = ut(), [s] = ae("report_id", ""), [o] = ae("metric", ""), [i] = ae("group_by", ""), [l] = ae("from", ""), [c] = ae("to", ""), [g] = ae("company", ""), [m, p] = S(da), [u, N] = S([]), [v, x] = S(null), [f, R] = S(""), [P, b] = S(!1), [d, h] = S(!1), [_, y] = S(""), B = te(null), A = te(""), O = te(""), G = te(0), ee = Ce(() => !o || !i ? "" : JSON.stringify(bs({
4697
+ const t = Le(), { sessions: n, createSession: a } = mt(), [s] = ae("report_id", ""), [o] = ae("metric", ""), [i] = ae("group_by", ""), [l] = ae("from", ""), [c] = ae("to", ""), [g] = ae("company", ""), [m, p] = S(da), [u, N] = S([]), [v, x] = S(null), [f, R] = S(""), [P, b] = S(!1), [d, h] = S(!1), [_, y] = S(""), B = te(null), D = te(""), O = te(""), G = te(0), ee = Ce(() => !o || !i ? "" : JSON.stringify(bs({
4698
4698
  metric: o,
4699
4699
  groupBy: i,
4700
4700
  fromDate: l || void 0,
@@ -4714,9 +4714,9 @@ function hs() {
4714
4714
  const Re = window.setTimeout(() => {
4715
4715
  fe.terminate(), ne(new Error("Report runtime exceeded 4 seconds"));
4716
4716
  }, 4e3);
4717
- fe.onmessage = (Ae) => {
4717
+ fe.onmessage = (De) => {
4718
4718
  var Ve, Me;
4719
- window.clearTimeout(Re), fe.terminate(), B.current === fe && (B.current = null), (Ve = Ae.data) != null && Ve.ok ? E(Ae.data.output) : ne(new Error(((Me = Ae.data) == null ? void 0 : Me.error) || "Runtime failed"));
4719
+ window.clearTimeout(Re), fe.terminate(), B.current === fe && (B.current = null), (Ve = De.data) != null && Ve.ok ? E(De.data.output) : ne(new Error(((Me = De.data) == null ? void 0 : Me.error) || "Runtime failed"));
4720
4720
  }, fe.postMessage({
4721
4721
  datasets: pe.datasets,
4722
4722
  params: {},
@@ -4734,21 +4734,21 @@ function hs() {
4734
4734
  };
4735
4735
  se(() => {
4736
4736
  let z = !1;
4737
- return s ? A.current === s ? void 0 : (h(!0), R(""), T.getRuntimeDraft(s).then((Y) => {
4737
+ return s ? D.current === s ? void 0 : (h(!0), R(""), T.getRuntimeDraft(s).then((Y) => {
4738
4738
  if (z) return;
4739
4739
  const re = JSON.stringify(Y.definition, null, 2);
4740
- return A.current = s, O.current = re, y(Y.source_chat_session_id || ""), p(re), C(re);
4740
+ return D.current = s, O.current = re, y(Y.source_chat_session_id || ""), p(re), C(re);
4741
4741
  }).catch((Y) => {
4742
4742
  z || (x(null), R(Y instanceof Error ? Y.message : String(Y)));
4743
4743
  }).finally(() => {
4744
4744
  z || h(!1);
4745
4745
  }), () => {
4746
4746
  z = !0;
4747
- }) : (A.current = "", O.current = "", y(""), ee && (O.current = ee, p(ee), C(ee)), () => {
4747
+ }) : (D.current = "", O.current = "", y(""), ee && (O.current = ee, p(ee), C(ee)), () => {
4748
4748
  z = !0;
4749
4749
  });
4750
4750
  }, [s, ee]);
4751
- const w = !!(!s && ee), q = Ce(() => ys(v), [v]), D = async () => {
4751
+ const w = !!(!s && ee), q = Ce(() => ys(v), [v]), A = async () => {
4752
4752
  var pe;
4753
4753
  const z = m.trim() !== O.current.trim(), Y = s || "unsaved-runtime-report", re = u.map((fe) => ({
4754
4754
  name: fe.name,
@@ -4796,7 +4796,7 @@ function hs() {
4796
4796
  "Loaded draft: ",
4797
4797
  s
4798
4798
  ] }) : w ? /* @__PURE__ */ e("div", { className: "text-xs text-gray-500", children: "Loaded runtime report from legacy URL filters." }) : null,
4799
- s ? /* @__PURE__ */ e(H, { variant: "secondary", onClick: () => void D(), children: "Fix In Chat" }) : null,
4799
+ s ? /* @__PURE__ */ e(H, { variant: "secondary", onClick: () => void A(), children: "Fix In Chat" }) : null,
4800
4800
  /* @__PURE__ */ e(H, { onClick: () => void C(), disabled: P, children: P ? "Running..." : "Run Report" })
4801
4801
  ] })
4802
4802
  ] }) }),
@@ -4925,7 +4925,7 @@ function ys(t) {
4925
4925
  function bs(t) {
4926
4926
  const n = `${vs(t.metric)} by ${fs(t.groupBy)}`, a = t.groupBy === "month" ? "helpers.monthKey" : t.groupBy === "quarter" ? "helpers.quarterKey" : "helpers.yearKey";
4927
4927
  if (t.metric === "sales_revenue")
4928
- return yt({
4928
+ return bt({
4929
4929
  title: n,
4930
4930
  dataset: t.groupBy === "item" ? "sales_invoice_lines" : "sales_invoices",
4931
4931
  requestName: "rows",
@@ -4942,7 +4942,7 @@ function bs(t) {
4942
4942
  chartType: t.groupBy === "customer" || t.groupBy === "item" ? "bar" : "line"
4943
4943
  });
4944
4944
  if (t.metric === "sales_returns")
4945
- return yt({
4945
+ return bt({
4946
4946
  title: n,
4947
4947
  dataset: "sales_invoices",
4948
4948
  requestName: "rows",
@@ -4959,7 +4959,7 @@ function bs(t) {
4959
4959
  chartType: t.groupBy === "customer" ? "bar" : "line"
4960
4960
  });
4961
4961
  if (t.metric === "purchases")
4962
- return yt({
4962
+ return bt({
4963
4963
  title: n,
4964
4964
  dataset: t.groupBy === "item" ? "purchase_invoice_lines" : "purchase_invoices",
4965
4965
  requestName: "rows",
@@ -4977,7 +4977,7 @@ function bs(t) {
4977
4977
  });
4978
4978
  if (t.metric === "payments_received" || t.metric === "payments_made") {
4979
4979
  const s = t.metric === "payments_received";
4980
- return yt({
4980
+ return bt({
4981
4981
  title: n,
4982
4982
  dataset: "payments",
4983
4983
  requestName: "rows",
@@ -4997,7 +4997,7 @@ function bs(t) {
4997
4997
  }
4998
4998
  if (t.metric === "outstanding_ar" || t.metric === "outstanding_ap") {
4999
4999
  const s = t.metric === "outstanding_ar", o = s ? "ar_open_items" : "ap_open_items", i = s ? "customer" : "supplier", l = "outstanding_amount";
5000
- return yt({
5000
+ return bt({
5001
5001
  title: n,
5002
5002
  dataset: o,
5003
5003
  requestName: "rows",
@@ -5013,7 +5013,7 @@ function bs(t) {
5013
5013
  chartType: "bar"
5014
5014
  });
5015
5015
  }
5016
- return t.metric === "stock_value" ? yt({
5016
+ return t.metric === "stock_value" ? bt({
5017
5017
  title: n,
5018
5018
  dataset: "stock_balances",
5019
5019
  requestName: "rows",
@@ -5028,7 +5028,7 @@ function bs(t) {
5028
5028
  chartType: "bar"
5029
5029
  }) : JSON.parse(da);
5030
5030
  }
5031
- function yt(t) {
5031
+ function bt(t) {
5032
5032
  const n = Object.fromEntries(Object.entries(t.filters).filter(([, s]) => s !== void 0)), a = ["month", "quarter", "year"].includes(t.groupBy) ? `${t.timeBucket}(row.${t.keyField})` : `row.${t.keyField} || "—"`;
5033
5033
  return {
5034
5034
  title: t.title,
@@ -5134,7 +5134,7 @@ function Ss() {
5134
5134
  email: "",
5135
5135
  phone: "",
5136
5136
  tax_id: ""
5137
- }), m = (y) => (B) => g((A) => ({ ...A, [y]: B.target.value })), [p, u] = S("quick"), [N, v] = S(!1), [x, f] = S(null), R = oe({
5137
+ }), m = (y) => (B) => g((D) => ({ ...D, [y]: B.target.value })), [p, u] = S("quick"), [N, v] = S(!1), [x, f] = S(null), R = oe({
5138
5138
  mutationFn: () => T.createCompany({ name: s, currency: i, ...c })
5139
5139
  }), P = oe({
5140
5140
  mutationFn: () => T.seedDemo()
@@ -5326,7 +5326,7 @@ function Cs({ company: t }) {
5326
5326
  t.default_currency && /* @__PURE__ */ e("span", { className: "shrink-0 rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600", children: t.default_currency })
5327
5327
  ] });
5328
5328
  }
5329
- const As = [
5329
+ const Ds = [
5330
5330
  {
5331
5331
  number: 1,
5332
5332
  title: "Set Up Your Company",
@@ -5464,7 +5464,7 @@ const As = [
5464
5464
  }
5465
5465
  ];
5466
5466
  function ma() {
5467
- const t = Le(), { sessions: n, createSession: a } = ut();
5467
+ const t = Le(), { sessions: n, createSession: a } = mt();
5468
5468
  return async (s) => {
5469
5469
  var i;
5470
5470
  let o = ((i = n[0]) == null ? void 0 : i.id) || "";
@@ -5478,7 +5478,7 @@ function ma() {
5478
5478
  t(`/chat/${o}`, { state: { prefillMessage: s } });
5479
5479
  };
5480
5480
  }
5481
- function Ds() {
5481
+ function As() {
5482
5482
  const { t } = Z(), n = ma();
5483
5483
  return /* @__PURE__ */ e($, { className: "border-emerald-200 bg-gradient-to-br from-emerald-50 to-white", children: /* @__PURE__ */ r("div", { className: "flex flex-col gap-4 md:flex-row md:items-start", children: [
5484
5484
  /* @__PURE__ */ e("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-lg font-bold text-emerald-700", children: "▶" }),
@@ -5704,11 +5704,11 @@ function Rs() {
5704
5704
  ] }),
5705
5705
  /* @__PURE__ */ e("p", { className: "mt-4 text-sm text-gray-500", children: t("tutorial.manualIntro") })
5706
5706
  ] }),
5707
- /* @__PURE__ */ e(Ds, {}),
5707
+ /* @__PURE__ */ e(As, {}),
5708
5708
  /* @__PURE__ */ e(Ps, {}),
5709
5709
  /* @__PURE__ */ e(_s, {}),
5710
5710
  /* @__PURE__ */ e(Ts, {}),
5711
- As.map((n) => {
5711
+ Ds.map((n) => {
5712
5712
  var a;
5713
5713
  return /* @__PURE__ */ e($, { children: /* @__PURE__ */ r("div", { className: "flex gap-4", children: [
5714
5714
  /* @__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 }),
@@ -5809,25 +5809,25 @@ function Ln(t) {
5809
5809
  });
5810
5810
  }
5811
5811
  function On() {
5812
- const { t } = Z(), { sessionId: n } = bt(), a = Le(), s = Ct(), [o] = qt(), i = o.get("demo") === "1", [l, c] = S(""), [g, m] = S(""), [p, u] = S([]), [N, v] = S(""), [x, f] = S(!1), [R, P] = S("idle"), b = te(null), d = te(null), h = te([]), {
5812
+ const { t } = Z(), { sessionId: n } = ut(), a = Le(), s = Ct(), [o] = qt(), i = o.get("demo") === "1", [l, c] = S(""), [g, m] = S(""), [p, u] = S([]), [N, v] = S(""), [x, f] = S(!1), [R, P] = S("idle"), b = te(null), d = te(null), h = te([]), {
5813
5813
  connectionStatus: _,
5814
5814
  connectionVersion: y,
5815
5815
  createSession: B,
5816
- startDemo: A,
5816
+ startDemo: D,
5817
5817
  completeDemoTyping: O,
5818
5818
  loadHistory: G,
5819
5819
  loadMoreHistory: ee,
5820
5820
  sendMessage: C,
5821
5821
  transcribeAudio: w,
5822
5822
  getMessages: q,
5823
- hasMoreHistory: D,
5823
+ hasMoreHistory: A,
5824
5824
  isLoadingOlder: z,
5825
5825
  isThinking: Y,
5826
5826
  getDemoStatus: re,
5827
5827
  getDemoTypingCue: ce
5828
- } = ut(), ge = te(null), _e = te(null), pe = te(null), fe = te(null), [Ue, E] = S(0), ne = te(!1), Re = te(null), Ae = te(0), Ve = te(!0), Me = te(null), vt = te(!1), mt = te(null), Je = q(n), ke = _ === "connected", Te = Y(n), Ke = re(n), Qe = ce(n), Ie = i || Ke === "running", pt = D(n), it = z(n), ht = Je[Je.length - 1], I = ht ? `${ht.type}:${ht.timestamp || ""}:${ht.content}` : "empty", V = Pe(() => {
5829
- vt.current = !0, mt.current !== null && window.clearTimeout(mt.current), mt.current = window.setTimeout(() => {
5830
- vt.current = !1, mt.current = null;
5828
+ } = mt(), ge = te(null), _e = te(null), pe = te(null), fe = te(null), [Ue, E] = S(0), ne = te(!1), Re = te(null), De = te(0), Ve = te(!0), Me = te(null), vt = te(!1), pt = te(null), Je = q(n), ke = _ === "connected", Te = Y(n), Ke = re(n), Qe = ce(n), Ie = i || Ke === "running", ht = A(n), it = z(n), gt = Je[Je.length - 1], I = gt ? `${gt.type}:${gt.timestamp || ""}:${gt.content}` : "empty", V = Pe(() => {
5829
+ vt.current = !0, pt.current !== null && window.clearTimeout(pt.current), pt.current = window.setTimeout(() => {
5830
+ vt.current = !1, pt.current = null;
5831
5831
  }, 600);
5832
5832
  }, []), W = Pe((k = "smooth") => {
5833
5833
  const U = ge.current;
@@ -5867,14 +5867,14 @@ function On() {
5867
5867
  return U.observe(k), () => U.disconnect();
5868
5868
  }, []);
5869
5869
  const ve = Pe(() => {
5870
- if (!n || it || !pt) return;
5870
+ if (!n || it || !ht) return;
5871
5871
  const k = ge.current;
5872
5872
  Me.current = k ? k.scrollHeight : null, Ve.current = !1, ee(n).catch(() => {
5873
5873
  Me.current = null;
5874
5874
  });
5875
- }, [n, it, pt, ee]), xe = te(null);
5875
+ }, [n, it, ht, ee]), xe = te(null);
5876
5876
  se(() => {
5877
- m(""), Re.current = null, Ae.current += 1, n && sa(n);
5877
+ m(""), Re.current = null, De.current += 1, n && sa(n);
5878
5878
  const k = s.state;
5879
5879
  k != null && k.prefillMessage && xe.current !== k ? (xe.current = k, c(k.prefillMessage), window.setTimeout(() => {
5880
5880
  var U;
@@ -5890,11 +5890,11 @@ function On() {
5890
5890
  k = !0;
5891
5891
  };
5892
5892
  }, [n, ke, a]);
5893
- const De = te(G);
5893
+ const Ae = te(G);
5894
5894
  se(() => {
5895
- De.current = G;
5895
+ Ae.current = G;
5896
5896
  }, [G]), se(() => {
5897
- !n || !ke || i || Ke === "running" || De.current(n).catch(() => {
5897
+ !n || !ke || i || Ke === "running" || Ae.current(n).catch(() => {
5898
5898
  });
5899
5899
  }, [n, ke, y, i, Ke]), se(() => {
5900
5900
  ne.current && !Te && ke && setTimeout(() => {
@@ -5908,10 +5908,10 @@ function On() {
5908
5908
  Ve.current = X < 80;
5909
5909
  }
5910
5910
  se(() => {
5911
- !n || !ke || !i || Re.current !== n && (Re.current = n, m(""), A(n).catch((k) => {
5911
+ !n || !ke || !i || Re.current !== n && (Re.current = n, m(""), D(n).catch((k) => {
5912
5912
  Re.current = null, m(k instanceof Error ? k.message : t("chat.demoError"));
5913
5913
  }));
5914
- }, [n, ke, i, A]), se(() => {
5914
+ }, [n, ke, i, D]), se(() => {
5915
5915
  !n || !i || Ke !== "complete" || (c(""), a(`/chat/${n}`, { replace: !0 }));
5916
5916
  }, [n, i, Ke, a]);
5917
5917
  const K = te(O);
@@ -5922,18 +5922,18 @@ function On() {
5922
5922
  se(() => {
5923
5923
  if (!Qe || !n || Ze.current === Qe.seq) return;
5924
5924
  Ze.current = Qe.seq;
5925
- const k = n, U = Qe.content, X = U.length > 0 ? Math.max(8, Qe.typingMs / U.length) : 0, de = Qe.seq, he = ++Ae.current;
5925
+ const k = n, U = Qe.content, X = U.length > 0 ? Math.max(8, Qe.typingMs / U.length) : 0, de = Qe.seq, he = ++De.current;
5926
5926
  async function et() {
5927
5927
  c("");
5928
- for (const ft of U) {
5929
- if (he !== Ae.current) return;
5930
- c((je) => je + ft), await Es(X);
5928
+ for (const yt of U) {
5929
+ if (he !== De.current) return;
5930
+ c((je) => je + yt), await Es(X);
5931
5931
  }
5932
- he === Ae.current && K.current(k, de);
5932
+ he === De.current && K.current(k, de);
5933
5933
  }
5934
5934
  et();
5935
5935
  }, [Qe, n]), se(() => {
5936
- Ke === "complete" && (Ae.current += 1, c(""));
5936
+ Ke === "complete" && (De.current += 1, c(""));
5937
5937
  }, [Ke]);
5938
5938
  const me = Pe((k) => {
5939
5939
  if (!n) return;
@@ -5954,18 +5954,18 @@ function On() {
5954
5954
  v(`"${he.name}" is too large (max 10 MB).`);
5955
5955
  continue;
5956
5956
  }
5957
- const et = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, ft = he.type.startsWith("image/") ? URL.createObjectURL(he) : void 0, je = { localId: et, file: he, previewUrl: ft, uploading: !0 };
5957
+ const et = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, yt = he.type.startsWith("image/") ? URL.createObjectURL(he) : void 0, je = { localId: et, file: he, previewUrl: yt, uploading: !0 };
5958
5958
  de.push(je), T.uploadChatAttachment(n, he).then((lt) => {
5959
5959
  u(
5960
- (At) => At.map(
5960
+ (Dt) => Dt.map(
5961
5961
  (Nt) => Nt.localId === et ? { ...Nt, uploading: !1, uploadedId: lt.id } : Nt
5962
5962
  )
5963
5963
  );
5964
5964
  }).catch((lt) => {
5965
- const At = (lt == null ? void 0 : lt.message) || "Upload failed";
5966
- v(`"${he.name}": ${At}`), u(
5965
+ const Dt = (lt == null ? void 0 : lt.message) || "Upload failed";
5966
+ v(`"${he.name}": ${Dt}`), u(
5967
5967
  (Nt) => Nt.map(
5968
- (Ut) => Ut.localId === et ? { ...Ut, uploading: !1, error: At } : Ut
5968
+ (Ut) => Ut.localId === et ? { ...Ut, uploading: !1, error: Dt } : Ut
5969
5969
  )
5970
5970
  );
5971
5971
  });
@@ -5993,7 +5993,7 @@ function On() {
5993
5993
  }
5994
5994
  U.length > 0 && (k.preventDefault(), me(U));
5995
5995
  }, Ne = p.some((k) => k.uploading), le = p.some((k) => k.error), ue = p.filter((k) => k.uploadedId && !k.error).map((k) => k.uploadedId);
5996
- function gt() {
5996
+ function ft() {
5997
5997
  const k = l.trim();
5998
5998
  if (n && !(!k && ue.length === 0) && !Ne && C(n, k, ue.length > 0 ? ue : void 0)) {
5999
5999
  for (const U of p)
@@ -6002,7 +6002,7 @@ function On() {
6002
6002
  }
6003
6003
  }
6004
6004
  function xt(k) {
6005
- k.key === "Enter" && !k.shiftKey && (k.preventDefault(), gt());
6005
+ k.key === "Enter" && !k.shiftKey && (k.preventDefault(), ft());
6006
6006
  }
6007
6007
  function Xe(k) {
6008
6008
  const U = k.trim();
@@ -6025,14 +6025,14 @@ function On() {
6025
6025
  d.current = U, h.current = [], U.ondataavailable = (X) => {
6026
6026
  X.data.size > 0 && h.current.push(X.data);
6027
6027
  }, U.onstop = async () => {
6028
- var ft;
6028
+ var yt;
6029
6029
  k.getTracks().forEach((je) => je.stop());
6030
6030
  const X = h.current;
6031
6031
  if (h.current = [], d.current = null, X.length === 0) {
6032
6032
  P("idle");
6033
6033
  return;
6034
6034
  }
6035
- const de = U.mimeType || ((ft = X[0]) == null ? void 0 : ft.type) || "audio/webm", he = new Blob(X, { type: de }), et = (de.split(";")[0].split("/")[1] || "webm").toLowerCase();
6035
+ const de = U.mimeType || ((yt = X[0]) == null ? void 0 : yt.type) || "audio/webm", he = new Blob(X, { type: de }), et = (de.split(";")[0].split("/")[1] || "webm").toLowerCase();
6036
6036
  P("transcribing");
6037
6037
  try {
6038
6038
  const je = await Ls(he), lt = await w(je, et, n);
@@ -6072,11 +6072,11 @@ function On() {
6072
6072
  className: "mx-auto max-w-3xl space-y-4",
6073
6073
  style: { paddingBottom: (Ue || 96) + 16 },
6074
6074
  children: [
6075
- (pt || it) && Je.length > 0 && /* @__PURE__ */ e("div", { className: "flex justify-center", children: /* @__PURE__ */ e(
6075
+ (ht || it) && Je.length > 0 && /* @__PURE__ */ e("div", { className: "flex justify-center", children: /* @__PURE__ */ e(
6076
6076
  "button",
6077
6077
  {
6078
6078
  onClick: ve,
6079
- disabled: it || !pt,
6079
+ disabled: it || !ht,
6080
6080
  className: "rounded-full bg-surface px-3 py-1 text-xs text-fg-muted ring-1 ring-line transition-colors hover:bg-surface-subtle hover:text-fg disabled:cursor-not-allowed disabled:opacity-60",
6081
6081
  children: t(it ? "common.loading" : "chat.loadOlder")
6082
6082
  }
@@ -6204,7 +6204,7 @@ function On() {
6204
6204
  /* @__PURE__ */ e(
6205
6205
  "button",
6206
6206
  {
6207
- onClick: gt,
6207
+ onClick: ft,
6208
6208
  disabled: !l.trim() && ue.length === 0 || !ke || !n || Te || Ie || Ne || le,
6209
6209
  className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-lg text-brand transition-all hover:bg-brand/10 active:translate-y-px disabled:cursor-not-allowed disabled:text-fg-muted disabled:active:translate-y-0 md:h-10 md:w-10",
6210
6210
  children: /* @__PURE__ */ e(
@@ -6393,7 +6393,7 @@ function Fs(t, n) {
6393
6393
  return s < t.length && a.push(t.slice(s)), a.length > 0 ? a : [t];
6394
6394
  }
6395
6395
  function $s() {
6396
- const t = Le(), [n] = qt(), { user: a, login: s, register: o } = st(), { t: i } = Z(), l = n.get("invite") || "", [c, g] = S(l ? "register" : "login"), [m, p] = S(!1), [u, N] = S(!1), [v, x] = S([]), [f, R] = S(!0), [P, b] = S(""), [d, h] = S(""), [_, y] = S(""), [B, A] = S(""), [O, G] = S("");
6396
+ const t = Le(), [n] = qt(), { user: a, login: s, register: o } = st(), { t: i } = Z(), l = n.get("invite") || "", [c, g] = S(l ? "register" : "login"), [m, p] = S(!1), [u, N] = S(!1), [v, x] = S([]), [f, R] = S(!0), [P, b] = S(""), [d, h] = S(""), [_, y] = S(""), [B, D] = S(""), [O, G] = S("");
6397
6397
  se(() => {
6398
6398
  a && a.role !== "public_manager" && t("/", { replace: !0 });
6399
6399
  }, [a, t]), se(() => {
@@ -6461,7 +6461,7 @@ function $s() {
6461
6461
  label: i("login.password"),
6462
6462
  type: "password",
6463
6463
  value: B,
6464
- onChange: (C) => A(C.target.value),
6464
+ onChange: (C) => D(C.target.value),
6465
6465
  required: !0
6466
6466
  }
6467
6467
  ),
@@ -6609,9 +6609,9 @@ function js() {
6609
6609
  }),
6610
6610
  onSuccess: (h) => f((_) => ({ ..._, invoices: h }))
6611
6611
  });
6612
- function d(h, _, y, B, A) {
6612
+ function d(h, _, y, B, D) {
6613
6613
  const O = [...h];
6614
- O[y][B] = A, _(O);
6614
+ O[y][B] = D, _(O);
6615
6615
  }
6616
6616
  return /* @__PURE__ */ r("div", { className: "space-y-6", children: [
6617
6617
  /* @__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." }),
@@ -6917,7 +6917,7 @@ const Ws = { save: "Save", saving: "Saving...", submit: "Submit", cancel: "Cance
6917
6917
  tutorial: di,
6918
6918
  notesMarkup: ui,
6919
6919
  coa: mi
6920
- }, hi = { 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" }, gi = { title: "Sprache", help: "Wählen Sie die Sprache der Oberfläche. Ihre Auswahl wird in diesem Browser gespeichert.", label: "Sprache" }, fi = { back: "Zurück", logout: "Abmelden", openMenu: "Menü öffnen", closeMenu: "Menü schließen", new: "Neu: {{label}}" }, yi = { 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", "chart-of-accounts": "Kontenplan" }, bi = { 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" } }, vi = { 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" } }, xi = { 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", "Chart of Accounts": "Kontenplan" } }, Ni = { 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", orContinueWith: "oder weiter mit", continueWithProvider: "Weiter mit {{provider}}", oauthError: { generic: "Anmeldung fehlgeschlagen. Bitte erneut versuchen.", email_exists: "Ein Konto mit dieser E-Mail existiert bereits. Melden Sie sich an und verknüpfen Sie diesen Anbieter in den Kontoeinstellungen.", email_unverified: "Ihr Anbieter hat keine bestätigte E-Mail übermittelt, daher ist keine Anmeldung möglich.", registration_closed: "Für diese E-Mail besteht noch kein Konto und die Registrierung ist nur per Einladung möglich.", invite_invalid: "Diese Einladung ist ungültig, bereits verwendet oder für eine andere E-Mail ausgestellt.", identity_taken: "Dieses Anbieterkonto ist bereits mit einem anderen Benutzer verknüpft.", account_disabled: "Dieses Konto wurde deaktiviert.", token_exchange_failed: "Anmeldung beim Anbieter fehlgeschlagen. Bitte erneut versuchen." } }, wi = { 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.", setPasswordTitle: "Passwort festlegen", setPasswordBody: "Ihr Konto meldet sich mit Google an. Legen Sie ein Passwort fest, um sich auch mit E-Mail und Passwort anzumelden — ein praktischer Rückfall, falls Sie den Zugang zu Ihrem Google-Konto verlieren.", setPassword: "Passwort festlegen", passwordSet: "Passwort festgelegt.", linkedAccountsTitle: "Verknüpfte Konten", linkedAccountsBody: "Verknüpfen Sie ein Google- oder Apple-Konto, um sich ohne Passwort anzumelden.", linked: "Verknüpft", linkProvider: "{{provider}} verknüpfen", 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.", chatApiTitle: "Chat-API", apiTitle: "Programmatische API", restApiBody: "Konnektoren und Skripten erlauben, dieses ERP über seine REST-API (Belege, Stammdaten, Berichte) mit denselben Bearer-API-Schlüsseln zu steuern. Standardmäßig deaktiviert.", restApiEnabled: "Derzeit aktiviert — ausgestellte Schlüssel können /api/documents, /api/masters und die übrige REST-API aufrufen.", restApiDisabled: "Derzeit deaktiviert — die REST-API akzeptiert nur das Sitzungs-Cookie; Schlüssel werden abgewiesen.", restApiDeactivateTitle: "REST-API deaktivieren?", restApiDeactivateBody: "Der Bearer-Schlüssel-Zugriff auf die REST-API wird abgeschaltet — Konnektoren und Skripte werden abgewiesen, bis Sie ihn wieder einschalten. Die Web-App (Sitzungs-Cookie) ist nicht betroffen, und Ihre API-Schlüssel werden NICHT gelöscht: Sie funktionieren wieder, sobald Sie die API erneut aktivieren.", chatApiBody: "Externen Anwendungen erlauben, über eine HTTP-API mit dem Chat-Agenten dieses ERPs zu sprechen — per Bearer-API-Schlüssel. Standardmäßig deaktiviert.", chatApiEnabled: "Derzeit aktiviert — ausgestellte Schlüssel können POST /api/v1/chat aufrufen.", chatApiDisabled: "Derzeit deaktiviert — die API liefert 404 und Schlüssel funktionieren nicht.", chatApiDeactivateTitle: "Chat-API deaktivieren?", chatApiDeactivateBody: "Die Chat-API wird abgeschaltet — jede programmatische Anfrage (Bearer-API-Schlüssel) wird abgewiesen, bis Sie sie wieder einschalten. Ihre API-Schlüssel werden NICHT gelöscht: Sie bleiben gespeichert und funktionieren wieder, sobald Sie die API erneut aktivieren.", chatApiDeactivateConfirm: "API deaktivieren", chatApiKeysTitle: "API-Schlüssel", chatApiTokenOnce: "Kopieren Sie diesen Token jetzt — er wird nicht erneut angezeigt.", chatApiCopy: "Kopieren", chatApiDismiss: "Schließen", chatApiRevoked: "widerrufen", chatApiRevoke: "Widerrufen", chatApiNoKeys: "Noch keine API-Schlüssel.", chatApiName: "Name", chatApiRole: "Rolle", chatApiCreate: "Schlüssel erstellen", chatApiWarn: "Ein Key handelt mit Ihrer Identität und höchstens Ihrer Rolle — wie ein Passwort behandeln. Erst widerrufen, dann löschen.", 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", chatApiDelete: "Löschen", chatApiYourKeys: "Ihre Schlüssel", chatApiYouBadge: "Sie", chatApiUnknownUser: "Unbekannter Benutzer", chatApiAdminAllNote: "Als Administrator enthält die Liste unten die Schlüssel aller Benutzer, nach Eigentümer gruppiert. Ihre eigenen stehen oben.", chatApiConfirmTitle: "Dieser Schlüssel gehört nicht Ihnen", chatApiConfirmRevokeBody: "„{{key}}“ gehört {{name}}. Beim Widerrufen verliert diese Person sofort den API-Zugriff. Fortfahren?", chatApiConfirmDeleteBody: "„{{key}}“ gehört {{name}}. Beim Löschen wird der Schlüssel dieser Person dauerhaft entfernt. Fortfahren?", chatApiPersonal: "Persönliche Bearer-Keys für die programmatische Chat-API. Ein Key handelt als SIE: begrenzt auf Ihre Rolle, folgt Rollenänderungen live und erlischt mit Ihrem Konto. Setzt voraus, dass der Admin die Chat-API aktiviert hat.", version: "Version {{version}}" }, ki = { 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" }, Si = { 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" }, Ci = { 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." }, Ai = { Account: "Konto", Amount: "Betrag", Balance: "Saldo", Credit: "Haben", Debit: "Soll", Date: "Datum", Party: "Partner", "Party Type": "Partnertyp", "Voucher Type": "Belegart", "Voucher No": "Belegnr.", Invoice: "Rechnung", Customer: "Kunde", Supplier: "Lieferant", "Due Date": "Fälligkeitsdatum", Outstanding: "Offen", "Outstanding Amount": "Offener Betrag", "Item Code": "Artikelnr.", "Item Name": "Artikelname", Item: "Artikel", Warehouse: "Lager", Qty: "Menge", "Valuation Rate": "Bewertungspreis", "Stock Value": "Lagerwert", Name: "Name", Status: "Status", Company: "Unternehmen", "From Date": "Von Datum", "To Date": "Bis Datum", "As of Date": "Stichtag", "Valid Till": "Gültig bis", "Net Total": "Nettobetrag", Tax: "Steuer", "Grand Total": "Gesamtbetrag", Frequency: "Frequenz", "Notes / Terms": "Notizen / Bedingungen", "Posting Date": "Buchungsdatum", "Transaction Date": "Belegdatum", "Delivery Date": "Lieferdatum", "% Delivered": "% geliefert", "% Billed": "% abgerechnet", "Update Stock": "Lager aktualisieren", "Payment Type": "Zahlungsart", "Paid From": "Bezahlt von", "Paid To": "Bezahlt an", "Paid Amount": "Zahlbetrag", Type: "Art", Total: "Gesamt", Allocated: "Zugeordnet", Unallocated: "Nicht zugeordnet", Remark: "Bemerkung", "Total Debit": "Summe Soll", "Total Credit": "Summe Haben", "Cost Center": "Kostenstelle", "Source Warehouse": "Quelllager", "Target Warehouse": "Ziellager", Source: "Quelle", Target: "Ziel", "Incoming Value": "Eingangswert", "Outgoing Value": "Ausgangswert", Rate: "Preis", "Income Account": "Ertragskonto", "Expense Account": "Aufwandskonto", Description: "Beschreibung", "Rate (%)": "Satz (%)", Mode: "Art", Change: "Rückgeld", Currency: "Währung", Title: "Titel", Selling: "Verkauf", Buying: "Einkauf", "Discount %": "Rabatt %", "Discount Amt": "Rabattbetrag", "Min Qty": "Mindestmenge", "Valid From": "Gültig ab", "Valid Upto": "Gültig bis", Priority: "Priorität", Enabled: "Aktiviert", "Fiscal Year": "Geschäftsjahr", "Budget Amount": "Budgetbetrag", "If Exceeded": "Bei Überschreitung", Month: "Monat", "Bank Account": "Bankkonto", Deposit: "Einzahlung", Withdrawal: "Auszahlung", "Reference No": "Referenznr.", "Matched Type": "Zugeordnete Art", "Matched Doc": "Zugeordneter Beleg", "Start Date": "Startdatum", "End Date": "Enddatum", "Billing Interval": "Abrechnungsintervall", "Current Period Start": "Aktueller Periodenbeginn", "Current Period End": "Aktuelles Periodenende", "Plan Items": "Planpositionen", "Total Amount": "Gesamtbetrag", "Stock Entry Type": "Lagerbuchungsart", "Rate Or Discount": "Preis oder Rabatt", "Discount Percentage": "Rabattprozentsatz", ID: "ID", "Customer Name": "Kundenname", "Customer Group": "Kundengruppe", Territory: "Region", "Credit Limit": "Kreditlimit", Email: "E-Mail", Phone: "Telefon", Address: "Adresse", City: "Stadt", "Zip Code": "PLZ", Country: "Land", "Tax ID": "Steuernummer", "Contact Person": "Ansprechperson", "Contact Email": "E-Mail Ansprechperson", "Contact Phone": "Telefon Ansprechperson", "Supplier Name": "Lieferantenname", "Supplier Group": "Lieferantengruppe", "Item Group": "Artikelgruppe", "Stock UOM": "Lagereinheit", "Standard Rate": "Standardpreis", "Warehouse Name": "Lagername", "Company Name": "Firmenname" }, Di = { items: "Positionen", taxes: "Steuern", references: "Zahlungsreferenzen", accounts: "Kontobuchungen", payments: "Zahlungen", plans: "Planpositionen", monthly_distribution: "Monatliche Verteilung" }, Pi = { "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" }, _i = { totalRevenue: "Gesamtumsatz", outstandingReceivable: "Offene Forderungen", outstandingPayable: "Offene Verbindlichkeiten", totalStockValue: "Gesamter Lagerwert", recentDocuments: "Letzte Dokumente", noRecentDocuments: "Keine aktuellen Dokumente" }, Ti = { 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." }, Ri = /* @__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."}},"setupTitle":"Richten Sie Ihr Unternehmen ein — KI-geführt","setupBadge":"Hier starten","setupBody":"Sagen Sie dem Assistenten, welche Art von Unternehmen Sie führen, und er erstellt Ihren Kontenplan für Sie — zugeschnitten auf Ihre Branche, mit den passenden Konten und sinnvollen Voreinstellungen. Er erklärt jede Entscheidung und legt erst dann etwas an, wenn Sie zustimmen.","setupSectors":"Zugeschnitten auf Dienstleistungen, Einzelhandel & POS, Gastronomie, Großhandel & Distribution, Import/Export, Fertigung und Bauwesen.","setupGetStarted":"Im Chat loslegen","setupManual":"Lieber ein manuelles Formular? Nutzen Sie die klassische Einrichtung.","setupManualLink":"Klassische Einrichtung","setupPrompt":"Ich möchte mein Unternehmen einrichten. Können Sie mich durch den Prozess führen?"}'), Ii = { title: "Formatierungshilfe", intro: "Der Text unter Notizen / Konditionen unterstützt eine einfache Formatierung im PDF:", heading: "fette Überschrift", emphasis: "kursiv / fett", rule: "horizontale Trennlinie", price: "rechtsbündiger Preis neben dem Text darüber (z. B. Monatlich | CHF 380.—)", block: "Trennen Sie Blöcke durch eine Leerzeile." }, Bi = { period: "Periode", allTime: "Gesamter Zeitraum", semantics: "Bilanzkonten: Saldo per Periodenende. Erfolgskonten: Bewegung innerhalb der Periode. Konto anklicken für den Kontoauszug.", empty: "Keine Konten gefunden. Zuerst die Firmeneinrichtung abschliessen.", disabled: "deaktiviert", rootType: { Asset: "Aktiven", Liability: "Passiven", Equity: "Eigenkapital", Income: "Ertrag", Expense: "Aufwand" } }, Ei = {
6920
+ }, hi = { 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" }, gi = { title: "Sprache", help: "Wählen Sie die Sprache der Oberfläche. Ihre Auswahl wird in diesem Browser gespeichert.", label: "Sprache" }, fi = { back: "Zurück", logout: "Abmelden", openMenu: "Menü öffnen", closeMenu: "Menü schließen", new: "Neu: {{label}}" }, yi = { 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", "chart-of-accounts": "Kontenplan" }, bi = { 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" } }, vi = { 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" } }, xi = { 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", "Chart of Accounts": "Kontenplan" } }, Ni = { 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", orContinueWith: "oder weiter mit", continueWithProvider: "Weiter mit {{provider}}", oauthError: { generic: "Anmeldung fehlgeschlagen. Bitte erneut versuchen.", email_exists: "Ein Konto mit dieser E-Mail existiert bereits. Melden Sie sich an und verknüpfen Sie diesen Anbieter in den Kontoeinstellungen.", email_unverified: "Ihr Anbieter hat keine bestätigte E-Mail übermittelt, daher ist keine Anmeldung möglich.", registration_closed: "Für diese E-Mail besteht noch kein Konto und die Registrierung ist nur per Einladung möglich.", invite_invalid: "Diese Einladung ist ungültig, bereits verwendet oder für eine andere E-Mail ausgestellt.", identity_taken: "Dieses Anbieterkonto ist bereits mit einem anderen Benutzer verknüpft.", account_disabled: "Dieses Konto wurde deaktiviert.", token_exchange_failed: "Anmeldung beim Anbieter fehlgeschlagen. Bitte erneut versuchen." } }, wi = { 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.", setPasswordTitle: "Passwort festlegen", setPasswordBody: "Ihr Konto meldet sich mit Google an. Legen Sie ein Passwort fest, um sich auch mit E-Mail und Passwort anzumelden — ein praktischer Rückfall, falls Sie den Zugang zu Ihrem Google-Konto verlieren.", setPassword: "Passwort festlegen", passwordSet: "Passwort festgelegt.", linkedAccountsTitle: "Verknüpfte Konten", linkedAccountsBody: "Verknüpfen Sie ein Google- oder Apple-Konto, um sich ohne Passwort anzumelden.", linked: "Verknüpft", linkProvider: "{{provider}} verknüpfen", 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.", chatApiTitle: "Chat-API", apiTitle: "Programmatische API", restApiBody: "Konnektoren und Skripten erlauben, dieses ERP über seine REST-API (Belege, Stammdaten, Berichte) mit denselben Bearer-API-Schlüsseln zu steuern. Standardmäßig deaktiviert.", restApiEnabled: "Derzeit aktiviert — ausgestellte Schlüssel können /api/documents, /api/masters und die übrige REST-API aufrufen.", restApiDisabled: "Derzeit deaktiviert — die REST-API akzeptiert nur das Sitzungs-Cookie; Schlüssel werden abgewiesen.", restApiDeactivateTitle: "REST-API deaktivieren?", restApiDeactivateBody: "Der Bearer-Schlüssel-Zugriff auf die REST-API wird abgeschaltet — Konnektoren und Skripte werden abgewiesen, bis Sie ihn wieder einschalten. Die Web-App (Sitzungs-Cookie) ist nicht betroffen, und Ihre API-Schlüssel werden NICHT gelöscht: Sie funktionieren wieder, sobald Sie die API erneut aktivieren.", chatApiBody: "Externen Anwendungen erlauben, über eine HTTP-API mit dem Chat-Agenten dieses ERPs zu sprechen — per Bearer-API-Schlüssel. Standardmäßig deaktiviert.", chatApiEnabled: "Derzeit aktiviert — ausgestellte Schlüssel können POST /api/v1/chat aufrufen.", chatApiDisabled: "Derzeit deaktiviert — die API liefert 404 und Schlüssel funktionieren nicht.", chatApiDeactivateTitle: "Chat-API deaktivieren?", chatApiDeactivateBody: "Die Chat-API wird abgeschaltet — jede programmatische Anfrage (Bearer-API-Schlüssel) wird abgewiesen, bis Sie sie wieder einschalten. Ihre API-Schlüssel werden NICHT gelöscht: Sie bleiben gespeichert und funktionieren wieder, sobald Sie die API erneut aktivieren.", chatApiDeactivateConfirm: "API deaktivieren", chatApiKeysTitle: "API-Schlüssel", chatApiTokenOnce: "Kopieren Sie diesen Token jetzt — er wird nicht erneut angezeigt.", chatApiCopy: "Kopieren", chatApiDismiss: "Schließen", chatApiRevoked: "widerrufen", chatApiRevoke: "Widerrufen", chatApiNoKeys: "Noch keine API-Schlüssel.", chatApiName: "Name", chatApiRole: "Rolle", chatApiCreate: "Schlüssel erstellen", chatApiWarn: "Ein Key handelt mit Ihrer Identität und höchstens Ihrer Rolle — wie ein Passwort behandeln. Erst widerrufen, dann löschen.", 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", chatApiDelete: "Löschen", chatApiYourKeys: "Ihre Schlüssel", chatApiYouBadge: "Sie", chatApiUnknownUser: "Unbekannter Benutzer", chatApiAdminAllNote: "Als Administrator enthält die Liste unten die Schlüssel aller Benutzer, nach Eigentümer gruppiert. Ihre eigenen stehen oben.", chatApiConfirmTitle: "Dieser Schlüssel gehört nicht Ihnen", chatApiConfirmRevokeBody: "„{{key}}“ gehört {{name}}. Beim Widerrufen verliert diese Person sofort den API-Zugriff. Fortfahren?", chatApiConfirmDeleteBody: "„{{key}}“ gehört {{name}}. Beim Löschen wird der Schlüssel dieser Person dauerhaft entfernt. Fortfahren?", chatApiPersonal: "Persönliche Bearer-Keys für die programmatische Chat-API. Ein Key handelt als SIE: begrenzt auf Ihre Rolle, folgt Rollenänderungen live und erlischt mit Ihrem Konto. Setzt voraus, dass der Admin die Chat-API aktiviert hat.", version: "Version {{version}}" }, ki = { 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" }, Si = { 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" }, Ci = { 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." }, Di = { Account: "Konto", Amount: "Betrag", Balance: "Saldo", Credit: "Haben", Debit: "Soll", Date: "Datum", Party: "Partner", "Party Type": "Partnertyp", "Voucher Type": "Belegart", "Voucher No": "Belegnr.", Invoice: "Rechnung", Customer: "Kunde", Supplier: "Lieferant", "Due Date": "Fälligkeitsdatum", Outstanding: "Offen", "Outstanding Amount": "Offener Betrag", "Item Code": "Artikelnr.", "Item Name": "Artikelname", Item: "Artikel", Warehouse: "Lager", Qty: "Menge", "Valuation Rate": "Bewertungspreis", "Stock Value": "Lagerwert", Name: "Name", Status: "Status", Company: "Unternehmen", "From Date": "Von Datum", "To Date": "Bis Datum", "As of Date": "Stichtag", "Valid Till": "Gültig bis", "Net Total": "Nettobetrag", Tax: "Steuer", "Grand Total": "Gesamtbetrag", Frequency: "Frequenz", "Notes / Terms": "Notizen / Bedingungen", "Posting Date": "Buchungsdatum", "Transaction Date": "Belegdatum", "Delivery Date": "Lieferdatum", "% Delivered": "% geliefert", "% Billed": "% abgerechnet", "Update Stock": "Lager aktualisieren", "Payment Type": "Zahlungsart", "Paid From": "Bezahlt von", "Paid To": "Bezahlt an", "Paid Amount": "Zahlbetrag", Type: "Art", Total: "Gesamt", Allocated: "Zugeordnet", Unallocated: "Nicht zugeordnet", Remark: "Bemerkung", "Total Debit": "Summe Soll", "Total Credit": "Summe Haben", "Cost Center": "Kostenstelle", "Source Warehouse": "Quelllager", "Target Warehouse": "Ziellager", Source: "Quelle", Target: "Ziel", "Incoming Value": "Eingangswert", "Outgoing Value": "Ausgangswert", Rate: "Preis", "Income Account": "Ertragskonto", "Expense Account": "Aufwandskonto", Description: "Beschreibung", "Rate (%)": "Satz (%)", Mode: "Art", Change: "Rückgeld", Currency: "Währung", Title: "Titel", Selling: "Verkauf", Buying: "Einkauf", "Discount %": "Rabatt %", "Discount Amt": "Rabattbetrag", "Min Qty": "Mindestmenge", "Valid From": "Gültig ab", "Valid Upto": "Gültig bis", Priority: "Priorität", Enabled: "Aktiviert", "Fiscal Year": "Geschäftsjahr", "Budget Amount": "Budgetbetrag", "If Exceeded": "Bei Überschreitung", Month: "Monat", "Bank Account": "Bankkonto", Deposit: "Einzahlung", Withdrawal: "Auszahlung", "Reference No": "Referenznr.", "Matched Type": "Zugeordnete Art", "Matched Doc": "Zugeordneter Beleg", "Start Date": "Startdatum", "End Date": "Enddatum", "Billing Interval": "Abrechnungsintervall", "Current Period Start": "Aktueller Periodenbeginn", "Current Period End": "Aktuelles Periodenende", "Plan Items": "Planpositionen", "Total Amount": "Gesamtbetrag", "Stock Entry Type": "Lagerbuchungsart", "Rate Or Discount": "Preis oder Rabatt", "Discount Percentage": "Rabattprozentsatz", ID: "ID", "Customer Name": "Kundenname", "Customer Group": "Kundengruppe", Territory: "Region", "Credit Limit": "Kreditlimit", Email: "E-Mail", Phone: "Telefon", Address: "Adresse", City: "Stadt", "Zip Code": "PLZ", Country: "Land", "Tax ID": "Steuernummer", "Contact Person": "Ansprechperson", "Contact Email": "E-Mail Ansprechperson", "Contact Phone": "Telefon Ansprechperson", "Supplier Name": "Lieferantenname", "Supplier Group": "Lieferantengruppe", "Item Group": "Artikelgruppe", "Stock UOM": "Lagereinheit", "Standard Rate": "Standardpreis", "Warehouse Name": "Lagername", "Company Name": "Firmenname" }, Ai = { items: "Positionen", taxes: "Steuern", references: "Zahlungsreferenzen", accounts: "Kontobuchungen", payments: "Zahlungen", plans: "Planpositionen", monthly_distribution: "Monatliche Verteilung" }, Pi = { "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" }, _i = { totalRevenue: "Gesamtumsatz", outstandingReceivable: "Offene Forderungen", outstandingPayable: "Offene Verbindlichkeiten", totalStockValue: "Gesamter Lagerwert", recentDocuments: "Letzte Dokumente", noRecentDocuments: "Keine aktuellen Dokumente" }, Ti = { 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." }, Ri = /* @__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."}},"setupTitle":"Richten Sie Ihr Unternehmen ein — KI-geführt","setupBadge":"Hier starten","setupBody":"Sagen Sie dem Assistenten, welche Art von Unternehmen Sie führen, und er erstellt Ihren Kontenplan für Sie — zugeschnitten auf Ihre Branche, mit den passenden Konten und sinnvollen Voreinstellungen. Er erklärt jede Entscheidung und legt erst dann etwas an, wenn Sie zustimmen.","setupSectors":"Zugeschnitten auf Dienstleistungen, Einzelhandel & POS, Gastronomie, Großhandel & Distribution, Import/Export, Fertigung und Bauwesen.","setupGetStarted":"Im Chat loslegen","setupManual":"Lieber ein manuelles Formular? Nutzen Sie die klassische Einrichtung.","setupManualLink":"Klassische Einrichtung","setupPrompt":"Ich möchte mein Unternehmen einrichten. Können Sie mich durch den Prozess führen?"}'), Ii = { title: "Formatierungshilfe", intro: "Der Text unter Notizen / Konditionen unterstützt eine einfache Formatierung im PDF:", heading: "fette Überschrift", emphasis: "kursiv / fett", rule: "horizontale Trennlinie", price: "rechtsbündiger Preis neben dem Text darüber (z. B. Monatlich | CHF 380.—)", block: "Trennen Sie Blöcke durch eine Leerzeile." }, Bi = { period: "Periode", allTime: "Gesamter Zeitraum", semantics: "Bilanzkonten: Saldo per Periodenende. Erfolgskonten: Bewegung innerhalb der Periode. Konto anklicken für den Kontoauszug.", empty: "Keine Konten gefunden. Zuerst die Firmeneinrichtung abschliessen.", disabled: "deaktiviert", rootType: { Asset: "Aktiven", Liability: "Passiven", Equity: "Eigenkapital", Income: "Ertrag", Expense: "Aufwand" } }, Ei = {
6921
6921
  common: hi,
6922
6922
  language: gi,
6923
6923
  header: fi,
@@ -6930,8 +6930,8 @@ const Ws = { save: "Save", saving: "Saving...", submit: "Submit", cancel: "Cance
6930
6930
  status: ki,
6931
6931
  reports: Si,
6932
6932
  masterForm: Ci,
6933
- fields: Ai,
6934
- tables: Di,
6933
+ fields: Di,
6934
+ tables: Ai,
6935
6935
  conversions: Pi,
6936
6936
  dashboard: _i,
6937
6937
  chat: Ti,
@@ -7402,16 +7402,16 @@ function fa({ ownRole: t }) {
7402
7402
  }), P = (y) => y.is_mine ?? y.user === (a == null ? void 0 : a.name), b = (y) => y.owner_full_name || y.owner_email || y.user || n("settings.chatApiUnknownUser"), d = Ce(() => {
7403
7403
  const y = /* @__PURE__ */ new Map();
7404
7404
  for (const B of v ?? []) {
7405
- const A = B.is_mine ?? B.user === (a == null ? void 0 : a.name), O = A ? "__me__" : B.user ?? "__unknown__";
7405
+ const D = B.is_mine ?? B.user === (a == null ? void 0 : a.name), O = D ? "__me__" : B.user ?? "__unknown__";
7406
7406
  y.has(O) || y.set(O, {
7407
- label: A ? n("settings.chatApiYourKeys") : B.owner_full_name || B.owner_email || B.user || n("settings.chatApiUnknownUser"),
7408
- sublabel: A ? void 0 : B.owner_email ?? void 0,
7409
- isMine: A,
7407
+ label: D ? n("settings.chatApiYourKeys") : B.owner_full_name || B.owner_email || B.user || n("settings.chatApiUnknownUser"),
7408
+ sublabel: D ? void 0 : B.owner_email ?? void 0,
7409
+ isMine: D,
7410
7410
  keys: []
7411
7411
  }), y.get(O).keys.push(B);
7412
7412
  }
7413
7413
  return Array.from(y.values()).sort(
7414
- (B, A) => B.isMine ? -1 : A.isMine ? 1 : B.label.localeCompare(A.label)
7414
+ (B, D) => B.isMine ? -1 : D.isMine ? 1 : B.label.localeCompare(D.label)
7415
7415
  );
7416
7416
  }, [v, a, n]), h = (y, B) => {
7417
7417
  B === "revoke" ? f.mutate(y) : R.mutate(y);
@@ -7783,7 +7783,7 @@ function mo() {
7783
7783
  ] });
7784
7784
  }
7785
7785
  const ya = {};
7786
- function Oo(t, n) {
7786
+ function Mo(t, n) {
7787
7787
  ya[t] = n;
7788
7788
  }
7789
7789
  function po(t, n) {
@@ -7830,7 +7830,7 @@ const go = [
7830
7830
  { path: "admin/users", element: /* @__PURE__ */ e(Gs, {}) },
7831
7831
  { path: "admin/settings", element: /* @__PURE__ */ e(mo, {}) }
7832
7832
  ], ba = [], va = [];
7833
- function qo(t, n) {
7833
+ function yo(t, n) {
7834
7834
  (n == null ? void 0 : n.area) === "top" ? ba.push(t) : va.push(t);
7835
7835
  }
7836
7836
  const Un = (t) => t.index ? "__index__" : t.path ?? "";
@@ -7842,7 +7842,7 @@ function Vn(t, n) {
7842
7842
  }
7843
7843
  return a;
7844
7844
  }
7845
- function yo() {
7845
+ function bo() {
7846
7846
  return [
7847
7847
  ...Vn(go, ba),
7848
7848
  {
@@ -7852,18 +7852,51 @@ function yo() {
7852
7852
  }
7853
7853
  ];
7854
7854
  }
7855
- function bo() {
7856
- return new Aa({
7855
+ function vo({ slug: t, parentSlug: n, linkField: a }) {
7856
+ const { name: s = "" } = ut(), o = Le();
7857
+ return se(() => {
7858
+ let i = !0;
7859
+ return T.getDocument(t, s).then((l) => {
7860
+ if (!i) return;
7861
+ const c = l == null ? void 0 : l[a];
7862
+ o(c ? `/app/${n}/${c}` : `/app/${t}`, { replace: !0 });
7863
+ }).catch(() => {
7864
+ i && o("/app", { replace: !0 });
7865
+ }), () => {
7866
+ i = !1;
7867
+ };
7868
+ }, [t, s, n, a, o]), /* @__PURE__ */ e("div", { className: "p-6 text-sm text-fg-muted", children: "…" });
7869
+ }
7870
+ async function xo() {
7871
+ try {
7872
+ const t = await L(
7873
+ "/chat-doctypes",
7874
+ { signal: AbortSignal.timeout(1500) }
7875
+ );
7876
+ for (const n of t.doctypes || []) {
7877
+ const a = n.page;
7878
+ a && a.kind === "via" && yo({
7879
+ path: `app/${n.slug}/:name`,
7880
+ element: /* @__PURE__ */ e(vo, { slug: n.slug, parentSlug: a.parent_slug, linkField: a.link_field })
7881
+ });
7882
+ }
7883
+ } catch {
7884
+ }
7885
+ }
7886
+ function No() {
7887
+ return new Da({
7857
7888
  defaultOptions: {
7858
7889
  queries: { retry: 1, refetchOnWindowFocus: !1 }
7859
7890
  }
7860
7891
  });
7861
7892
  }
7862
- function zo(t = {}) {
7893
+ async function Fo(t = {}) {
7863
7894
  const n = t.rootElement ?? document.getElementById("root");
7864
7895
  if (!n)
7865
7896
  throw new Error('bootstrap: no mount element (pass rootElement or add <div id="root">)');
7866
- const a = t.queryClient ?? bo(), s = _a(yo());
7897
+ const a = t.queryClient ?? No();
7898
+ await xo();
7899
+ const s = _a(bo());
7867
7900
  Sa(n).render(
7868
7901
  /* @__PURE__ */ e(ka, { children: /* @__PURE__ */ e(Ca, { client: a, children: /* @__PURE__ */ e(tr, { children: /* @__PURE__ */ e(Ta, { router: s }) }) }) })
7869
7902
  );
@@ -7874,23 +7907,23 @@ export {
7874
7907
  tr as AuthProvider,
7875
7908
  ha as SUPPORTED_LANGUAGES,
7876
7909
  T as api,
7877
- zo as bootstrap,
7878
- yo as buildRoutes,
7879
- To as configureApiBase,
7880
- Bo as configureBranding,
7881
- bo as createAppQueryClient,
7882
- Lo as getAllDoctypeConfigs,
7910
+ Fo as bootstrap,
7911
+ bo as buildRoutes,
7912
+ Bo as configureApiBase,
7913
+ Oo as configureBranding,
7914
+ No as createAppQueryClient,
7915
+ zo as getAllDoctypeConfigs,
7883
7916
  ir as getBranding,
7884
7917
  po as getComponent,
7885
7918
  oa as getDoctypeConfig,
7886
7919
  sr as getNavGroups,
7887
7920
  ao as getStoredLanguage,
7888
- $o as i18n,
7889
- Oo as registerComponent,
7890
- Eo as registerDoctype,
7891
- Ro as registerNavGroup,
7892
- Io as registerNavItem,
7893
- qo as registerRoute,
7921
+ Vo as i18n,
7922
+ Mo as registerComponent,
7923
+ qo as registerDoctype,
7924
+ Eo as registerNavGroup,
7925
+ Lo as registerNavItem,
7926
+ yo as registerRoute,
7894
7927
  L as request,
7895
7928
  st as useAuth
7896
7929
  };