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