@tomei/finance 0.3.31 → 0.3.33

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.
@@ -9,6 +9,10 @@ import FinanceCustomerModel from '../models/customer.entity';
9
9
  import { AccountSystemEntity } from '../account-system-entity/account-system-entity';
10
10
  import { FinanceCustomerRepository } from './finance-customer.repository';
11
11
  import * as cuid from 'cuid';
12
+ import Account from '../account/account';
13
+ import { AccountRepository } from '../account/account.repository';
14
+ import type from '../helpers/typeof';
15
+ import * as FinanceDb from '../database';
12
16
 
13
17
  // const AccountSystemEntity = import('../account-system-entity').then(({AccountSystemEntity}) => AccountSystemEntity);
14
18
  export default abstract class FinanceCustomerBase
@@ -22,6 +26,11 @@ export default abstract class FinanceCustomerBase
22
26
  abstract Email: string;
23
27
  abstract DefaultAddress: IAddress;
24
28
 
29
+ private _AccountReceivable: Account;
30
+ private _AccountPayable: Account;
31
+
32
+ private static _AccountRepository = new AccountRepository();
33
+
25
34
  // note: getDetails from spec is void type. Meaning that this probably needed a fix soon
26
35
  async getDetails(): Promise<{
27
36
  FullName: string;
@@ -72,6 +81,92 @@ export default abstract class FinanceCustomerBase
72
81
  }
73
82
  }
74
83
 
84
+ get AccountReceivable(): Promise<Account> {
85
+ return new Promise((resolve, reject) => {
86
+ let transaction;
87
+ if (this._AccountReceivable) {
88
+ resolve(this._AccountReceivable);
89
+ } else {
90
+ FinanceDb.getConnection()
91
+ .transaction()
92
+ .then((t) => {
93
+ transaction = t;
94
+ return FinanceCustomerBase._AccountRepository.findOne({
95
+ where: {
96
+ AccountType: 'Account Receivable',
97
+ OwnerId: this.CustomerId,
98
+ OwnerType: type(this),
99
+ },
100
+ });
101
+ })
102
+ .then((accountData) => {
103
+ this._AccountReceivable = new Account(transaction);
104
+ if (accountData) {
105
+ this._AccountReceivable.AccountNo = accountData.AccountNo;
106
+ this._AccountReceivable.ParentAccountNo =
107
+ accountData.ParentAccountNo;
108
+ this._AccountReceivable.AccountType = accountData.AccountType;
109
+ this._AccountReceivable.OwnerId = accountData.OwnerId;
110
+ this._AccountReceivable.OwnerType = accountData.OwnerType;
111
+ } else {
112
+ this._AccountReceivable.AccountNo = `${this.CustSystemCode}-AR-123456789`;
113
+ this._AccountReceivable.ParentAccountNo = `${this.CustSystemCode}-AR`;
114
+ this._AccountReceivable.AccountType = 'Account Receivable';
115
+ this._AccountReceivable.OwnerId = this.CustomerId;
116
+ this._AccountReceivable.OwnerType = type(this);
117
+ }
118
+ resolve(this._AccountReceivable);
119
+ })
120
+ .catch((err) => {
121
+ reject(err);
122
+ });
123
+ }
124
+ });
125
+ }
126
+
127
+ get AccountPayable(): Promise<Account> {
128
+ return new Promise((resolve, reject) => {
129
+ let transaction;
130
+ if (this._AccountPayable) {
131
+ resolve(this._AccountPayable);
132
+ } else {
133
+ FinanceDb.getConnection()
134
+ .transaction()
135
+ .then((t) => {
136
+ transaction = t;
137
+ return FinanceCustomerBase._AccountRepository.findOne({
138
+ where: {
139
+ AccountType: 'Account Payable',
140
+ OwnerId: this.CustomerId,
141
+ OwnerType: type(this),
142
+ },
143
+ });
144
+ })
145
+ .then((accountData) => {
146
+ this._AccountPayable = new Account(transaction);
147
+ if (accountData) {
148
+ this._AccountPayable.AccountNo = accountData.AccountNo;
149
+ this._AccountPayable.ParentAccountNo =
150
+ accountData.ParentAccountNo;
151
+ this._AccountPayable.AccountType = accountData.AccountType;
152
+ this._AccountPayable.OwnerId = accountData.OwnerId;
153
+ this._AccountPayable.OwnerType = accountData.OwnerType;
154
+ } else {
155
+ this._AccountPayable.AccountNo = `${this.CustSystemCode}-AP-123456789`;
156
+ this._AccountPayable.ParentAccountNo = `${this.CustSystemCode}-AP`;
157
+ this._AccountPayable.AccountType = 'Account Payable';
158
+ this._AccountPayable.OwnerId = this.CustomerId;
159
+ this._AccountPayable.OwnerType = type(this);
160
+ }
161
+ resolve(this._AccountPayable);
162
+ })
163
+ .catch((err) => {
164
+ reject(err);
165
+ });
166
+ }
167
+ });
168
+ }
169
+
75
170
  /*
76
171
  * Get the billing address for a person.
77
172
  **/
@@ -21,6 +21,11 @@ import FinanceCompany from '../finance-company/finance-company';
21
21
  import FinanceCustomerBase from '../customer/customer';
22
22
  import DocumentModel from '../models/document.entity';
23
23
 
24
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
25
+ const getConfig = require('../config');
26
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
27
+ const config = getConfig();
28
+
24
29
  export default class Document extends AccountSystemEntity {
25
30
  private _DocNo = 'New';
26
31
  private _DocType: DocType;
@@ -127,6 +132,7 @@ export default class Document extends AccountSystemEntity {
127
132
 
128
133
  constructor(dbTransaction?: any, docNo?: string) {
129
134
  super();
135
+ console.log(config, '<<< test config from finance');
130
136
  if (dbTransaction) {
131
137
  this._DbTransaction = dbTransaction;
132
138
  }
@@ -14,7 +14,12 @@ import { IAccountSystem } from '../interfaces';
14
14
  import { FinanceCompanyRepository } from './finance-company.repository';
15
15
  import { FinanceCustomerRepository } from '../customer/finance-customer.repository';
16
16
  import { LedgerTransactionRepository } from '../ledger-transaction/ledger-transaction.repository';
17
- import { DocType, PaymentStatus, TransactionTypeOptions } from '../enum';
17
+ import {
18
+ DocType,
19
+ PaymentStatus,
20
+ PaymentType,
21
+ TransactionTypeOptions,
22
+ } from '../enum';
18
23
  import PaymentMethodType from '../payment-method-type/payment-method-type';
19
24
  import { PaymentRepository } from '../payment/payment.repository';
20
25
  import { PaymentItemRepository } from '../payment-item/payment-item.repository';
@@ -26,7 +31,7 @@ import { PaymentMethodTypeRepository } from '../payment-method-type/payment-meth
26
31
  import PaymentMethod from '../payment-method/payment-method';
27
32
 
28
33
  // eslint-disable-next-line @typescript-eslint/no-var-requires
29
- const { getConfig } = require('../config');
34
+ const getConfig = require('../config');
30
35
  // eslint-disable-next-line @typescript-eslint/no-var-requires
31
36
  const config = getConfig();
32
37
 
@@ -982,7 +987,7 @@ export default class FinanceCompany extends ObjectBase {
982
987
  * @param loginUser - The user collecting the payment
983
988
  * @param payment - The payment object containing payment details
984
989
  * @param customer - The customer making the payment
985
- * @param ctAccountNo - The customer's Account Receivable (AR) account to credit
990
+ * @param ctAccountNo - The account number of the customer's Account Receivable account to transact, else the default customer account payable receivable will be used
986
991
  *
987
992
  * @returns {Payment} - Payment object representing the full detals of the payment collection recorded
988
993
  */
@@ -1008,6 +1013,7 @@ export default class FinanceCompany extends ObjectBase {
1008
1013
  }
1009
1014
 
1010
1015
  payment.PaymentId = cuid();
1016
+ payment.PaymentType = PaymentType.PAYMENT_RECEIVED;
1011
1017
 
1012
1018
  await FinanceCompany._PaymentRepository.create(
1013
1019
  {
@@ -1070,8 +1076,7 @@ export default class FinanceCompany extends ObjectBase {
1070
1076
  if (ctAccountNo) {
1071
1077
  creditLT.AccountNo = ctAccountNo;
1072
1078
  } else {
1073
- // const config = getConfig();
1074
- creditLT.AccountNo = customer.CustSystemCode + '-AR';
1079
+ creditLT.AccountNo = (await customer.AccountReceivable).AccountNo;
1075
1080
  }
1076
1081
  creditLT.Currency = payment.Currency;
1077
1082
  creditLT.CreditAmount = payment.Amount;
@@ -1092,6 +1097,122 @@ export default class FinanceCompany extends ObjectBase {
1092
1097
  }
1093
1098
  }
1094
1099
 
1100
+ /**
1101
+ * Method to make payment to a customer.
1102
+ *
1103
+ * @param dbTransaction - The database transaction to be used
1104
+ * @param loginUser - The user logging in and the user who collected the payment.
1105
+ * @param payment - The payment object containing payment details
1106
+ * @param customer - The customer who is receiving the payment.
1107
+ * @param ctAccountNo - The account number of the customer's Account Payable account to transact, else the default customer account payable will be used.
1108
+ *
1109
+ * @returns {Payment} - Payment object representing the full detals of the payment collection recorded
1110
+ */
1111
+ async makePayment(
1112
+ dbTransaction: any,
1113
+ loginUser: LoginUserBase,
1114
+ payment: Payment,
1115
+ customer: FinanceCustomerBase,
1116
+ dtAccountNo?: string,
1117
+ ): Promise<Payment> {
1118
+ let paymentMethodType: PaymentMethodType;
1119
+ try {
1120
+ paymentMethodType = new PaymentMethodType(
1121
+ dbTransaction,
1122
+ payment.MethodTypeId,
1123
+ );
1124
+
1125
+ const paymentItems = await payment.PaymentItems;
1126
+ if (paymentItems.length < 1) {
1127
+ throw new Error(
1128
+ 'Atleast one payment item is required to identify what payment is being paid for',
1129
+ );
1130
+ }
1131
+
1132
+ payment.PaymentId = cuid();
1133
+ payment.PaymentType = PaymentType.PAYOUT;
1134
+
1135
+ await FinanceCompany._PaymentRepository.create(
1136
+ {
1137
+ PaymentId: payment.PaymentId,
1138
+ PaymentType: payment.PaymentType,
1139
+ PaymentDate: payment.PaymentDate,
1140
+ CompanyId: this.CompanyId,
1141
+ MethodTypeId: payment.MethodTypeId,
1142
+ Currency: payment.Currency,
1143
+ Amount: payment.Amount,
1144
+ Status: PaymentStatus.SUCCESSFUL,
1145
+ TransactionId: payment.TransactionId,
1146
+ TransactionApprovalCode: payment.TransactionApprovalCode,
1147
+ TransactionAccountName: payment.TransactionAccountName,
1148
+ TransactionAccountNo: payment.TransactionAccountNo,
1149
+ ReceivedBy: payment.ReceivedBy,
1150
+ PostedToAccSystemYN: 'N',
1151
+ UpdatedAt: new Date(),
1152
+ UpdatedBy: loginUser.ObjectId,
1153
+ CreatedAt: new Date(),
1154
+ CreatedBy: loginUser.ObjectId,
1155
+ },
1156
+ { transaction: dbTransaction },
1157
+ );
1158
+
1159
+ paymentItems.forEach(async (paymentItem) => {
1160
+ await FinanceCompany._PaymentItemRepository.create(
1161
+ {
1162
+ PaymentId: payment.PaymentId,
1163
+ PayForObjectId: paymentItem.PayForObjectId,
1164
+ PayForObjectType: paymentItem.PayForObjectType,
1165
+ Currency: paymentItem.Currency,
1166
+ Amount: paymentItem.Amount,
1167
+ },
1168
+ { transaction: dbTransaction },
1169
+ );
1170
+ });
1171
+
1172
+ const journalEntry = new JournalEntry(dbTransaction);
1173
+ //Temporary fix to successfully save journal entry in PostJournal
1174
+ journalEntry.init({
1175
+ CompanyId: this.CompanyId,
1176
+ Name: 'Make Payment for ' + payment.PaymentId,
1177
+ });
1178
+ const transactionDate = new Date();
1179
+
1180
+ const creditLT = await journalEntry.newLedgerTransaction(
1181
+ TransactionTypeOptions.CREDIT,
1182
+ );
1183
+ creditLT.AccountNo = paymentMethodType.AccountNo;
1184
+ creditLT.Currency = payment.Currency;
1185
+ creditLT.CreditAmount = payment.Amount;
1186
+ creditLT.Date = transactionDate;
1187
+ creditLT.Name = customer.FullName;
1188
+
1189
+ const debitLT = await journalEntry.newLedgerTransaction(
1190
+ TransactionTypeOptions.DEBIT,
1191
+ );
1192
+ if (dtAccountNo) {
1193
+ debitLT.AccountNo = dtAccountNo;
1194
+ } else {
1195
+ debitLT.AccountNo = (await customer.AccountPayable).AccountNo;
1196
+ }
1197
+ debitLT.Currency = payment.Currency;
1198
+ debitLT.DebitAmount = payment.Amount;
1199
+ debitLT.Date = transactionDate;
1200
+ debitLT.Name = paymentMethodType.Name;
1201
+
1202
+ await this.postJournal(dbTransaction, journalEntry);
1203
+
1204
+ /*todo: saving a record into the activity history table*/
1205
+
1206
+ return payment;
1207
+ } catch (error) {
1208
+ if (error instanceof RecordNotFoundError) {
1209
+ throw new Error('Invalid PaymentMethodType id');
1210
+ } else {
1211
+ throw error;
1212
+ }
1213
+ }
1214
+ }
1215
+
1095
1216
  get PaymentMethods() {
1096
1217
  if (this._PaymentMethods === null || this._PaymentMethods.length === 0) {
1097
1218
  this.LoadPaymentMethods();
@@ -1104,7 +1225,7 @@ export default class FinanceCompany extends ObjectBase {
1104
1225
  */
1105
1226
  async LoadPaymentMethods(): Promise<void> {
1106
1227
  /*Retrieve the payment method from the config file */
1107
- const { companyId, paymentMethods } = config.systemConfig['EZC'];
1228
+ const { companyId, paymentMethods } = config.financeCompanies['TXG-FS'];
1108
1229
  const paymentMethod = new PaymentMethod();
1109
1230
 
1110
1231
  for (const method in paymentMethods) {
@@ -1145,6 +1266,11 @@ export default class FinanceCompany extends ObjectBase {
1145
1266
  MethodId: paymentMethodTypeData.MethodId,
1146
1267
  MethodTypeId: configPaymentMethodTypes[methodType].id,
1147
1268
  Name: configPaymentMethodTypes[methodType].name,
1269
+ AccountNo: configPaymentMethodTypes[methodType].accountno,
1270
+ ProcessingFeeRate:
1271
+ configPaymentMethodTypes[methodType].processingFeeRate,
1272
+ ProcessingFeeAccountNo:
1273
+ configPaymentMethodTypes[methodType].processingFeeAccountNo,
1148
1274
  };
1149
1275
 
1150
1276
  await paymentMethod.newPaymentMethodType(paymentMethodTypePayload);
@@ -0,0 +1,29 @@
1
+ export default function type(value: any): string {
2
+ if (value === null) {
3
+ return 'null';
4
+ }
5
+ const baseType = typeof value;
6
+
7
+ if (!['object', 'function'].includes(baseType)) {
8
+ return baseType;
9
+ }
10
+
11
+ const tag = value[Symbol.toStringTag];
12
+ if (typeof tag === 'string') {
13
+ return tag;
14
+ }
15
+
16
+ if (
17
+ baseType === 'function' &&
18
+ Function.prototype.toString.call(value).startsWith('class')
19
+ ) {
20
+ return 'class';
21
+ }
22
+
23
+ const className = value.constructor.name;
24
+ if (typeof className === 'string' && className !== '') {
25
+ return className;
26
+ }
27
+
28
+ return baseType;
29
+ }
@@ -26,6 +26,9 @@ export default class LedgerTransaction {
26
26
  if (dbTransaction) {
27
27
  this._DbTransaction = dbTransaction;
28
28
  }
29
+ if (transactionId) {
30
+ this.TransactionId = transactionId;
31
+ }
29
32
  }
30
33
 
31
34
  init(params?: ILedgerTransactionAttr) {