@goweekdays/core 2.15.0 → 2.15.2

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/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.");
@@ -19145,7 +19146,12 @@ function useAccountBalanceRepo() {
19145
19146
  { key: { account: 1 } },
19146
19147
  { key: { "period.fiscalYear": 1 } },
19147
19148
  {
19148
- key: { org: 1, account: 1, "period.fiscalYear": 1, "period.month": 1 },
19149
+ key: {
19150
+ org: 1,
19151
+ account: 1,
19152
+ "period.fiscalYear": 1,
19153
+ "period.month": 1
19154
+ },
19149
19155
  unique: true,
19150
19156
  name: "unique_balance_per_account_month"
19151
19157
  }
@@ -19320,9 +19326,7 @@ function useAccountBalanceRepo() {
19320
19326
  if (error instanceof AppError43) {
19321
19327
  throw error;
19322
19328
  }
19323
- throw new InternalServerError39(
19324
- "Failed to get account balance."
19325
- );
19329
+ throw new InternalServerError39("Failed to get account balance.");
19326
19330
  }
19327
19331
  }
19328
19332
  async function getYearBalancesByAccount(options) {
@@ -19347,9 +19351,7 @@ function useAccountBalanceRepo() {
19347
19351
  if (error instanceof AppError43) {
19348
19352
  throw error;
19349
19353
  }
19350
- throw new InternalServerError39(
19351
- "Failed to get account balances by year."
19352
- );
19354
+ throw new InternalServerError39("Failed to get account balances by year.");
19353
19355
  }
19354
19356
  }
19355
19357
  async function updateById(account, org, fiscalYear, month, options, session) {
@@ -19435,7 +19437,7 @@ var journalTypes = [
19435
19437
  var schemaJournalBase = {
19436
19438
  date: Joi83.date().required(),
19437
19439
  type: Joi83.string().allow(...journalTypes).required(),
19438
- transaction: Joi83.string().required(),
19440
+ transaction: Joi83.string().hex().required(),
19439
19441
  customer: Joi83.string().hex().optional().allow("", null),
19440
19442
  description: Joi83.string().required(),
19441
19443
  invoiceNumber: Joi83.string().optional().allow("", null)
@@ -19452,6 +19454,7 @@ var schemaJournalRepo = Joi83.object({
19452
19454
  id: Joi83.string().required(),
19453
19455
  createdBy: Joi83.string().hex().required(),
19454
19456
  createdByName: Joi83.string().required(),
19457
+ transactionName: Joi83.string().required(),
19455
19458
  customerName: Joi83.string().optional().allow("", null),
19456
19459
  status: Joi83.string().valid(...JournalStatuses).required(),
19457
19460
  reversedEntry: Joi83.string().hex().optional().allow("", null),
@@ -19463,6 +19466,7 @@ var schemaJournalRepoUpdate = Joi83.object({
19463
19466
  date: Joi83.date().optional().allow("", null),
19464
19467
  type: Joi83.string().allow(...journalTypes).optional().allow("", null),
19465
19468
  transaction: Joi83.string().optional().allow("", null),
19469
+ transactionName: Joi83.string().optional().allow("", null),
19466
19470
  description: Joi83.string().optional().allow("", null),
19467
19471
  status: Joi83.string().valid(...JournalStatuses).optional().allow("", null),
19468
19472
  customerName: Joi83.string().optional().allow("", null),
@@ -19491,6 +19495,11 @@ function modelJournal(data) {
19491
19495
  } catch (error2) {
19492
19496
  throw new BadRequestError93(`Invalid org ID: ${data.org}`);
19493
19497
  }
19498
+ try {
19499
+ data.transaction = new ObjectId50(data.transaction);
19500
+ } catch (error2) {
19501
+ throw new BadRequestError93(`Invalid transaction ID: ${data.transaction}`);
19502
+ }
19494
19503
  try {
19495
19504
  data.createdBy = new ObjectId50(data.createdBy);
19496
19505
  } catch (error2) {
@@ -19535,6 +19544,7 @@ function modelJournal(data) {
19535
19544
  org: data.org,
19536
19545
  type: data.type,
19537
19546
  transaction: data.transaction,
19547
+ transactionName: data.transactionName ?? "",
19538
19548
  date,
19539
19549
  invoiceNumber: data.invoiceNumber ?? "",
19540
19550
  customer: data.customer ?? "",
@@ -19839,6 +19849,24 @@ function useJournalRepo() {
19839
19849
  throw new InternalServerError40("Failed to update journal status.");
19840
19850
  }
19841
19851
  }
19852
+ async function existsByTransactionId(org, transactionId) {
19853
+ try {
19854
+ org = new ObjectId51(org);
19855
+ } catch {
19856
+ throw new BadRequestError94("Invalid org ID.");
19857
+ }
19858
+ try {
19859
+ transactionId = new ObjectId51(transactionId);
19860
+ } catch {
19861
+ throw new BadRequestError94("Invalid transaction ID.");
19862
+ }
19863
+ const count = await repo.collection.countDocuments({
19864
+ org,
19865
+ transaction: transactionId,
19866
+ status: { $ne: "voided" }
19867
+ });
19868
+ return count > 0;
19869
+ }
19842
19870
  return {
19843
19871
  createIndexes,
19844
19872
  delCachedData: repo.delCachedData,
@@ -19847,12 +19875,13 @@ function useJournalRepo() {
19847
19875
  getById,
19848
19876
  updateById,
19849
19877
  deleteById,
19850
- updateStatusById
19878
+ updateStatusById,
19879
+ existsByTransactionId
19851
19880
  };
19852
19881
  }
19853
19882
 
19854
19883
  // src/resources/finance-journal/finance.journal.service.ts
19855
- import Joi90 from "joi";
19884
+ import Joi93 from "joi";
19856
19885
 
19857
19886
  // src/resources/finance-journal-line/finance.journal.line.model.ts
19858
19887
  import { BadRequestError as BadRequestError95 } from "@goweekdays/utils";
@@ -20192,6 +20221,23 @@ function useJournalLineRepo() {
20192
20221
  throw new InternalServerError41("Failed to delete journal line.");
20193
20222
  }
20194
20223
  }
20224
+ async function updateBalanceById(_id, balance, session) {
20225
+ try {
20226
+ _id = new ObjectId53(_id);
20227
+ } catch (error) {
20228
+ throw new BadRequestError96("Invalid Journal Line ID.");
20229
+ }
20230
+ try {
20231
+ await collection.updateOne(
20232
+ { _id },
20233
+ { $set: { balance, updatedAt: /* @__PURE__ */ new Date() } },
20234
+ { session }
20235
+ );
20236
+ delCachedData();
20237
+ } catch (error) {
20238
+ throw new InternalServerError41("Failed to update journal line balance.");
20239
+ }
20240
+ }
20195
20241
  async function updateStatusByJournal(journalEntry, status2, session) {
20196
20242
  const validation = Joi86.object({
20197
20243
  journalEntry: Joi86.string().hex().required(),
@@ -20232,6 +20278,7 @@ function useJournalLineRepo() {
20232
20278
  getById,
20233
20279
  getByEntry,
20234
20280
  updateById,
20281
+ updateBalanceById,
20235
20282
  deleteById,
20236
20283
  updateStatusByJournal
20237
20284
  };
@@ -20239,10 +20286,10 @@ function useJournalLineRepo() {
20239
20286
 
20240
20287
  // src/resources/finance-journal/finance.journal.service.ts
20241
20288
  import {
20242
- AppError as AppError47,
20243
- BadRequestError as BadRequestError101,
20244
- InternalServerError as InternalServerError43,
20245
- NotFoundError as NotFoundError6,
20289
+ AppError as AppError49,
20290
+ BadRequestError as BadRequestError105,
20291
+ InternalServerError as InternalServerError45,
20292
+ NotFoundError as NotFoundError7,
20246
20293
  useAtlas as useAtlas16
20247
20294
  } from "@goweekdays/utils";
20248
20295
 
@@ -20661,6 +20708,542 @@ function useJournalLogRepo() {
20661
20708
  import Joi89 from "joi";
20662
20709
  import { BadRequestError as BadRequestError100, logger as logger51 } from "@goweekdays/utils";
20663
20710
 
20711
+ // src/resources/finance-journal-transaction/finance.journal.transaction.model.ts
20712
+ import { BadRequestError as BadRequestError101 } from "@goweekdays/utils";
20713
+ import Joi90 from "joi";
20714
+ import { ObjectId as ObjectId56 } from "mongodb";
20715
+ var schemaJournalTransactionAccount = Joi90.object({
20716
+ title: Joi90.string().required(),
20717
+ value: Joi90.string().hex().required()
20718
+ });
20719
+ var schemaJournalTransactionBase = {
20720
+ type: Joi90.string().valid(...journalTypes).required(),
20721
+ code: Joi90.string().required(),
20722
+ title: Joi90.string().required(),
20723
+ debits: Joi90.array().items(schemaJournalTransactionAccount).min(1).required(),
20724
+ credits: Joi90.array().items(schemaJournalTransactionAccount).min(1).required(),
20725
+ template: Joi90.boolean().required(),
20726
+ description: Joi90.string().optional().allow("", null)
20727
+ };
20728
+ var schemaJournalTransactionCtrl = Joi90.object({
20729
+ ...schemaJournalTransactionBase,
20730
+ org: Joi90.string().hex().required(),
20731
+ createdBy: Joi90.string().hex().required()
20732
+ });
20733
+ var schemaJournalTransactionCtrlUpdate = Joi90.object({
20734
+ code: Joi90.string().optional(),
20735
+ title: Joi90.string().optional(),
20736
+ debits: Joi90.array().items(schemaJournalTransactionAccount).min(1).optional(),
20737
+ credits: Joi90.array().items(schemaJournalTransactionAccount).min(1).optional(),
20738
+ template: Joi90.boolean().optional(),
20739
+ description: Joi90.string().optional().allow("", null)
20740
+ });
20741
+ var schemaJournalTransactionRepo = Joi90.object({
20742
+ ...schemaJournalTransactionBase,
20743
+ org: Joi90.string().hex().required(),
20744
+ createdBy: Joi90.string().hex().required(),
20745
+ createdByName: Joi90.string().optional().allow("", null)
20746
+ });
20747
+ var schemaJournalTransactionGetAll = Joi90.object({
20748
+ org: Joi90.string().hex().required(),
20749
+ type: Joi90.string().optional().allow("", null),
20750
+ search: Joi90.string().optional().allow("", null),
20751
+ page: Joi90.number().optional().allow("", null),
20752
+ limit: Joi90.number().max(100).optional().allow("", null)
20753
+ });
20754
+ function modelJournalTransaction(data) {
20755
+ const { error } = schemaJournalTransactionRepo.validate(data);
20756
+ if (error) {
20757
+ throw new BadRequestError101(
20758
+ `Invalid journal transaction data: ${error.message}`
20759
+ );
20760
+ }
20761
+ try {
20762
+ data.org = new ObjectId56(data.org);
20763
+ } catch (error2) {
20764
+ throw new BadRequestError101(`Invalid org ID: ${data.org}`);
20765
+ }
20766
+ try {
20767
+ data.createdBy = new ObjectId56(data.createdBy);
20768
+ } catch (error2) {
20769
+ throw new BadRequestError101(`Invalid createdBy ID: ${data.createdBy}`);
20770
+ }
20771
+ for (let i = 0; i < data.debits.length; i++) {
20772
+ try {
20773
+ data.debits[i].value = new ObjectId56(data.debits[i].value);
20774
+ } catch (error2) {
20775
+ throw new BadRequestError101(`Invalid debit account ID at index ${i}`);
20776
+ }
20777
+ }
20778
+ for (let i = 0; i < data.credits.length; i++) {
20779
+ try {
20780
+ data.credits[i].value = new ObjectId56(data.credits[i].value);
20781
+ } catch (error2) {
20782
+ throw new BadRequestError101(`Invalid credit account ID at index ${i}`);
20783
+ }
20784
+ }
20785
+ const now = /* @__PURE__ */ new Date();
20786
+ return {
20787
+ _id: data._id,
20788
+ org: data.org,
20789
+ type: data.type,
20790
+ code: data.code,
20791
+ title: data.title,
20792
+ debits: data.debits,
20793
+ credits: data.credits,
20794
+ template: data.template ?? false,
20795
+ description: data.description ?? "",
20796
+ createdBy: data.createdBy,
20797
+ createdByName: data.createdByName ?? "",
20798
+ createdAt: data.createdAt ?? now,
20799
+ updatedAt: data.updatedAt ?? ""
20800
+ };
20801
+ }
20802
+
20803
+ // src/resources/finance-journal-transaction/finance.journal.transaction.repository.ts
20804
+ import {
20805
+ AppError as AppError47,
20806
+ BadRequestError as BadRequestError102,
20807
+ makeCacheKey as makeCacheKey32,
20808
+ paginate as paginate28,
20809
+ logger as logger52,
20810
+ InternalServerError as InternalServerError43,
20811
+ useRepo as useRepo31
20812
+ } from "@goweekdays/utils";
20813
+ import { ObjectId as ObjectId57 } from "mongodb";
20814
+ function useJournalTransactionRepo() {
20815
+ const namespace_collection = "finance.journal.transactions";
20816
+ const repo = useRepo31(namespace_collection);
20817
+ async function createIndexes() {
20818
+ try {
20819
+ await repo.collection.createIndexes([
20820
+ { key: { org: 1, type: 1, _id: 1 } },
20821
+ { key: { org: 1 } },
20822
+ { key: { type: 1 } },
20823
+ { key: { code: 1 } },
20824
+ { key: { org: 1, type: 1 } },
20825
+ {
20826
+ key: {
20827
+ title: "text",
20828
+ code: "text",
20829
+ description: "text"
20830
+ }
20831
+ },
20832
+ {
20833
+ key: { org: 1, type: 1, code: 1 },
20834
+ unique: true,
20835
+ name: "unique_org_type_code"
20836
+ }
20837
+ ]);
20838
+ } catch (error) {
20839
+ throw new Error("Failed to create index on journal transactions.");
20840
+ }
20841
+ }
20842
+ async function add(value, session) {
20843
+ try {
20844
+ value = modelJournalTransaction(value);
20845
+ const res = await repo.collection.insertOne(value, { session });
20846
+ repo.delCachedData();
20847
+ return res.insertedId;
20848
+ } catch (error) {
20849
+ logger52.log({ level: "error", message: error.message });
20850
+ throw new BadRequestError102(
20851
+ `Failed to create journal transaction: ${error.message}`
20852
+ );
20853
+ }
20854
+ }
20855
+ async function getAll(options) {
20856
+ options.page = options.page && options.page > 0 ? options.page - 1 : 0;
20857
+ options.limit = options.limit ?? 10;
20858
+ options.search = options.search ?? "";
20859
+ const { error } = schemaJournalTransactionGetAll.validate(options);
20860
+ if (error) {
20861
+ throw new BadRequestError102(`Invalid query parameters: ${error.message}`);
20862
+ }
20863
+ const query = {};
20864
+ const cacheKeyOptions = {
20865
+ page: options.page,
20866
+ limit: options.limit
20867
+ };
20868
+ try {
20869
+ query.org = new ObjectId57(options.org);
20870
+ cacheKeyOptions.org = String(options.org);
20871
+ } catch (error2) {
20872
+ throw new BadRequestError102("Invalid organization ID.");
20873
+ }
20874
+ if (options.type) {
20875
+ query.type = options.type;
20876
+ cacheKeyOptions.type = options.type;
20877
+ }
20878
+ if (options.search) {
20879
+ query.$text = { $search: options.search };
20880
+ cacheKeyOptions.search = options.search;
20881
+ }
20882
+ const cacheKey = makeCacheKey32(namespace_collection, cacheKeyOptions);
20883
+ logger52.log({
20884
+ level: "info",
20885
+ message: `Cache key for getAll journal transactions: ${cacheKey}`
20886
+ });
20887
+ try {
20888
+ const cached = await repo.getCache(cacheKey);
20889
+ if (cached) {
20890
+ logger52.log({
20891
+ level: "info",
20892
+ message: `Cache hit for getAll journal transactions: ${cacheKey}`
20893
+ });
20894
+ return cached;
20895
+ }
20896
+ const items = await repo.collection.aggregate([
20897
+ { $match: query },
20898
+ { $sort: { title: 1 } },
20899
+ { $skip: options.page * options.limit },
20900
+ { $limit: options.limit }
20901
+ ]).toArray();
20902
+ const length = await repo.collection.countDocuments(query);
20903
+ const data = paginate28(items, options.page, options.limit, length);
20904
+ repo.setCache(cacheKey, data, 600).then(() => {
20905
+ logger52.log({
20906
+ level: "info",
20907
+ message: `Cache set for getAll journal transactions: ${cacheKey}`
20908
+ });
20909
+ }).catch((err) => {
20910
+ logger52.log({
20911
+ level: "error",
20912
+ message: `Failed to set cache for getAll journal transactions: ${err.message}`
20913
+ });
20914
+ });
20915
+ return data;
20916
+ } catch (error2) {
20917
+ logger52.log({ level: "error", message: `${error2}` });
20918
+ throw error2;
20919
+ }
20920
+ }
20921
+ async function getByOrgTypeId(options) {
20922
+ try {
20923
+ options._id = new ObjectId57(options._id);
20924
+ } catch (error) {
20925
+ throw new BadRequestError102("Invalid ID.");
20926
+ }
20927
+ try {
20928
+ options.org = new ObjectId57(options.org);
20929
+ } catch (error) {
20930
+ throw new BadRequestError102("Invalid organization ID.");
20931
+ }
20932
+ const cacheKey = makeCacheKey32(namespace_collection, {
20933
+ org: String(options.org),
20934
+ type: options.type,
20935
+ _id: String(options._id),
20936
+ tag: "org_type_id"
20937
+ });
20938
+ try {
20939
+ const cached = await repo.getCache(cacheKey);
20940
+ if (cached) {
20941
+ logger52.log({
20942
+ level: "info",
20943
+ message: `Cache hit for get by org + type + id journal transaction: ${cacheKey}`
20944
+ });
20945
+ return cached;
20946
+ }
20947
+ const result = await repo.collection.findOne({
20948
+ _id: options._id,
20949
+ org: options.org,
20950
+ type: options.type
20951
+ });
20952
+ repo.setCache(cacheKey, result, 300).then(() => {
20953
+ logger52.log({
20954
+ level: "info",
20955
+ message: `Cache set for journal transaction by org + type + id: ${cacheKey}`
20956
+ });
20957
+ }).catch((err) => {
20958
+ logger52.log({
20959
+ level: "error",
20960
+ message: `Failed to set cache for journal transaction by org + type + id: ${err.message}`
20961
+ });
20962
+ });
20963
+ return result;
20964
+ } catch (error) {
20965
+ if (error instanceof AppError47) {
20966
+ throw error;
20967
+ } else {
20968
+ throw new InternalServerError43("Failed to get journal transaction.");
20969
+ }
20970
+ }
20971
+ }
20972
+ async function updateById(_id, options, session) {
20973
+ const { error } = schemaJournalTransactionCtrlUpdate.validate(options);
20974
+ if (error) {
20975
+ throw new BadRequestError102(
20976
+ `Invalid journal transaction update data: ${error.message}`
20977
+ );
20978
+ }
20979
+ try {
20980
+ _id = new ObjectId57(_id);
20981
+ } catch (error2) {
20982
+ throw new BadRequestError102("Invalid journal transaction ID.");
20983
+ }
20984
+ if (options.debits) {
20985
+ for (let i = 0; i < options.debits.length; i++) {
20986
+ try {
20987
+ options.debits[i].value = new ObjectId57(options.debits[i].value);
20988
+ } catch (error2) {
20989
+ throw new BadRequestError102(`Invalid debit account ID at index ${i}`);
20990
+ }
20991
+ }
20992
+ }
20993
+ if (options.credits) {
20994
+ for (let i = 0; i < options.credits.length; i++) {
20995
+ try {
20996
+ options.credits[i].value = new ObjectId57(options.credits[i].value);
20997
+ } catch (error2) {
20998
+ throw new BadRequestError102(`Invalid credit account ID at index ${i}`);
20999
+ }
21000
+ }
21001
+ }
21002
+ try {
21003
+ await repo.collection.updateOne(
21004
+ { _id },
21005
+ { $set: { ...options, updatedAt: /* @__PURE__ */ new Date() } },
21006
+ { session }
21007
+ );
21008
+ repo.delCachedData();
21009
+ return "Successfully updated journal transaction.";
21010
+ } catch (error2) {
21011
+ throw new InternalServerError43("Failed to update journal transaction.");
21012
+ }
21013
+ }
21014
+ async function deleteById(_id, session) {
21015
+ try {
21016
+ _id = new ObjectId57(_id);
21017
+ } catch (error) {
21018
+ throw new BadRequestError102("Invalid ID.");
21019
+ }
21020
+ try {
21021
+ await repo.collection.deleteOne({ _id }, { session });
21022
+ repo.delCachedData();
21023
+ return "Successfully deleted journal transaction.";
21024
+ } catch (error) {
21025
+ throw new InternalServerError43("Failed to delete journal transaction.");
21026
+ }
21027
+ }
21028
+ return {
21029
+ createIndexes,
21030
+ add,
21031
+ getAll,
21032
+ getByOrgTypeId,
21033
+ updateById,
21034
+ deleteById
21035
+ };
21036
+ }
21037
+
21038
+ // src/resources/finance-journal-transaction/finance.journal.transaction.service.ts
21039
+ import {
21040
+ AppError as AppError48,
21041
+ BadRequestError as BadRequestError103,
21042
+ InternalServerError as InternalServerError44,
21043
+ NotFoundError as NotFoundError6
21044
+ } from "@goweekdays/utils";
21045
+ import Joi91 from "joi";
21046
+ function validateNoDuplicateAccounts(debits, credits) {
21047
+ const debitIds = debits.map((d) => String(d.value));
21048
+ const creditIds = credits.map((c) => String(c.value));
21049
+ const debitSet = new Set(debitIds);
21050
+ if (debitSet.size !== debitIds.length) {
21051
+ throw new BadRequestError103("Duplicate accounts found in debits.");
21052
+ }
21053
+ const creditSet = new Set(creditIds);
21054
+ if (creditSet.size !== creditIds.length) {
21055
+ throw new BadRequestError103("Duplicate accounts found in credits.");
21056
+ }
21057
+ }
21058
+ function useJournalTransactionService() {
21059
+ const {
21060
+ add: _add,
21061
+ updateById: _updateById,
21062
+ getByOrgTypeId
21063
+ } = useJournalTransactionRepo();
21064
+ const { getUserById } = useUserRepo();
21065
+ async function add(value) {
21066
+ const { error } = schemaJournalTransactionCtrl.validate(value);
21067
+ if (error) {
21068
+ throw new BadRequestError103(
21069
+ `Invalid journal transaction data: ${error.message}`
21070
+ );
21071
+ }
21072
+ validateNoDuplicateAccounts(value.debits, value.credits);
21073
+ const user = await getUserById(value.createdBy);
21074
+ if (!user) {
21075
+ throw new NotFoundError6("User not found.");
21076
+ }
21077
+ value.createdByName = `${user.firstName} ${user.lastName}`;
21078
+ try {
21079
+ const id = await _add(value);
21080
+ return id;
21081
+ } catch (error2) {
21082
+ if (error2 instanceof AppError48) {
21083
+ throw error2;
21084
+ }
21085
+ throw new InternalServerError44(
21086
+ `Failed to create journal transaction: ${error2.message}`
21087
+ );
21088
+ }
21089
+ }
21090
+ async function updateById(org, type, _id, options) {
21091
+ const { error: idError } = Joi91.string().hex().required().validate(_id);
21092
+ if (idError) {
21093
+ throw new BadRequestError103("Invalid journal transaction ID.");
21094
+ }
21095
+ const { error } = schemaJournalTransactionCtrlUpdate.validate(options);
21096
+ if (error) {
21097
+ throw new BadRequestError103(`Invalid update data: ${error.message}`);
21098
+ }
21099
+ const existing = await getByOrgTypeId({ org, type, _id });
21100
+ if (!existing) {
21101
+ throw new NotFoundError6("Journal transaction not found.");
21102
+ }
21103
+ const debits = options.debits ?? existing.debits;
21104
+ const credits = options.credits ?? existing.credits;
21105
+ validateNoDuplicateAccounts(debits, credits);
21106
+ try {
21107
+ return await _updateById(_id, options);
21108
+ } catch (error2) {
21109
+ if (error2 instanceof AppError48) {
21110
+ throw error2;
21111
+ }
21112
+ throw new InternalServerError44(
21113
+ `Failed to update journal transaction: ${error2.message}`
21114
+ );
21115
+ }
21116
+ }
21117
+ return {
21118
+ add,
21119
+ updateById
21120
+ };
21121
+ }
21122
+
21123
+ // src/resources/finance-journal-transaction/finance.journal.transaction.controller.ts
21124
+ import Joi92 from "joi";
21125
+ import { BadRequestError as BadRequestError104 } from "@goweekdays/utils";
21126
+ function useJournalTransactionController() {
21127
+ const {
21128
+ getAll: _getAll,
21129
+ getByOrgTypeId: _getByOrgTypeId,
21130
+ deleteById: _deleteById
21131
+ } = useJournalTransactionRepo();
21132
+ const { add: _add, updateById: _updateById } = useJournalTransactionService();
21133
+ async function add(req, res, next) {
21134
+ const value = req.body;
21135
+ const { error } = schemaJournalTransactionCtrl.validate(value);
21136
+ if (error) {
21137
+ next(new BadRequestError104(error.message));
21138
+ return;
21139
+ }
21140
+ try {
21141
+ const id = await _add(value);
21142
+ res.json({ message: "Journal transaction created successfully.", id });
21143
+ return;
21144
+ } catch (error2) {
21145
+ next(error2);
21146
+ }
21147
+ }
21148
+ async function getAll(req, res, next) {
21149
+ const org = req.params.org ?? "";
21150
+ const type = req.params.type ?? "";
21151
+ const search = req.query.search ?? "";
21152
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
21153
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
21154
+ const { error } = schemaJournalTransactionGetAll.validate({
21155
+ ...req.params,
21156
+ ...req.query
21157
+ });
21158
+ if (!isFinite(page)) {
21159
+ next(new BadRequestError104("Invalid page number."));
21160
+ return;
21161
+ }
21162
+ if (!isFinite(limit)) {
21163
+ next(new BadRequestError104("Invalid limit number."));
21164
+ return;
21165
+ }
21166
+ if (error) {
21167
+ next(new BadRequestError104(error.message));
21168
+ return;
21169
+ }
21170
+ try {
21171
+ const data = await _getAll({ org, type, search, page, limit });
21172
+ res.json(data);
21173
+ return;
21174
+ } catch (error2) {
21175
+ next(error2);
21176
+ }
21177
+ }
21178
+ async function getByOrgTypeId(req, res, next) {
21179
+ const { error } = Joi92.object({
21180
+ org: Joi92.string().hex().required(),
21181
+ type: Joi92.string().required(),
21182
+ id: Joi92.string().hex().required()
21183
+ }).validate(req.params);
21184
+ if (error) {
21185
+ next(new BadRequestError104(error.message));
21186
+ return;
21187
+ }
21188
+ const _id = req.params.id;
21189
+ const org = req.params.org;
21190
+ const type = req.params.type;
21191
+ try {
21192
+ const data = await _getByOrgTypeId({ org, type, _id });
21193
+ res.json(data);
21194
+ return;
21195
+ } catch (error2) {
21196
+ next(error2);
21197
+ }
21198
+ }
21199
+ async function updateById(req, res, next) {
21200
+ const value = req.body;
21201
+ const { error } = Joi92.object({
21202
+ id: Joi92.string().hex().required(),
21203
+ org: Joi92.string().hex().required(),
21204
+ type: Joi92.string().allow(...journalTypes).required()
21205
+ }).concat(schemaJournalTransactionCtrlUpdate).validate({ ...req.params, ...value });
21206
+ if (error) {
21207
+ next(new BadRequestError104(error.message));
21208
+ return;
21209
+ }
21210
+ const id = req.params.id ?? "";
21211
+ const org = req.params.org ?? "";
21212
+ const type = req.params.type ?? "";
21213
+ try {
21214
+ const message = await _updateById(org, type, id, value);
21215
+ res.json({ message });
21216
+ return;
21217
+ } catch (error2) {
21218
+ next(error2);
21219
+ }
21220
+ }
21221
+ async function deleteById(req, res, next) {
21222
+ const id = req.params.id;
21223
+ const { error } = Joi92.object({
21224
+ id: Joi92.string().hex().required()
21225
+ }).validate({ id });
21226
+ if (error) {
21227
+ next(new BadRequestError104(error.message));
21228
+ return;
21229
+ }
21230
+ try {
21231
+ const message = await _deleteById(id);
21232
+ res.json({ message });
21233
+ return;
21234
+ } catch (error2) {
21235
+ next(error2);
21236
+ }
21237
+ }
21238
+ return {
21239
+ add,
21240
+ getAll,
21241
+ getByOrgTypeId,
21242
+ updateById,
21243
+ deleteById
21244
+ };
21245
+ }
21246
+
20664
21247
  // src/resources/finance-journal/finance.journal.service.ts
20665
21248
  function useJournalService() {
20666
21249
  const {
@@ -20670,10 +21253,12 @@ function useJournalService() {
20670
21253
  updateById: _updateById,
20671
21254
  delCachedData: delJournalCache
20672
21255
  } = useJournalRepo();
21256
+ const { getByOrgTypeId: getJournalTransaction } = useJournalTransactionRepo();
20673
21257
  const {
20674
21258
  add: addLine,
20675
21259
  getByEntry: getJournalLinesByEntry,
20676
21260
  updateById: updateJournalLineById,
21261
+ updateBalanceById: updateJournalLineBalance,
20677
21262
  deleteById: deleteJournalLineById
20678
21263
  } = useJournalLineRepo();
20679
21264
  const { getUserById } = useUserRepo();
@@ -20687,21 +21272,21 @@ function useJournalService() {
20687
21272
  const { add: addJournalLog } = useJournalLogRepo();
20688
21273
  const { getById: getCustomerById } = useCustomerRepo();
20689
21274
  async function add(entry, lines) {
20690
- const { error } = Joi90.object({
21275
+ const { error } = Joi93.object({
20691
21276
  journalEntry: schemaJournalCtrl.required(),
20692
- journalLines: Joi90.array().items(schemaJournalLineCtrl).min(1).required()
21277
+ journalLines: Joi93.array().items(schemaJournalLineCtrl).min(1).required()
20693
21278
  }).validate({
20694
21279
  journalEntry: entry,
20695
21280
  journalLines: lines
20696
21281
  });
20697
21282
  if (error) {
20698
- throw new BadRequestError101(
21283
+ throw new BadRequestError105(
20699
21284
  `Invalid general journal data: ${error.message}`
20700
21285
  );
20701
21286
  }
20702
21287
  const session = useAtlas16.getClient()?.startSession();
20703
21288
  if (!session) {
20704
- throw new BadRequestError101("Unable to start database session.");
21289
+ throw new BadRequestError105("Unable to start database session.");
20705
21290
  }
20706
21291
  try {
20707
21292
  session.startTransaction();
@@ -20716,16 +21301,25 @@ function useJournalService() {
20716
21301
  await validateJournalLines(lines);
20717
21302
  const user = await getUserById(entry.createdBy);
20718
21303
  if (!user) {
20719
- throw new NotFoundError6("User not found.");
21304
+ throw new NotFoundError7("User not found.");
20720
21305
  }
20721
21306
  entry.createdByName = `${user.firstName} ${user.lastName}`;
20722
21307
  if (entry.customer) {
20723
21308
  const customer = await getCustomerById(String(entry.customer));
20724
21309
  if (!customer) {
20725
- throw new NotFoundError6("Customer not found.");
21310
+ throw new NotFoundError7("Customer not found.");
20726
21311
  }
20727
21312
  entry.customerName = `${customer.firstName} ${customer.lastName}`;
20728
21313
  }
21314
+ const journalTx = await getJournalTransaction({
21315
+ org: String(entry.org),
21316
+ type: entry.type,
21317
+ _id: String(entry.transaction)
21318
+ });
21319
+ if (!journalTx) {
21320
+ throw new NotFoundError7("Transaction not found.");
21321
+ }
21322
+ entry.transactionName = journalTx.title;
20729
21323
  entry.status = "draft";
20730
21324
  const entryId = await _add(entry, session);
20731
21325
  for (const line of lines) {
@@ -20733,7 +21327,7 @@ function useJournalService() {
20733
21327
  line.journalEntry = entryId.toString();
20734
21328
  const account = await getAccountById(String(line.account));
20735
21329
  if (!account) {
20736
- throw new NotFoundError6(`Account not found: ${line.account}`);
21330
+ throw new NotFoundError7(`Account not found: ${line.account}`);
20737
21331
  }
20738
21332
  line.accountName = account.name;
20739
21333
  line.accountCode = account.code;
@@ -20765,10 +21359,10 @@ function useJournalService() {
20765
21359
  return "Journal entry created successfully.";
20766
21360
  } catch (error2) {
20767
21361
  await session.abortTransaction();
20768
- if (error2 instanceof AppError47) {
21362
+ if (error2 instanceof AppError49) {
20769
21363
  throw error2;
20770
21364
  }
20771
- throw new InternalServerError43(
21365
+ throw new InternalServerError45(
20772
21366
  `Failed to create general journal: ${error2.message}`
20773
21367
  );
20774
21368
  } finally {
@@ -20782,18 +21376,19 @@ function useJournalService() {
20782
21376
  getYearBalancesByAccount,
20783
21377
  updateById: updateAccountBalance
20784
21378
  } = useAccountBalanceRepo();
21379
+ const { getByOrg: getBusinessProfileByOrg } = useBusinessProfileRepo();
20785
21380
  async function updateStatusById(_id, status2, user) {
20786
- const validation = Joi90.object({
20787
- _id: Joi90.string().hex().required(),
20788
- status: Joi90.string().valid("posted", "voided").required()
21381
+ const validation = Joi93.object({
21382
+ _id: Joi93.string().hex().required(),
21383
+ status: Joi93.string().valid("posted", "voided").required()
20789
21384
  });
20790
21385
  const { error } = validation.validate({ _id, status: status2 });
20791
21386
  if (error) {
20792
- throw new BadRequestError101(`Invalid input: ${error.message}`);
21387
+ throw new BadRequestError105(`Invalid input: ${error.message}`);
20793
21388
  }
20794
21389
  const session = useAtlas16.getClient()?.startSession();
20795
21390
  if (!session) {
20796
- throw new BadRequestError101("Unable to start database session.");
21391
+ throw new BadRequestError105("Unable to start database session.");
20797
21392
  }
20798
21393
  try {
20799
21394
  let computeClosingBalance2 = function(openingDebit, openingCredit, movementDebit, movementCredit) {
@@ -20807,18 +21402,18 @@ function useJournalService() {
20807
21402
  var computeClosingBalance = computeClosingBalance2;
20808
21403
  const journalEntry = await getJournalById(_id);
20809
21404
  if (!journalEntry) {
20810
- throw new NotFoundError6("Journal entry not found.");
21405
+ throw new NotFoundError7("Journal entry not found.");
20811
21406
  }
20812
21407
  if (journalEntry.status === "voided") {
20813
- throw new BadRequestError101("Cannot update a voided general journal.");
21408
+ throw new BadRequestError105("Cannot update a voided general journal.");
20814
21409
  }
20815
21410
  if (journalEntry.status === "posted" && status2 === "draft") {
20816
- throw new BadRequestError101(
21411
+ throw new BadRequestError105(
20817
21412
  "Cannot revert a posted general journal to draft."
20818
21413
  );
20819
21414
  }
20820
21415
  if (status2 === "voided" && journalEntry.reversalDraft) {
20821
- throw new BadRequestError101(
21416
+ throw new BadRequestError105(
20822
21417
  "Cannot void a general journal with an existing reversal draft."
20823
21418
  );
20824
21419
  }
@@ -20840,9 +21435,17 @@ function useJournalService() {
20840
21435
  if (status2 === "posted") {
20841
21436
  await updateStatusByJournal(_id, status2, session);
20842
21437
  await _updateStatusById(_id, status2, session);
21438
+ const businessProfile = await getBusinessProfileByOrg(
21439
+ String(journalEntry.org)
21440
+ );
21441
+ if (!businessProfile) {
21442
+ throw new NotFoundError7(
21443
+ "Business profile not found for organization."
21444
+ );
21445
+ }
20843
21446
  const linesToPost = await getJournalLinesByEntry(_id);
20844
21447
  const journalDate = new Date(journalEntry.date);
20845
- const fiscalYear = journalDate.getFullYear();
21448
+ const fiscalYear = Number(businessProfile.currentFiscalYear);
20846
21449
  const month = journalDate.toLocaleString("en-US", { month: "long" });
20847
21450
  for (const line of linesToPost) {
20848
21451
  const existingBalance = await getAccountBalance({
@@ -20865,9 +21468,16 @@ function useJournalService() {
20865
21468
  String(journalEntry.org),
20866
21469
  fiscalYear,
20867
21470
  month,
20868
- { movementDebit, movementCredit, closingDebit, closingCredit, netBalance },
21471
+ {
21472
+ movementDebit,
21473
+ movementCredit,
21474
+ closingDebit,
21475
+ closingCredit,
21476
+ netBalance
21477
+ },
20869
21478
  session
20870
21479
  );
21480
+ await updateJournalLineBalance(String(line._id), netBalance, session);
20871
21481
  } else {
20872
21482
  const allYearBalances = await getYearBalancesByAccount({
20873
21483
  account: String(line.account),
@@ -20875,7 +21485,9 @@ function useJournalService() {
20875
21485
  fiscalYear
20876
21486
  });
20877
21487
  const currentMonthIdx = MONTHS.indexOf(month);
20878
- const previousRecord = allYearBalances.filter((r) => MONTHS.indexOf(r.period.month) < currentMonthIdx).sort((a, b) => MONTHS.indexOf(b.period.month) - MONTHS.indexOf(a.period.month))[0];
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];
20879
21491
  const openingDebit = previousRecord?.closingDebit ?? 0;
20880
21492
  const openingCredit = previousRecord?.closingCredit ?? 0;
20881
21493
  const movementDebit = line.debit || 0;
@@ -20904,6 +21516,7 @@ function useJournalService() {
20904
21516
  },
20905
21517
  session
20906
21518
  );
21519
+ await updateJournalLineBalance(String(line._id), netBalance, session);
20907
21520
  }
20908
21521
  }
20909
21522
  await addJournalLog(
@@ -20918,7 +21531,7 @@ function useJournalService() {
20918
21531
  if (journalEntry.reversedEntry) {
20919
21532
  const userData = await getUserById(user);
20920
21533
  if (!userData) {
20921
- throw new NotFoundError6("User not found.");
21534
+ throw new NotFoundError7("User not found.");
20922
21535
  }
20923
21536
  await _updateById(
20924
21537
  journalEntry.reversedEntry,
@@ -20930,6 +21543,7 @@ function useJournalService() {
20930
21543
  },
20931
21544
  session
20932
21545
  );
21546
+ await updateStatusByJournal(String(journalEntry.reversedEntry), "voided", session);
20933
21547
  await addJournalLog(
20934
21548
  {
20935
21549
  journalId: String(journalEntry._id),
@@ -20946,7 +21560,7 @@ function useJournalService() {
20946
21560
  const counterName = `${journalEntry.org.toString()}-general-journal`;
20947
21561
  const counter = await getCounterByType(counterName);
20948
21562
  if (!counter) {
20949
- throw new NotFoundError6("Counter not found for general journal.");
21563
+ throw new NotFoundError7("Counter not found for general journal.");
20950
21564
  }
20951
21565
  const date = /* @__PURE__ */ new Date();
20952
21566
  const entryNumber = counter ? counter.count + 1 : 1;
@@ -20955,7 +21569,8 @@ function useJournalService() {
20955
21569
  org: String(journalEntry.org),
20956
21570
  id: entryNumber.toString().padStart(6, "0"),
20957
21571
  type: journalEntry.type,
20958
- transaction: journalEntry.transaction,
21572
+ transaction: String(journalEntry.transaction),
21573
+ transactionName: journalEntry.transactionName,
20959
21574
  date,
20960
21575
  description: `Reversal of ${getPrefixByType(journalEntry.type)}-${journalEntry.id}`,
20961
21576
  createdBy: String(journalEntry.createdBy),
@@ -20974,7 +21589,7 @@ function useJournalService() {
20974
21589
  );
20975
21590
  const lines = await getJournalLinesByEntry(String(journalEntry._id));
20976
21591
  if (lines && lines.length === 0) {
20977
- throw new NotFoundError6("Journal lines not found for reversal.");
21592
+ throw new NotFoundError7("Journal lines not found for reversal.");
20978
21593
  }
20979
21594
  const reversedLines = [];
20980
21595
  for (const line of lines) {
@@ -21019,10 +21634,10 @@ function useJournalService() {
21019
21634
  return "Journal entry status updated successfully.";
21020
21635
  } catch (error2) {
21021
21636
  await session.abortTransaction();
21022
- if (error2 instanceof AppError47) {
21637
+ if (error2 instanceof AppError49) {
21023
21638
  throw error2;
21024
21639
  }
21025
- throw new InternalServerError43(
21640
+ throw new InternalServerError45(
21026
21641
  `Failed to update general journal status: ${error2.message}`
21027
21642
  );
21028
21643
  } finally {
@@ -21030,11 +21645,11 @@ function useJournalService() {
21030
21645
  }
21031
21646
  }
21032
21647
  async function updateById(id, entry, lines, user) {
21033
- const { error } = Joi90.object({
21034
- id: Joi90.string().hex().required(),
21648
+ const { error } = Joi93.object({
21649
+ id: Joi93.string().hex().required(),
21035
21650
  journalEntry: schemaJournalCtrlUpdate.required(),
21036
- journalLines: Joi90.array().items(schemaJournalLineCtrlUpdate).min(1).required(),
21037
- user: Joi90.string().hex().required()
21651
+ journalLines: Joi93.array().items(schemaJournalLineCtrlUpdate).min(1).required(),
21652
+ user: Joi93.string().hex().required()
21038
21653
  }).validate({
21039
21654
  id,
21040
21655
  journalEntry: entry,
@@ -21042,13 +21657,13 @@ function useJournalService() {
21042
21657
  user
21043
21658
  });
21044
21659
  if (error) {
21045
- throw new BadRequestError101(
21660
+ throw new BadRequestError105(
21046
21661
  `Invalid general journal data: ${error.message}`
21047
21662
  );
21048
21663
  }
21049
21664
  const session = useAtlas16.getClient()?.startSession();
21050
21665
  if (!session) {
21051
- throw new BadRequestError101("Unable to start database session.");
21666
+ throw new BadRequestError105("Unable to start database session.");
21052
21667
  }
21053
21668
  try {
21054
21669
  let hasLineChanged2 = function(existing, incoming) {
@@ -21058,24 +21673,37 @@ function useJournalService() {
21058
21673
  session.startTransaction();
21059
21674
  const existingEntry = await getJournalById(id);
21060
21675
  if (!existingEntry) {
21061
- throw new NotFoundError6("Journal entry not found.");
21676
+ throw new NotFoundError7("Journal entry not found.");
21062
21677
  }
21063
21678
  if (existingEntry.status !== "draft") {
21064
- throw new BadRequestError101("Only draft journal entries can be updated.");
21679
+ throw new BadRequestError105("Only draft journal entries can be updated.");
21065
21680
  }
21066
21681
  const updatedBy = await getUserById(user);
21067
21682
  if (!updatedBy) {
21068
- throw new NotFoundError6("User not found.");
21683
+ throw new NotFoundError7("User not found.");
21069
21684
  }
21070
21685
  await validateJournalLines(lines);
21071
- const headerChanged = new Date(existingEntry.date).getTime() !== new Date(entry.date).getTime() || existingEntry.description !== entry.description || String(existingEntry.customer || "") !== String(entry.customer || "") || existingEntry.transaction !== entry.transaction;
21686
+ const headerChanged = new Date(existingEntry.date).getTime() !== new Date(entry.date).getTime() || existingEntry.description !== entry.description || String(existingEntry.customer || "") !== String(entry.customer || "") || String(existingEntry.transaction) !== String(entry.transaction);
21072
21687
  if (entry.customer && String(entry.customer) !== String(existingEntry.customer)) {
21073
21688
  const customer = await getCustomerById(String(entry.customer));
21074
21689
  if (!customer) {
21075
- throw new NotFoundError6("Customer not found.");
21690
+ throw new NotFoundError7("Customer not found.");
21076
21691
  }
21077
21692
  entry.customerName = `${customer.firstName} ${customer.lastName}`;
21078
21693
  }
21694
+ if (String(existingEntry.transaction) !== String(entry.transaction)) {
21695
+ const journalTx = await getJournalTransaction({
21696
+ org: String(existingEntry.org),
21697
+ type: entry.type,
21698
+ _id: String(entry.transaction)
21699
+ });
21700
+ if (!journalTx) {
21701
+ throw new NotFoundError7("Transaction not found.");
21702
+ }
21703
+ entry.transactionName = journalTx.title;
21704
+ } else {
21705
+ entry.transactionName = existingEntry.transactionName;
21706
+ }
21079
21707
  const existingLines = await getJournalLinesByEntry(id);
21080
21708
  const existingLineMap = new Map(
21081
21709
  existingLines.map((line) => [String(line._id), line])
@@ -21090,7 +21718,7 @@ function useJournalService() {
21090
21718
  (existingId) => !incomingIds.has(existingId)
21091
21719
  );
21092
21720
  if (existingLines.length > 0 && removedLineIds.length === existingLines.length && lines.length > 0) {
21093
- throw new BadRequestError101(
21721
+ throw new BadRequestError105(
21094
21722
  "All journal lines marked for deletion. Identity mismatch suspected."
21095
21723
  );
21096
21724
  }
@@ -21108,7 +21736,7 @@ function useJournalService() {
21108
21736
  const newLines = lines.filter((line) => !line._id);
21109
21737
  const nothingChanged = !headerChanged && removedLineIds.length === 0 && updatedLines.length === 0 && newLines.length === 0;
21110
21738
  if (nothingChanged) {
21111
- throw new BadRequestError101("No changes detected.");
21739
+ throw new BadRequestError105("No changes detected.");
21112
21740
  }
21113
21741
  for (const lineId of removedLineIds) {
21114
21742
  await deleteJournalLineById(lineId, session);
@@ -21123,7 +21751,7 @@ function useJournalService() {
21123
21751
  if (existing && String(existing.account) !== String(line.account)) {
21124
21752
  const account = await getAccountById(String(line.account));
21125
21753
  if (!account) {
21126
- throw new NotFoundError6(`Account not found: ${line.account}`);
21754
+ throw new NotFoundError7(`Account not found: ${line.account}`);
21127
21755
  }
21128
21756
  updatePayload.accountName = account.name;
21129
21757
  updatePayload.accountCode = account.code;
@@ -21133,7 +21761,7 @@ function useJournalService() {
21133
21761
  for (const line of newLines) {
21134
21762
  const account = await getAccountById(String(line.account));
21135
21763
  if (!account) {
21136
- throw new NotFoundError6(`Account not found: ${line.account}`);
21764
+ throw new NotFoundError7(`Account not found: ${line.account}`);
21137
21765
  }
21138
21766
  await addLine(
21139
21767
  {
@@ -21218,10 +21846,10 @@ function useJournalService() {
21218
21846
  return "Journal entry updated successfully.";
21219
21847
  } catch (error2) {
21220
21848
  await session.abortTransaction();
21221
- if (error2 instanceof AppError47) {
21849
+ if (error2 instanceof AppError49) {
21222
21850
  throw error2;
21223
21851
  }
21224
- throw new InternalServerError43(
21852
+ throw new InternalServerError45(
21225
21853
  `Failed to update general journal: ${error2.message}`
21226
21854
  );
21227
21855
  } finally {
@@ -21236,8 +21864,8 @@ function useJournalService() {
21236
21864
  }
21237
21865
 
21238
21866
  // src/resources/finance-journal/finance.journal.controller.ts
21239
- import Joi91 from "joi";
21240
- import { BadRequestError as BadRequestError102, logger as logger52 } from "@goweekdays/utils";
21867
+ import Joi94 from "joi";
21868
+ import { BadRequestError as BadRequestError106, logger as logger53 } from "@goweekdays/utils";
21241
21869
  function useJournalController() {
21242
21870
  const {
21243
21871
  getAll: _getAll,
@@ -21251,13 +21879,13 @@ function useJournalController() {
21251
21879
  } = useJournalService();
21252
21880
  async function add(req, res, next) {
21253
21881
  const value = req.body;
21254
- const { error } = Joi91.object({
21882
+ const { error } = Joi94.object({
21255
21883
  journalEntry: schemaJournalCtrl.required(),
21256
- journalLines: Joi91.array().items(schemaJournalLineCtrl).min(1).required()
21884
+ journalLines: Joi94.array().items(schemaJournalLineCtrl).min(1).required()
21257
21885
  }).validate(value);
21258
21886
  if (error) {
21259
- next(new BadRequestError102(error.message));
21260
- logger52.info(`Controller: ${error.message}`);
21887
+ next(new BadRequestError106(error.message));
21888
+ logger53.info(`Controller: ${error.message}`);
21261
21889
  return;
21262
21890
  }
21263
21891
  try {
@@ -21278,15 +21906,15 @@ function useJournalController() {
21278
21906
  const search = req.query.search ?? "";
21279
21907
  const status2 = req.query.status ?? "all";
21280
21908
  if (!isFinite(page)) {
21281
- next(new BadRequestError102("Invalid page number."));
21909
+ next(new BadRequestError106("Invalid page number."));
21282
21910
  return;
21283
21911
  }
21284
21912
  if (!isFinite(limit)) {
21285
- next(new BadRequestError102("Invalid limit number."));
21913
+ next(new BadRequestError106("Invalid limit number."));
21286
21914
  return;
21287
21915
  }
21288
21916
  if (error) {
21289
- next(new BadRequestError102(error.message));
21917
+ next(new BadRequestError106(error.message));
21290
21918
  return;
21291
21919
  }
21292
21920
  try {
@@ -21306,12 +21934,12 @@ function useJournalController() {
21306
21934
  }
21307
21935
  async function getById(req, res, next) {
21308
21936
  const id = req.params.id;
21309
- const validation = Joi91.object({
21310
- id: Joi91.string().hex().required()
21937
+ const validation = Joi94.object({
21938
+ id: Joi94.string().hex().required()
21311
21939
  });
21312
21940
  const { error } = validation.validate({ id });
21313
21941
  if (error) {
21314
- next(new BadRequestError102(error.message));
21942
+ next(new BadRequestError106(error.message));
21315
21943
  return;
21316
21944
  }
21317
21945
  try {
@@ -21326,15 +21954,15 @@ function useJournalController() {
21326
21954
  const value = req.body;
21327
21955
  const id = req.params.id ?? "";
21328
21956
  const user = req.cookies.user;
21329
- const { error } = Joi91.object({
21330
- id: Joi91.string().hex().required(),
21957
+ const { error } = Joi94.object({
21958
+ id: Joi94.string().hex().required(),
21331
21959
  journalEntry: schemaJournalCtrlUpdate.required(),
21332
- journalLines: Joi91.array().items(schemaJournalLineCtrlUpdate).min(1).required(),
21333
- user: Joi91.string().hex().required()
21960
+ journalLines: Joi94.array().items(schemaJournalLineCtrlUpdate).min(1).required(),
21961
+ user: Joi94.string().hex().required()
21334
21962
  }).validate({ id, user, ...value });
21335
21963
  if (error) {
21336
- next(new BadRequestError102(error.message));
21337
- logger52.info(`Controller: ${error.message}`);
21964
+ next(new BadRequestError106(error.message));
21965
+ logger53.info(`Controller: ${error.message}`);
21338
21966
  return;
21339
21967
  }
21340
21968
  try {
@@ -21353,7 +21981,7 @@ function useJournalController() {
21353
21981
  async function deleteById(req, res, next) {
21354
21982
  const id = req.params.id;
21355
21983
  if (!id) {
21356
- next(new BadRequestError102("Journal Entry ID is required."));
21984
+ next(new BadRequestError106("Journal Entry ID is required."));
21357
21985
  return;
21358
21986
  }
21359
21987
  try {
@@ -21368,14 +21996,14 @@ function useJournalController() {
21368
21996
  const id = req.params.id;
21369
21997
  const status2 = req.params.status;
21370
21998
  const user = req.cookies.user;
21371
- const validation = Joi91.object({
21372
- id: Joi91.string().hex().required(),
21373
- status: Joi91.string().required(),
21374
- user: Joi91.string().hex().required()
21999
+ const validation = Joi94.object({
22000
+ id: Joi94.string().hex().required(),
22001
+ status: Joi94.string().required(),
22002
+ user: Joi94.string().hex().required()
21375
22003
  });
21376
22004
  const { error } = validation.validate({ id, status: status2, user });
21377
22005
  if (error) {
21378
- next(new BadRequestError102(error.message));
22006
+ next(new BadRequestError106(error.message));
21379
22007
  return;
21380
22008
  }
21381
22009
  try {
@@ -21397,8 +22025,8 @@ function useJournalController() {
21397
22025
  }
21398
22026
 
21399
22027
  // src/resources/finance-journal-line/finance.journal.line.controller.ts
21400
- import Joi92 from "joi";
21401
- import { BadRequestError as BadRequestError103 } from "@goweekdays/utils";
22028
+ import Joi95 from "joi";
22029
+ import { BadRequestError as BadRequestError107 } from "@goweekdays/utils";
21402
22030
  function useJournalLineController() {
21403
22031
  const {
21404
22032
  getAll: _getAll,
@@ -21409,14 +22037,14 @@ function useJournalLineController() {
21409
22037
  } = useJournalLineRepo();
21410
22038
  async function getAll(req, res, next) {
21411
22039
  const query = req.query;
21412
- const validation = Joi92.object({
21413
- org: Joi92.string().hex().required(),
21414
- JournalGeneral: Joi92.string().hex().optional(),
21415
- page: Joi92.number().min(1).optional().allow("", null),
21416
- limit: Joi92.number().min(1).optional().allow("", null),
21417
- account: Joi92.string().hex().optional().allow("", null),
21418
- search: Joi92.string().optional().allow("", null),
21419
- status: Joi92.string().valid("draft", "posted").optional().allow("", null)
22040
+ const validation = Joi95.object({
22041
+ org: Joi95.string().hex().required(),
22042
+ JournalGeneral: Joi95.string().hex().optional(),
22043
+ page: Joi95.number().min(1).optional().allow("", null),
22044
+ limit: Joi95.number().min(1).optional().allow("", null),
22045
+ account: Joi95.string().hex().optional().allow("", null),
22046
+ search: Joi95.string().optional().allow("", null),
22047
+ status: Joi95.string().valid("draft", "posted").optional().allow("", null)
21420
22048
  });
21421
22049
  const org = req.params.org ?? "";
21422
22050
  const JournalGeneral = req.query.JournalGeneral;
@@ -21432,15 +22060,15 @@ function useJournalLineController() {
21432
22060
  account
21433
22061
  });
21434
22062
  if (!isFinite(page)) {
21435
- next(new BadRequestError103("Invalid page number."));
22063
+ next(new BadRequestError107("Invalid page number."));
21436
22064
  return;
21437
22065
  }
21438
22066
  if (!isFinite(limit)) {
21439
- next(new BadRequestError103("Invalid limit number."));
22067
+ next(new BadRequestError107("Invalid limit number."));
21440
22068
  return;
21441
22069
  }
21442
22070
  if (error) {
21443
- next(new BadRequestError103(error.message));
22071
+ next(new BadRequestError107(error.message));
21444
22072
  return;
21445
22073
  }
21446
22074
  try {
@@ -21461,12 +22089,12 @@ function useJournalLineController() {
21461
22089
  }
21462
22090
  async function getById(req, res, next) {
21463
22091
  const id = req.params.id;
21464
- const validation = Joi92.object({
21465
- id: Joi92.string().hex().required()
22092
+ const validation = Joi95.object({
22093
+ id: Joi95.string().hex().required()
21466
22094
  });
21467
22095
  const { error } = validation.validate({ id });
21468
22096
  if (error) {
21469
- next(new BadRequestError103(error.message));
22097
+ next(new BadRequestError107(error.message));
21470
22098
  return;
21471
22099
  }
21472
22100
  try {
@@ -21555,6 +22183,7 @@ export {
21555
22183
  modelJobSummary,
21556
22184
  modelJournal,
21557
22185
  modelJournalLine,
22186
+ modelJournalTransaction,
21558
22187
  modelLedgerBill,
21559
22188
  modelMember,
21560
22189
  modelOption,
@@ -21624,6 +22253,11 @@ export {
21624
22253
  schemaJournalLineRepo,
21625
22254
  schemaJournalRepo,
21626
22255
  schemaJournalRepoUpdate,
22256
+ schemaJournalTransactionAccount,
22257
+ schemaJournalTransactionCtrl,
22258
+ schemaJournalTransactionCtrlUpdate,
22259
+ schemaJournalTransactionGetAll,
22260
+ schemaJournalTransactionRepo,
21627
22261
  schemaLanguage,
21628
22262
  schemaLedgerBill,
21629
22263
  schemaLedgerBillingSummary,
@@ -21705,6 +22339,9 @@ export {
21705
22339
  useJournalLineRepo,
21706
22340
  useJournalRepo,
21707
22341
  useJournalService,
22342
+ useJournalTransactionController,
22343
+ useJournalTransactionRepo,
22344
+ useJournalTransactionService,
21708
22345
  useLedgerBillingController,
21709
22346
  useLedgerBillingRepo,
21710
22347
  useMemberController,