@mulmoclaude/accounting-plugin 2.1.0 → 3.0.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.
- package/README.md +37 -0
- package/dist/server/context.d.ts +45 -3
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/eventPublisher.d.ts +9 -4
- package/dist/server/eventPublisher.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/router.d.ts +27 -3
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/snapshotCache.d.ts +3 -3
- package/dist/server/snapshotCache.d.ts.map +1 -1
- package/dist/server.cjs +149 -80
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +149 -80
- package/dist/server.js.map +1 -1
- package/dist/shared/api.d.ts +12 -0
- package/dist/shared/api.d.ts.map +1 -1
- package/dist/shared/channels.d.ts +22 -2
- package/dist/shared/channels.d.ts.map +1 -1
- package/dist/{shared-BZAAF-I4.js → shared-BccLo0Ux.js} +39 -5
- package/dist/shared-BccLo0Ux.js.map +1 -0
- package/dist/{shared-BpFVwa6Y.cjs → shared-Dgt-i23T.cjs} +50 -4
- package/dist/shared-Dgt-i23T.cjs.map +1 -0
- package/dist/shared.cjs +3 -1
- package/dist/shared.js +2 -2
- package/dist/style.css +19 -10
- package/dist/vue/View.vue.d.ts +5 -0
- package/dist/vue/View.vue.d.ts.map +1 -1
- package/dist/vue/api.d.ts +132 -100
- package/dist/vue/api.d.ts.map +1 -1
- package/dist/vue/components/AccountsModal.vue.d.ts.map +1 -1
- package/dist/vue/components/BalanceSheet.vue.d.ts.map +1 -1
- package/dist/vue/components/BookSettings.vue.d.ts.map +1 -1
- package/dist/vue/components/JournalEntryForm.vue.d.ts.map +1 -1
- package/dist/vue/components/JournalList.vue.d.ts.map +1 -1
- package/dist/vue/components/Ledger.vue.d.ts.map +1 -1
- package/dist/vue/components/NewBookForm.vue.d.ts.map +1 -1
- package/dist/vue/components/OpeningBalancesForm.vue.d.ts.map +1 -1
- package/dist/vue/components/ProfitLoss.vue.d.ts.map +1 -1
- package/dist/vue/hostContext.d.ts +15 -0
- package/dist/vue/hostContext.d.ts.map +1 -1
- package/dist/vue/useAccountingChannel.d.ts +13 -3
- package/dist/vue/useAccountingChannel.d.ts.map +1 -1
- package/dist/vue.cjs +227 -98
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +228 -99
- package/dist/vue.js.map +1 -1
- package/package.json +4 -3
- package/dist/shared-BZAAF-I4.js.map +0 -1
- package/dist/shared-BpFVwa6Y.cjs.map +0 -1
package/dist/vue.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as resolveFiscalYearEnd, C as currentFiscalYearRange, E as fiscalYearEndMonthLabel, F as isUnknownArray,
|
|
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";
|
|
1
|
+
import { A as resolveFiscalYearEnd, B as ACCOUNT_TYPES, C as currentFiscalYearRange, E as fiscalYearEndMonthLabel, F as isUnknownArray, G as ACCOUNTING_ACTIONS, 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_API, W as ACCOUNTING_PROJECT_FIELD, _ 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 booksChannel } from "./shared-BccLo0Ux.js";
|
|
2
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, nextTick, normalizeClass, onMounted, onUnmounted, openBlock, provide, 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
|
|
5
5
|
var ctx = null;
|
|
@@ -22,6 +22,12 @@ function hostSubscribe(channel, handler) {
|
|
|
22
22
|
function hostLocaleTag() {
|
|
23
23
|
return requireCtx().localeTag();
|
|
24
24
|
}
|
|
25
|
+
/** The host's opaque project id for the mounted surface, or `null` when
|
|
26
|
+
* the host serves a single root (MulmoClaude) or the surface belongs to
|
|
27
|
+
* its default one. */
|
|
28
|
+
function hostProjectScope() {
|
|
29
|
+
return ctx?.projectScope?.() ?? null;
|
|
30
|
+
}
|
|
25
31
|
//#endregion
|
|
26
32
|
//#region src/vue/lang/index.ts
|
|
27
33
|
/** The plugin's i18n composable — a drop-in for vue-i18n's `useI18n()` over the
|
|
@@ -1722,78 +1728,163 @@ var useAccountingI18n = createPluginI18n({
|
|
|
1722
1728
|
//#region src/vue/api.ts
|
|
1723
1729
|
var DISPATCH_URL = ACCOUNTING_API.dispatch.path;
|
|
1724
1730
|
var DISPATCH_METHOD = ACCOUNTING_API.dispatch.method;
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
}
|
|
1743
|
-
function deleteBook(bookId) {
|
|
1744
|
-
return call(ACCOUNTING_ACTIONS.deleteBook, {
|
|
1745
|
-
bookId,
|
|
1746
|
-
confirm: true
|
|
1747
|
-
});
|
|
1748
|
-
}
|
|
1749
|
-
function getAccounts(bookId) {
|
|
1750
|
-
return call(ACCOUNTING_ACTIONS.getAccounts, { bookId });
|
|
1751
|
-
}
|
|
1752
|
-
function upsertAccount(account, bookId) {
|
|
1753
|
-
return call(ACCOUNTING_ACTIONS.upsertAccount, {
|
|
1754
|
-
account,
|
|
1755
|
-
bookId
|
|
1756
|
-
});
|
|
1757
|
-
}
|
|
1758
|
-
function addEntries(input) {
|
|
1759
|
-
return call(ACCOUNTING_ACTIONS.addEntries, input);
|
|
1760
|
-
}
|
|
1761
|
-
function voidEntry(input) {
|
|
1762
|
-
return call(ACCOUNTING_ACTIONS.voidEntry, input);
|
|
1731
|
+
/** The one call every helper goes through, bound to a scope RESOLVER
|
|
1732
|
+
* rather than a fixed scope, so the host-scoped client tracks a host
|
|
1733
|
+
* that changes its active project while a pinned one does not. Absent
|
|
1734
|
+
* (single-root host) every request body is byte-identical to what it
|
|
1735
|
+
* was before scopes existed. */
|
|
1736
|
+
function makeCall(getScope) {
|
|
1737
|
+
return function call(action, args = {}) {
|
|
1738
|
+
const project = getScope();
|
|
1739
|
+
const scopeField = project ? { [ACCOUNTING_PROJECT_FIELD]: project } : {};
|
|
1740
|
+
return hostApiCall(DISPATCH_URL, {
|
|
1741
|
+
method: DISPATCH_METHOD,
|
|
1742
|
+
body: {
|
|
1743
|
+
action,
|
|
1744
|
+
...args,
|
|
1745
|
+
...scopeField
|
|
1746
|
+
}
|
|
1747
|
+
});
|
|
1748
|
+
};
|
|
1763
1749
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1750
|
+
/** Books — the list and its lifecycle. */
|
|
1751
|
+
function booksApi(call) {
|
|
1752
|
+
function getBooks() {
|
|
1753
|
+
return call(ACCOUNTING_ACTIONS.getBooks);
|
|
1754
|
+
}
|
|
1755
|
+
function createBook(input) {
|
|
1756
|
+
return call(ACCOUNTING_ACTIONS.createBook, input);
|
|
1757
|
+
}
|
|
1758
|
+
function updateBook(input) {
|
|
1759
|
+
return call(ACCOUNTING_ACTIONS.updateBook, input);
|
|
1760
|
+
}
|
|
1761
|
+
function deleteBook(bookId) {
|
|
1762
|
+
return call(ACCOUNTING_ACTIONS.deleteBook, {
|
|
1763
|
+
bookId,
|
|
1764
|
+
confirm: true
|
|
1765
|
+
});
|
|
1766
|
+
}
|
|
1767
|
+
return {
|
|
1768
|
+
getBooks,
|
|
1769
|
+
createBook,
|
|
1770
|
+
updateBook,
|
|
1771
|
+
deleteBook
|
|
1772
|
+
};
|
|
1766
1773
|
}
|
|
1767
|
-
|
|
1768
|
-
|
|
1774
|
+
/** The chart of accounts. */
|
|
1775
|
+
function accountsApi(call) {
|
|
1776
|
+
function getAccounts(bookId) {
|
|
1777
|
+
return call(ACCOUNTING_ACTIONS.getAccounts, { bookId });
|
|
1778
|
+
}
|
|
1779
|
+
function upsertAccount(account, bookId) {
|
|
1780
|
+
return call(ACCOUNTING_ACTIONS.upsertAccount, {
|
|
1781
|
+
account,
|
|
1782
|
+
bookId
|
|
1783
|
+
});
|
|
1784
|
+
}
|
|
1785
|
+
return {
|
|
1786
|
+
getAccounts,
|
|
1787
|
+
upsertAccount
|
|
1788
|
+
};
|
|
1769
1789
|
}
|
|
1770
|
-
|
|
1771
|
-
|
|
1790
|
+
/** Journal entries and the opening balance. */
|
|
1791
|
+
function journalApi(call) {
|
|
1792
|
+
function addEntries(input) {
|
|
1793
|
+
return call(ACCOUNTING_ACTIONS.addEntries, input);
|
|
1794
|
+
}
|
|
1795
|
+
function voidEntry(input) {
|
|
1796
|
+
return call(ACCOUNTING_ACTIONS.voidEntry, input);
|
|
1797
|
+
}
|
|
1798
|
+
function getJournalEntries(input) {
|
|
1799
|
+
return call(ACCOUNTING_ACTIONS.getJournalEntries, input);
|
|
1800
|
+
}
|
|
1801
|
+
function getOpeningBalances(bookId) {
|
|
1802
|
+
return call(ACCOUNTING_ACTIONS.getOpeningBalances, { bookId });
|
|
1803
|
+
}
|
|
1804
|
+
function setOpeningBalances(input) {
|
|
1805
|
+
return call(ACCOUNTING_ACTIONS.setOpeningBalances, input);
|
|
1806
|
+
}
|
|
1807
|
+
return {
|
|
1808
|
+
addEntries,
|
|
1809
|
+
voidEntry,
|
|
1810
|
+
getJournalEntries,
|
|
1811
|
+
getOpeningBalances,
|
|
1812
|
+
setOpeningBalances
|
|
1813
|
+
};
|
|
1772
1814
|
}
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1815
|
+
/** Reports, series, and snapshot maintenance. */
|
|
1816
|
+
function reportsApi(call) {
|
|
1817
|
+
function getBalanceSheet(period, bookId) {
|
|
1818
|
+
return call(ACCOUNTING_ACTIONS.getReport, {
|
|
1819
|
+
kind: "balance",
|
|
1820
|
+
period,
|
|
1821
|
+
bookId
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
function getProfitLoss(period, bookId) {
|
|
1825
|
+
return call(ACCOUNTING_ACTIONS.getReport, {
|
|
1826
|
+
kind: "pl",
|
|
1827
|
+
period,
|
|
1828
|
+
bookId
|
|
1829
|
+
});
|
|
1830
|
+
}
|
|
1831
|
+
function getLedger(accountCode, period, bookId) {
|
|
1832
|
+
return call(ACCOUNTING_ACTIONS.getReport, {
|
|
1833
|
+
kind: "ledger",
|
|
1834
|
+
accountCode,
|
|
1835
|
+
period,
|
|
1836
|
+
bookId
|
|
1837
|
+
});
|
|
1838
|
+
}
|
|
1839
|
+
function getTimeSeries(input) {
|
|
1840
|
+
return call(ACCOUNTING_ACTIONS.getTimeSeries, { ...input });
|
|
1841
|
+
}
|
|
1842
|
+
function rebuildSnapshots(bookId) {
|
|
1843
|
+
return call(ACCOUNTING_ACTIONS.rebuildSnapshots, { bookId });
|
|
1844
|
+
}
|
|
1845
|
+
return {
|
|
1846
|
+
getBalanceSheet,
|
|
1847
|
+
getProfitLoss,
|
|
1848
|
+
getLedger,
|
|
1849
|
+
getTimeSeries,
|
|
1850
|
+
rebuildSnapshots
|
|
1851
|
+
};
|
|
1779
1852
|
}
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1853
|
+
/** Build an api client bound to ONE project scope. */
|
|
1854
|
+
function makeApi(getScope) {
|
|
1855
|
+
const call = makeCall(getScope);
|
|
1856
|
+
return {
|
|
1857
|
+
...booksApi(call),
|
|
1858
|
+
...accountsApi(call),
|
|
1859
|
+
...journalApi(call),
|
|
1860
|
+
...reportsApi(call)
|
|
1861
|
+
};
|
|
1786
1862
|
}
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1863
|
+
/** Follows whatever project the HOST currently considers active. Used
|
|
1864
|
+
* by any surface mounted outside a scoped tree, and by every
|
|
1865
|
+
* single-root host, where the scope is always `null`. */
|
|
1866
|
+
var hostScopedApi = makeApi(hostProjectScope);
|
|
1867
|
+
var API_KEY = Symbol("accounting-api");
|
|
1868
|
+
/** Bind a component tree to the project its surface belongs to.
|
|
1869
|
+
*
|
|
1870
|
+
* A card was opened against the project its server envelope named
|
|
1871
|
+
* (`OpenAppPayload.scope`). If its requests kept resolving the host's
|
|
1872
|
+
* CURRENT project instead, switching projects would silently repoint
|
|
1873
|
+
* an already-open card's reads and writes at another project's books —
|
|
1874
|
+
* same bookId, different company. Call this once in the mounted app's
|
|
1875
|
+
* setup, passing a GETTER: the surface's own scope can change when it
|
|
1876
|
+
* is retargeted at another card, and the tree must follow the card it
|
|
1877
|
+
* is showing rather than the one it first showed. */
|
|
1878
|
+
function provideAccountingApi(getScope) {
|
|
1879
|
+
const api = makeApi(getScope);
|
|
1880
|
+
provide(API_KEY, api);
|
|
1881
|
+
return api;
|
|
1794
1882
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1883
|
+
/** The api client for the surrounding tree, falling back to the
|
|
1884
|
+
* host-scoped one for a surface nobody bound (a single-root host's
|
|
1885
|
+
* every surface). */
|
|
1886
|
+
function useAccountingApi() {
|
|
1887
|
+
return inject(API_KEY, hostScopedApi);
|
|
1797
1888
|
}
|
|
1798
1889
|
//#endregion
|
|
1799
1890
|
//#region src/vue/components/NewBookForm.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -1840,6 +1931,7 @@ var NewBookForm_default = /* @__PURE__ */ defineComponent({
|
|
|
1840
1931
|
},
|
|
1841
1932
|
emits: ["cancel", "created"],
|
|
1842
1933
|
setup(__props, { emit: __emit }) {
|
|
1934
|
+
const api = useAccountingApi();
|
|
1843
1935
|
const { t, locale } = useAccountingI18n();
|
|
1844
1936
|
function regionFromLocaleTag(tag) {
|
|
1845
1937
|
try {
|
|
@@ -1893,7 +1985,7 @@ var NewBookForm_default = /* @__PURE__ */ defineComponent({
|
|
|
1893
1985
|
error.value = null;
|
|
1894
1986
|
try {
|
|
1895
1987
|
const pickedCountry = country.value === "" ? void 0 : country.value;
|
|
1896
|
-
const result = await createBook({
|
|
1988
|
+
const result = await api.createBook({
|
|
1897
1989
|
name: name.value.trim(),
|
|
1898
1990
|
currency: currency.value,
|
|
1899
1991
|
country: pickedCountry,
|
|
@@ -2592,6 +2684,7 @@ var AccountsModal_default = /* @__PURE__ */ defineComponent({
|
|
|
2592
2684
|
},
|
|
2593
2685
|
emits: ["close", "changed"],
|
|
2594
2686
|
setup(__props, { emit: __emit }) {
|
|
2687
|
+
const api = useAccountingApi();
|
|
2595
2688
|
const { t } = useAccountingI18n();
|
|
2596
2689
|
const props = __props;
|
|
2597
2690
|
const emit = __emit;
|
|
@@ -2703,7 +2796,7 @@ var AccountsModal_default = /* @__PURE__ */ defineComponent({
|
|
|
2703
2796
|
if (!isNew) {
|
|
2704
2797
|
if (props.accounts.find((entry) => entry.code === account.code)?.active === false) account.active = false;
|
|
2705
2798
|
}
|
|
2706
|
-
const result = await upsertAccount(account, props.bookId);
|
|
2799
|
+
const result = await api.upsertAccount(account, props.bookId);
|
|
2707
2800
|
if (!result.ok) {
|
|
2708
2801
|
error.value = result.error;
|
|
2709
2802
|
return;
|
|
@@ -2731,7 +2824,7 @@ var AccountsModal_default = /* @__PURE__ */ defineComponent({
|
|
|
2731
2824
|
};
|
|
2732
2825
|
if (account.note !== void 0 && account.note.length > 0) next.note = account.note;
|
|
2733
2826
|
next.active = !willDeactivate;
|
|
2734
|
-
const result = await upsertAccount(next, props.bookId);
|
|
2827
|
+
const result = await api.upsertAccount(next, props.bookId);
|
|
2735
2828
|
if (!result.ok) {
|
|
2736
2829
|
toggleError.value = result.error;
|
|
2737
2830
|
return;
|
|
@@ -2926,6 +3019,7 @@ var JournalEntryForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
2926
3019
|
},
|
|
2927
3020
|
emits: ["submitted", "cancel"],
|
|
2928
3021
|
setup(__props, { emit: __emit }) {
|
|
3022
|
+
const api = useAccountingApi();
|
|
2929
3023
|
const { t } = useAccountingI18n();
|
|
2930
3024
|
const props = __props;
|
|
2931
3025
|
const emit = __emit;
|
|
@@ -3032,7 +3126,7 @@ var JournalEntryForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
3032
3126
|
const editingId = props.entryToEdit?.id;
|
|
3033
3127
|
if (editingId) {
|
|
3034
3128
|
editAttempted.value = true;
|
|
3035
|
-
const voidResult = await voidEntry({
|
|
3129
|
+
const voidResult = await api.voidEntry({
|
|
3036
3130
|
bookId: props.bookId,
|
|
3037
3131
|
entryId: editingId,
|
|
3038
3132
|
reason: t("pluginAccounting.entryForm.editVoidReason")
|
|
@@ -3042,7 +3136,7 @@ var JournalEntryForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
3042
3136
|
return;
|
|
3043
3137
|
}
|
|
3044
3138
|
}
|
|
3045
|
-
const result = await addEntries({
|
|
3139
|
+
const result = await api.addEntries({
|
|
3046
3140
|
bookId: props.bookId,
|
|
3047
3141
|
entries: [{
|
|
3048
3142
|
date: date.value,
|
|
@@ -3233,7 +3327,7 @@ var _plugin_vue_export_helper_default = (sfc, props) => {
|
|
|
3233
3327
|
};
|
|
3234
3328
|
//#endregion
|
|
3235
3329
|
//#region src/vue/components/JournalEntryForm.vue
|
|
3236
|
-
var JournalEntryForm_default = /*#__PURE__*/ _plugin_vue_export_helper_default(JournalEntryForm_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
3330
|
+
var JournalEntryForm_default = /*#__PURE__*/ _plugin_vue_export_helper_default(JournalEntryForm_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-8624a7bf"]]);
|
|
3237
3331
|
//#endregion
|
|
3238
3332
|
//#region src/vue/components/JournalList.vue?vue&type=script&setup=true&lang.ts
|
|
3239
3333
|
var _hoisted_1$8 = { class: "flex flex-col h-full gap-3" };
|
|
@@ -3345,6 +3439,7 @@ var JournalList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
|
|
|
3345
3439
|
},
|
|
3346
3440
|
emits: ["editOpening", "preselectConsumed"],
|
|
3347
3441
|
setup(__props, { emit: __emit }) {
|
|
3442
|
+
const api = useAccountingApi();
|
|
3348
3443
|
const { t } = useAccountingI18n();
|
|
3349
3444
|
const props = __props;
|
|
3350
3445
|
const emit = __emit;
|
|
@@ -3442,7 +3537,7 @@ var JournalList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
|
|
|
3442
3537
|
loading.value = true;
|
|
3443
3538
|
error.value = null;
|
|
3444
3539
|
try {
|
|
3445
|
-
const result = await getJournalEntries({
|
|
3540
|
+
const result = await api.getJournalEntries({
|
|
3446
3541
|
bookId: props.bookId,
|
|
3447
3542
|
from: range.value.from || void 0,
|
|
3448
3543
|
to: range.value.to || void 0,
|
|
@@ -3473,7 +3568,7 @@ var JournalList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
|
|
|
3473
3568
|
const reason = window.prompt(t("pluginAccounting.journalList.voidReason"));
|
|
3474
3569
|
if (reason === null) return;
|
|
3475
3570
|
try {
|
|
3476
|
-
const result = await voidEntry({
|
|
3571
|
+
const result = await api.voidEntry({
|
|
3477
3572
|
entryId: entry.id,
|
|
3478
3573
|
reason: reason || void 0,
|
|
3479
3574
|
bookId: props.bookId
|
|
@@ -3665,7 +3760,7 @@ var JournalList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
|
|
|
3665
3760
|
]);
|
|
3666
3761
|
};
|
|
3667
3762
|
}
|
|
3668
|
-
}), [["__scopeId", "data-v-
|
|
3763
|
+
}), [["__scopeId", "data-v-6d11cf47"]]);
|
|
3669
3764
|
//#endregion
|
|
3670
3765
|
//#region src/vue/components/OpeningBalancesForm.vue?vue&type=script&setup=true&lang.ts
|
|
3671
3766
|
var _hoisted_1$7 = { class: "flex items-center justify-between gap-2" };
|
|
@@ -3738,6 +3833,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
|
|
|
3738
3833
|
},
|
|
3739
3834
|
emits: ["submitted"],
|
|
3740
3835
|
setup(__props, { emit: __emit }) {
|
|
3836
|
+
const api = useAccountingApi();
|
|
3741
3837
|
const { t } = useAccountingI18n();
|
|
3742
3838
|
const props = __props;
|
|
3743
3839
|
const emit = __emit;
|
|
@@ -3816,7 +3912,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
|
|
|
3816
3912
|
async function loadExisting() {
|
|
3817
3913
|
const token = beginLoad();
|
|
3818
3914
|
const next = freshRows();
|
|
3819
|
-
const result = await getOpeningBalances(props.bookId);
|
|
3915
|
+
const result = await api.getOpeningBalances(props.bookId);
|
|
3820
3916
|
if (!isCurrentLoad(token)) return;
|
|
3821
3917
|
if (!result.ok) {
|
|
3822
3918
|
existing.value = null;
|
|
@@ -3839,7 +3935,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
|
|
|
3839
3935
|
error.value = null;
|
|
3840
3936
|
successMessage.value = null;
|
|
3841
3937
|
try {
|
|
3842
|
-
const result = await setOpeningBalances({
|
|
3938
|
+
const result = await api.setOpeningBalances({
|
|
3843
3939
|
bookId: props.bookId,
|
|
3844
3940
|
asOfDate: asOfDate.value,
|
|
3845
3941
|
lines: toApiLines()
|
|
@@ -3950,7 +4046,7 @@ var OpeningBalancesForm_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
|
|
|
3950
4046
|
}, null, 8, ["book-id", "accounts"])) : createCommentVNode("", true)], 64);
|
|
3951
4047
|
};
|
|
3952
4048
|
}
|
|
3953
|
-
}), [["__scopeId", "data-v-
|
|
4049
|
+
}), [["__scopeId", "data-v-08e2a48f"]]);
|
|
3954
4050
|
//#endregion
|
|
3955
4051
|
//#region src/vue/components/AccountsList.vue?vue&type=script&setup=true&lang.ts
|
|
3956
4052
|
var _hoisted_1$6 = {
|
|
@@ -4111,6 +4207,7 @@ var Ledger_default = /* @__PURE__ */ defineComponent({
|
|
|
4111
4207
|
preselectAccountCode: {}
|
|
4112
4208
|
},
|
|
4113
4209
|
setup(__props) {
|
|
4210
|
+
const api = useAccountingApi();
|
|
4114
4211
|
const { t } = useAccountingI18n();
|
|
4115
4212
|
const props = __props;
|
|
4116
4213
|
const accountCode = ref("");
|
|
@@ -4150,7 +4247,7 @@ var Ledger_default = /* @__PURE__ */ defineComponent({
|
|
|
4150
4247
|
loading.value = true;
|
|
4151
4248
|
error.value = null;
|
|
4152
4249
|
try {
|
|
4153
|
-
const result = await getLedger(accountCode.value, periodFromRange(range.value), props.bookId);
|
|
4250
|
+
const result = await api.getLedger(accountCode.value, periodFromRange(range.value), props.bookId);
|
|
4154
4251
|
if (!isCurrent(token)) return;
|
|
4155
4252
|
if (!result.ok) {
|
|
4156
4253
|
error.value = result.error;
|
|
@@ -4292,6 +4389,7 @@ var BalanceSheet_default = /* @__PURE__ */ defineComponent({
|
|
|
4292
4389
|
},
|
|
4293
4390
|
emits: ["selectAccount"],
|
|
4294
4391
|
setup(__props, { emit: __emit }) {
|
|
4392
|
+
const api = useAccountingApi();
|
|
4295
4393
|
const { t } = useAccountingI18n();
|
|
4296
4394
|
const props = __props;
|
|
4297
4395
|
const emit = __emit;
|
|
@@ -4348,7 +4446,7 @@ var BalanceSheet_default = /* @__PURE__ */ defineComponent({
|
|
|
4348
4446
|
loading.value = true;
|
|
4349
4447
|
error.value = null;
|
|
4350
4448
|
try {
|
|
4351
|
-
const result = await getBalanceSheet({
|
|
4449
|
+
const result = await api.getBalanceSheet({
|
|
4352
4450
|
kind: "month",
|
|
4353
4451
|
period: period.value
|
|
4354
4452
|
}, props.bookId);
|
|
@@ -4483,6 +4581,7 @@ var ProfitLoss_default = /* @__PURE__ */ defineComponent({
|
|
|
4483
4581
|
},
|
|
4484
4582
|
emits: ["selectAccount"],
|
|
4485
4583
|
setup(__props, { emit: __emit }) {
|
|
4584
|
+
const api = useAccountingApi();
|
|
4486
4585
|
const { t } = useAccountingI18n();
|
|
4487
4586
|
const props = __props;
|
|
4488
4587
|
const emit = __emit;
|
|
@@ -4507,10 +4606,12 @@ var ProfitLoss_default = /* @__PURE__ */ defineComponent({
|
|
|
4507
4606
|
loading.value = true;
|
|
4508
4607
|
error.value = null;
|
|
4509
4608
|
try {
|
|
4510
|
-
const
|
|
4609
|
+
const fromBound = range.value.from || "0000-01-01";
|
|
4610
|
+
const toBound = range.value.to || "9999-12-31";
|
|
4611
|
+
const result = await api.getProfitLoss({
|
|
4511
4612
|
kind: "range",
|
|
4512
|
-
from:
|
|
4513
|
-
to:
|
|
4613
|
+
from: fromBound,
|
|
4614
|
+
to: toBound
|
|
4514
4615
|
}, props.bookId);
|
|
4515
4616
|
if (!isCurrent(token)) return;
|
|
4516
4617
|
if (!result.ok) {
|
|
@@ -4654,6 +4755,7 @@ var BookSettings_default = /* @__PURE__ */ defineComponent({
|
|
|
4654
4755
|
},
|
|
4655
4756
|
emits: ["deleted", "books-changed"],
|
|
4656
4757
|
setup(__props, { emit: __emit }) {
|
|
4758
|
+
const api = useAccountingApi();
|
|
4657
4759
|
const { t, locale } = useAccountingI18n();
|
|
4658
4760
|
const props = __props;
|
|
4659
4761
|
const emit = __emit;
|
|
@@ -4690,7 +4792,7 @@ var BookSettings_default = /* @__PURE__ */ defineComponent({
|
|
|
4690
4792
|
rebuildOk.value = null;
|
|
4691
4793
|
rebuildError.value = null;
|
|
4692
4794
|
try {
|
|
4693
|
-
const result = await rebuildSnapshots(props.bookId);
|
|
4795
|
+
const result = await api.rebuildSnapshots(props.bookId);
|
|
4694
4796
|
if (!result.ok) {
|
|
4695
4797
|
rebuildError.value = result.error;
|
|
4696
4798
|
return;
|
|
@@ -4708,7 +4810,7 @@ var BookSettings_default = /* @__PURE__ */ defineComponent({
|
|
|
4708
4810
|
try {
|
|
4709
4811
|
const rawCountry = selectedCountry.value;
|
|
4710
4812
|
const country = rawCountry === "" || isSupportedCountryCode(rawCountry) ? rawCountry : "";
|
|
4711
|
-
const result = await updateBook({
|
|
4813
|
+
const result = await api.updateBook({
|
|
4712
4814
|
bookId: props.bookId,
|
|
4713
4815
|
name: selectedName.value.trim(),
|
|
4714
4816
|
country,
|
|
@@ -4729,7 +4831,7 @@ var BookSettings_default = /* @__PURE__ */ defineComponent({
|
|
|
4729
4831
|
deleting.value = true;
|
|
4730
4832
|
deleteError.value = null;
|
|
4731
4833
|
try {
|
|
4732
|
-
const result = await deleteBook(props.bookId);
|
|
4834
|
+
const result = await api.deleteBook(props.bookId);
|
|
4733
4835
|
if (!result.ok) {
|
|
4734
4836
|
deleteError.value = result.error;
|
|
4735
4837
|
return;
|
|
@@ -4860,7 +4962,20 @@ function toBookChannelPayload(data) {
|
|
|
4860
4962
|
period
|
|
4861
4963
|
};
|
|
4862
4964
|
}
|
|
4863
|
-
|
|
4965
|
+
/** Resolves the scope REACTIVELY, so a subscription re-binds instead of
|
|
4966
|
+
* sitting on a channel that stopped being the caller's. A host whose
|
|
4967
|
+
* `projectScope` getter reads reactive state gets that for free on the
|
|
4968
|
+
* host-following path too; one that does not simply never changes. */
|
|
4969
|
+
function resolveScope(scope) {
|
|
4970
|
+
return computed(() => scope === void 0 ? hostProjectScope() : typeof scope === "function" ? scope() : scope);
|
|
4971
|
+
}
|
|
4972
|
+
/** `scope` binds the subscription to one project — pass the scope the
|
|
4973
|
+
* surface was opened for. Omit it and the channel follows whatever
|
|
4974
|
+
* project the host currently considers active, which is right for a
|
|
4975
|
+
* surface the host itself scopes and always `null` on a single-root
|
|
4976
|
+
* host. */
|
|
4977
|
+
function useAccountingChannel(bookId, onPayload, scope) {
|
|
4978
|
+
const channelScope = resolveScope(scope);
|
|
4864
4979
|
const version = ref(0);
|
|
4865
4980
|
let unsubscribe = null;
|
|
4866
4981
|
function bind(nextBookId) {
|
|
@@ -4868,13 +4983,13 @@ function useAccountingChannel(bookId, onPayload) {
|
|
|
4868
4983
|
unsubscribe = null;
|
|
4869
4984
|
version.value = 0;
|
|
4870
4985
|
if (!nextBookId) return;
|
|
4871
|
-
unsubscribe = hostSubscribe(bookChannel(nextBookId), (data) => {
|
|
4986
|
+
unsubscribe = hostSubscribe(bookChannel(nextBookId, channelScope.value), (data) => {
|
|
4872
4987
|
version.value += 1;
|
|
4873
4988
|
const event = toBookChannelPayload(data);
|
|
4874
4989
|
if (event) onPayload?.(event);
|
|
4875
4990
|
});
|
|
4876
4991
|
}
|
|
4877
|
-
watch(bookId, bind, { immediate: true });
|
|
4992
|
+
watch([bookId, channelScope], ([nextBookId]) => bind(nextBookId), { immediate: true });
|
|
4878
4993
|
onUnmounted(() => {
|
|
4879
4994
|
unsubscribe?.();
|
|
4880
4995
|
unsubscribe = null;
|
|
@@ -4883,10 +4998,19 @@ function useAccountingChannel(bookId, onPayload) {
|
|
|
4883
4998
|
}
|
|
4884
4999
|
/** Subscribe to "the list of books changed" events. Use in
|
|
4885
5000
|
* BookSwitcher.vue to refetch the dropdown contents when a sibling
|
|
4886
|
-
* tab adds / deletes a book.
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
5001
|
+
* tab adds / deletes a book. Re-binds on a scope change, like
|
|
5002
|
+
* `useAccountingChannel`. */
|
|
5003
|
+
function useAccountingBooksChannel(onChange, scope) {
|
|
5004
|
+
const channelScope = resolveScope(scope);
|
|
5005
|
+
let unsubscribe = null;
|
|
5006
|
+
watch(channelScope, (nextScope) => {
|
|
5007
|
+
unsubscribe?.();
|
|
5008
|
+
unsubscribe = hostSubscribe(booksChannel(nextScope), onChange);
|
|
5009
|
+
}, { immediate: true });
|
|
5010
|
+
onUnmounted(() => {
|
|
5011
|
+
unsubscribe?.();
|
|
5012
|
+
unsubscribe = null;
|
|
5013
|
+
});
|
|
4890
5014
|
}
|
|
4891
5015
|
//#endregion
|
|
4892
5016
|
//#region src/vue/View.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -4990,6 +5114,11 @@ var View_default = /* @__PURE__ */ defineComponent({
|
|
|
4990
5114
|
return TAB_KEYS.some((key) => key === value);
|
|
4991
5115
|
}
|
|
4992
5116
|
const initialPayload = computed(() => props.selectedResult?.data ?? props.selectedResult?.jsonData ?? {});
|
|
5117
|
+
const cardScope = computed(() => {
|
|
5118
|
+
const payload = initialPayload.value;
|
|
5119
|
+
return "scope" in payload ? payload.scope ?? null : hostProjectScope();
|
|
5120
|
+
});
|
|
5121
|
+
const api = provideAccountingApi(() => cardScope.value);
|
|
4993
5122
|
const initialTab = computed(() => isTabKey(initialPayload.value.initialTab) ? initialPayload.value.initialTab : "journal");
|
|
4994
5123
|
const currentTab = ref(initialTab.value);
|
|
4995
5124
|
const books = ref([]);
|
|
@@ -5008,8 +5137,8 @@ var View_default = /* @__PURE__ */ defineComponent({
|
|
|
5008
5137
|
const activeCurrency = computed(() => activeBook.value?.currency ?? "USD");
|
|
5009
5138
|
const activeCountry = computed(() => activeBook.value?.country);
|
|
5010
5139
|
const activeFiscalYearEnd = computed(() => activeBook.value?.fiscalYearEnd);
|
|
5011
|
-
const { version: bookVersion } = useAccountingChannel(activeBookId);
|
|
5012
|
-
useAccountingBooksChannel(() => void refetchBooks());
|
|
5140
|
+
const { version: bookVersion } = useAccountingChannel(activeBookId, void 0, () => cardScope.value);
|
|
5141
|
+
useAccountingBooksChannel(() => void refetchBooks(), () => cardScope.value);
|
|
5013
5142
|
function pickInitialBookId() {
|
|
5014
5143
|
const [firstBook] = books.value;
|
|
5015
5144
|
if (!firstBook) return null;
|
|
@@ -5022,7 +5151,7 @@ var View_default = /* @__PURE__ */ defineComponent({
|
|
|
5022
5151
|
bookLoadError.value = null;
|
|
5023
5152
|
const previousActive = activeBook.value;
|
|
5024
5153
|
try {
|
|
5025
|
-
const result = await getBooks();
|
|
5154
|
+
const result = await api.getBooks();
|
|
5026
5155
|
if (!result.ok) {
|
|
5027
5156
|
bookLoadError.value = result.error;
|
|
5028
5157
|
return;
|
|
@@ -5062,7 +5191,7 @@ var View_default = /* @__PURE__ */ defineComponent({
|
|
|
5062
5191
|
accounts.value = [];
|
|
5063
5192
|
return;
|
|
5064
5193
|
}
|
|
5065
|
-
const result = await getAccounts(activeBookId.value);
|
|
5194
|
+
const result = await api.getAccounts(activeBookId.value);
|
|
5066
5195
|
if (!result.ok) return;
|
|
5067
5196
|
accounts.value = result.data.accounts;
|
|
5068
5197
|
}
|
|
@@ -5072,7 +5201,7 @@ var View_default = /* @__PURE__ */ defineComponent({
|
|
|
5072
5201
|
activeOpeningDate.value = void 0;
|
|
5073
5202
|
return;
|
|
5074
5203
|
}
|
|
5075
|
-
const result = await getOpeningBalances(activeBookId.value);
|
|
5204
|
+
const result = await api.getOpeningBalances(activeBookId.value);
|
|
5076
5205
|
if (!result.ok) return;
|
|
5077
5206
|
hasOpening.value = result.data.opening !== null;
|
|
5078
5207
|
activeOpeningDate.value = result.data.opening?.date;
|