@mulmoclaude/accounting-plugin 1.2.1 → 1.3.0

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.
Files changed (42) hide show
  1. package/dist/server/bodyFields.d.ts +8 -1
  2. package/dist/server/bodyFields.d.ts.map +1 -1
  3. package/dist/server/io.d.ts.map +1 -1
  4. package/dist/server/journal.d.ts +7 -0
  5. package/dist/server/journal.d.ts.map +1 -1
  6. package/dist/server/report.d.ts.map +1 -1
  7. package/dist/server/router.d.ts.map +1 -1
  8. package/dist/server/service.d.ts.map +1 -1
  9. package/dist/server/snapshotCache.d.ts.map +1 -1
  10. package/dist/server/timeSeries.d.ts.map +1 -1
  11. package/dist/server.cjs +364 -323
  12. package/dist/server.cjs.map +1 -1
  13. package/dist/server.js +364 -323
  14. package/dist/server.js.map +1 -1
  15. package/dist/shared/fiscalYear.d.ts.map +1 -1
  16. package/dist/shared/types.d.ts +2 -1
  17. package/dist/shared/types.d.ts.map +1 -1
  18. package/dist/{shared-qp9j-GTD.js → shared-BZAAF-I4.js} +16 -11
  19. package/dist/shared-BZAAF-I4.js.map +1 -0
  20. package/dist/{shared-C9K9ZkfK.cjs → shared-BpFVwa6Y.cjs} +27 -10
  21. package/dist/shared-BpFVwa6Y.cjs.map +1 -0
  22. package/dist/shared.cjs +2 -1
  23. package/dist/shared.js +2 -2
  24. package/dist/style.css +3 -3
  25. package/dist/vue/Preview.vue.d.ts.map +1 -1
  26. package/dist/vue/View.vue.d.ts.map +1 -1
  27. package/dist/vue/components/BalanceSheet.vue.d.ts.map +1 -1
  28. package/dist/vue/components/BookSwitcher.vue.d.ts.map +1 -1
  29. package/dist/vue/components/DateRangePicker.vue.d.ts.map +1 -1
  30. package/dist/vue/components/NewBookForm.vue.d.ts.map +1 -1
  31. package/dist/vue/components/OpeningBalancesForm.vue.d.ts.map +1 -1
  32. package/dist/vue/components/accountNumbering.d.ts.map +1 -1
  33. package/dist/vue/previewSummary.d.ts +15 -0
  34. package/dist/vue/previewSummary.d.ts.map +1 -0
  35. package/dist/vue/useAccountingChannel.d.ts.map +1 -1
  36. package/dist/vue.cjs +138 -89
  37. package/dist/vue.cjs.map +1 -1
  38. package/dist/vue.js +138 -89
  39. package/dist/vue.js.map +1 -1
  40. package/package.json +3 -3
  41. package/dist/shared-C9K9ZkfK.cjs.map +0 -1
  42. package/dist/shared-qp9j-GTD.js.map +0 -1
package/dist/vue.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as resolveFiscalYearEnd, B as ACCOUNTING_API, C as currentFiscalYearRange, E as fiscalYearEndMonthLabel, F as ACCOUNTING_BOOKS_CHANNEL, L as bookChannel, M as errorMessage, O as previousFiscalYearRange, S as FISCAL_YEAR_END_MONTHS, V as ACCOUNTING_ACTIONS, _ as SUPPORTED_COUNTRY_CODES, a as localDateString, b as localizedCountryName, c as previousMonthString, d as formatAmountNumeric, i as lastMonthOfPreviousQuarterString, k as previousQuarterRange, l as SUPPORTED_CURRENCY_CODES, m as localizedCurrencyName, o as localMonthString, p as inputStepFor, r as decemberOfPreviousYearString, u as formatAmount, v as countryHasFeature, w as currentQuarterRange, y as isSupportedCountryCode } from "./shared-qp9j-GTD.js";
1
+ import { A as resolveFiscalYearEnd, C as currentFiscalYearRange, E as fiscalYearEndMonthLabel, F as isUnknownArray, H as ACCOUNTING_API, I as ACCOUNTING_BOOKS_CHANNEL, L as BOOK_EVENT_KINDS, M as errorMessage, O as previousFiscalYearRange, P as isRecord, R as bookChannel, S as FISCAL_YEAR_END_MONTHS, U as ACCOUNTING_ACTIONS, _ as SUPPORTED_COUNTRY_CODES, a as localDateString, b as localizedCountryName, c as previousMonthString, d as formatAmountNumeric, i as lastMonthOfPreviousQuarterString, k as previousQuarterRange, l as SUPPORTED_CURRENCY_CODES, m as localizedCurrencyName, o as localMonthString, p as inputStepFor, r as decemberOfPreviousYearString, u as formatAmount, v as countryHasFeature, w as currentQuarterRange, y as isSupportedCountryCode, z as ACCOUNT_TYPES } from "./shared-BZAAF-I4.js";
2
2
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, onMounted, onUnmounted, openBlock, reactive, ref, renderList, toDisplayString, unref, vModelSelect, vModelText, watch, withDirectives, withKeys, withModifiers } from "vue";
3
3
  import { createPluginI18n } from "@mulmoclaude/core/plugin-vue/i18n";
4
4
  //#region src/vue/hostContext.ts
@@ -1844,7 +1844,7 @@ var NewBookForm_default = /* @__PURE__ */ defineComponent({
1844
1844
  function regionFromLocaleTag(tag) {
1845
1845
  try {
1846
1846
  const { region } = new Intl.Locale(tag).maximize();
1847
- if (region && SUPPORTED_COUNTRY_CODES.includes(region)) return region;
1847
+ if (isSupportedCountryCode(region)) return region;
1848
1848
  } catch {}
1849
1849
  return "";
1850
1850
  }
@@ -2015,7 +2015,8 @@ var BookSwitcher_default = /* @__PURE__ */ defineComponent({
2015
2015
  return `${book.name} (${suffix})`;
2016
2016
  }
2017
2017
  function onSelect(event) {
2018
- const target = event.target;
2018
+ const { target } = event;
2019
+ if (!(target instanceof HTMLSelectElement)) return;
2019
2020
  const bookId = target.value;
2020
2021
  if (bookId === NEW_BOOK_SENTINEL) {
2021
2022
  target.value = props.modelValue;
@@ -2139,7 +2140,10 @@ var DateRangePicker_default = /* @__PURE__ */ defineComponent({
2139
2140
  if (rangesEqual(value, UNBOUNDED_RANGE)) return "all";
2140
2141
  return "";
2141
2142
  });
2142
- function onShortcutChange(raw) {
2143
+ function onShortcutChange(event) {
2144
+ const { target } = event;
2145
+ if (!(target instanceof HTMLSelectElement)) return;
2146
+ const raw = target.value;
2143
2147
  const today = /* @__PURE__ */ new Date();
2144
2148
  if (raw === "currentQuarter") emit("update:modelValue", currentQuarterRange(props.fiscalYearEnd, today));
2145
2149
  else if (raw === "previousQuarter") emit("update:modelValue", previousQuarterRange(props.fiscalYearEnd, today));
@@ -2150,16 +2154,20 @@ var DateRangePicker_default = /* @__PURE__ */ defineComponent({
2150
2154
  if (lifetime) emit("update:modelValue", lifetime);
2151
2155
  } else if (raw === "all") emit("update:modelValue", UNBOUNDED_RANGE);
2152
2156
  }
2153
- function onFromChange(value) {
2157
+ function onFromChange(event) {
2158
+ const { target } = event;
2159
+ if (!(target instanceof HTMLInputElement)) return;
2154
2160
  emit("update:modelValue", {
2155
- from: value,
2161
+ from: target.value,
2156
2162
  to: props.modelValue.to
2157
2163
  });
2158
2164
  }
2159
- function onToChange(value) {
2165
+ function onToChange(event) {
2166
+ const { target } = event;
2167
+ if (!(target instanceof HTMLInputElement)) return;
2160
2168
  emit("update:modelValue", {
2161
2169
  from: props.modelValue.from,
2162
- to: value
2170
+ to: target.value
2163
2171
  });
2164
2172
  }
2165
2173
  return (_ctx, _cache) => {
@@ -2168,9 +2176,9 @@ var DateRangePicker_default = /* @__PURE__ */ defineComponent({
2168
2176
  value: selectedShortcut.value,
2169
2177
  class: "h-8 px-2 rounded border border-gray-300 text-sm bg-white",
2170
2178
  "data-testid": "accounting-daterange-shortcut",
2171
- onChange: _cache[0] || (_cache[0] = ($event) => onShortcutChange($event.target.value))
2179
+ onChange: onShortcutChange
2172
2180
  }, [
2173
- _cache[3] || (_cache[3] = createElementVNode("option", {
2181
+ _cache[0] || (_cache[0] = createElementVNode("option", {
2174
2182
  value: "",
2175
2183
  hidden: ""
2176
2184
  }, null, -1)),
@@ -2186,14 +2194,14 @@ var DateRangePicker_default = /* @__PURE__ */ defineComponent({
2186
2194
  type: "date",
2187
2195
  class: "h-8 px-2 rounded border border-gray-300 text-sm",
2188
2196
  "data-testid": "accounting-daterange-from",
2189
- onInput: _cache[1] || (_cache[1] = ($event) => onFromChange($event.target.value))
2197
+ onInput: onFromChange
2190
2198
  }, null, 40, _hoisted_11$9)]),
2191
2199
  createElementVNode("label", _hoisted_12$9, [createTextVNode(toDisplayString(unref(t)("pluginAccounting.dateRange.toLabel")) + " ", 1), createElementVNode("input", {
2192
2200
  value: __props.modelValue.to,
2193
2201
  type: "date",
2194
2202
  class: "h-8 px-2 rounded border border-gray-300 text-sm",
2195
2203
  "data-testid": "accounting-daterange-to",
2196
- onInput: _cache[2] || (_cache[2] = ($event) => onToChange($event.target.value))
2204
+ onInput: onToChange
2197
2205
  }, null, 40, _hoisted_13$9)])
2198
2206
  ]);
2199
2207
  };
@@ -2226,9 +2234,8 @@ function isValidAccountCode(code) {
2226
2234
  }
2227
2235
  function typeForCode(code) {
2228
2236
  if (!isValidAccountCode(code)) return null;
2229
- const leading = Number.parseInt(code[0], 10);
2230
- for (const [type, prefix] of Object.entries(ACCOUNT_TYPE_PREFIX)) if (prefix === leading) return type;
2231
- return null;
2237
+ const leading = Number.parseInt(code.charAt(0), 10);
2238
+ return ACCOUNT_TYPES.find((type) => ACCOUNT_TYPE_PREFIX[type] === leading) ?? null;
2232
2239
  }
2233
2240
  function codeMatchesType(code, type) {
2234
2241
  return typeForCode(code) === type;
@@ -2640,7 +2647,7 @@ var AccountsModal_default = /* @__PURE__ */ defineComponent({
2640
2647
  }
2641
2648
  function bindNewEditor(node, sectionType) {
2642
2649
  if (sectionType !== draft.value.type) return;
2643
- newEditorWrapper.value = node ?? null;
2650
+ newEditorWrapper.value = node instanceof HTMLDivElement ? node : null;
2644
2651
  }
2645
2652
  function onEdit(account) {
2646
2653
  addingNew.value = false;
@@ -3749,12 +3756,21 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3749
3756
  credit: null
3750
3757
  };
3751
3758
  }
3759
+ const accountRows = computed(() => bsAccounts.value.flatMap((account) => {
3760
+ const row = rows.value[account.code];
3761
+ return row ? [{
3762
+ account,
3763
+ row
3764
+ }] : [];
3765
+ }));
3752
3766
  function onDebitInput(code) {
3753
3767
  const row = rows.value[code];
3768
+ if (!row) return;
3754
3769
  if (row.debit !== null && row.debit !== 0) row.credit = null;
3755
3770
  }
3756
3771
  function onCreditInput(code) {
3757
3772
  const row = rows.value[code];
3773
+ if (!row) return;
3758
3774
  if (row.credit !== null && row.credit !== 0) row.debit = null;
3759
3775
  }
3760
3776
  const imbalance = computed(() => {
@@ -3778,12 +3794,13 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3778
3794
  for (const account of bsAccounts.value) {
3779
3795
  const row = rows.value[account.code];
3780
3796
  if (!row) continue;
3781
- const debitOk = isPositiveAmount(row.debit);
3782
- const creditOk = isPositiveAmount(row.credit);
3797
+ const { debit, credit } = row;
3798
+ const debitOk = isPositiveAmount(debit);
3799
+ const creditOk = isPositiveAmount(credit);
3783
3800
  if (!debitOk && !creditOk) continue;
3784
3801
  const line = { accountCode: account.code };
3785
- if (debitOk) line.debit = row.debit;
3786
- if (creditOk) line.credit = row.credit;
3802
+ if (debitOk) line.debit = debit;
3803
+ if (creditOk) line.credit = credit;
3787
3804
  out.push(line);
3788
3805
  }
3789
3806
  return out;
@@ -3873,7 +3890,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3873
3890
  createElementVNode("th", _hoisted_11$5, toDisplayString(unref(t)("pluginAccounting.entryForm.accountLabel")), 1),
3874
3891
  createElementVNode("th", _hoisted_12$5, toDisplayString(unref(t)("pluginAccounting.entryForm.debitLabel")), 1),
3875
3892
  createElementVNode("th", _hoisted_13$5, toDisplayString(unref(t)("pluginAccounting.entryForm.creditLabel")), 1)
3876
- ])]), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(bsAccounts.value, (account) => {
3893
+ ])]), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(accountRows.value, ({ account, row }) => {
3877
3894
  return openBlock(), createElementBlock("tr", {
3878
3895
  key: account.code,
3879
3896
  class: "border-b border-gray-100"
@@ -3884,7 +3901,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3884
3901
  createElementVNode("span", _hoisted_16$4, toDisplayString(account.type), 1)
3885
3902
  ]),
3886
3903
  createElementVNode("td", _hoisted_17$4, [withDirectives(createElementVNode("input", {
3887
- "onUpdate:modelValue": ($event) => rows.value[account.code].debit = $event,
3904
+ "onUpdate:modelValue": ($event) => row.debit = $event,
3888
3905
  type: "number",
3889
3906
  step: step.value,
3890
3907
  min: "0",
@@ -3893,12 +3910,12 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3893
3910
  onInput: ($event) => onDebitInput(account.code)
3894
3911
  }, null, 40, _hoisted_18$4), [[
3895
3912
  vModelText,
3896
- rows.value[account.code].debit,
3913
+ row.debit,
3897
3914
  void 0,
3898
3915
  { number: true }
3899
3916
  ]])]),
3900
3917
  createElementVNode("td", _hoisted_19$4, [withDirectives(createElementVNode("input", {
3901
- "onUpdate:modelValue": ($event) => rows.value[account.code].credit = $event,
3918
+ "onUpdate:modelValue": ($event) => row.credit = $event,
3902
3919
  type: "number",
3903
3920
  step: step.value,
3904
3921
  min: "0",
@@ -3907,7 +3924,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3907
3924
  onInput: ($event) => onCreditInput(account.code)
3908
3925
  }, null, 40, _hoisted_20$4), [[
3909
3926
  vModelText,
3910
- rows.value[account.code].credit,
3927
+ row.credit,
3911
3928
  void 0,
3912
3929
  { number: true }
3913
3930
  ]])])
@@ -3933,7 +3950,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
3933
3950
  }, null, 8, ["book-id", "accounts"])) : createCommentVNode("", true)], 64);
3934
3951
  };
3935
3952
  }
3936
- }), [["__scopeId", "data-v-530643ac"]]);
3953
+ }), [["__scopeId", "data-v-eb577d9f"]]);
3937
3954
  //#endregion
3938
3955
  //#region src/vue/components/AccountsList.vue?vue&type=script&setup=true&lang.ts
3939
3956
  var _hoisted_1$6 = {
@@ -4316,7 +4333,10 @@ var BalanceSheet_default = /* @__PURE__ */ defineComponent({
4316
4333
  if (value === decemberOfPreviousYearString(now)) return "lastYear";
4317
4334
  return "";
4318
4335
  });
4319
- function onShortcutChange(raw) {
4336
+ function onShortcutChange(event) {
4337
+ const { target } = event;
4338
+ if (!(target instanceof HTMLSelectElement)) return;
4339
+ const raw = target.value;
4320
4340
  const now = /* @__PURE__ */ new Date();
4321
4341
  if (raw === "thisMonth") period.value = localMonthString(now);
4322
4342
  else if (raw === "lastMonth") period.value = previousMonthString(now);
@@ -4354,9 +4374,9 @@ var BalanceSheet_default = /* @__PURE__ */ defineComponent({
4354
4374
  value: selectedShortcut.value,
4355
4375
  class: "h-8 px-2 rounded border border-gray-300 text-sm bg-white",
4356
4376
  "data-testid": "accounting-bs-shortcut",
4357
- onChange: _cache[0] || (_cache[0] = ($event) => onShortcutChange($event.target.value))
4377
+ onChange: onShortcutChange
4358
4378
  }, [
4359
- _cache[2] || (_cache[2] = createElementVNode("option", {
4379
+ _cache[1] || (_cache[1] = createElementVNode("option", {
4360
4380
  value: "",
4361
4381
  hidden: ""
4362
4382
  }, null, -1)),
@@ -4366,7 +4386,7 @@ var BalanceSheet_default = /* @__PURE__ */ defineComponent({
4366
4386
  createElementVNode("option", _hoisted_8$3, toDisplayString(unref(t)("pluginAccounting.balanceSheet.lastYear")), 1)
4367
4387
  ], 40, _hoisted_4$3)]),
4368
4388
  createElementVNode("label", _hoisted_9$3, [createTextVNode(toDisplayString(unref(t)("pluginAccounting.balanceSheet.asOfLabel")) + " ", 1), withDirectives(createElementVNode("input", {
4369
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => period.value = $event),
4389
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => period.value = $event),
4370
4390
  type: "month",
4371
4391
  class: "h-8 px-2 rounded border border-gray-300 text-sm",
4372
4392
  "data-testid": "accounting-bs-period"
@@ -4374,7 +4394,7 @@ var BalanceSheet_default = /* @__PURE__ */ defineComponent({
4374
4394
  createElementVNode("button", {
4375
4395
  class: "h-8 px-2.5 rounded border border-gray-300 text-sm text-gray-600 hover:bg-gray-50",
4376
4396
  onClick: refresh
4377
- }, [..._cache[3] || (_cache[3] = [createElementVNode("span", { class: "material-icons text-base align-middle" }, "refresh", -1)])])
4397
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("span", { class: "material-icons text-base align-middle" }, "refresh", -1)])])
4378
4398
  ]), loading.value ? (openBlock(), createElementBlock("p", _hoisted_10$3, toDisplayString(unref(t)("pluginAccounting.common.loading")), 1)) : error.value ? (openBlock(), createElementBlock("p", _hoisted_11$3, toDisplayString(unref(t)("pluginAccounting.common.error", { error: error.value })), 1)) : balanceSheet.value ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [createElementVNode("div", _hoisted_12$3, [(openBlock(true), createElementBlock(Fragment, null, renderList(balanceSheet.value.sections, (section) => {
4379
4399
  return openBlock(), createElementBlock("section", {
4380
4400
  key: section.type,
@@ -4827,6 +4847,19 @@ var BookSettings_default = /* @__PURE__ */ defineComponent({
4827
4847
  });
4828
4848
  //#endregion
4829
4849
  //#region src/vue/useAccountingChannel.ts
4850
+ var BOOK_EVENT_KIND_VALUES = Object.values(BOOK_EVENT_KINDS);
4851
+ /** The host hands subscribers an `unknown`, so rebuild the payload from
4852
+ * the fields we can prove rather than trusting the publisher's type. */
4853
+ function toBookChannelPayload(data) {
4854
+ if (typeof data !== "object" || data === null || !("kind" in data)) return null;
4855
+ const kind = BOOK_EVENT_KIND_VALUES.find((candidate) => candidate === data.kind);
4856
+ if (kind === void 0) return null;
4857
+ const period = "period" in data && typeof data.period === "string" ? data.period : void 0;
4858
+ return period === void 0 ? { kind } : {
4859
+ kind,
4860
+ period
4861
+ };
4862
+ }
4830
4863
  function useAccountingChannel(bookId, onPayload) {
4831
4864
  const version = ref(0);
4832
4865
  let unsubscribe = null;
@@ -4836,9 +4869,9 @@ function useAccountingChannel(bookId, onPayload) {
4836
4869
  version.value = 0;
4837
4870
  if (!nextBookId) return;
4838
4871
  unsubscribe = hostSubscribe(bookChannel(nextBookId), (data) => {
4839
- const event = data;
4840
4872
  version.value += 1;
4841
- onPayload?.(event);
4873
+ const event = toBookChannelPayload(data);
4874
+ if (event) onPayload?.(event);
4842
4875
  });
4843
4876
  }
4844
4877
  watch(bookId, bind, { immediate: true });
@@ -4954,7 +4987,7 @@ var View_default = /* @__PURE__ */ defineComponent({
4954
4987
  }
4955
4988
  ];
4956
4989
  function isTabKey(value) {
4957
- return typeof value === "string" && TAB_KEYS.includes(value);
4990
+ return TAB_KEYS.some((key) => key === value);
4958
4991
  }
4959
4992
  const initialPayload = computed(() => props.selectedResult?.data ?? props.selectedResult?.jsonData ?? {});
4960
4993
  const currentTab = ref(computed(() => isTabKey(initialPayload.value.initialTab) ? initialPayload.value.initialTab : "journal").value);
@@ -4977,10 +5010,11 @@ var View_default = /* @__PURE__ */ defineComponent({
4977
5010
  const { version: bookVersion } = useAccountingChannel(activeBookId);
4978
5011
  useAccountingBooksChannel(() => void refetchBooks());
4979
5012
  function pickInitialBookId() {
4980
- if (books.value.length === 0) return null;
5013
+ const [firstBook] = books.value;
5014
+ if (!firstBook) return null;
4981
5015
  const requested = initialPayload.value.bookId;
4982
5016
  if (requested && books.value.some((book) => book.id === requested)) return requested;
4983
- return books.value[0].id;
5017
+ return firstBook.id;
4984
5018
  }
4985
5019
  async function refetchBooks() {
4986
5020
  loadingBooks.value = true;
@@ -5259,6 +5293,73 @@ var View_default = /* @__PURE__ */ defineComponent({
5259
5293
  }
5260
5294
  });
5261
5295
  //#endregion
5296
+ //#region src/vue/previewSummary.ts
5297
+ var optionalString = (value) => typeof value === "string" ? value : void 0;
5298
+ var optionalNumber = (value) => typeof value === "number" ? value : void 0;
5299
+ function summariseError(json, translate) {
5300
+ const error = optionalString(json.error);
5301
+ if (error === void 0) return null;
5302
+ return translate("pluginAccounting.previewError", { error });
5303
+ }
5304
+ function summariseEntry(json, translate) {
5305
+ const [first] = isUnknownArray(json.entries) ? json.entries : [];
5306
+ const entry = isRecord(first) ? first : void 0;
5307
+ const entryId = optionalString(entry?.id);
5308
+ const date = optionalString(entry?.date);
5309
+ if (!entryId || !date) return null;
5310
+ return translate("pluginAccounting.preview.entry", { date });
5311
+ }
5312
+ function summarisePl(json, translate) {
5313
+ const { profitLoss } = json;
5314
+ if (!isRecord(profitLoss)) return null;
5315
+ const netIncome = optionalNumber(profitLoss.netIncome);
5316
+ if (netIncome === void 0) return null;
5317
+ return translate("pluginAccounting.preview.pl", {
5318
+ from: optionalString(profitLoss.from) ?? "?",
5319
+ to: optionalString(profitLoss.to) ?? "?",
5320
+ net: formatAmountNumeric(netIncome)
5321
+ });
5322
+ }
5323
+ function summariseBs(json, translate) {
5324
+ const { balanceSheet } = json;
5325
+ if (!isRecord(balanceSheet)) return null;
5326
+ const date = optionalString(balanceSheet.asOf);
5327
+ const sections = isUnknownArray(balanceSheet.sections) ? balanceSheet.sections : void 0;
5328
+ if (!date || !sections) return null;
5329
+ const assets = sections.find((section) => isRecord(section) && section.type === "asset");
5330
+ return translate("pluginAccounting.preview.bs", {
5331
+ date,
5332
+ assets: isRecord(assets) ? formatAmountNumeric(optionalNumber(assets.total) ?? 0) : "?"
5333
+ });
5334
+ }
5335
+ function summariseBook(json, translate) {
5336
+ const { book } = json;
5337
+ if (!isRecord(book)) return null;
5338
+ const bookId = optionalString(book.id);
5339
+ const name = optionalString(book.name);
5340
+ if (!bookId || !name) return null;
5341
+ return translate("pluginAccounting.preview.bookCreated", {
5342
+ name,
5343
+ id: bookId
5344
+ });
5345
+ }
5346
+ function summariseFallback(json, translate) {
5347
+ const bookId = optionalString(json.bookId);
5348
+ if (bookId !== void 0) return translate("pluginAccounting.previewSummary", { bookId });
5349
+ return translate("pluginAccounting.previewGeneric");
5350
+ }
5351
+ /** Merge the two props a host might carry the payload on. `isRecord` rejects
5352
+ * arrays, which the old `typeof value === "object"` check spread into the
5353
+ * payload. */
5354
+ var asPayload = (value) => isRecord(value) ? value : {};
5355
+ function summarisePreview(data, jsonData, translate) {
5356
+ const json = {
5357
+ ...asPayload(data),
5358
+ ...asPayload(jsonData)
5359
+ };
5360
+ return summariseError(json, translate) ?? summariseEntry(json, translate) ?? summarisePl(json, translate) ?? summariseBs(json, translate) ?? summariseBook(json, translate) ?? summariseFallback(json, translate);
5361
+ }
5362
+ //#endregion
5262
5363
  //#region src/vue/Preview.vue?vue&type=script&setup=true&lang.ts
5263
5364
  var _hoisted_1 = {
5264
5365
  class: "text-sm text-gray-700",
@@ -5275,59 +5376,7 @@ var Preview_default = /* @__PURE__ */ defineComponent({
5275
5376
  setup(__props) {
5276
5377
  const { t } = useAccountingI18n();
5277
5378
  const props = __props;
5278
- function summariseError(json) {
5279
- const { error } = json;
5280
- if (typeof error !== "string") return null;
5281
- return t("pluginAccounting.previewError", { error });
5282
- }
5283
- function summariseEntry(json) {
5284
- const { entries } = json;
5285
- if (!Array.isArray(entries) || entries.length === 0) return null;
5286
- const [first] = entries;
5287
- if (!first?.id || !first?.date) return null;
5288
- return t("pluginAccounting.preview.entry", { date: first.date });
5289
- }
5290
- function summarisePl(json) {
5291
- const { profitLoss } = json;
5292
- if (!profitLoss || typeof profitLoss.netIncome !== "number") return null;
5293
- return t("pluginAccounting.preview.pl", {
5294
- from: profitLoss.from ?? "?",
5295
- to: profitLoss.to ?? "?",
5296
- net: formatAmountNumeric(profitLoss.netIncome)
5297
- });
5298
- }
5299
- function summariseBs(json) {
5300
- const { balanceSheet } = json;
5301
- if (!balanceSheet?.asOf || !balanceSheet.sections) return null;
5302
- const assets = balanceSheet.sections.find((section) => section.type === "asset");
5303
- return t("pluginAccounting.preview.bs", {
5304
- date: balanceSheet.asOf,
5305
- assets: assets ? formatAmountNumeric(assets.total ?? 0) : "?"
5306
- });
5307
- }
5308
- function summariseBook(json) {
5309
- const { book } = json;
5310
- if (!book?.id || !book?.name) return null;
5311
- return t("pluginAccounting.preview.bookCreated", {
5312
- name: book.name,
5313
- id: book.id
5314
- });
5315
- }
5316
- function summariseFallback(json) {
5317
- const { bookId } = json;
5318
- if (typeof bookId === "string") return t("pluginAccounting.previewSummary", { bookId });
5319
- return t("pluginAccounting.previewGeneric");
5320
- }
5321
- function asObject(value) {
5322
- return value && typeof value === "object" ? value : {};
5323
- }
5324
- const summary = computed(() => {
5325
- const json = {
5326
- ...asObject(props.data),
5327
- ...asObject(props.jsonData)
5328
- };
5329
- return summariseError(json) ?? summariseEntry(json) ?? summarisePl(json) ?? summariseBs(json) ?? summariseBook(json) ?? summariseFallback(json);
5330
- });
5379
+ const summary = computed(() => summarisePreview(props.data, props.jsonData, t));
5331
5380
  return (_ctx, _cache) => {
5332
5381
  return openBlock(), createElementBlock("div", _hoisted_1, [_cache[0] || (_cache[0] = createElementVNode("span", { class: "material-icons text-base align-middle mr-1" }, "account_balance", -1)), createElementVNode("span", null, toDisplayString(summary.value), 1)]);
5333
5382
  };