@goweekdays/core 2.15.2 → 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 +6 -0
- package/dist/index.d.ts +27 -4
- package/dist/index.js +463 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +463 -36
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -18701,6 +18701,242 @@ function useChartOfAccountRepo() {
|
|
|
18701
18701
|
throw new InternalServerError38("Failed to update children count.");
|
|
18702
18702
|
}
|
|
18703
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
|
+
}
|
|
18704
18940
|
return {
|
|
18705
18941
|
createIndexes,
|
|
18706
18942
|
add,
|
|
@@ -18711,7 +18947,9 @@ function useChartOfAccountRepo() {
|
|
|
18711
18947
|
deleteById,
|
|
18712
18948
|
updateStatusById,
|
|
18713
18949
|
countByPath,
|
|
18714
|
-
updateChildrenCountById
|
|
18950
|
+
updateChildrenCountById,
|
|
18951
|
+
getTrialBalance,
|
|
18952
|
+
getBalanceSheet
|
|
18715
18953
|
};
|
|
18716
18954
|
}
|
|
18717
18955
|
|
|
@@ -18729,7 +18967,9 @@ function useChartOfAccountService() {
|
|
|
18729
18967
|
updateById: _updateById,
|
|
18730
18968
|
deleteById: _deleteById,
|
|
18731
18969
|
countByPath,
|
|
18732
|
-
updateChildrenCountById
|
|
18970
|
+
updateChildrenCountById,
|
|
18971
|
+
getTrialBalance: _getTrialBalance,
|
|
18972
|
+
getBalanceSheet: _getBalanceSheet
|
|
18733
18973
|
} = useChartOfAccountRepo();
|
|
18734
18974
|
async function add(value) {
|
|
18735
18975
|
const { error } = schemaChartOfAccountBase.validate(value);
|
|
@@ -18870,10 +19110,112 @@ function useChartOfAccountService() {
|
|
|
18870
19110
|
session.endSession();
|
|
18871
19111
|
}
|
|
18872
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
|
+
}
|
|
18873
19212
|
return {
|
|
18874
19213
|
add,
|
|
18875
19214
|
updateById,
|
|
18876
|
-
deleteById
|
|
19215
|
+
deleteById,
|
|
19216
|
+
getTrialBalance,
|
|
19217
|
+
getBalanceSheet,
|
|
19218
|
+
getIncomeStatement
|
|
18877
19219
|
};
|
|
18878
19220
|
}
|
|
18879
19221
|
|
|
@@ -18888,7 +19230,10 @@ function useChartOfAccountController() {
|
|
|
18888
19230
|
const {
|
|
18889
19231
|
add: _add,
|
|
18890
19232
|
updateById: _updateById,
|
|
18891
|
-
deleteById: _deleteById
|
|
19233
|
+
deleteById: _deleteById,
|
|
19234
|
+
getTrialBalance: _getTrialBalance,
|
|
19235
|
+
getBalanceSheet: _getBalanceSheet,
|
|
19236
|
+
getIncomeStatement: _getIncomeStatement
|
|
18892
19237
|
} = useChartOfAccountService();
|
|
18893
19238
|
async function add(req, res, next) {
|
|
18894
19239
|
const value = req.body;
|
|
@@ -19044,6 +19389,75 @@ function useChartOfAccountController() {
|
|
|
19044
19389
|
next(error);
|
|
19045
19390
|
}
|
|
19046
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
|
+
}
|
|
19047
19461
|
async function updateStatusById(req, res, next) {
|
|
19048
19462
|
const id = req.params.id;
|
|
19049
19463
|
const status2 = req.params.status;
|
|
@@ -19071,7 +19485,10 @@ function useChartOfAccountController() {
|
|
|
19071
19485
|
getById,
|
|
19072
19486
|
updateById,
|
|
19073
19487
|
deleteById,
|
|
19074
|
-
updateStatusById
|
|
19488
|
+
updateStatusById,
|
|
19489
|
+
getTrialBalance,
|
|
19490
|
+
getBalanceSheet,
|
|
19491
|
+
getIncomeStatement
|
|
19075
19492
|
};
|
|
19076
19493
|
}
|
|
19077
19494
|
|
|
@@ -19085,7 +19502,9 @@ var schemaAccountBalance = Joi81.object({
|
|
|
19085
19502
|
accountType: Joi81.string().required(),
|
|
19086
19503
|
period: Joi81.object({
|
|
19087
19504
|
fiscalYear: Joi81.number().required(),
|
|
19088
|
-
|
|
19505
|
+
fiscalMonth: Joi81.number().min(1).max(12).required(),
|
|
19506
|
+
year: Joi81.number().required(),
|
|
19507
|
+
month: Joi81.number().min(1).max(12).required()
|
|
19089
19508
|
}).required(),
|
|
19090
19509
|
openingDebit: Joi81.number().required(),
|
|
19091
19510
|
openingCredit: Joi81.number().required(),
|
|
@@ -19150,10 +19569,18 @@ function useAccountBalanceRepo() {
|
|
|
19150
19569
|
org: 1,
|
|
19151
19570
|
account: 1,
|
|
19152
19571
|
"period.fiscalYear": 1,
|
|
19153
|
-
"period.
|
|
19572
|
+
"period.fiscalMonth": 1
|
|
19154
19573
|
},
|
|
19155
19574
|
unique: true,
|
|
19156
|
-
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"
|
|
19157
19584
|
}
|
|
19158
19585
|
]);
|
|
19159
19586
|
} catch (error) {
|
|
@@ -19212,7 +19639,7 @@ function useAccountBalanceRepo() {
|
|
|
19212
19639
|
}
|
|
19213
19640
|
const items = await repo.collection.aggregate([
|
|
19214
19641
|
{ $match: query },
|
|
19215
|
-
{ $sort: { "period.fiscalYear": -1 } },
|
|
19642
|
+
{ $sort: { "period.fiscalYear": -1, "period.fiscalMonth": -1 } },
|
|
19216
19643
|
{ $skip: options.page * options.limit },
|
|
19217
19644
|
{ $limit: options.limit }
|
|
19218
19645
|
]).toArray();
|
|
@@ -19290,13 +19717,13 @@ function useAccountBalanceRepo() {
|
|
|
19290
19717
|
account,
|
|
19291
19718
|
org,
|
|
19292
19719
|
"period.fiscalYear": options.fiscalYear,
|
|
19293
|
-
"period.
|
|
19720
|
+
"period.fiscalMonth": options.fiscalMonth
|
|
19294
19721
|
};
|
|
19295
19722
|
const cacheKey = makeCacheKey28(namespace_collection, {
|
|
19296
19723
|
account: String(account),
|
|
19297
19724
|
org: String(org),
|
|
19298
19725
|
fiscalYear: options.fiscalYear,
|
|
19299
|
-
|
|
19726
|
+
fiscalMonth: options.fiscalMonth
|
|
19300
19727
|
});
|
|
19301
19728
|
try {
|
|
19302
19729
|
const cached = await repo.getCache(cacheKey);
|
|
@@ -19345,7 +19772,7 @@ function useAccountBalanceRepo() {
|
|
|
19345
19772
|
try {
|
|
19346
19773
|
return await repo.collection.find(
|
|
19347
19774
|
{ account, org, "period.fiscalYear": options.fiscalYear },
|
|
19348
|
-
{ sort: { "period.
|
|
19775
|
+
{ sort: { "period.fiscalMonth": 1 } }
|
|
19349
19776
|
).toArray();
|
|
19350
19777
|
} catch (error) {
|
|
19351
19778
|
if (error instanceof AppError43) {
|
|
@@ -19354,7 +19781,7 @@ function useAccountBalanceRepo() {
|
|
|
19354
19781
|
throw new InternalServerError39("Failed to get account balances by year.");
|
|
19355
19782
|
}
|
|
19356
19783
|
}
|
|
19357
|
-
async function updateById(account, org, fiscalYear,
|
|
19784
|
+
async function updateById(account, org, fiscalYear, fiscalMonth, options, session) {
|
|
19358
19785
|
const { error } = Joi82.object({
|
|
19359
19786
|
openingDebit: Joi82.number().min(0).optional(),
|
|
19360
19787
|
openingCredit: Joi82.number().min(0).optional(),
|
|
@@ -19385,7 +19812,7 @@ function useAccountBalanceRepo() {
|
|
|
19385
19812
|
account,
|
|
19386
19813
|
org,
|
|
19387
19814
|
"period.fiscalYear": fiscalYear,
|
|
19388
|
-
"period.
|
|
19815
|
+
"period.fiscalMonth": fiscalMonth
|
|
19389
19816
|
},
|
|
19390
19817
|
{ $set: { ...options, updatedAt: /* @__PURE__ */ new Date() } },
|
|
19391
19818
|
{ session, upsert: true }
|
|
@@ -21418,20 +21845,6 @@ function useJournalService() {
|
|
|
21418
21845
|
);
|
|
21419
21846
|
}
|
|
21420
21847
|
session.startTransaction();
|
|
21421
|
-
const MONTHS = [
|
|
21422
|
-
"January",
|
|
21423
|
-
"February",
|
|
21424
|
-
"March",
|
|
21425
|
-
"April",
|
|
21426
|
-
"May",
|
|
21427
|
-
"June",
|
|
21428
|
-
"July",
|
|
21429
|
-
"August",
|
|
21430
|
-
"September",
|
|
21431
|
-
"October",
|
|
21432
|
-
"November",
|
|
21433
|
-
"December"
|
|
21434
|
-
];
|
|
21435
21848
|
if (status2 === "posted") {
|
|
21436
21849
|
await updateStatusByJournal(_id, status2, session);
|
|
21437
21850
|
await _updateStatusById(_id, status2, session);
|
|
@@ -21446,13 +21859,30 @@ function useJournalService() {
|
|
|
21446
21859
|
const linesToPost = await getJournalLinesByEntry(_id);
|
|
21447
21860
|
const journalDate = new Date(journalEntry.date);
|
|
21448
21861
|
const fiscalYear = Number(businessProfile.currentFiscalYear);
|
|
21449
|
-
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;
|
|
21450
21880
|
for (const line of linesToPost) {
|
|
21451
21881
|
const existingBalance = await getAccountBalance({
|
|
21452
21882
|
account: String(line.account),
|
|
21453
21883
|
org: String(journalEntry.org),
|
|
21454
21884
|
fiscalYear,
|
|
21455
|
-
|
|
21885
|
+
fiscalMonth
|
|
21456
21886
|
});
|
|
21457
21887
|
if (existingBalance) {
|
|
21458
21888
|
const movementDebit = existingBalance.movementDebit + (line.debit || 0);
|
|
@@ -21467,7 +21897,7 @@ function useJournalService() {
|
|
|
21467
21897
|
String(line.account),
|
|
21468
21898
|
String(journalEntry.org),
|
|
21469
21899
|
fiscalYear,
|
|
21470
|
-
|
|
21900
|
+
fiscalMonth,
|
|
21471
21901
|
{
|
|
21472
21902
|
movementDebit,
|
|
21473
21903
|
movementCredit,
|
|
@@ -21484,10 +21914,7 @@ function useJournalService() {
|
|
|
21484
21914
|
org: String(journalEntry.org),
|
|
21485
21915
|
fiscalYear
|
|
21486
21916
|
});
|
|
21487
|
-
const
|
|
21488
|
-
const previousRecord = allYearBalances.filter((r) => MONTHS.indexOf(r.period.month) < currentMonthIdx).sort(
|
|
21489
|
-
(a, b) => MONTHS.indexOf(b.period.month) - MONTHS.indexOf(a.period.month)
|
|
21490
|
-
)[0];
|
|
21917
|
+
const previousRecord = allYearBalances.filter((r) => r.period.fiscalMonth < fiscalMonth).sort((a, b) => b.period.fiscalMonth - a.period.fiscalMonth)[0];
|
|
21491
21918
|
const openingDebit = previousRecord?.closingDebit ?? 0;
|
|
21492
21919
|
const openingCredit = previousRecord?.closingCredit ?? 0;
|
|
21493
21920
|
const movementDebit = line.debit || 0;
|
|
@@ -21503,7 +21930,7 @@ function useJournalService() {
|
|
|
21503
21930
|
org: String(journalEntry.org),
|
|
21504
21931
|
account: String(line.account),
|
|
21505
21932
|
accountType: line.accountType || "",
|
|
21506
|
-
period: { fiscalYear, month },
|
|
21933
|
+
period: { fiscalYear, fiscalMonth, year: calendarYear, month: calendarMonth },
|
|
21507
21934
|
openingDebit,
|
|
21508
21935
|
openingCredit,
|
|
21509
21936
|
movementDebit,
|