@goweekdays/core 2.15.1 → 2.15.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/CHANGELOG.md +12 -0
- package/dist/index.d.ts +27 -4
- package/dist/index.js +465 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +465 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -18339,7 +18339,8 @@ function useChartOfAccountRepo() {
|
|
|
18339
18339
|
{ key: { code: 1 } },
|
|
18340
18340
|
{ key: { path: 1 } },
|
|
18341
18341
|
{ key: { name: 1, org: 1 }, unique: true, name: "unique_name_per_org" },
|
|
18342
|
-
{ key: { code: 1, org: 1 }, unique: true, name: "unique_code_per_org" }
|
|
18342
|
+
{ key: { code: 1, org: 1 }, unique: true, name: "unique_code_per_org" },
|
|
18343
|
+
{ key: { name: "text", code: "text" }, name: "text_search" }
|
|
18343
18344
|
]);
|
|
18344
18345
|
} catch (error) {
|
|
18345
18346
|
throw new Error("Failed to create index on chart of account.");
|
|
@@ -18700,6 +18701,242 @@ function useChartOfAccountRepo() {
|
|
|
18700
18701
|
throw new InternalServerError38("Failed to update children count.");
|
|
18701
18702
|
}
|
|
18702
18703
|
}
|
|
18704
|
+
async function getTrialBalance(options) {
|
|
18705
|
+
options.page = options.page && options.page > 0 ? options.page - 1 : 0;
|
|
18706
|
+
options.limit = options.limit ?? 10;
|
|
18707
|
+
try {
|
|
18708
|
+
options.org = new ObjectId47(options.org);
|
|
18709
|
+
} catch (error) {
|
|
18710
|
+
throw new BadRequestError88("Invalid organization ID.");
|
|
18711
|
+
}
|
|
18712
|
+
const cacheKey = makeCacheKey27(namespace_collection, {
|
|
18713
|
+
org: String(options.org),
|
|
18714
|
+
fiscalYear: options.fiscalYear,
|
|
18715
|
+
from: options.from ?? "",
|
|
18716
|
+
to: options.to ?? "",
|
|
18717
|
+
limit: options.limit,
|
|
18718
|
+
page: options.page
|
|
18719
|
+
});
|
|
18720
|
+
logger45.log({
|
|
18721
|
+
level: "info",
|
|
18722
|
+
message: `Cache key for getTrialBalance: ${cacheKey}`
|
|
18723
|
+
});
|
|
18724
|
+
try {
|
|
18725
|
+
const cachedData = await repo.getCache(cacheKey);
|
|
18726
|
+
if (cachedData) {
|
|
18727
|
+
logger45.log({
|
|
18728
|
+
level: "info",
|
|
18729
|
+
message: `Cache hit for getTrialBalance: ${cacheKey}`
|
|
18730
|
+
});
|
|
18731
|
+
return cachedData;
|
|
18732
|
+
}
|
|
18733
|
+
const query = {
|
|
18734
|
+
org: options.org,
|
|
18735
|
+
status: "active",
|
|
18736
|
+
childrenCount: 0
|
|
18737
|
+
};
|
|
18738
|
+
const pipeline = [
|
|
18739
|
+
{ $eq: ["$account", "$$account"] },
|
|
18740
|
+
{ $eq: ["$period.fiscalYear", options.fiscalYear] }
|
|
18741
|
+
];
|
|
18742
|
+
if (options.from !== void 0) {
|
|
18743
|
+
pipeline.push({ $gte: ["$period.fiscalMonth", options.from] });
|
|
18744
|
+
}
|
|
18745
|
+
if (options.to !== void 0) {
|
|
18746
|
+
pipeline.push({ $lte: ["$period.fiscalMonth", options.to] });
|
|
18747
|
+
}
|
|
18748
|
+
const accounts = await repo.collection.aggregate([
|
|
18749
|
+
{
|
|
18750
|
+
$match: query
|
|
18751
|
+
},
|
|
18752
|
+
{ $sort: { path: 1 } },
|
|
18753
|
+
{
|
|
18754
|
+
$skip: options.page * options.limit
|
|
18755
|
+
},
|
|
18756
|
+
{
|
|
18757
|
+
$limit: options.limit
|
|
18758
|
+
},
|
|
18759
|
+
{
|
|
18760
|
+
$lookup: {
|
|
18761
|
+
from: "finance.account.balances",
|
|
18762
|
+
let: {
|
|
18763
|
+
account: "$_id"
|
|
18764
|
+
},
|
|
18765
|
+
pipeline: [
|
|
18766
|
+
{
|
|
18767
|
+
$match: {
|
|
18768
|
+
$expr: {
|
|
18769
|
+
$and: pipeline
|
|
18770
|
+
}
|
|
18771
|
+
}
|
|
18772
|
+
},
|
|
18773
|
+
{
|
|
18774
|
+
$group: {
|
|
18775
|
+
_id: "$account",
|
|
18776
|
+
debit: {
|
|
18777
|
+
$sum: "$closingDebit"
|
|
18778
|
+
},
|
|
18779
|
+
credit: {
|
|
18780
|
+
$sum: "$closingCredit"
|
|
18781
|
+
}
|
|
18782
|
+
}
|
|
18783
|
+
}
|
|
18784
|
+
],
|
|
18785
|
+
as: "balance"
|
|
18786
|
+
}
|
|
18787
|
+
},
|
|
18788
|
+
{
|
|
18789
|
+
$unwind: {
|
|
18790
|
+
path: "$balance",
|
|
18791
|
+
preserveNullAndEmptyArrays: true
|
|
18792
|
+
}
|
|
18793
|
+
},
|
|
18794
|
+
{
|
|
18795
|
+
$project: {
|
|
18796
|
+
name: 1,
|
|
18797
|
+
code: 1,
|
|
18798
|
+
type: 1,
|
|
18799
|
+
debit: { $ifNull: ["$balance.debit", 0] },
|
|
18800
|
+
credit: { $ifNull: ["$balance.credit", 0] }
|
|
18801
|
+
}
|
|
18802
|
+
},
|
|
18803
|
+
{
|
|
18804
|
+
$match: {
|
|
18805
|
+
$or: [{ debit: { $ne: 0 } }, { credit: { $ne: 0 } }]
|
|
18806
|
+
}
|
|
18807
|
+
}
|
|
18808
|
+
]).toArray();
|
|
18809
|
+
const length = await repo.collection.countDocuments(query);
|
|
18810
|
+
const data = paginate23(accounts, options.page, options.limit, length);
|
|
18811
|
+
repo.setCache(cacheKey, data, 300).then(() => {
|
|
18812
|
+
logger45.log({
|
|
18813
|
+
level: "info",
|
|
18814
|
+
message: `Cache set for getTrialBalance: ${cacheKey}`
|
|
18815
|
+
});
|
|
18816
|
+
}).catch((err) => {
|
|
18817
|
+
logger45.log({
|
|
18818
|
+
level: "error",
|
|
18819
|
+
message: `Failed to set cache for getTrialBalance: ${err.message}`
|
|
18820
|
+
});
|
|
18821
|
+
});
|
|
18822
|
+
return data;
|
|
18823
|
+
} catch (error) {
|
|
18824
|
+
logger45.log({
|
|
18825
|
+
level: "error",
|
|
18826
|
+
message: `Error in getTrialBalance: ${error}`
|
|
18827
|
+
});
|
|
18828
|
+
throw new InternalServerError38("Failed to get trial balance.");
|
|
18829
|
+
}
|
|
18830
|
+
}
|
|
18831
|
+
async function getBalanceSheet(options) {
|
|
18832
|
+
options.page = options.page && options.page > 0 ? options.page - 1 : 0;
|
|
18833
|
+
options.limit = options.limit ?? 10;
|
|
18834
|
+
try {
|
|
18835
|
+
options.org = new ObjectId47(options.org);
|
|
18836
|
+
} catch (error) {
|
|
18837
|
+
throw new BadRequestError88("Invalid organization ID.");
|
|
18838
|
+
}
|
|
18839
|
+
const cacheKey = makeCacheKey27(namespace_collection, {
|
|
18840
|
+
type: "balance-sheet",
|
|
18841
|
+
org: String(options.org),
|
|
18842
|
+
fiscalYear: options.fiscalYear,
|
|
18843
|
+
from: options.from ?? "",
|
|
18844
|
+
to: options.to ?? "",
|
|
18845
|
+
limit: options.limit,
|
|
18846
|
+
page: options.page
|
|
18847
|
+
});
|
|
18848
|
+
try {
|
|
18849
|
+
const cachedData = await repo.getCache(cacheKey);
|
|
18850
|
+
if (cachedData) {
|
|
18851
|
+
return cachedData;
|
|
18852
|
+
}
|
|
18853
|
+
const query = {
|
|
18854
|
+
org: options.org,
|
|
18855
|
+
status: "active",
|
|
18856
|
+
childrenCount: 0
|
|
18857
|
+
};
|
|
18858
|
+
const pipeline = [
|
|
18859
|
+
{ $eq: ["$account", "$$account"] },
|
|
18860
|
+
{ $eq: ["$period.fiscalYear", options.fiscalYear] }
|
|
18861
|
+
];
|
|
18862
|
+
if (options.from !== void 0) {
|
|
18863
|
+
pipeline.push({ $gte: ["$period.fiscalMonth", options.from] });
|
|
18864
|
+
}
|
|
18865
|
+
if (options.to !== void 0) {
|
|
18866
|
+
pipeline.push({ $lte: ["$period.fiscalMonth", options.to] });
|
|
18867
|
+
}
|
|
18868
|
+
const accounts = await repo.collection.aggregate([
|
|
18869
|
+
{ $match: query },
|
|
18870
|
+
{ $sort: { path: 1 } },
|
|
18871
|
+
{ $skip: options.page * options.limit },
|
|
18872
|
+
{ $limit: options.limit },
|
|
18873
|
+
{
|
|
18874
|
+
$lookup: {
|
|
18875
|
+
from: "finance.account.balances",
|
|
18876
|
+
let: { account: "$_id" },
|
|
18877
|
+
pipeline: [
|
|
18878
|
+
{
|
|
18879
|
+
$match: {
|
|
18880
|
+
$expr: { $and: pipeline }
|
|
18881
|
+
}
|
|
18882
|
+
},
|
|
18883
|
+
{
|
|
18884
|
+
$group: {
|
|
18885
|
+
_id: "$account",
|
|
18886
|
+
debit: { $sum: "$closingDebit" },
|
|
18887
|
+
credit: { $sum: "$closingCredit" }
|
|
18888
|
+
}
|
|
18889
|
+
}
|
|
18890
|
+
],
|
|
18891
|
+
as: "balance"
|
|
18892
|
+
}
|
|
18893
|
+
},
|
|
18894
|
+
{
|
|
18895
|
+
$unwind: {
|
|
18896
|
+
path: "$balance",
|
|
18897
|
+
preserveNullAndEmptyArrays: true
|
|
18898
|
+
}
|
|
18899
|
+
},
|
|
18900
|
+
{
|
|
18901
|
+
$project: {
|
|
18902
|
+
name: 1,
|
|
18903
|
+
code: 1,
|
|
18904
|
+
type: 1,
|
|
18905
|
+
normalBalance: 1,
|
|
18906
|
+
isContra: 1,
|
|
18907
|
+
parent: 1,
|
|
18908
|
+
childrenCount: 1,
|
|
18909
|
+
debit: { $ifNull: ["$balance.debit", 0] },
|
|
18910
|
+
credit: { $ifNull: ["$balance.credit", 0] }
|
|
18911
|
+
}
|
|
18912
|
+
},
|
|
18913
|
+
{
|
|
18914
|
+
$match: {
|
|
18915
|
+
$or: [
|
|
18916
|
+
{ childrenCount: { $gt: 0 } },
|
|
18917
|
+
{ debit: { $ne: 0 } },
|
|
18918
|
+
{ credit: { $ne: 0 } }
|
|
18919
|
+
]
|
|
18920
|
+
}
|
|
18921
|
+
}
|
|
18922
|
+
]).toArray();
|
|
18923
|
+
const length = await repo.collection.countDocuments(query);
|
|
18924
|
+
const data = paginate23(accounts, options.page, options.limit, length);
|
|
18925
|
+
repo.setCache(cacheKey, data, 300).catch((err) => {
|
|
18926
|
+
logger45.log({
|
|
18927
|
+
level: "error",
|
|
18928
|
+
message: `Failed to set cache for getBalanceSheet: ${err.message}`
|
|
18929
|
+
});
|
|
18930
|
+
});
|
|
18931
|
+
return data;
|
|
18932
|
+
} catch (error) {
|
|
18933
|
+
logger45.log({
|
|
18934
|
+
level: "error",
|
|
18935
|
+
message: `Error in getBalanceSheet: ${error}`
|
|
18936
|
+
});
|
|
18937
|
+
throw new InternalServerError38("Failed to get balance sheet data.");
|
|
18938
|
+
}
|
|
18939
|
+
}
|
|
18703
18940
|
return {
|
|
18704
18941
|
createIndexes,
|
|
18705
18942
|
add,
|
|
@@ -18710,7 +18947,9 @@ function useChartOfAccountRepo() {
|
|
|
18710
18947
|
deleteById,
|
|
18711
18948
|
updateStatusById,
|
|
18712
18949
|
countByPath,
|
|
18713
|
-
updateChildrenCountById
|
|
18950
|
+
updateChildrenCountById,
|
|
18951
|
+
getTrialBalance,
|
|
18952
|
+
getBalanceSheet
|
|
18714
18953
|
};
|
|
18715
18954
|
}
|
|
18716
18955
|
|
|
@@ -18728,7 +18967,9 @@ function useChartOfAccountService() {
|
|
|
18728
18967
|
updateById: _updateById,
|
|
18729
18968
|
deleteById: _deleteById,
|
|
18730
18969
|
countByPath,
|
|
18731
|
-
updateChildrenCountById
|
|
18970
|
+
updateChildrenCountById,
|
|
18971
|
+
getTrialBalance: _getTrialBalance,
|
|
18972
|
+
getBalanceSheet: _getBalanceSheet
|
|
18732
18973
|
} = useChartOfAccountRepo();
|
|
18733
18974
|
async function add(value) {
|
|
18734
18975
|
const { error } = schemaChartOfAccountBase.validate(value);
|
|
@@ -18869,10 +19110,112 @@ function useChartOfAccountService() {
|
|
|
18869
19110
|
session.endSession();
|
|
18870
19111
|
}
|
|
18871
19112
|
}
|
|
19113
|
+
async function getTrialBalance(options) {
|
|
19114
|
+
const LIMIT = 100;
|
|
19115
|
+
const allAccounts = [];
|
|
19116
|
+
let page = 1;
|
|
19117
|
+
let totalPages = 1;
|
|
19118
|
+
do {
|
|
19119
|
+
const result = await _getTrialBalance({
|
|
19120
|
+
org: options.org,
|
|
19121
|
+
fiscalYear: options.fiscalYear,
|
|
19122
|
+
from: options.from,
|
|
19123
|
+
to: options.to,
|
|
19124
|
+
page,
|
|
19125
|
+
limit: LIMIT
|
|
19126
|
+
});
|
|
19127
|
+
allAccounts.push(...result.items);
|
|
19128
|
+
totalPages = result.pages;
|
|
19129
|
+
page++;
|
|
19130
|
+
} while (page <= totalPages);
|
|
19131
|
+
return allAccounts;
|
|
19132
|
+
}
|
|
19133
|
+
async function getBalanceSheet(options) {
|
|
19134
|
+
const LIMIT = 100;
|
|
19135
|
+
const allAccounts = [];
|
|
19136
|
+
let page = 1;
|
|
19137
|
+
let totalPages = 1;
|
|
19138
|
+
do {
|
|
19139
|
+
const result = await _getBalanceSheet({
|
|
19140
|
+
org: options.org,
|
|
19141
|
+
fiscalYear: options.fiscalYear,
|
|
19142
|
+
from: options.from,
|
|
19143
|
+
to: options.to,
|
|
19144
|
+
page,
|
|
19145
|
+
limit: LIMIT
|
|
19146
|
+
});
|
|
19147
|
+
allAccounts.push(...result.items);
|
|
19148
|
+
totalPages = result.pages;
|
|
19149
|
+
page++;
|
|
19150
|
+
} while (page <= totalPages);
|
|
19151
|
+
const netBalance = (a) => a.normalBalance === "debit" ? a.debit - a.credit : a.credit - a.debit;
|
|
19152
|
+
const section = (type) => {
|
|
19153
|
+
const accounts = allAccounts.filter((a) => a.type === type).map((a) => ({ ...a, balance: netBalance(a) }));
|
|
19154
|
+
const total = accounts.reduce((sum, a) => sum + a.balance, 0);
|
|
19155
|
+
return { accounts, total };
|
|
19156
|
+
};
|
|
19157
|
+
const assets = section("asset");
|
|
19158
|
+
const liabilities = section("liability");
|
|
19159
|
+
const equity = section("equity");
|
|
19160
|
+
const incomeTotal = allAccounts.filter((a) => a.type === "income").reduce((sum, a) => sum + netBalance(a), 0);
|
|
19161
|
+
const expenseTotal = allAccounts.filter((a) => a.type === "expense").reduce((sum, a) => sum + netBalance(a), 0);
|
|
19162
|
+
const netIncome = incomeTotal - expenseTotal;
|
|
19163
|
+
const totalEquity = equity.total + netIncome;
|
|
19164
|
+
const totalLiabilitiesAndEquity = liabilities.total + totalEquity;
|
|
19165
|
+
return {
|
|
19166
|
+
assets: assets.accounts,
|
|
19167
|
+
liabilities: liabilities.accounts,
|
|
19168
|
+
equity: equity.accounts,
|
|
19169
|
+
netIncome,
|
|
19170
|
+
totalAssets: assets.total,
|
|
19171
|
+
totalLiabilities: liabilities.total,
|
|
19172
|
+
totalEquity,
|
|
19173
|
+
totalLiabilitiesAndEquity,
|
|
19174
|
+
isBalanced: assets.total === totalLiabilitiesAndEquity
|
|
19175
|
+
};
|
|
19176
|
+
}
|
|
19177
|
+
async function getIncomeStatement(options) {
|
|
19178
|
+
const LIMIT = 100;
|
|
19179
|
+
const allAccounts = [];
|
|
19180
|
+
let page = 1;
|
|
19181
|
+
let totalPages = 1;
|
|
19182
|
+
do {
|
|
19183
|
+
const result = await _getBalanceSheet({
|
|
19184
|
+
org: options.org,
|
|
19185
|
+
fiscalYear: options.fiscalYear,
|
|
19186
|
+
from: options.from,
|
|
19187
|
+
to: options.to,
|
|
19188
|
+
page,
|
|
19189
|
+
limit: LIMIT
|
|
19190
|
+
});
|
|
19191
|
+
allAccounts.push(...result.items);
|
|
19192
|
+
totalPages = result.pages;
|
|
19193
|
+
page++;
|
|
19194
|
+
} while (page <= totalPages);
|
|
19195
|
+
const netBalance = (a) => a.normalBalance === "debit" ? a.debit - a.credit : a.credit - a.debit;
|
|
19196
|
+
const section = (type) => {
|
|
19197
|
+
const accounts = allAccounts.filter((a) => a.type === type).map((a) => ({ ...a, balance: netBalance(a) }));
|
|
19198
|
+
const total = accounts.reduce((sum, a) => sum + a.balance, 0);
|
|
19199
|
+
return { accounts, total };
|
|
19200
|
+
};
|
|
19201
|
+
const revenues = section("income");
|
|
19202
|
+
const expenses = section("expense");
|
|
19203
|
+
const netIncome = revenues.total - expenses.total;
|
|
19204
|
+
return {
|
|
19205
|
+
revenues: revenues.accounts,
|
|
19206
|
+
expenses: expenses.accounts,
|
|
19207
|
+
totalRevenues: revenues.total,
|
|
19208
|
+
totalExpenses: expenses.total,
|
|
19209
|
+
netIncome
|
|
19210
|
+
};
|
|
19211
|
+
}
|
|
18872
19212
|
return {
|
|
18873
19213
|
add,
|
|
18874
19214
|
updateById,
|
|
18875
|
-
deleteById
|
|
19215
|
+
deleteById,
|
|
19216
|
+
getTrialBalance,
|
|
19217
|
+
getBalanceSheet,
|
|
19218
|
+
getIncomeStatement
|
|
18876
19219
|
};
|
|
18877
19220
|
}
|
|
18878
19221
|
|
|
@@ -18887,7 +19230,10 @@ function useChartOfAccountController() {
|
|
|
18887
19230
|
const {
|
|
18888
19231
|
add: _add,
|
|
18889
19232
|
updateById: _updateById,
|
|
18890
|
-
deleteById: _deleteById
|
|
19233
|
+
deleteById: _deleteById,
|
|
19234
|
+
getTrialBalance: _getTrialBalance,
|
|
19235
|
+
getBalanceSheet: _getBalanceSheet,
|
|
19236
|
+
getIncomeStatement: _getIncomeStatement
|
|
18891
19237
|
} = useChartOfAccountService();
|
|
18892
19238
|
async function add(req, res, next) {
|
|
18893
19239
|
const value = req.body;
|
|
@@ -19043,6 +19389,75 @@ function useChartOfAccountController() {
|
|
|
19043
19389
|
next(error);
|
|
19044
19390
|
}
|
|
19045
19391
|
}
|
|
19392
|
+
async function getTrialBalance(req, res, next) {
|
|
19393
|
+
const org = req.params.org ?? "";
|
|
19394
|
+
const fiscalYear = typeof req.params.fiscalYear === "string" ? Number(req.params.fiscalYear) : NaN;
|
|
19395
|
+
const from = typeof req.query.from === "string" ? Number(req.query.from) : NaN;
|
|
19396
|
+
const to = typeof req.query.to === "string" ? Number(req.query.to) : NaN;
|
|
19397
|
+
const validation = Joi80.object({
|
|
19398
|
+
org: Joi80.string().hex().required(),
|
|
19399
|
+
fiscalYear: Joi80.number().required(),
|
|
19400
|
+
from: Joi80.number().optional().allow("", null),
|
|
19401
|
+
to: Joi80.number().optional().allow("", null)
|
|
19402
|
+
});
|
|
19403
|
+
const { error } = validation.validate({ ...req.params, ...req.query });
|
|
19404
|
+
if (error) {
|
|
19405
|
+
next(new BadRequestError90(error.message));
|
|
19406
|
+
return;
|
|
19407
|
+
}
|
|
19408
|
+
try {
|
|
19409
|
+
const accounts = await _getTrialBalance({ org, fiscalYear, from, to });
|
|
19410
|
+
res.json(accounts);
|
|
19411
|
+
} catch (error2) {
|
|
19412
|
+
next(error2);
|
|
19413
|
+
}
|
|
19414
|
+
}
|
|
19415
|
+
async function getBalanceSheet(req, res, next) {
|
|
19416
|
+
const org = req.params.org ?? "";
|
|
19417
|
+
const fiscalYear = typeof req.params.fiscalYear === "string" ? Number(req.params.fiscalYear) : NaN;
|
|
19418
|
+
const from = typeof req.query.from === "string" ? Number(req.query.from) : void 0;
|
|
19419
|
+
const to = typeof req.query.to === "string" ? Number(req.query.to) : void 0;
|
|
19420
|
+
const validation = Joi80.object({
|
|
19421
|
+
org: Joi80.string().hex().required(),
|
|
19422
|
+
fiscalYear: Joi80.number().required(),
|
|
19423
|
+
from: Joi80.number().optional().allow("", null),
|
|
19424
|
+
to: Joi80.number().optional().allow("", null)
|
|
19425
|
+
});
|
|
19426
|
+
const { error } = validation.validate({ ...req.params, ...req.query });
|
|
19427
|
+
if (error) {
|
|
19428
|
+
next(new BadRequestError90(error.message));
|
|
19429
|
+
return;
|
|
19430
|
+
}
|
|
19431
|
+
try {
|
|
19432
|
+
const data = await _getBalanceSheet({ org, fiscalYear, from, to });
|
|
19433
|
+
res.json(data);
|
|
19434
|
+
} catch (error2) {
|
|
19435
|
+
next(error2);
|
|
19436
|
+
}
|
|
19437
|
+
}
|
|
19438
|
+
async function getIncomeStatement(req, res, next) {
|
|
19439
|
+
const org = req.params.org ?? "";
|
|
19440
|
+
const fiscalYear = typeof req.params.fiscalYear === "string" ? Number(req.params.fiscalYear) : NaN;
|
|
19441
|
+
const from = typeof req.query.from === "string" ? Number(req.query.from) : void 0;
|
|
19442
|
+
const to = typeof req.query.to === "string" ? Number(req.query.to) : void 0;
|
|
19443
|
+
const validation = Joi80.object({
|
|
19444
|
+
org: Joi80.string().hex().required(),
|
|
19445
|
+
fiscalYear: Joi80.number().required(),
|
|
19446
|
+
from: Joi80.number().optional().allow("", null),
|
|
19447
|
+
to: Joi80.number().optional().allow("", null)
|
|
19448
|
+
});
|
|
19449
|
+
const { error } = validation.validate({ ...req.params, ...req.query });
|
|
19450
|
+
if (error) {
|
|
19451
|
+
next(new BadRequestError90(error.message));
|
|
19452
|
+
return;
|
|
19453
|
+
}
|
|
19454
|
+
try {
|
|
19455
|
+
const data = await _getIncomeStatement({ org, fiscalYear, from, to });
|
|
19456
|
+
res.json(data);
|
|
19457
|
+
} catch (error2) {
|
|
19458
|
+
next(error2);
|
|
19459
|
+
}
|
|
19460
|
+
}
|
|
19046
19461
|
async function updateStatusById(req, res, next) {
|
|
19047
19462
|
const id = req.params.id;
|
|
19048
19463
|
const status2 = req.params.status;
|
|
@@ -19070,7 +19485,10 @@ function useChartOfAccountController() {
|
|
|
19070
19485
|
getById,
|
|
19071
19486
|
updateById,
|
|
19072
19487
|
deleteById,
|
|
19073
|
-
updateStatusById
|
|
19488
|
+
updateStatusById,
|
|
19489
|
+
getTrialBalance,
|
|
19490
|
+
getBalanceSheet,
|
|
19491
|
+
getIncomeStatement
|
|
19074
19492
|
};
|
|
19075
19493
|
}
|
|
19076
19494
|
|
|
@@ -19084,7 +19502,9 @@ var schemaAccountBalance = Joi81.object({
|
|
|
19084
19502
|
accountType: Joi81.string().required(),
|
|
19085
19503
|
period: Joi81.object({
|
|
19086
19504
|
fiscalYear: Joi81.number().required(),
|
|
19087
|
-
|
|
19505
|
+
fiscalMonth: Joi81.number().min(1).max(12).required(),
|
|
19506
|
+
year: Joi81.number().required(),
|
|
19507
|
+
month: Joi81.number().min(1).max(12).required()
|
|
19088
19508
|
}).required(),
|
|
19089
19509
|
openingDebit: Joi81.number().required(),
|
|
19090
19510
|
openingCredit: Joi81.number().required(),
|
|
@@ -19149,10 +19569,18 @@ function useAccountBalanceRepo() {
|
|
|
19149
19569
|
org: 1,
|
|
19150
19570
|
account: 1,
|
|
19151
19571
|
"period.fiscalYear": 1,
|
|
19152
|
-
"period.
|
|
19572
|
+
"period.fiscalMonth": 1
|
|
19153
19573
|
},
|
|
19154
19574
|
unique: true,
|
|
19155
|
-
name: "
|
|
19575
|
+
name: "unique_balance_per_account_fiscal_month"
|
|
19576
|
+
},
|
|
19577
|
+
{
|
|
19578
|
+
key: {
|
|
19579
|
+
org: 1,
|
|
19580
|
+
"period.fiscalYear": 1,
|
|
19581
|
+
"period.fiscalMonth": 1
|
|
19582
|
+
},
|
|
19583
|
+
name: "balance_reporting_fiscal_month"
|
|
19156
19584
|
}
|
|
19157
19585
|
]);
|
|
19158
19586
|
} catch (error) {
|
|
@@ -19211,7 +19639,7 @@ function useAccountBalanceRepo() {
|
|
|
19211
19639
|
}
|
|
19212
19640
|
const items = await repo.collection.aggregate([
|
|
19213
19641
|
{ $match: query },
|
|
19214
|
-
{ $sort: { "period.fiscalYear": -1 } },
|
|
19642
|
+
{ $sort: { "period.fiscalYear": -1, "period.fiscalMonth": -1 } },
|
|
19215
19643
|
{ $skip: options.page * options.limit },
|
|
19216
19644
|
{ $limit: options.limit }
|
|
19217
19645
|
]).toArray();
|
|
@@ -19289,13 +19717,13 @@ function useAccountBalanceRepo() {
|
|
|
19289
19717
|
account,
|
|
19290
19718
|
org,
|
|
19291
19719
|
"period.fiscalYear": options.fiscalYear,
|
|
19292
|
-
"period.
|
|
19720
|
+
"period.fiscalMonth": options.fiscalMonth
|
|
19293
19721
|
};
|
|
19294
19722
|
const cacheKey = makeCacheKey28(namespace_collection, {
|
|
19295
19723
|
account: String(account),
|
|
19296
19724
|
org: String(org),
|
|
19297
19725
|
fiscalYear: options.fiscalYear,
|
|
19298
|
-
|
|
19726
|
+
fiscalMonth: options.fiscalMonth
|
|
19299
19727
|
});
|
|
19300
19728
|
try {
|
|
19301
19729
|
const cached = await repo.getCache(cacheKey);
|
|
@@ -19344,7 +19772,7 @@ function useAccountBalanceRepo() {
|
|
|
19344
19772
|
try {
|
|
19345
19773
|
return await repo.collection.find(
|
|
19346
19774
|
{ account, org, "period.fiscalYear": options.fiscalYear },
|
|
19347
|
-
{ sort: { "period.
|
|
19775
|
+
{ sort: { "period.fiscalMonth": 1 } }
|
|
19348
19776
|
).toArray();
|
|
19349
19777
|
} catch (error) {
|
|
19350
19778
|
if (error instanceof AppError43) {
|
|
@@ -19353,7 +19781,7 @@ function useAccountBalanceRepo() {
|
|
|
19353
19781
|
throw new InternalServerError39("Failed to get account balances by year.");
|
|
19354
19782
|
}
|
|
19355
19783
|
}
|
|
19356
|
-
async function updateById(account, org, fiscalYear,
|
|
19784
|
+
async function updateById(account, org, fiscalYear, fiscalMonth, options, session) {
|
|
19357
19785
|
const { error } = Joi82.object({
|
|
19358
19786
|
openingDebit: Joi82.number().min(0).optional(),
|
|
19359
19787
|
openingCredit: Joi82.number().min(0).optional(),
|
|
@@ -19384,7 +19812,7 @@ function useAccountBalanceRepo() {
|
|
|
19384
19812
|
account,
|
|
19385
19813
|
org,
|
|
19386
19814
|
"period.fiscalYear": fiscalYear,
|
|
19387
|
-
"period.
|
|
19815
|
+
"period.fiscalMonth": fiscalMonth
|
|
19388
19816
|
},
|
|
19389
19817
|
{ $set: { ...options, updatedAt: /* @__PURE__ */ new Date() } },
|
|
19390
19818
|
{ session, upsert: true }
|
|
@@ -21417,20 +21845,6 @@ function useJournalService() {
|
|
|
21417
21845
|
);
|
|
21418
21846
|
}
|
|
21419
21847
|
session.startTransaction();
|
|
21420
|
-
const MONTHS = [
|
|
21421
|
-
"January",
|
|
21422
|
-
"February",
|
|
21423
|
-
"March",
|
|
21424
|
-
"April",
|
|
21425
|
-
"May",
|
|
21426
|
-
"June",
|
|
21427
|
-
"July",
|
|
21428
|
-
"August",
|
|
21429
|
-
"September",
|
|
21430
|
-
"October",
|
|
21431
|
-
"November",
|
|
21432
|
-
"December"
|
|
21433
|
-
];
|
|
21434
21848
|
if (status2 === "posted") {
|
|
21435
21849
|
await updateStatusByJournal(_id, status2, session);
|
|
21436
21850
|
await _updateStatusById(_id, status2, session);
|
|
@@ -21445,13 +21859,30 @@ function useJournalService() {
|
|
|
21445
21859
|
const linesToPost = await getJournalLinesByEntry(_id);
|
|
21446
21860
|
const journalDate = new Date(journalEntry.date);
|
|
21447
21861
|
const fiscalYear = Number(businessProfile.currentFiscalYear);
|
|
21448
|
-
const
|
|
21862
|
+
const calendarYear = journalDate.getFullYear();
|
|
21863
|
+
const calendarMonth = journalDate.getMonth() + 1;
|
|
21864
|
+
const FISCAL_MONTHS = [
|
|
21865
|
+
"January",
|
|
21866
|
+
"February",
|
|
21867
|
+
"March",
|
|
21868
|
+
"April",
|
|
21869
|
+
"May",
|
|
21870
|
+
"June",
|
|
21871
|
+
"July",
|
|
21872
|
+
"August",
|
|
21873
|
+
"September",
|
|
21874
|
+
"October",
|
|
21875
|
+
"November",
|
|
21876
|
+
"December"
|
|
21877
|
+
];
|
|
21878
|
+
const fiscalStartIdx = FISCAL_MONTHS.indexOf(businessProfile.fiscalYearStart);
|
|
21879
|
+
const fiscalMonth = (calendarMonth - 1 - fiscalStartIdx + 12) % 12 + 1;
|
|
21449
21880
|
for (const line of linesToPost) {
|
|
21450
21881
|
const existingBalance = await getAccountBalance({
|
|
21451
21882
|
account: String(line.account),
|
|
21452
21883
|
org: String(journalEntry.org),
|
|
21453
21884
|
fiscalYear,
|
|
21454
|
-
|
|
21885
|
+
fiscalMonth
|
|
21455
21886
|
});
|
|
21456
21887
|
if (existingBalance) {
|
|
21457
21888
|
const movementDebit = existingBalance.movementDebit + (line.debit || 0);
|
|
@@ -21466,7 +21897,7 @@ function useJournalService() {
|
|
|
21466
21897
|
String(line.account),
|
|
21467
21898
|
String(journalEntry.org),
|
|
21468
21899
|
fiscalYear,
|
|
21469
|
-
|
|
21900
|
+
fiscalMonth,
|
|
21470
21901
|
{
|
|
21471
21902
|
movementDebit,
|
|
21472
21903
|
movementCredit,
|
|
@@ -21483,10 +21914,7 @@ function useJournalService() {
|
|
|
21483
21914
|
org: String(journalEntry.org),
|
|
21484
21915
|
fiscalYear
|
|
21485
21916
|
});
|
|
21486
|
-
const
|
|
21487
|
-
const previousRecord = allYearBalances.filter((r) => MONTHS.indexOf(r.period.month) < currentMonthIdx).sort(
|
|
21488
|
-
(a, b) => MONTHS.indexOf(b.period.month) - MONTHS.indexOf(a.period.month)
|
|
21489
|
-
)[0];
|
|
21917
|
+
const previousRecord = allYearBalances.filter((r) => r.period.fiscalMonth < fiscalMonth).sort((a, b) => b.period.fiscalMonth - a.period.fiscalMonth)[0];
|
|
21490
21918
|
const openingDebit = previousRecord?.closingDebit ?? 0;
|
|
21491
21919
|
const openingCredit = previousRecord?.closingCredit ?? 0;
|
|
21492
21920
|
const movementDebit = line.debit || 0;
|
|
@@ -21502,7 +21930,7 @@ function useJournalService() {
|
|
|
21502
21930
|
org: String(journalEntry.org),
|
|
21503
21931
|
account: String(line.account),
|
|
21504
21932
|
accountType: line.accountType || "",
|
|
21505
|
-
period: { fiscalYear, month },
|
|
21933
|
+
period: { fiscalYear, fiscalMonth, year: calendarYear, month: calendarMonth },
|
|
21506
21934
|
openingDebit,
|
|
21507
21935
|
openingCredit,
|
|
21508
21936
|
movementDebit,
|