@tomei/finance 0.6.99 → 0.6.102

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.
Files changed (223) hide show
  1. package/.husky/commit-msg +12 -3
  2. package/.husky/pre-commit +4 -4
  3. package/configs/config.js +1 -1
  4. package/dist/account/account.d.ts +37 -37
  5. package/dist/account/account.js +251 -263
  6. package/dist/account/account.js.map +1 -1
  7. package/dist/account/account.repository.d.ts +5 -5
  8. package/dist/account/account.repository.js +11 -11
  9. package/dist/account/interfaces/account-attr.interface.d.ts +29 -29
  10. package/dist/account/interfaces/account-attr.interface.js +2 -2
  11. package/dist/account-system-entity/account-system-entity.d.ts +12 -12
  12. package/dist/account-system-entity/account-system-entity.js +55 -66
  13. package/dist/account-system-entity/account-system-entity.js.map +1 -1
  14. package/dist/account-system-entity/post-history.repository.d.ts +5 -5
  15. package/dist/account-system-entity/post-history.repository.js +11 -11
  16. package/dist/config.d.ts +1888 -1888
  17. package/dist/config.js +331 -331
  18. package/dist/config.js.map +1 -1
  19. package/dist/customer/customer.d.ts +44 -44
  20. package/dist/customer/customer.js +212 -234
  21. package/dist/customer/customer.js.map +1 -1
  22. package/dist/customer/finance-customer.repository.d.ts +5 -5
  23. package/dist/customer/finance-customer.repository.js +25 -25
  24. package/dist/customer/finance-customer.repository.js.map +1 -1
  25. package/dist/customer/interfaces/customer.repository.interface.d.ts +3 -3
  26. package/dist/customer/interfaces/customer.repository.interface.js +2 -2
  27. package/dist/customer/interfaces/finance-customer-attr.interface.d.ts +10 -10
  28. package/dist/customer/interfaces/finance-customer-attr.interface.js +2 -2
  29. package/dist/customer/interfaces/finance-customer.repository.interface.d.ts +3 -3
  30. package/dist/customer/interfaces/finance-customer.repository.interface.js +2 -2
  31. package/dist/database.d.ts +4 -4
  32. package/dist/database.js +46 -47
  33. package/dist/database.js.map +1 -1
  34. package/dist/document/document-item.d.ts +46 -46
  35. package/dist/document/document-item.js +122 -132
  36. package/dist/document/document-item.js.map +1 -1
  37. package/dist/document/document-item.repository.d.ts +5 -5
  38. package/dist/document/document-item.repository.js +11 -11
  39. package/dist/document/document.d.ts +87 -88
  40. package/dist/document/document.js +735 -766
  41. package/dist/document/document.js.map +1 -1
  42. package/dist/document/document.repository.d.ts +5 -5
  43. package/dist/document/document.repository.js +11 -11
  44. package/dist/document/interfaces/document-attr.interface.d.ts +27 -27
  45. package/dist/document/interfaces/document-attr.interface.js +6 -6
  46. package/dist/document/interfaces/document-find-all.interface.d.ts +13 -13
  47. package/dist/document/interfaces/document-find-all.interface.js +2 -2
  48. package/dist/document/interfaces/document-item-attr.interface.d.ts +26 -26
  49. package/dist/document/interfaces/document-item-attr.interface.js +6 -6
  50. package/dist/document/interfaces/document-item.repository.interface.d.ts +3 -3
  51. package/dist/document/interfaces/document-item.repository.interface.js +2 -2
  52. package/dist/enum/collect-payment-type.d.ts +4 -4
  53. package/dist/enum/collect-payment-type.js +8 -8
  54. package/dist/enum/collect-payment-type.js.map +1 -1
  55. package/dist/enum/doc-type.enum.d.ts +8 -8
  56. package/dist/enum/doc-type.enum.js +12 -12
  57. package/dist/enum/doc-type.enum.js.map +1 -1
  58. package/dist/enum/document-status.enum.d.ts +6 -6
  59. package/dist/enum/document-status.enum.js +10 -10
  60. package/dist/enum/document-status.enum.js.map +1 -1
  61. package/dist/enum/index.d.ts +9 -9
  62. package/dist/enum/index.js +19 -19
  63. package/dist/enum/payment-method.enum.d.ts +3 -3
  64. package/dist/enum/payment-method.enum.js +7 -7
  65. package/dist/enum/payment-method.enum.js.map +1 -1
  66. package/dist/enum/payment-status.enum.d.ts +10 -10
  67. package/dist/enum/payment-status.enum.js +15 -16
  68. package/dist/enum/payment-status.enum.js.map +1 -1
  69. package/dist/enum/payment-type.enum.d.ts +4 -4
  70. package/dist/enum/payment-type.enum.js +8 -8
  71. package/dist/enum/payment-type.enum.js.map +1 -1
  72. package/dist/enum/quick-book-client-scopes.enum.d.ts +13 -13
  73. package/dist/enum/quick-book-client-scopes.enum.js +18 -18
  74. package/dist/enum/quick-book-client-scopes.enum.js.map +1 -1
  75. package/dist/enum/transaction-type.enum.d.ts +4 -4
  76. package/dist/enum/transaction-type.enum.js +8 -8
  77. package/dist/enum/transaction-type.enum.js.map +1 -1
  78. package/dist/finance-company/finance-company.d.ts +88 -88
  79. package/dist/finance-company/finance-company.js +1533 -1576
  80. package/dist/finance-company/finance-company.js.map +1 -1
  81. package/dist/finance-company/finance-company.repository.d.ts +5 -5
  82. package/dist/finance-company/finance-company.repository.js +11 -11
  83. package/dist/helpers/login-user.d.ts +13 -13
  84. package/dist/helpers/login-user.js +28 -28
  85. package/dist/helpers/login-user.js.map +1 -1
  86. package/dist/helpers/typeof.d.ts +1 -1
  87. package/dist/helpers/typeof.js +28 -29
  88. package/dist/helpers/typeof.js.map +1 -1
  89. package/dist/index.d.ts +17 -17
  90. package/dist/index.js +32 -32
  91. package/dist/interfaces/account-system.interface.d.ts +30 -30
  92. package/dist/interfaces/account-system.interface.js +2 -2
  93. package/dist/interfaces/index.d.ts +2 -2
  94. package/dist/interfaces/index.js +2 -2
  95. package/dist/journal-entry/interfaces/journal-entry-attr.interface.d.ts +12 -12
  96. package/dist/journal-entry/interfaces/journal-entry-attr.interface.js +2 -2
  97. package/dist/journal-entry/journal-entry.d.ts +42 -42
  98. package/dist/journal-entry/journal-entry.js +216 -233
  99. package/dist/journal-entry/journal-entry.js.map +1 -1
  100. package/dist/journal-entry/journal-entry.repository.d.ts +6 -6
  101. package/dist/journal-entry/journal-entry.repository.js +16 -27
  102. package/dist/journal-entry/journal-entry.repository.js.map +1 -1
  103. package/dist/ledger-transaction/interfaces/ledger-transaction-attr.interface.d.ts +17 -17
  104. package/dist/ledger-transaction/interfaces/ledger-transaction-attr.interface.js +2 -2
  105. package/dist/ledger-transaction/interfaces/ledger-transaction.repository.interface.d.ts +5 -5
  106. package/dist/ledger-transaction/interfaces/ledger-transaction.repository.interface.js +2 -2
  107. package/dist/ledger-transaction/ledger-transaction.d.ts +54 -54
  108. package/dist/ledger-transaction/ledger-transaction.js +143 -164
  109. package/dist/ledger-transaction/ledger-transaction.js.map +1 -1
  110. package/dist/ledger-transaction/ledger-transaction.repository.d.ts +6 -6
  111. package/dist/ledger-transaction/ledger-transaction.repository.js +16 -27
  112. package/dist/ledger-transaction/ledger-transaction.repository.js.map +1 -1
  113. package/dist/models/account.entity.d.ts +30 -30
  114. package/dist/models/account.entity.js +232 -232
  115. package/dist/models/account.entity.js.map +1 -1
  116. package/dist/models/customer.entity.d.ts +13 -13
  117. package/dist/models/customer.entity.js +109 -109
  118. package/dist/models/customer.entity.js.map +1 -1
  119. package/dist/models/document-item.entity.d.ts +31 -31
  120. package/dist/models/document-item.entity.js +200 -200
  121. package/dist/models/document-item.entity.js.map +1 -1
  122. package/dist/models/document.entity.d.ts +36 -36
  123. package/dist/models/document.entity.js +242 -242
  124. package/dist/models/document.entity.js.map +1 -1
  125. package/dist/models/finance-company.entity.d.ts +15 -15
  126. package/dist/models/finance-company.entity.js +93 -93
  127. package/dist/models/finance-company.entity.js.map +1 -1
  128. package/dist/models/journal-entry.entity.d.ts +16 -16
  129. package/dist/models/journal-entry.entity.js +127 -127
  130. package/dist/models/journal-entry.entity.js.map +1 -1
  131. package/dist/models/ledger-transaction.entity.d.ts +24 -24
  132. package/dist/models/ledger-transaction.entity.js +172 -172
  133. package/dist/models/ledger-transaction.entity.js.map +1 -1
  134. package/dist/models/payment-item.entity.d.ts +12 -12
  135. package/dist/models/payment-item.entity.js +75 -75
  136. package/dist/models/payment-item.entity.js.map +1 -1
  137. package/dist/models/payment-method-type.entity.d.ts +13 -13
  138. package/dist/models/payment-method-type.entity.js +85 -85
  139. package/dist/models/payment-method-type.entity.js.map +1 -1
  140. package/dist/models/payment-method.entity.d.ts +10 -10
  141. package/dist/models/payment-method.entity.js +62 -62
  142. package/dist/models/payment-method.entity.js.map +1 -1
  143. package/dist/models/payment-paid-with.entity.d.ts +24 -24
  144. package/dist/models/payment-paid-with.entity.js +158 -158
  145. package/dist/models/payment-paid-with.entity.js.map +1 -1
  146. package/dist/models/payment.entity.d.ts +29 -29
  147. package/dist/models/payment.entity.js +193 -193
  148. package/dist/models/payment.entity.js.map +1 -1
  149. package/dist/models/post-history.entity.d.ts +11 -11
  150. package/dist/models/post-history.entity.js +63 -63
  151. package/dist/models/post-history.entity.js.map +1 -1
  152. package/dist/models/tax.entity.d.ts +13 -13
  153. package/dist/models/tax.entity.js +89 -89
  154. package/dist/models/tax.entity.js.map +1 -1
  155. package/dist/payment/interfaces/payment-attr.interface.d.ts +22 -22
  156. package/dist/payment/interfaces/payment-attr.interface.js +6 -6
  157. package/dist/payment/interfaces/payment-params.interface.d.ts +7 -7
  158. package/dist/payment/interfaces/payment-params.interface.js +2 -2
  159. package/dist/payment/payment.d.ts +53 -53
  160. package/dist/payment/payment.js +186 -201
  161. package/dist/payment/payment.js.map +1 -1
  162. package/dist/payment/payment.repository.d.ts +5 -5
  163. package/dist/payment/payment.repository.js +11 -11
  164. package/dist/payment-item/interfaces/payment-item-attr.interface.d.ts +10 -10
  165. package/dist/payment-item/interfaces/payment-item-attr.interface.js +6 -6
  166. package/dist/payment-item/payment-item.d.ts +25 -25
  167. package/dist/payment-item/payment-item.js +111 -122
  168. package/dist/payment-item/payment-item.js.map +1 -1
  169. package/dist/payment-item/payment-item.repository.d.ts +5 -5
  170. package/dist/payment-item/payment-item.repository.js +11 -11
  171. package/dist/payment-method/interfaces/payment-method-attr.interface.d.ts +5 -5
  172. package/dist/payment-method/interfaces/payment-method-attr.interface.js +2 -2
  173. package/dist/payment-method/payment-method.d.ts +21 -21
  174. package/dist/payment-method/payment-method.js +104 -117
  175. package/dist/payment-method/payment-method.js.map +1 -1
  176. package/dist/payment-method/payment-method.repository.d.ts +5 -5
  177. package/dist/payment-method/payment-method.repository.js +11 -11
  178. package/dist/payment-method-type/interfaces/payment-method-type-attr.interface.d.ts +8 -8
  179. package/dist/payment-method-type/interfaces/payment-method-type-attr.interface.js +2 -2
  180. package/dist/payment-method-type/payment-method-type.d.ts +18 -18
  181. package/dist/payment-method-type/payment-method-type.js +65 -76
  182. package/dist/payment-method-type/payment-method-type.js.map +1 -1
  183. package/dist/payment-method-type/payment-method-type.repository.d.ts +5 -5
  184. package/dist/payment-method-type/payment-method-type.repository.js +11 -11
  185. package/dist/payment-paid-with/interfaces/payment-paid-with.interface.d.ts +19 -19
  186. package/dist/payment-paid-with/interfaces/payment-paid-with.interface.js +6 -6
  187. package/dist/payment-paid-with/payment-paid-with.d.ts +33 -33
  188. package/dist/payment-paid-with/payment-paid-with.js +56 -56
  189. package/dist/payment-paid-with/payment-paid-with.js.map +1 -1
  190. package/dist/payment-paid-with/payment-paid-with.repository.d.ts +5 -5
  191. package/dist/payment-paid-with/payment-paid-with.repository.js +11 -11
  192. package/dist/tax/interfaces/tax-attr.interface.d.ts +10 -10
  193. package/dist/tax/interfaces/tax-attr.interface.js +2 -2
  194. package/dist/tax/tax.d.ts +26 -26
  195. package/dist/tax/tax.js +51 -51
  196. package/dist/tax/tax.js.map +1 -1
  197. package/dist/tax/tax.repository.d.ts +5 -5
  198. package/dist/tax/tax.repository.js +11 -11
  199. package/dist/test-document.d.ts +3 -3
  200. package/dist/test-document.js +18 -18
  201. package/dist/test.d.ts +1 -1
  202. package/dist/test.js +6 -7
  203. package/dist/test.js.map +1 -1
  204. package/dist/tsconfig.tsbuildinfo +1 -1
  205. package/eslint.config.mjs +58 -0
  206. package/invoice-template/assets/js/html2canvas.min.js +16 -16
  207. package/package.json +35 -41
  208. package/src/account/account.ts +2 -1
  209. package/src/customer/customer.ts +8 -7
  210. package/src/document/document-item.ts +3 -2
  211. package/src/document/document.ts +20 -13
  212. package/src/enum/collect-payment-type.ts +3 -3
  213. package/src/enum/payment-status.enum.ts +1 -1
  214. package/src/finance-company/finance-company.ts +5 -7
  215. package/src/journal-entry/journal-entry.ts +0 -1
  216. package/src/ledger-transaction/ledger-transaction.ts +4 -4
  217. package/src/payment-method-type/payment-method-type.ts +1 -1
  218. package/src/tax/tax.ts +0 -1
  219. package/tsconfig.json +4 -3
  220. package/.eslintrc.js +0 -72
  221. package/img.png +0 -0
  222. package/img_1.png +0 -0
  223. package/tslint.json +0 -18
@@ -1,1577 +1,1534 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const axios_1 = require("axios");
13
- const general_1 = require("@tomei/general");
14
- const account_1 = require("../account/account");
15
- const journal_entry_1 = require("../journal-entry/journal-entry");
16
- const document_1 = require("../document/document");
17
- const finance_company_repository_1 = require("./finance-company.repository");
18
- const finance_customer_repository_1 = require("../customer/finance-customer.repository");
19
- const ledger_transaction_repository_1 = require("../ledger-transaction/ledger-transaction.repository");
20
- const enum_1 = require("../enum");
21
- const payment_method_type_1 = require("../payment-method-type/payment-method-type");
22
- const payment_repository_1 = require("../payment/payment.repository");
23
- const payment_item_repository_1 = require("../payment-item/payment-item.repository");
24
- const document_repository_1 = require("../document/document.repository");
25
- const document_item_repository_1 = require("../document/document-item.repository");
26
- const payment_method_repository_1 = require("../payment-method/payment-method.repository");
27
- const payment_method_type_repository_1 = require("../payment-method-type/payment-method-type.repository");
28
- const payment_method_1 = require("../payment-method/payment-method");
29
- const account_repository_1 = require("../account/account.repository");
30
- const payment_paid_with_repository_1 = require("../payment-paid-with/payment-paid-with.repository");
31
- const document_item_1 = require("../document/document-item");
32
- const typeof_1 = require("../helpers/typeof");
33
- const activity_history_1 = require("@tomei/activity-history");
34
- const config_1 = require("@tomei/config");
35
- const tax_repository_1 = require("../tax/tax.repository");
36
- const tax_1 = require("../tax/tax");
37
- const collect_payment_type_1 = require("../enum/collect-payment-type");
38
- class FinanceCompany extends general_1.ObjectBase {
39
- get ObjectType() {
40
- return this._ObjectType;
41
- }
42
- get CompSystemCode() {
43
- return this._CompSystemCode;
44
- }
45
- set CompSystemCode(code) {
46
- this._CompSystemCode = code;
47
- }
48
- get CompSystemRefId() {
49
- return this._CompSystemRefId;
50
- }
51
- set CompSystemRefId(id) {
52
- this._CompSystemRefId = id;
53
- }
54
- get AccSystemCode() {
55
- return this._AccSystemCode;
56
- }
57
- get AccSystemRefId() {
58
- return this._AccSystemRefId;
59
- }
60
- set AccSystemRefId(id) {
61
- this._AccSystemRefId = id;
62
- }
63
- get PostedToAccSystemYN() {
64
- return this._PostedToAccSystemYN;
65
- }
66
- set PostedToAccSystemYN(value) {
67
- this._PostedToAccSystemYN = value;
68
- }
69
- get PostedById() {
70
- return this._PostedById;
71
- }
72
- set PostedById(id) {
73
- this._PostedById = id;
74
- }
75
- get PostedDateTime() {
76
- return this._PostedDateTime;
77
- }
78
- set PostedDateTime(date) {
79
- this._PostedDateTime = date;
80
- }
81
- set AccSystemCode(code) {
82
- this._AccSystemCode = code;
83
- }
84
- get CompanyId() {
85
- return this._CompanyId;
86
- }
87
- get ObjectId() {
88
- return this._CompanyId;
89
- }
90
- set ObjectId(id) {
91
- this._CompanyId = id;
92
- }
93
- get ObjectName() {
94
- return `${this.CompSystemCode}-${this.CompSystemRefId}-${this.AccSystemCode}`;
95
- }
96
- get TableName() {
97
- return 'finance_Company';
98
- }
99
- get AccountingSystem() {
100
- return this._AccountingSystem;
101
- }
102
- set AccountingSystem(system) {
103
- this._AccountingSystem = system;
104
- }
105
- constructor(compSystemCode, compSystemRefId, accSystemCode) {
106
- super();
107
- this._CompanyId = 'New';
108
- this._CompSystemCode = '';
109
- this._CompSystemRefId = '';
110
- this._AccSystemCode = '';
111
- this._AccSystemRefId = 'REF';
112
- this._PostedToAccSystemYN = 'N';
113
- this._PostedById = null;
114
- this._PostedDateTime = null;
115
- this._ObjectType = 'FinanceCompany';
116
- this._PaymentMethods = [];
117
- this._Taxes = [];
118
- this.CompSystemCode = compSystemCode;
119
- this.CompSystemRefId = compSystemRefId;
120
- this.AccSystemCode = accSystemCode;
121
- this.AccSystemRefId = 'REF';
122
- this.PostedToAccSystemYN = 'N';
123
- }
124
- static getFinanceCompanyId(compSystemCode, compSystemRefId, accSystemCode) {
125
- return __awaiter(this, void 0, void 0, function* () {
126
- let sCompanyId = '';
127
- const sKey = `${compSystemCode}-${compSystemRefId}-${accSystemCode}`;
128
- if (!FinanceCompany._htFinanceCompanyIds.get(sKey)) {
129
- const financeCompany = new FinanceCompany(compSystemCode, compSystemRefId, accSystemCode);
130
- const company = yield FinanceCompany._financeCompanyRepository.findOne({
131
- where: {
132
- CompSystemCode: compSystemCode,
133
- CompSystemRefId: compSystemRefId,
134
- AccSystemCode: accSystemCode,
135
- },
136
- });
137
- financeCompany.ObjectId = company.CompanyId;
138
- sCompanyId = financeCompany.ObjectId;
139
- FinanceCompany._htFinanceCompanyIds.add(sKey, financeCompany.ObjectId);
140
- FinanceCompany._htFinanceCompanies.add(sCompanyId, financeCompany);
141
- }
142
- if (typeof FinanceCompany._htFinanceCompanyIds.get(sKey) === 'string') {
143
- sCompanyId = FinanceCompany._htFinanceCompanyIds.get(sKey);
144
- }
145
- return sCompanyId;
146
- });
147
- }
148
- static getFinanceCompany(companyId) {
149
- return __awaiter(this, void 0, void 0, function* () {
150
- if (!FinanceCompany._htFinanceCompanies.get(companyId)) {
151
- const company = yield FinanceCompany._financeCompanyRepository.findOne({
152
- where: { CompanyId: companyId },
153
- });
154
- if (!company) {
155
- throw Error('No finance company found. Please create first.');
156
- }
157
- const compSystemCode = company.CompSystemCode;
158
- const compSystemRefId = company.CompSystemRefId;
159
- const accSystemCode = company.AccSystemCode;
160
- const financeCompany = new FinanceCompany(compSystemCode, compSystemRefId, accSystemCode);
161
- financeCompany.ObjectId = company.CompanyId;
162
- financeCompany._CompanyId = company.CompanyId;
163
- const sKey = `${compSystemCode}-${compSystemRefId}-${accSystemCode}`;
164
- FinanceCompany._htFinanceCompanyIds.add(sKey, financeCompany.ObjectId);
165
- FinanceCompany._htFinanceCompanies.add(financeCompany.ObjectId, financeCompany);
166
- }
167
- console.log('return from hash table');
168
- return FinanceCompany._htFinanceCompanies.get(companyId);
169
- });
170
- }
171
- static createFinanceCompany(dbTransaction, loginUser, companyId, compSystemCode, compSystemRefId, accSystemCode) {
172
- return __awaiter(this, void 0, void 0, function* () {
173
- const financeCompany = new FinanceCompany(compSystemCode, compSystemRefId, accSystemCode);
174
- const company = yield FinanceCompany._financeCompanyRepository.findOne({
175
- where: {
176
- CompSystemCode: compSystemCode,
177
- CompSystemRefId: compSystemRefId,
178
- AccSystemCode: accSystemCode,
179
- },
180
- });
181
- if (company) {
182
- throw Error('There is already another Finance Company with the compSystemCode, CompSystemRefId and accSystemCode specified.');
183
- }
184
- financeCompany.ObjectId = companyId;
185
- const accSystemRefId = config_1.ComponentConfig.getComponentConfigValue('finance-config.json', 'accountSystemRefId');
186
- const postedToAccSystemYN = config_1.ComponentConfig.getComponentConfigValue('finance-config.json', 'postedToAccSystemYN');
187
- financeCompany.PostedById = loginUser.ObjectId || null;
188
- financeCompany.PostedDateTime = new Date();
189
- yield FinanceCompany._financeCompanyRepository.create({
190
- CompanyId: financeCompany.CompanyId,
191
- CompSystemCode: financeCompany.CompSystemCode,
192
- CompSystemRefId: financeCompany.CompSystemRefId,
193
- AccSystemCode: financeCompany.AccSystemCode,
194
- AccSystemRefId: postedToAccSystemYN === 'Y'
195
- ? accSystemRefId
196
- : financeCompany.AccSystemRefId,
197
- PostedToAccSystemYN: postedToAccSystemYN || financeCompany.PostedToAccSystemYN,
198
- PostedById: financeCompany.PostedById,
199
- PostedDateTime: financeCompany.PostedDateTime,
200
- }, {
201
- transaction: dbTransaction,
202
- });
203
- const sKey = `${compSystemCode}-${compSystemRefId}-${accSystemCode}`;
204
- FinanceCompany._htFinanceCompanyIds.add(sKey, financeCompany.ObjectId);
205
- FinanceCompany._htFinanceCompanies.add(financeCompany.ObjectId, financeCompany);
206
- console.log('return from hash table');
207
- return FinanceCompany._htFinanceCompanies.get(companyId);
208
- });
209
- }
210
- static findAccount(loginUser, dbTransaction, accountNo) {
211
- return __awaiter(this, void 0, void 0, function* () {
212
- try {
213
- const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
214
- const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'FINANCECOMPANY_VIEW_ACCOUNT');
215
- if (!isPrivileged) {
216
- throw new general_1.ClassError('FinanceCompany', 'findAccountErrMsg0X', 'User not privileged to view finance company account');
217
- }
218
- const record = yield FinanceCompany._AccountRepository.findOne({
219
- where: {
220
- AccountNo: accountNo,
221
- },
222
- transaction: dbTransaction,
223
- });
224
- if (record) {
225
- const account = new account_1.default(dbTransaction);
226
- account.init(record.get({ plain: true }));
227
- return account;
228
- }
229
- return undefined;
230
- }
231
- catch (error) {
232
- throw error;
233
- }
234
- });
235
- }
236
- createCustomer(dbTransaction, custSystemCode, custSystemRefId, customer, loginUser) {
237
- return __awaiter(this, void 0, void 0, function* () {
238
- try {
239
- if (!custSystemCode || !custSystemRefId) {
240
- throw new Error('CustSystemCode and CustomerRefId are required fields.');
241
- }
242
- const financeCustomerData = yield FinanceCompany._FinanceCustomerRepository.findOne({
243
- where: {
244
- CompanyId: this._CompanyId,
245
- CustSystemCode: custSystemCode,
246
- CustSystemRefId: custSystemRefId,
247
- },
248
- });
249
- if (financeCustomerData) {
250
- throw new Error('Customer already created previously.');
251
- }
252
- let AccCustomerRefId = 'REF';
253
- if (this.AccountingSystem) {
254
- AccCustomerRefId = yield this.AccountingSystem.createCustomer(customer, dbTransaction);
255
- }
256
- customer.CompanyId = this._CompanyId;
257
- const newCustomer = yield customer.save(AccCustomerRefId, custSystemCode, custSystemRefId, dbTransaction);
258
- const activity = new activity_history_1.Activity();
259
- activity.ActivityId = this._createId().toUpperCase();
260
- activity.Action = activity_history_1.ActionEnum.ADD;
261
- activity.Description = 'Add Finance Customer';
262
- activity.EntityType = 'FinanceCustomer';
263
- activity.EntityId = newCustomer.CustomerId;
264
- activity.EntityValueBefore = JSON.stringify({});
265
- activity.EntityValueAfter = JSON.stringify(newCustomer);
266
- yield activity.create(loginUser.ObjectId, dbTransaction);
267
- return customer;
268
- }
269
- catch (error) {
270
- throw error;
271
- }
272
- });
273
- }
274
- postJournal(dbTransaction, journalEntry, loginUser) {
275
- return __awaiter(this, void 0, void 0, function* () {
276
- const debitTransactions = yield journalEntry.DebitTransactions;
277
- const creditTransactions = yield journalEntry.CreditTransactions;
278
- try {
279
- if (creditTransactions.length < 1 || (debitTransactions === null || debitTransactions === void 0 ? void 0 : debitTransactions.length) < 1) {
280
- throw new Error('There should be at least 1 debit ledger transaction and 1 credit ledger transaction in the journal entry');
281
- }
282
- let totalCreditAmount = creditTransactions.reduce((accumulator, currentValue) => accumulator + currentValue.CreditAmount, 0);
283
- let totalDebitAmount = debitTransactions.reduce((accumulator, currentValue) => accumulator + currentValue.DebitAmount, 0);
284
- console.log('totalCreditAmount: ', totalCreditAmount);
285
- console.log('totalDebitAmount: ', totalDebitAmount);
286
- if (typeof totalCreditAmount === 'string') {
287
- totalCreditAmount = parseFloat(totalCreditAmount);
288
- }
289
- if (typeof totalDebitAmount === 'string') {
290
- totalDebitAmount = parseFloat(totalDebitAmount);
291
- }
292
- if (totalCreditAmount.toFixed(2) !== totalDebitAmount.toFixed(2)) {
293
- throw new Error('Credit ledger transaction and debit ledger transaction should the same amount');
294
- }
295
- const newJournalEntry = yield journalEntry.save(loginUser.ObjectId, dbTransaction);
296
- for (const ledgerTransaction of debitTransactions) {
297
- ledgerTransaction.JournalEntryId = newJournalEntry.JournalEntryId;
298
- yield ledgerTransaction.save(dbTransaction);
299
- }
300
- for (const ledgerTransaction of creditTransactions) {
301
- ledgerTransaction.JournalEntryId = newJournalEntry.JournalEntryId;
302
- yield ledgerTransaction.save(dbTransaction);
303
- }
304
- const payload = {
305
- Action: 'Create',
306
- Activity: 'Post Journal Entry',
307
- Description: `Journal Entry (ID: ${newJournalEntry.JournalEntryId}) has been created`,
308
- EntityType: 'JournalEntry',
309
- EntityValueBefore: JSON.stringify({}),
310
- EntityValueAfter: JSON.stringify(newJournalEntry),
311
- PerformedById: loginUser.ObjectId,
312
- PerformedAt: new Date(),
313
- EntityId: newJournalEntry.JournalEntryId,
314
- };
315
- yield axios_1.default.post(`${process.env.COMMON_API_URL}/activity-histories`, payload);
316
- }
317
- catch (error) {
318
- throw error;
319
- }
320
- });
321
- }
322
- createAccount(dbTransaction, account, loginUser) {
323
- return __awaiter(this, void 0, void 0, function* () {
324
- try {
325
- let accSystemRefId;
326
- if (!account.AccountType) {
327
- throw new Error('AccountType is required.');
328
- }
329
- const accountNoLength = config_1.ComponentConfig.getComponentConfigValue('@tomei/finance', 'accountNoLength');
330
- if (accountNoLength && account.AccountNo.length > accountNoLength) {
331
- throw new Error(`Account No length should not exceed ${accountNoLength} characters.`);
332
- }
333
- let createAccountPayload = {
334
- Name: account.Name,
335
- AcctNum: account.AccountNo,
336
- AccountType: account.AccountType,
337
- AccountSubType: account.AccountSubtype,
338
- };
339
- if (this.AccountingSystem) {
340
- accSystemRefId = yield this.AccountingSystem.createAccount(account, dbTransaction);
341
- }
342
- if (account.isParentAccountExists()) {
343
- createAccountPayload = Object.assign(Object.assign({}, createAccountPayload), { CurrencyRef: 'MYR', ParentRef: account.ParentAccountNo, SubAccount: true });
344
- }
345
- console.log('Finance Company Create Account: Before accSystemAccountId Create');
346
- console.log('Finance Company Create Account: After accSystemAccountId Create');
347
- console.log('Finance Company Create Account: Before new Account Create');
348
- if (accSystemRefId) {
349
- account.PostedToAccSystemYN = 'Y';
350
- account.PostedById = loginUser.ObjectId;
351
- account.PostedDateTime = new Date();
352
- }
353
- const newAccount = yield account.save(this.CompanyId, accSystemRefId || 'REF', loginUser.ObjectId, dbTransaction);
354
- console.log('Finance Company Create Account: After new Account Create');
355
- const payload = {
356
- Action: 'Create',
357
- Activity: 'Account Created',
358
- Description: `Account (ID: ${newAccount.AccountNo}) has been created`,
359
- EntityType: 'Account',
360
- EntityValueBefore: JSON.stringify({}),
361
- EntityValueAfter: JSON.stringify(newAccount),
362
- PerformedById: loginUser.ObjectId,
363
- PerformedAt: new Date(),
364
- EntityId: newAccount.AccountNo,
365
- };
366
- yield axios_1.default.post(`${process.env.COMMON_API_URL}/activity-histories`, payload);
367
- return account;
368
- }
369
- catch (error) {
370
- throw error;
371
- }
372
- });
373
- }
374
- issueInvoice(dbTransaction, invoice, loginUser, customer, dtAccountNo) {
375
- return __awaiter(this, void 0, void 0, function* () {
376
- try {
377
- const duplicateInvoice = yield FinanceCompany._DocumentRepository.findOne({
378
- where: {
379
- DocNo: invoice.DocNo,
380
- },
381
- transaction: dbTransaction,
382
- });
383
- if (duplicateInvoice) {
384
- throw new Error('Invoice number already exists');
385
- }
386
- const documentItems = yield invoice.getDocumentItems(dbTransaction);
387
- if (!documentItems.length) {
388
- throw new Error('Document must have at least 1 document item');
389
- }
390
- for (const invoiceItem of documentItems) {
391
- if (!invoiceItem.CtAccountNo) {
392
- throw new Error('Each document item should have CtAccountNo provided');
393
- }
394
- }
395
- invoice.DocType = enum_1.DocType.INVOICE;
396
- let invoiceMedia;
397
- if (invoice.UseAccSystemDocYN === 'Y') {
398
- const accInvoiceRefIdDetail = yield this.AccountingSystem.createInvoice({
399
- customer,
400
- invoice,
401
- paymentMode: 'credit',
402
- }, dbTransaction);
403
- invoice.DocNo = accInvoiceRefIdDetail.invoiceNo;
404
- invoice.AccSystemRefId = accInvoiceRefIdDetail.invoiceRefId;
405
- invoice.PostedToAccSystemYN = 'Y';
406
- invoice.PostedById = loginUser.ObjectId;
407
- invoice.PostedDateTime = new Date();
408
- for (const documentItem of documentItems) {
409
- const accItem = accInvoiceRefIdDetail.invoiceItems.find((item) => item.name === documentItem.Name);
410
- if (accItem) {
411
- documentItem.DocNo = accInvoiceRefIdDetail.invoiceNo;
412
- documentItem.AccSystemRefId = accItem.itemRefId;
413
- documentItem.PostedToAccSystemYN = 'Y';
414
- documentItem.PostedById = loginUser.ObjectId;
415
- documentItem.PostedDateTime = new Date();
416
- }
417
- }
418
- }
419
- else {
420
- invoiceMedia = yield invoice.generateInvoice(invoice.IssuedById, customer, dbTransaction);
421
- }
422
- yield FinanceCompany._DocumentRepository.create({
423
- DocNo: invoice.DocNo,
424
- DocType: invoice.DocType,
425
- DocDate: invoice.DocDate,
426
- CompanyId: invoice.CompanyId,
427
- Currency: invoice.Currency,
428
- Amount: invoice.Amount,
429
- Description: invoice.Description,
430
- Status: invoice.Status,
431
- IssuedById: invoice.IssuedById,
432
- IssuedToId: invoice.IssuedToId,
433
- IssuedToType: invoice.IssuedToType,
434
- RelatedObjectId: invoice.RelatedObjectId,
435
- RelatedObjectType: invoice.RelatedObjectType,
436
- CreatedById: invoice.CreatedById,
437
- CreatedAt: new Date(),
438
- UpdatedById: invoice.UpdatedById,
439
- UpdatedAt: new Date(),
440
- DocPDFFileMediaId: invoice.UseAccSystemDocYN == 'N'
441
- ? invoiceMedia.PDFMedia.MediaId
442
- : null,
443
- DocHTMLFileMediaId: invoice.UseAccSystemDocYN == 'N'
444
- ? invoiceMedia.HTMLMedia.MediaId
445
- : null,
446
- AccSystemRefId: invoice.AccSystemRefId,
447
- PostedToAccSystemYN: invoice.PostedToAccSystemYN,
448
- PostedById: invoice.UseAccSystemDocYN == 'Y' ? invoice.PostedById : null,
449
- PostedDateTime: new Date(),
450
- UseAccSystemDocYN: invoice.UseAccSystemDocYN,
451
- }, {
452
- transaction: dbTransaction,
453
- });
454
- for (const documentItem of documentItems) {
455
- yield FinanceCompany._DocumentItemRepository.create({
456
- DocumentItemId: this._createId().toUpperCase(),
457
- DocNo: invoice.DocNo,
458
- Name: documentItem.Name,
459
- NameBM: documentItem.NameBM,
460
- Description: documentItem.Description,
461
- ItemId: documentItem.ItemId,
462
- ItemType: documentItem.ItemType,
463
- ItemSKU: documentItem.ItemSKU,
464
- ItemSerialNo: documentItem.ItemSerialNo,
465
- Currency: documentItem.Currency,
466
- UnitPrice: documentItem.UnitPrice,
467
- Quantity: documentItem.Quantity,
468
- QuantityUOM: documentItem.QuantityUOM,
469
- Amount: documentItem.Amount,
470
- TaxCode: documentItem.TaxCode,
471
- TaxAmount: documentItem.TaxAmount,
472
- TaxRate: documentItem.TaxRate,
473
- TaxInclusiveYN: documentItem.TaxInclusiveYN,
474
- DtAccountNo: documentItem.DtAccountNo
475
- ? documentItem.DtAccountNo
476
- : null,
477
- CtAccountNo: documentItem.CtAccountNo
478
- ? documentItem.CtAccountNo
479
- : null,
480
- AccSystemRefId: documentItem.AccSystemRefId,
481
- PostedToAccSystemYN: documentItem.PostedToAccSystemYN,
482
- PostedById: documentItem.PostedById,
483
- PostedDateTime: documentItem.PostedDateTime,
484
- }, {
485
- transaction: dbTransaction,
486
- });
487
- }
488
- const transactionDate = new Date();
489
- const htCreditAccountAmount = new general_1.HashTable();
490
- const htCreditAccountCurrency = new general_1.HashTable();
491
- const htCreditAccountPurpose = new general_1.HashTable();
492
- documentItems.forEach((invoiceItem) => {
493
- if (!htCreditAccountAmount.exists(invoiceItem.CtAccountNo)) {
494
- htCreditAccountAmount.add(invoiceItem.CtAccountNo, invoiceItem.Amount);
495
- htCreditAccountCurrency.add(invoiceItem.CtAccountNo, invoiceItem.Currency);
496
- htCreditAccountPurpose.add(invoiceItem.CtAccountNo, invoiceItem.Name);
497
- }
498
- else {
499
- const d = htCreditAccountAmount.get(invoiceItem.CtAccountNo);
500
- htCreditAccountAmount.add(invoiceItem.CtAccountNo, d + invoiceItem.Amount);
501
- }
502
- });
503
- const savedItems = htCreditAccountAmount.list();
504
- for (const item of savedItems) {
505
- const journalEntry = new journal_entry_1.default(dbTransaction);
506
- journalEntry.init({
507
- CompanyId: this.CompanyId,
508
- Name: 'Issue Invoice ' + invoice.DocNo,
509
- });
510
- const creditAmount = item.value[1];
511
- const currency = htCreditAccountCurrency.get(item.value[0]);
512
- const purpose = htCreditAccountPurpose.get(item.value[0]);
513
- const dt = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
514
- if (dtAccountNo) {
515
- dt.AccountNo = dtAccountNo;
516
- }
517
- else {
518
- const arAccount = yield customer.getAccountReceivable();
519
- dt.AccountNo = arAccount.AccountNo;
520
- }
521
- dt.Currency = currency ? currency : 'MYR';
522
- dt.DebitAmount = creditAmount ? creditAmount : 0.0;
523
- dt.Date = transactionDate;
524
- dt.Description = `${purpose}`;
525
- dt.Name = `${purpose}`;
526
- dt.RelatedDocNo = invoice.DocNo;
527
- dt.RelatedObjectId = invoice.RelatedObjectId;
528
- dt.RelatedObjectType = invoice.RelatedObjectType;
529
- const ct = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
530
- ct.AccountNo = item.value[0];
531
- ct.Currency = currency ? currency : 'MYR';
532
- ct.CreditAmount = creditAmount ? creditAmount : 0.0;
533
- ct.Date = transactionDate;
534
- ct.Description = customer.FullName;
535
- ct.Name = customer.FullName;
536
- ct.RelatedDocNo = invoice.DocNo;
537
- ct.RelatedObjectId = invoice.RelatedObjectId;
538
- ct.RelatedObjectType = invoice.RelatedObjectType;
539
- yield this.postJournal(dbTransaction, journalEntry, loginUser);
540
- }
541
- return invoice;
542
- }
543
- catch (err) {
544
- console.log('Issue invoice err: ', err);
545
- throw err;
546
- }
547
- });
548
- }
549
- static findCustomer(custSystemRefId, dbTransaction) {
550
- return __awaiter(this, void 0, void 0, function* () {
551
- const data = yield FinanceCompany._FinanceCustomerRepository.findOne({
552
- where: {
553
- CustSystemRefId: custSystemRefId,
554
- },
555
- transaction: dbTransaction,
556
- });
557
- return data;
558
- });
559
- }
560
- issueDebitNote(dbTransaction, loginUser, invoice, customer, dtAccountNo) {
561
- return __awaiter(this, void 0, void 0, function* () {
562
- try {
563
- const duplicateInvoice = yield FinanceCompany._DocumentRepository.findOne({
564
- where: {
565
- DocNo: invoice.DocNo,
566
- },
567
- transaction: dbTransaction,
568
- });
569
- if (duplicateInvoice) {
570
- throw new Error('Invoice number already exists');
571
- }
572
- const documentItems = yield invoice.getDocumentItems(dbTransaction);
573
- if (!documentItems.length) {
574
- throw new Error('Document must have at least 1 document item');
575
- }
576
- for (const invoiceItem of documentItems) {
577
- if (!invoiceItem.CtAccountNo) {
578
- throw new Error('Each document item should have CtAccountNo provided');
579
- }
580
- }
581
- invoice.DocType = enum_1.DocType.DEBIT_NOTE;
582
- if (invoice.UseAccSystemDocYN === 'Y') {
583
- const accInvoiceRefIDetail = yield this.AccountingSystem.createInvoice({
584
- customer,
585
- invoice,
586
- paymentMode: 'credit',
587
- }, dbTransaction);
588
- invoice.AccSystemRefId = accInvoiceRefIDetail.invoiceRefId;
589
- invoice.PostedToAccSystemYN = 'Y';
590
- invoice.PostedById = loginUser.ObjectId;
591
- invoice.PostedDateTime = new Date();
592
- for (const documentItem of documentItems) {
593
- const accItem = accInvoiceRefIDetail.invoiceItems.find((item) => item.name === documentItem.Name);
594
- if (accItem) {
595
- documentItem.AccSystemRefId = accItem.itemRefId;
596
- documentItem.PostedToAccSystemYN = 'Y';
597
- documentItem.PostedById = loginUser.ObjectId;
598
- documentItem.PostedDateTime = new Date();
599
- }
600
- }
601
- }
602
- else {
603
- invoice.generateInvoice(loginUser.IDNo, customer, dbTransaction);
604
- }
605
- yield FinanceCompany._DocumentRepository.create({
606
- DocNo: invoice.DocNo,
607
- DocType: invoice.DocType,
608
- DocDate: invoice.DocDate,
609
- CompanyId: invoice.CompanyId,
610
- Currency: invoice.Currency,
611
- Amount: invoice.Amount,
612
- Description: invoice.Description,
613
- Status: invoice.Status,
614
- IssuedById: loginUser.ObjectId,
615
- IssuedToId: customer.ObjectId,
616
- IssuedToType: invoice.IssuedToType,
617
- RelatedObjectId: invoice.RelatedObjectId,
618
- RelatedObjectType: invoice.RelatedObjectType,
619
- CreatedById: loginUser.ObjectId,
620
- CreatedAt: new Date(),
621
- UpdatedById: loginUser.ObjectId,
622
- UpdatedAt: new Date(),
623
- DocPDFFileMediaId: invoice.DocPDFFileMediaId,
624
- DocHTMLFileMediaId: invoice.DocHTMLFileMediaId,
625
- AccSystemRefId: invoice.AccSystemRefId,
626
- PostedToAccSystemYN: invoice.PostedToAccSystemYN,
627
- PostedById: invoice.PostedToAccSystemYN == 'Y' ? invoice.PostedById : null,
628
- PostedDateTime: new Date(),
629
- UseAccSystemDocYN: invoice.UseAccSystemDocYN,
630
- }, {
631
- transaction: dbTransaction,
632
- });
633
- documentItems.forEach((documentItem) => __awaiter(this, void 0, void 0, function* () {
634
- yield FinanceCompany._DocumentItemRepository.create({
635
- DocumentItemId: this._createId().toUpperCase(),
636
- DocNo: documentItem.DocNo,
637
- Name: documentItem.Name,
638
- NameBM: documentItem.NameBM,
639
- Description: documentItem.Description,
640
- ItemId: documentItem.ItemId,
641
- ItemType: documentItem.ItemType,
642
- ItemSKU: documentItem.ItemSKU,
643
- ItemSerialNo: documentItem.ItemSerialNo,
644
- Currency: documentItem.Currency,
645
- UnitPrice: documentItem.UnitPrice,
646
- Quantity: documentItem.Quantity,
647
- QuantityUOM: documentItem.QuantityUOM,
648
- Amount: documentItem.Amount,
649
- TaxCode: documentItem.TaxCode,
650
- TaxAmount: documentItem.TaxAmount,
651
- TaxRate: documentItem.TaxRate,
652
- TaxInclusiveYN: documentItem.TaxInclusiveYN,
653
- DtAccountNo: documentItem.DtAccountNo,
654
- CtAccountNo: documentItem.CtAccountNo,
655
- AccSystemRefId: documentItem.AccSystemRefId,
656
- PostedToAccSystemYN: documentItem.PostedToAccSystemYN,
657
- PostedById: documentItem.PostedById,
658
- PostedDateTime: documentItem.PostedDateTime,
659
- }, {
660
- transaction: dbTransaction,
661
- });
662
- }));
663
- const transactionDate = new Date();
664
- const htCreditAccountAmount = new general_1.HashTable();
665
- const htCreditAccountCurrency = new general_1.HashTable();
666
- const htCreditAccountPurpose = new general_1.HashTable();
667
- documentItems.forEach((invoiceItem) => {
668
- if (!htCreditAccountAmount.exists(invoiceItem.CtAccountNo)) {
669
- htCreditAccountAmount.add(invoiceItem.CtAccountNo, invoiceItem.Amount);
670
- htCreditAccountCurrency.add(invoiceItem.CtAccountNo, invoiceItem.Currency);
671
- htCreditAccountPurpose.add(invoiceItem.CtAccountNo, invoiceItem.Name);
672
- }
673
- else {
674
- const d = htCreditAccountAmount.get(invoiceItem.CtAccountNo);
675
- htCreditAccountAmount.add(invoiceItem.CtAccountNo, d + invoiceItem.Amount);
676
- }
677
- });
678
- const savedItems = htCreditAccountAmount.list();
679
- for (const item of savedItems) {
680
- const journalEntry = new journal_entry_1.default(dbTransaction);
681
- journalEntry.init({
682
- CompanyId: this.CompanyId,
683
- Name: 'issue Invoice ' + invoice.DocNo,
684
- });
685
- const creditAmount = item.value[1];
686
- const currency = htCreditAccountCurrency.get(item.value[0]);
687
- const purpose = htCreditAccountPurpose.get(item.value[0]);
688
- const dt = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
689
- if (dtAccountNo) {
690
- dt.AccountNo = dtAccountNo;
691
- }
692
- else {
693
- const arAccount = yield customer.getAccountReceivable();
694
- dt.AccountNo = arAccount.AccountNo;
695
- }
696
- dt.Currency = currency ? currency : 'MYR';
697
- dt.DebitAmount = creditAmount ? creditAmount : 0.0;
698
- dt.Date = transactionDate;
699
- dt.Description = `${purpose}`;
700
- dt.Name = `${purpose}`;
701
- dt.RelatedDocNo = invoice.DocNo;
702
- dt.RelatedObjectId = invoice.RelatedObjectId;
703
- dt.RelatedObjectType = invoice.RelatedObjectType;
704
- const ct = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
705
- ct.AccountNo = item.value[0];
706
- ct.Currency = currency ? currency : 'MYR';
707
- ct.CreditAmount = creditAmount ? creditAmount : 0.0;
708
- ct.Date = transactionDate;
709
- ct.Description = customer.FullName;
710
- ct.Name = customer.FullName;
711
- ct.RelatedDocNo = invoice.DocNo;
712
- ct.RelatedObjectId = invoice.RelatedObjectId;
713
- ct.RelatedObjectType = invoice.RelatedObjectType;
714
- yield this.postJournal(dbTransaction, journalEntry, loginUser);
715
- }
716
- return invoice;
717
- }
718
- catch (err) {
719
- console.log('Issue debit note err: ', err);
720
- throw err;
721
- }
722
- });
723
- }
724
- issueCreditNote(dbTransaction, loginUser, creditNote, customer, ctAccountNo) {
725
- return __awaiter(this, void 0, void 0, function* () {
726
- try {
727
- const duplicateCreditNote = yield FinanceCompany._DocumentRepository.findOne({
728
- where: {
729
- DocNo: creditNote.DocNo,
730
- },
731
- transaction: dbTransaction,
732
- });
733
- if (duplicateCreditNote) {
734
- throw new Error('Invoice number already exists');
735
- }
736
- const documentItems = yield creditNote.getDocumentItems(dbTransaction);
737
- if (!documentItems.length) {
738
- throw new Error('Document must have at least 1 document item');
739
- }
740
- for (const invoiceItem of documentItems) {
741
- if (!invoiceItem.DtAccountNo) {
742
- throw new Error('Each document item should have DtAccountNo provided');
743
- }
744
- const actualDocument = yield document_1.default.initDocument(dbTransaction, invoiceItem.ItemId);
745
- if (actualDocument.IssuedToId !== creditNote.IssuedToId) {
746
- throw new general_1.ClassError('FinanceCompany', 'FinanceCompanyErrMsgOX', 'To issue credit note, all invoices must belong to same customer.');
747
- }
748
- }
749
- creditNote.DocType = enum_1.DocType.CREDIT_NOTE;
750
- creditNote.Status = enum_1.DocumentStatus.SETTLED;
751
- yield FinanceCompany._DocumentRepository.create({
752
- DocNo: creditNote.DocNo,
753
- DocType: creditNote.DocType,
754
- DocDate: creditNote.DocDate,
755
- CompanyId: creditNote.CompanyId,
756
- Currency: creditNote.Currency,
757
- Amount: creditNote.Amount,
758
- Description: creditNote.Description,
759
- Status: creditNote.Status,
760
- IssuedById: loginUser.ObjectId,
761
- IssuedToId: customer.ObjectId,
762
- IssuedToType: creditNote.IssuedToType,
763
- RelatedObjectId: creditNote.RelatedObjectId,
764
- RelatedObjectType: creditNote.RelatedObjectType,
765
- CreatedById: loginUser.ObjectId,
766
- CreatedAt: new Date(),
767
- UpdatedById: loginUser.ObjectId,
768
- UpdatedAt: new Date(),
769
- DocPDFFileMediaId: creditNote.DocPDFFileMediaId,
770
- DocHTMLFileMediaId: creditNote.DocHTMLFileMediaId,
771
- AccSystemRefId: creditNote.AccSystemRefId,
772
- PostedToAccSystemYN: creditNote.PostedToAccSystemYN,
773
- PostedById: creditNote.PostedToAccSystemYN == 'Y'
774
- ? creditNote.PostedById
775
- : null,
776
- PostedDateTime: new Date(),
777
- UseAccSystemDocYN: creditNote.UseAccSystemDocYN,
778
- }, {
779
- transaction: dbTransaction,
780
- });
781
- for (const docItem of documentItems) {
782
- yield FinanceCompany._DocumentItemRepository.create({
783
- DocumentItemId: this._createId().toUpperCase(),
784
- DocNo: docItem.DocNo,
785
- Name: docItem.Name,
786
- NameBM: docItem.NameBM,
787
- Description: docItem.Description,
788
- ItemId: docItem.ItemId,
789
- ItemType: docItem.ItemType,
790
- ItemSKU: docItem.ItemSKU,
791
- ItemSerialNo: docItem.ItemSerialNo,
792
- Currency: docItem.Currency,
793
- UnitPrice: docItem.UnitPrice,
794
- Quantity: docItem.Quantity,
795
- QuantityUOM: docItem.QuantityUOM,
796
- Amount: docItem.Amount,
797
- TaxCode: docItem.TaxCode,
798
- TaxAmount: docItem.TaxAmount,
799
- TaxRate: docItem.TaxRate,
800
- TaxInclusiveYN: docItem.TaxInclusiveYN,
801
- DtAccountNo: docItem.DtAccountNo ? docItem.DtAccountNo : null,
802
- CtAccountNo: docItem.CtAccountNo ? docItem.CtAccountNo : null,
803
- }, {
804
- transaction: dbTransaction,
805
- });
806
- yield document_1.default.settleByCreditNote(loginUser, dbTransaction, docItem.ItemId, docItem.Amount);
807
- }
808
- if (creditNote.UseAccSystemDocYN === 'Y') {
809
- }
810
- else {
811
- creditNote.generateCreditNote(loginUser.IDNo, customer);
812
- }
813
- const journalEntry = new journal_entry_1.default(dbTransaction);
814
- journalEntry.init({
815
- CompanyId: this.CompanyId,
816
- Name: 'Issue Credit Note ' + creditNote.DocNo,
817
- });
818
- const transactionDate = new Date();
819
- const creditTransaction = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
820
- if (ctAccountNo) {
821
- creditTransaction.AccountNo = ctAccountNo;
822
- }
823
- else {
824
- const arAccount = yield customer.getAccountPayable();
825
- creditTransaction.AccountNo = arAccount.AccountNo;
826
- }
827
- creditTransaction.Currency = creditNote.Currency;
828
- creditTransaction.CreditAmount = creditNote.Amount;
829
- creditTransaction.Date = transactionDate;
830
- creditTransaction.Description = creditNote.DocNo;
831
- creditTransaction.Name = creditNote.DocNo;
832
- creditTransaction.RelatedDocNo = creditNote.DocNo;
833
- creditTransaction.RelatedObjectId = creditNote.RelatedObjectId;
834
- creditTransaction.RelatedObjectType = creditNote.RelatedObjectType;
835
- for (const invoiceItem of documentItems) {
836
- const itemLedger = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
837
- itemLedger.AccountNo = invoiceItem.DtAccountNo;
838
- itemLedger.Currency = invoiceItem.Currency;
839
- itemLedger.DebitAmount = invoiceItem.Amount;
840
- itemLedger.Date = transactionDate;
841
- itemLedger.Description = invoiceItem.Name;
842
- itemLedger.RelatedDocNo = creditNote.DocNo;
843
- itemLedger.RelatedObjectId = creditNote.RelatedObjectId;
844
- itemLedger.RelatedObjectType = creditNote.RelatedObjectType;
845
- }
846
- yield this.postJournal(dbTransaction, journalEntry, loginUser);
847
- const entityValueAfter = {
848
- LedgerNo: creditTransaction.LedgerNo,
849
- TransactionType: creditTransaction.TransactionType,
850
- JournalEntryId: creditTransaction.JournalEntryId,
851
- AccountNo: creditTransaction.AccountNo,
852
- Date: creditTransaction.Date,
853
- Name: creditTransaction.Name,
854
- Description: creditTransaction.Description,
855
- Currency: creditTransaction.Currency,
856
- DebitAmount: creditTransaction.DebitAmount,
857
- CreditAmount: creditTransaction.CreditAmount,
858
- RelatedObjectId: creditTransaction.RelatedObjectId,
859
- RelatedObjectType: creditTransaction.RelatedObjectType,
860
- RelatedDocNo: creditTransaction.RelatedDocNo,
861
- RelatedPaymentId: creditTransaction.RelatedPaymentId,
862
- };
863
- const payload = {
864
- Action: 'Create',
865
- Activity: 'Issuing a Credit Note Transaction',
866
- Description: `Credit Transaction (ID: ${creditTransaction.LedgerNo}) has been created`,
867
- EntityType: 'CreditTransaction',
868
- EntityValueBefore: JSON.stringify({}),
869
- EntityValueAfter: JSON.stringify(entityValueAfter),
870
- PerformedById: loginUser.ObjectId,
871
- PerformedAt: transactionDate,
872
- EntityId: creditTransaction.LedgerNo,
873
- };
874
- yield axios_1.default.post(`${process.env.COMMON_API_URL}/activity-histories`, payload);
875
- return creditNote;
876
- }
877
- catch (err) {
878
- console.log('Issue credit note err: ', err);
879
- throw err;
880
- }
881
- });
882
- }
883
- collectPayment(dbTransaction, loginUser, payment, collectPaymentType = collect_payment_type_1.CollectPaymentType.AUTOMATIC) {
884
- return __awaiter(this, void 0, void 0, function* () {
885
- try {
886
- const paymentItems = yield payment.getPaymentItems();
887
- if (paymentItems.length < 1) {
888
- throw new Error('Atleast one payment item is required to identify what payment is being paid for.');
889
- }
890
- const paymentPaidWithItems = yield payment.getPaymentPaidWith();
891
- if (paymentPaidWithItems.length < 1) {
892
- throw new Error('Atleast one payment paid with item is required to identify how the payment was made.');
893
- }
894
- payment.PaymentId = this._createId().toUpperCase();
895
- payment.PaymentType = enum_1.PaymentType.PAYMENT_RECEIVED;
896
- payment.ReceivedBy = loginUser.ObjectId;
897
- payment.IssuedBy = loginUser.ObjectId;
898
- yield FinanceCompany._PaymentRepository.create({
899
- PaymentId: payment.PaymentId,
900
- PaymentType: payment.PaymentType,
901
- PaymentDate: payment.PaymentDate,
902
- Description: payment.Description,
903
- Currency: payment.Currency,
904
- Amount: payment.Amount,
905
- Status: collectPaymentType === collect_payment_type_1.CollectPaymentType.AUTOMATIC
906
- ? enum_1.PaymentStatus.CONFIRMED
907
- : enum_1.PaymentStatus.PENDING,
908
- PostedToAccSystemYN: 'N',
909
- ReceivedBy: payment.ReceivedBy,
910
- IssuedBy: payment.IssuedBy,
911
- Remarks: payment.Remarks,
912
- RelatedObjectId: payment.RelatedObjectId,
913
- RelatedObjectType: payment.RelatedObjectType,
914
- ReceiptDocNo: payment.ReceiptDocNo,
915
- UpdatedAt: new Date(),
916
- UpdatedBy: loginUser.ObjectId,
917
- CreatedAt: new Date(),
918
- CreatedBy: loginUser.ObjectId,
919
- }, { transaction: dbTransaction });
920
- for (const paymentItem of paymentItems) {
921
- yield FinanceCompany._PaymentItemRepository.create({
922
- PaymentId: payment.PaymentId,
923
- PayForObjectId: paymentItem.PayForObjectId,
924
- PayForObjectType: paymentItem.PayForObjectType,
925
- Currency: paymentItem.Currency,
926
- Amount: paymentItem.Amount,
927
- Name: paymentItem.Name,
928
- Description: paymentItem.Description,
929
- }, { transaction: dbTransaction });
930
- }
931
- for (const paymentPaidWithItem of paymentPaidWithItems) {
932
- yield payment_method_type_1.default.initMethodType(dbTransaction, paymentPaidWithItem.MethodTypeId);
933
- yield FinanceCompany._PaymentPaidWithRepository.create({
934
- PaymentId: payment.PaymentId,
935
- MethodTypeId: paymentPaidWithItem.MethodTypeId,
936
- Currency: paymentPaidWithItem.Currency,
937
- Amount: paymentPaidWithItem.Amount,
938
- Status: paymentPaidWithItem.Status,
939
- TransactionId: paymentPaidWithItem.TransactionId,
940
- RefBank: paymentPaidWithItem.RefBank,
941
- RefName: paymentPaidWithItem.RefName,
942
- RefNo: paymentPaidWithItem.RefNo,
943
- RefOther1: paymentPaidWithItem.RefOther1,
944
- RefOther2: paymentPaidWithItem.RefOther2,
945
- RefOther3: paymentPaidWithItem.RefOther3,
946
- RefOther4: paymentPaidWithItem.RefOther4,
947
- RefOther5: paymentPaidWithItem.RefOther5,
948
- Remarks: paymentPaidWithItem.Remarks,
949
- PaymentMediaId: paymentPaidWithItem.PaymentMediaId,
950
- }, { transaction: dbTransaction });
951
- }
952
- return payment;
953
- }
954
- catch (error) {
955
- throw error;
956
- }
957
- });
958
- }
959
- makePayment(dbTransaction, loginUser, payment, customer, dtAccountNo) {
960
- return __awaiter(this, void 0, void 0, function* () {
961
- let paymentMethodType;
962
- try {
963
- const paymentPaidWith = yield payment.getPaymentPaidWith();
964
- if (paymentPaidWith.length < 1) {
965
- throw new Error('Atleast one payment paid with item is required to identify how the payment was made.');
966
- }
967
- paymentMethodType = yield payment_method_type_1.default.initMethodType(dbTransaction, paymentPaidWith[0].MethodTypeId);
968
- const paymentItems = yield payment.getPaymentItems();
969
- if (paymentItems.length < 1) {
970
- throw new Error('Atleast one payment item is required to identify what payment is being paid for');
971
- }
972
- payment.PaymentId = this._createId().toUpperCase();
973
- payment.PaymentType = enum_1.PaymentType.PAYOUT;
974
- payment.ReceivedBy = loginUser.ObjectId;
975
- payment.IssuedBy = loginUser.ObjectId;
976
- yield FinanceCompany._PaymentRepository.create({
977
- PaymentId: payment.PaymentId,
978
- PaymentType: payment.PaymentType,
979
- PaymentDate: payment.PaymentDate,
980
- Description: payment.Description,
981
- Currency: payment.Currency,
982
- ReceivedBy: payment.ReceivedBy,
983
- IssuedBy: payment.IssuedBy,
984
- Remarks: payment.Remarks,
985
- RelatedObjectId: payment.RelatedObjectId,
986
- RelatedObjectType: payment.RelatedObjectType,
987
- Amount: payment.Amount,
988
- Status: enum_1.PaymentStatus.CONFIRMED,
989
- PostedToAccSystemYN: 'N',
990
- UpdatedAt: new Date(),
991
- UpdatedBy: loginUser.ObjectId,
992
- CreatedAt: new Date(),
993
- CreatedBy: loginUser.ObjectId,
994
- }, { transaction: dbTransaction });
995
- paymentItems.forEach((paymentItem) => __awaiter(this, void 0, void 0, function* () {
996
- yield FinanceCompany._PaymentItemRepository.create({
997
- PaymentId: payment.PaymentId,
998
- PayForObjectId: paymentItem.PayForObjectId,
999
- PayForObjectType: paymentItem.PayForObjectType,
1000
- Currency: paymentItem.Currency,
1001
- Amount: paymentItem.Amount,
1002
- Name: paymentItem.Name,
1003
- Description: paymentItem.Description,
1004
- }, { transaction: dbTransaction });
1005
- yield paymentItem.paid(dbTransaction);
1006
- }));
1007
- for (const paymentPaidWithItem of paymentPaidWith) {
1008
- yield FinanceCompany._PaymentPaidWithRepository.create({
1009
- PaymentId: payment.PaymentId,
1010
- MethodTypeId: paymentPaidWithItem.MethodTypeId,
1011
- Currency: paymentPaidWithItem.Currency,
1012
- Amount: paymentPaidWithItem.Amount,
1013
- Status: paymentPaidWithItem.Status,
1014
- TransactionId: paymentPaidWithItem.TransactionId,
1015
- RefBank: paymentPaidWithItem.RefBank,
1016
- RefName: paymentPaidWithItem.RefName,
1017
- RefNo: paymentPaidWithItem.RefNo,
1018
- RefOther1: paymentPaidWithItem.RefOther1,
1019
- RefOther2: paymentPaidWithItem.RefOther2,
1020
- RefOther3: paymentPaidWithItem.RefOther3,
1021
- RefOther4: paymentPaidWithItem.RefOther4,
1022
- RefOther5: paymentPaidWithItem.RefOther5,
1023
- Remarks: paymentPaidWithItem.Remarks,
1024
- PaymentMediaId: paymentPaidWithItem.PaymentMediaId,
1025
- }, { transaction: dbTransaction });
1026
- }
1027
- const transactionDate = new Date();
1028
- for (const paymentPaidWithItem of paymentPaidWith) {
1029
- try {
1030
- paymentMethodType = yield payment_method_type_1.default.initMethodType(dbTransaction, paymentPaidWithItem.MethodTypeId);
1031
- const journalEntry = new journal_entry_1.default(dbTransaction);
1032
- journalEntry.init({
1033
- CompanyId: this.CompanyId,
1034
- Name: 'Make Payment for ' + payment.PaymentId,
1035
- });
1036
- const creditLT = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
1037
- creditLT.AccountNo = paymentMethodType.AccountNo;
1038
- creditLT.Currency = paymentPaidWithItem.Currency;
1039
- creditLT.CreditAmount = paymentPaidWithItem.Amount;
1040
- creditLT.Date = transactionDate;
1041
- creditLT.Description = customer.FullName;
1042
- creditLT.Name = customer.FullName;
1043
- creditLT.RelatedObjectId = payment.RelatedObjectId;
1044
- creditLT.RelatedObjectType = payment.RelatedObjectType;
1045
- const debitLT = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
1046
- if (dtAccountNo) {
1047
- debitLT.AccountNo = dtAccountNo;
1048
- }
1049
- else {
1050
- const apAccount = yield customer.getAccountPayable();
1051
- debitLT.AccountNo = apAccount.AccountNo;
1052
- }
1053
- debitLT.Currency = paymentPaidWithItem.Currency;
1054
- debitLT.DebitAmount = paymentPaidWithItem.Amount;
1055
- debitLT.Date = transactionDate;
1056
- debitLT.Description = paymentMethodType.Name;
1057
- debitLT.Name = paymentMethodType.Name;
1058
- debitLT.RelatedObjectId = payment.RelatedObjectId;
1059
- debitLT.RelatedObjectType = payment.RelatedObjectType;
1060
- yield this.postJournal(dbTransaction, journalEntry, loginUser);
1061
- }
1062
- catch (error) {
1063
- if (error instanceof general_1.RecordNotFoundError) {
1064
- throw new Error('Invalid Payment Method Type Id');
1065
- }
1066
- else {
1067
- throw error;
1068
- }
1069
- }
1070
- }
1071
- return payment;
1072
- }
1073
- catch (error) {
1074
- if (error instanceof general_1.RecordNotFoundError) {
1075
- throw new Error('Invalid PaymentMethodType id');
1076
- }
1077
- else {
1078
- throw error;
1079
- }
1080
- }
1081
- });
1082
- }
1083
- get PaymentMethods() {
1084
- return new Promise((resolve, reject) => {
1085
- if (this.CompanyId !== 'New') {
1086
- FinanceCompany._PaymentMethodRepository
1087
- .findAll({
1088
- where: {
1089
- CompanyId: this.CompanyId,
1090
- },
1091
- })
1092
- .then((paymentMethod) => {
1093
- const paymentMethodObjects = paymentMethod.map((paymentMethodData) => {
1094
- return new Promise((resolve, reject) => {
1095
- FinanceCompany._PaymentMethodTypeRepository
1096
- .findAll({
1097
- where: {
1098
- MethodId: paymentMethodData.MethodId,
1099
- },
1100
- raw: true,
1101
- })
1102
- .then((paymentMethodTypes) => {
1103
- const paymentMethodObjects = Object.assign(Object.assign({}, paymentMethodData.get({ plain: true })), { Types: paymentMethodTypes });
1104
- resolve(paymentMethodObjects);
1105
- })
1106
- .catch((err) => {
1107
- reject(err);
1108
- });
1109
- }).then((paymentMethods) => paymentMethods);
1110
- });
1111
- return Promise.all(paymentMethodObjects);
1112
- })
1113
- .then((paymentMethodObjects) => {
1114
- this._PaymentMethods = paymentMethodObjects;
1115
- resolve(this._PaymentMethods);
1116
- })
1117
- .catch((err) => {
1118
- reject(err);
1119
- });
1120
- }
1121
- else {
1122
- resolve(this._PaymentMethods);
1123
- }
1124
- });
1125
- }
1126
- get TaxCodes() {
1127
- return new Promise((resolve, reject) => {
1128
- if (this.CompanyId !== 'New') {
1129
- FinanceCompany._TaxRepository
1130
- .findAll({
1131
- where: {
1132
- CompanyId: this.CompanyId,
1133
- },
1134
- transaction: this._DbTransaction,
1135
- })
1136
- .then((taxes) => {
1137
- const taxList = [];
1138
- taxes.forEach((tax) => {
1139
- taxList.push(new tax_1.Tax({
1140
- TaxCode: tax.TaxCode,
1141
- TaxRate: typeof tax.TaxRate === 'number'
1142
- ? tax.TaxRate
1143
- : parseFloat(tax.TaxRate),
1144
- Description: tax.Description,
1145
- CompanyId: tax.CompanyId,
1146
- CreatedAt: tax.CreatedAt,
1147
- CreatedById: tax.CreatedById,
1148
- UpdatedAt: tax.UpdatedAt,
1149
- UpdatedById: tax.UpdatedById,
1150
- }));
1151
- });
1152
- this._Taxes = taxList;
1153
- resolve(this._Taxes);
1154
- })
1155
- .catch((err) => {
1156
- reject(err);
1157
- });
1158
- }
1159
- else {
1160
- resolve(this._Taxes);
1161
- }
1162
- });
1163
- }
1164
- LoadPaymentMethods(companyId, paymentMethods, transaction) {
1165
- return __awaiter(this, void 0, void 0, function* () {
1166
- const paymentMethod = new payment_method_1.default();
1167
- for (const method in paymentMethods) {
1168
- const paymentMethodData = yield FinanceCompany._PaymentMethodRepository.findOne({
1169
- where: {
1170
- MethodId: paymentMethods[method].id,
1171
- Name: paymentMethods[method].name,
1172
- },
1173
- transaction: transaction,
1174
- });
1175
- if (!paymentMethodData) {
1176
- const newPaymentMethod = yield FinanceCompany._PaymentMethodRepository.create({
1177
- MethodId: paymentMethods[method].id,
1178
- Name: paymentMethods[method].name,
1179
- CompanyId: companyId,
1180
- }, {
1181
- transaction: transaction,
1182
- });
1183
- this._PaymentMethods.push(newPaymentMethod);
1184
- }
1185
- this._PaymentMethods.push(paymentMethodData);
1186
- }
1187
- this._PaymentMethods.forEach((item) => __awaiter(this, void 0, void 0, function* () {
1188
- var _a, _b;
1189
- const p = item === null || item === void 0 ? void 0 : item.get({ plain: true });
1190
- for (const method in paymentMethods) {
1191
- if (!p) {
1192
- continue;
1193
- }
1194
- if (p.MethodId === ((_a = paymentMethods[method]) === null || _a === void 0 ? void 0 : _a.id)) {
1195
- const paymentMethodTypeData = yield FinanceCompany._PaymentMethodTypeRepository.findOne({
1196
- where: {
1197
- MethodId: p.MethodId,
1198
- },
1199
- transaction: transaction,
1200
- });
1201
- if (!paymentMethodTypeData) {
1202
- const configPaymentMethodTypes = (_b = paymentMethods[method]) === null || _b === void 0 ? void 0 : _b.types;
1203
- for (const methodType in configPaymentMethodTypes) {
1204
- const accountData = yield FinanceCompany._AccountRepository.findOne({
1205
- where: {
1206
- AccountNo: configPaymentMethodTypes[methodType].accountNo,
1207
- },
1208
- transaction: transaction,
1209
- });
1210
- if (!accountData) {
1211
- const accountPayload = {
1212
- CompanyId: companyId,
1213
- Name: configPaymentMethodTypes[methodType].name,
1214
- AccountType: 'PaymentMethod',
1215
- CreatedAt: new Date(),
1216
- CreatedById: 'System',
1217
- AccSystemRefId: 'REF',
1218
- PostedToAccSystemYN: 'N',
1219
- };
1220
- try {
1221
- yield FinanceCompany._AccountRepository.create(Object.assign({ AccountNo: configPaymentMethodTypes[methodType].accountNo }, accountPayload), {
1222
- transaction: transaction,
1223
- });
1224
- yield FinanceCompany._AccountRepository.create(Object.assign({ AccountNo: configPaymentMethodTypes[methodType]
1225
- .processingFeeAccountNo }, accountPayload), {
1226
- transaction: transaction,
1227
- });
1228
- }
1229
- catch (err) {
1230
- throw err;
1231
- }
1232
- }
1233
- const paymentMethodTypePayload = {
1234
- MethodId: p.MethodId,
1235
- MethodTypeId: configPaymentMethodTypes[methodType].id,
1236
- Name: configPaymentMethodTypes[methodType].name,
1237
- AccountNo: configPaymentMethodTypes[methodType].accountNo,
1238
- ProcessingFeeRate: configPaymentMethodTypes[methodType].processingFeeRate,
1239
- ProcessingFeeAccountNo: configPaymentMethodTypes[methodType].processingFeeAccountNo,
1240
- };
1241
- try {
1242
- yield paymentMethod.newPaymentMethodType(paymentMethodTypePayload, transaction);
1243
- }
1244
- catch (err) { }
1245
- }
1246
- }
1247
- }
1248
- }
1249
- }));
1250
- });
1251
- }
1252
- LoadTaxCodes(companyId, companyTaxes, transaction) {
1253
- return __awaiter(this, void 0, void 0, function* () {
1254
- for (const tax in companyTaxes) {
1255
- let tx = yield FinanceCompany._TaxRepository.findOne({
1256
- where: {
1257
- TaxCode: companyTaxes[tax].taxCode,
1258
- },
1259
- transaction: transaction,
1260
- });
1261
- if (!tx) {
1262
- const newTx = yield FinanceCompany._TaxRepository.create({
1263
- TaxCode: companyTaxes[tax].taxCode,
1264
- TaxRate: companyTaxes[tax].taxRate,
1265
- Description: companyTaxes[tax].description,
1266
- CompanyId: companyId,
1267
- UpdatedAt: new Date(),
1268
- CreatedById: 'System',
1269
- CreatedAt: new Date(),
1270
- UpdatedById: 'System',
1271
- }, {
1272
- transaction: transaction,
1273
- });
1274
- tx = newTx;
1275
- }
1276
- this._Taxes.push(new tax_1.Tax(tx.get({ plain: true })));
1277
- }
1278
- });
1279
- }
1280
- collectPaymentForMultipleCustomers(dbTransaction, loginUser, payment, creditTransaction, receiptNo, collectPaymentType = collect_payment_type_1.CollectPaymentType.AUTOMATIC) {
1281
- return __awaiter(this, void 0, void 0, function* () {
1282
- try {
1283
- const systemCode = yield config_1.ApplicationConfig.getComponentConfigValue('system-code');
1284
- const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'Collect Payment For Multiple Customers');
1285
- if (!isPrivileged) {
1286
- throw new Error('User is not authorized to perform this action');
1287
- }
1288
- const paymentItems = yield payment.getPaymentItems();
1289
- if (paymentItems.length < 1) {
1290
- throw new Error('Atleast one payment item is required to identify what payment is being paid for.');
1291
- }
1292
- const paymentPaidWithItems = yield payment.getPaymentPaidWith();
1293
- if (paymentPaidWithItems.length < 1) {
1294
- throw new Error('Atleast one payment paid with item is required to identify how the payment was made.');
1295
- }
1296
- if (paymentItems.length !== creditTransaction.length) {
1297
- throw new Error('Payment items length is not equal to creditTransaction length');
1298
- }
1299
- let totalAmount = 0;
1300
- paymentItems.forEach((paymentItem) => {
1301
- totalAmount += paymentItem.Amount;
1302
- });
1303
- const totalCreditTransactionAmount = creditTransaction.reduce((accumulator, currentValue) => {
1304
- return accumulator + currentValue.Amount;
1305
- }, 0);
1306
- if (totalAmount !== totalCreditTransactionAmount) {
1307
- throw new Error('Payment items total Amount is dnot equal to credit transactions total Amount');
1308
- }
1309
- payment.PaymentId = this._createId().toUpperCase();
1310
- payment.PaymentType = enum_1.PaymentType.PAYMENT_RECEIVED;
1311
- payment.ReceivedBy = loginUser.ObjectId;
1312
- payment.IssuedBy = loginUser.ObjectId;
1313
- yield FinanceCompany._PaymentRepository.create({
1314
- PaymentId: payment.PaymentId,
1315
- PaymentType: payment.PaymentType,
1316
- PaymentDate: payment.PaymentDate,
1317
- Description: payment.Description,
1318
- Currency: payment.Currency,
1319
- Amount: payment.Amount,
1320
- Status: collectPaymentType === collect_payment_type_1.CollectPaymentType.MANUAL
1321
- ? enum_1.PaymentStatus.PENDING
1322
- : enum_1.PaymentStatus.CONFIRMED,
1323
- PostedToAccSystemYN: 'N',
1324
- ReceivedBy: payment.ReceivedBy,
1325
- IssuedBy: payment.IssuedBy,
1326
- Remarks: payment.Remarks,
1327
- RelatedObjectId: payment.RelatedObjectId,
1328
- RelatedObjectType: payment.RelatedObjectType,
1329
- ReceiptDocNo: payment.ReceiptDocNo,
1330
- UpdatedAt: new Date(),
1331
- UpdatedBy: loginUser.ObjectId,
1332
- CreatedAt: new Date(),
1333
- CreatedBy: loginUser.ObjectId,
1334
- }, { transaction: dbTransaction });
1335
- paymentItems.forEach((paymentItem) => __awaiter(this, void 0, void 0, function* () {
1336
- yield FinanceCompany._PaymentItemRepository.create({
1337
- PaymentId: payment.PaymentId,
1338
- PayForObjectId: paymentItem.PayForObjectId,
1339
- PayForObjectType: paymentItem.PayForObjectType,
1340
- Currency: paymentItem.Currency,
1341
- Amount: paymentItem.Amount,
1342
- Name: paymentItem.Name,
1343
- Description: paymentItem.Description,
1344
- }, { transaction: dbTransaction });
1345
- }));
1346
- paymentPaidWithItems.forEach((paymentPaidWithItem) => __awaiter(this, void 0, void 0, function* () {
1347
- yield FinanceCompany._PaymentPaidWithRepository.create({
1348
- PaymentId: payment.PaymentId,
1349
- MethodTypeId: paymentPaidWithItem.MethodTypeId,
1350
- Currency: paymentPaidWithItem.Currency,
1351
- Amount: paymentPaidWithItem.Amount,
1352
- Status: paymentPaidWithItem.Status,
1353
- LedgerNo: paymentPaidWithItem.TransactionId,
1354
- RefBank: paymentPaidWithItem.RefBank,
1355
- RefName: paymentPaidWithItem.RefName,
1356
- RefNo: paymentPaidWithItem.RefNo,
1357
- RefOther1: paymentPaidWithItem.RefOther1,
1358
- RefOther2: paymentPaidWithItem.RefOther2,
1359
- RefOther3: paymentPaidWithItem.RefOther3,
1360
- RefOther4: paymentPaidWithItem.RefOther4,
1361
- RefOther5: paymentPaidWithItem.RefOther5,
1362
- Remarks: paymentPaidWithItem.Remarks,
1363
- PaymentMediaId: paymentPaidWithItem.PaymentMediaId,
1364
- }, { transaction: dbTransaction });
1365
- }));
1366
- return payment;
1367
- }
1368
- catch (error) {
1369
- throw error;
1370
- }
1371
- });
1372
- }
1373
- confirmPayment(dbTransaction, loginUser, customer, payment, status, remarks, ctAccountNo, receiptNo) {
1374
- return __awaiter(this, void 0, void 0, function* () {
1375
- try {
1376
- this._DbTransaction = dbTransaction;
1377
- const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1378
- const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'FinanceCompany - Confirm Payment');
1379
- if (!isPrivileged) {
1380
- throw new general_1.ClassError('FinanceCompany', 'FinanceCompanyConfirmPaymentErrMsg00', `You do not have 'Payment - Confirm' privilege.`);
1381
- }
1382
- if (payment.PaymentId === 'New') {
1383
- throw new general_1.ClassError('FinanceCompany', 'FinanceCompanyConfirmPaymentErrMsg01', `Payment not found.`);
1384
- }
1385
- if (payment.Status !== enum_1.PaymentStatus.PENDING) {
1386
- throw new general_1.ClassError('Payment', 'PaymentConfirmPaymentErrMsg02', `Payment status is not 'Pending'.`);
1387
- }
1388
- payment.Remarks = remarks;
1389
- let receiptDocNo = null;
1390
- switch (status) {
1391
- case enum_1.PaymentStatus.REJECTED:
1392
- payment.Status = enum_1.PaymentStatus.REJECTED;
1393
- break;
1394
- case enum_1.PaymentStatus.FAILED:
1395
- payment.Status = enum_1.PaymentStatus.FAILED;
1396
- break;
1397
- case enum_1.PaymentStatus.CONFIRMED:
1398
- payment.Status = enum_1.PaymentStatus.CONFIRMED;
1399
- const receiptDocuments = yield FinanceCompany._DocumentRepository.findAll({
1400
- where: {
1401
- DocType: enum_1.DocType.RECEIPT,
1402
- CompanyId: this.ObjectId,
1403
- },
1404
- });
1405
- const receipt = new document_1.default(dbTransaction);
1406
- if (receiptNo) {
1407
- receipt.DocNo = receiptNo;
1408
- }
1409
- else {
1410
- receipt.DocNo = `EZC-RCT-${receiptDocuments.length + 1}`;
1411
- }
1412
- receipt.DocType = enum_1.DocType.RECEIPT;
1413
- receipt.DocDate = new Date();
1414
- receipt.CompanyId = this.ObjectId;
1415
- receipt.Currency = payment.Currency;
1416
- receipt.Description = 'Payment Received';
1417
- receipt.IssuedById = loginUser.ObjectId;
1418
- receipt.IssuedToId = customer.CustomerId;
1419
- receipt.IssuedToType = (0, typeof_1.type)(customer);
1420
- receipt.RelatedObjectId = payment.RelatedObjectId;
1421
- receipt.RelatedObjectType = payment.RelatedObjectType;
1422
- receipt.UseAccSystemDocYN = 'N';
1423
- receipt.CreatedById = loginUser.ObjectId;
1424
- receipt.UpdatedById = loginUser.ObjectId;
1425
- const paymentItems = yield payment.getPaymentItems(dbTransaction);
1426
- for (const paymentItem of paymentItems) {
1427
- const receiptItem = new document_item_1.default(dbTransaction, receipt);
1428
- receiptItem.Name = `Payment for ${paymentItem.PayForObjectType} No. ${paymentItem.PayForObjectId}`;
1429
- receiptItem.NameBM = `Bayaran untuk ${paymentItem.PayForObjectType} No. ${paymentItem.PayForObjectId}`;
1430
- receiptItem.Description = '-';
1431
- receiptItem.Currency = paymentItem.Currency;
1432
- receiptItem.UnitPrice = paymentItem.Amount;
1433
- receiptItem.Quantity = 1;
1434
- receiptItem.Amount = receiptItem.UnitPrice * receiptItem.Quantity;
1435
- receiptItem.ItemId = receipt.DocNo;
1436
- receiptItem.ItemType = (0, typeof_1.type)(payment);
1437
- receiptItem.CtAccountNo = ctAccountNo;
1438
- yield paymentItem.paid(dbTransaction);
1439
- yield receipt.newDocumentItem(receiptItem);
1440
- }
1441
- const receiptMedia = yield receipt.generateReceipt(receipt.IssuedById, customer, dbTransaction);
1442
- yield FinanceCompany._DocumentRepository.create({
1443
- DocNo: receipt.DocNo,
1444
- DocType: receipt.DocType,
1445
- DocDate: receipt.DocDate,
1446
- CompanyId: receipt.CompanyId,
1447
- Currency: receipt.Currency,
1448
- Amount: receipt.Amount,
1449
- Description: receipt.Description,
1450
- Status: receipt.Status,
1451
- IssuedById: receipt.IssuedById,
1452
- IssuedToId: receipt.IssuedToId,
1453
- IssuedToType: receipt.IssuedToType,
1454
- RelatedObjectId: receipt.RelatedObjectId,
1455
- RelatedObjectType: receipt.RelatedObjectType,
1456
- CreatedById: receipt.CreatedById,
1457
- CreatedAt: new Date(),
1458
- UpdatedById: receipt.UpdatedById,
1459
- UpdatedAt: new Date(),
1460
- DocPDFFileMediaId: receiptMedia.PDFMedia.MediaId,
1461
- DocHTMLFileMediaId: receiptMedia.HTMLMedia.MediaId,
1462
- AccSystemRefId: receipt.AccSystemRefId,
1463
- PostedToAccSystemYN: receipt.PostedToAccSystemYN,
1464
- PostedById: receipt.PostedToAccSystemYN == 'Y' ? receipt.PostedById : null,
1465
- PostedDateTime: new Date(),
1466
- UseAccSystemDocYN: receipt.UseAccSystemDocYN,
1467
- }, {
1468
- transaction: dbTransaction,
1469
- });
1470
- const receiptItems = yield receipt.getDocumentItems(dbTransaction);
1471
- for (const receiptItem of receiptItems) {
1472
- yield FinanceCompany._DocumentItemRepository.create({
1473
- DocumentItemId: this._createId().toUpperCase(),
1474
- DocNo: receipt.DocNo,
1475
- Name: receiptItem.Name,
1476
- NameBM: receiptItem.NameBM,
1477
- Description: receiptItem.Description,
1478
- ItemId: receiptItem.ItemId,
1479
- ItemType: receiptItem.ItemType,
1480
- ItemSKU: receiptItem.ItemSKU,
1481
- ItemSerialNo: receiptItem.ItemSerialNo,
1482
- Currency: receiptItem.Currency,
1483
- UnitPrice: receiptItem.UnitPrice,
1484
- Quantity: receiptItem.Quantity,
1485
- QuantityUOM: receiptItem.QuantityUOM,
1486
- Amount: receiptItem.Amount,
1487
- TaxCode: receiptItem.TaxCode,
1488
- TaxAmount: receiptItem.TaxAmount,
1489
- TaxRate: receiptItem.TaxRate,
1490
- TaxInclusiveYN: receiptItem.TaxInclusiveYN,
1491
- DtAccountNo: receiptItem.DtAccountNo
1492
- ? receiptItem.DtAccountNo
1493
- : null,
1494
- CtAccountNo: receiptItem.CtAccountNo
1495
- ? receiptItem.CtAccountNo
1496
- : null,
1497
- }, {
1498
- transaction: dbTransaction,
1499
- });
1500
- }
1501
- payment.ReceiptDocNo = receipt.DocNo;
1502
- receiptDocNo = receipt.DocNo;
1503
- const transactionDate = new Date();
1504
- const paymentPaidWithItems = yield payment.getPaymentPaidWith(dbTransaction);
1505
- for (const paymentPaidWith of paymentPaidWithItems) {
1506
- let paymentMethodType = yield payment_method_type_1.default.initMethodType(dbTransaction, paymentPaidWith.MethodTypeId);
1507
- const journalEntry = new journal_entry_1.default(dbTransaction);
1508
- journalEntry.init({
1509
- CompanyId: this.CompanyId,
1510
- Name: 'Collect-payments for ' + payment.PaymentId,
1511
- });
1512
- const debitLT = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
1513
- debitLT.AccountNo = paymentMethodType.AccountNo;
1514
- debitLT.Currency = paymentPaidWith.Currency;
1515
- debitLT.DebitAmount = paymentPaidWith.Amount;
1516
- debitLT.Date = transactionDate;
1517
- debitLT.Description = 'Payment Received';
1518
- debitLT.Name = customer.FullName;
1519
- debitLT.RelatedObjectId = payment.PaymentId;
1520
- debitLT.RelatedObjectType = 'Payment';
1521
- debitLT.RelatedPaymentId = payment.PaymentId;
1522
- const creditLT = yield journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
1523
- if (ctAccountNo) {
1524
- creditLT.AccountNo = ctAccountNo;
1525
- }
1526
- else {
1527
- const arAccount = yield customer.getAccountReceivable();
1528
- creditLT.AccountNo = arAccount.AccountNo;
1529
- }
1530
- creditLT.Currency = paymentPaidWith.Currency;
1531
- creditLT.CreditAmount = paymentPaidWith.Amount;
1532
- creditLT.Date = transactionDate;
1533
- creditLT.Description = 'Payment Received';
1534
- creditLT.Name = paymentMethodType.Name;
1535
- creditLT.RelatedObjectId = payment.PaymentId;
1536
- creditLT.RelatedObjectType = (0, typeof_1.type)(payment);
1537
- creditLT.RelatedPaymentId = payment.PaymentId;
1538
- yield this.postJournal(dbTransaction, journalEntry, loginUser);
1539
- }
1540
- break;
1541
- default:
1542
- throw new general_1.ClassError('FinanceCompany', 'FinanceCompanyConfirmPaymentErrMsg03', `Invalid status.`);
1543
- }
1544
- yield FinanceCompany._PaymentRepository.update({
1545
- ReceiptDocNo: receiptDocNo,
1546
- Status: payment.Status,
1547
- UpdatedAt: new Date(),
1548
- UpdatedBy: loginUser.ObjectId,
1549
- }, {
1550
- where: {
1551
- PaymentId: payment.PaymentId,
1552
- },
1553
- transaction: dbTransaction,
1554
- });
1555
- }
1556
- catch (error) {
1557
- throw error;
1558
- }
1559
- });
1560
- }
1561
- }
1562
- exports.default = FinanceCompany;
1563
- FinanceCompany._htFinanceCompanyIds = new general_1.HashTable();
1564
- FinanceCompany._htFinanceCompanies = new general_1.HashTable();
1565
- FinanceCompany._financeCompanyRepository = new finance_company_repository_1.FinanceCompanyRepository();
1566
- FinanceCompany._PaymentRepository = new payment_repository_1.PaymentRepository();
1567
- FinanceCompany._PaymentItemRepository = new payment_item_repository_1.PaymentItemRepository();
1568
- FinanceCompany._PaymentPaidWithRepository = new payment_paid_with_repository_1.PaymentPaidWithRepository();
1569
- FinanceCompany._PaymentMethodRepository = new payment_method_repository_1.PaymentMethodRepository();
1570
- FinanceCompany._PaymentMethodTypeRepository = new payment_method_type_repository_1.PaymentMethodTypeRepository();
1571
- FinanceCompany._DocumentRepository = new document_repository_1.DocumentRepository();
1572
- FinanceCompany._DocumentItemRepository = new document_item_repository_1.DocumentItemRepository();
1573
- FinanceCompany._FinanceCustomerRepository = new finance_customer_repository_1.FinanceCustomerRepository();
1574
- FinanceCompany._LedgerTransactionRepository = new ledger_transaction_repository_1.LedgerTransactionRepository();
1575
- FinanceCompany._AccountRepository = new account_repository_1.AccountRepository();
1576
- FinanceCompany._TaxRepository = new tax_repository_1.TaxRepository();
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const axios_1 = require("axios");
4
+ const general_1 = require("@tomei/general");
5
+ const account_1 = require("../account/account");
6
+ const journal_entry_1 = require("../journal-entry/journal-entry");
7
+ const document_1 = require("../document/document");
8
+ const finance_company_repository_1 = require("./finance-company.repository");
9
+ const finance_customer_repository_1 = require("../customer/finance-customer.repository");
10
+ const ledger_transaction_repository_1 = require("../ledger-transaction/ledger-transaction.repository");
11
+ const enum_1 = require("../enum");
12
+ const payment_method_type_1 = require("../payment-method-type/payment-method-type");
13
+ const payment_repository_1 = require("../payment/payment.repository");
14
+ const payment_item_repository_1 = require("../payment-item/payment-item.repository");
15
+ const document_repository_1 = require("../document/document.repository");
16
+ const document_item_repository_1 = require("../document/document-item.repository");
17
+ const payment_method_repository_1 = require("../payment-method/payment-method.repository");
18
+ const payment_method_type_repository_1 = require("../payment-method-type/payment-method-type.repository");
19
+ const payment_method_1 = require("../payment-method/payment-method");
20
+ const account_repository_1 = require("../account/account.repository");
21
+ const payment_paid_with_repository_1 = require("../payment-paid-with/payment-paid-with.repository");
22
+ const document_item_1 = require("../document/document-item");
23
+ const typeof_1 = require("../helpers/typeof");
24
+ const activity_history_1 = require("@tomei/activity-history");
25
+ const config_1 = require("@tomei/config");
26
+ const tax_repository_1 = require("../tax/tax.repository");
27
+ const tax_1 = require("../tax/tax");
28
+ const collect_payment_type_1 = require("../enum/collect-payment-type");
29
+ class FinanceCompany extends general_1.ObjectBase {
30
+ get ObjectType() {
31
+ return this._ObjectType;
32
+ }
33
+ get CompSystemCode() {
34
+ return this._CompSystemCode;
35
+ }
36
+ set CompSystemCode(code) {
37
+ this._CompSystemCode = code;
38
+ }
39
+ get CompSystemRefId() {
40
+ return this._CompSystemRefId;
41
+ }
42
+ set CompSystemRefId(id) {
43
+ this._CompSystemRefId = id;
44
+ }
45
+ get AccSystemCode() {
46
+ return this._AccSystemCode;
47
+ }
48
+ get AccSystemRefId() {
49
+ return this._AccSystemRefId;
50
+ }
51
+ set AccSystemRefId(id) {
52
+ this._AccSystemRefId = id;
53
+ }
54
+ get PostedToAccSystemYN() {
55
+ return this._PostedToAccSystemYN;
56
+ }
57
+ set PostedToAccSystemYN(value) {
58
+ this._PostedToAccSystemYN = value;
59
+ }
60
+ get PostedById() {
61
+ return this._PostedById;
62
+ }
63
+ set PostedById(id) {
64
+ this._PostedById = id;
65
+ }
66
+ get PostedDateTime() {
67
+ return this._PostedDateTime;
68
+ }
69
+ set PostedDateTime(date) {
70
+ this._PostedDateTime = date;
71
+ }
72
+ set AccSystemCode(code) {
73
+ this._AccSystemCode = code;
74
+ }
75
+ get CompanyId() {
76
+ return this._CompanyId;
77
+ }
78
+ get ObjectId() {
79
+ return this._CompanyId;
80
+ }
81
+ set ObjectId(id) {
82
+ this._CompanyId = id;
83
+ }
84
+ get ObjectName() {
85
+ return `${this.CompSystemCode}-${this.CompSystemRefId}-${this.AccSystemCode}`;
86
+ }
87
+ get TableName() {
88
+ return 'finance_Company';
89
+ }
90
+ get AccountingSystem() {
91
+ return this._AccountingSystem;
92
+ }
93
+ set AccountingSystem(system) {
94
+ this._AccountingSystem = system;
95
+ }
96
+ constructor(compSystemCode, compSystemRefId, accSystemCode) {
97
+ super();
98
+ this._CompanyId = 'New';
99
+ this._CompSystemCode = '';
100
+ this._CompSystemRefId = '';
101
+ this._AccSystemCode = '';
102
+ this._AccSystemRefId = 'REF';
103
+ this._PostedToAccSystemYN = 'N';
104
+ this._PostedById = null;
105
+ this._PostedDateTime = null;
106
+ this._ObjectType = 'FinanceCompany';
107
+ this._PaymentMethods = [];
108
+ this._Taxes = [];
109
+ this.CompSystemCode = compSystemCode;
110
+ this.CompSystemRefId = compSystemRefId;
111
+ this.AccSystemCode = accSystemCode;
112
+ this.AccSystemRefId = 'REF';
113
+ this.PostedToAccSystemYN = 'N';
114
+ }
115
+ static async getFinanceCompanyId(compSystemCode, compSystemRefId, accSystemCode) {
116
+ let sCompanyId = '';
117
+ const sKey = `${compSystemCode}-${compSystemRefId}-${accSystemCode}`;
118
+ if (!FinanceCompany._htFinanceCompanyIds.get(sKey)) {
119
+ const financeCompany = new FinanceCompany(compSystemCode, compSystemRefId, accSystemCode);
120
+ const company = await FinanceCompany._financeCompanyRepository.findOne({
121
+ where: {
122
+ CompSystemCode: compSystemCode,
123
+ CompSystemRefId: compSystemRefId,
124
+ AccSystemCode: accSystemCode,
125
+ },
126
+ });
127
+ financeCompany.ObjectId = company.CompanyId;
128
+ sCompanyId = financeCompany.ObjectId;
129
+ FinanceCompany._htFinanceCompanyIds.add(sKey, financeCompany.ObjectId);
130
+ FinanceCompany._htFinanceCompanies.add(sCompanyId, financeCompany);
131
+ }
132
+ if (typeof FinanceCompany._htFinanceCompanyIds.get(sKey) === 'string') {
133
+ sCompanyId = FinanceCompany._htFinanceCompanyIds.get(sKey);
134
+ }
135
+ return sCompanyId;
136
+ }
137
+ static async getFinanceCompany(companyId) {
138
+ if (!FinanceCompany._htFinanceCompanies.get(companyId)) {
139
+ const company = await FinanceCompany._financeCompanyRepository.findOne({
140
+ where: { CompanyId: companyId },
141
+ });
142
+ if (!company) {
143
+ throw Error('No finance company found. Please create first.');
144
+ }
145
+ const compSystemCode = company.CompSystemCode;
146
+ const compSystemRefId = company.CompSystemRefId;
147
+ const accSystemCode = company.AccSystemCode;
148
+ const financeCompany = new FinanceCompany(compSystemCode, compSystemRefId, accSystemCode);
149
+ financeCompany.ObjectId = company.CompanyId;
150
+ financeCompany._CompanyId = company.CompanyId;
151
+ const sKey = `${compSystemCode}-${compSystemRefId}-${accSystemCode}`;
152
+ FinanceCompany._htFinanceCompanyIds.add(sKey, financeCompany.ObjectId);
153
+ FinanceCompany._htFinanceCompanies.add(financeCompany.ObjectId, financeCompany);
154
+ }
155
+ console.log('return from hash table');
156
+ return FinanceCompany._htFinanceCompanies.get(companyId);
157
+ }
158
+ static async createFinanceCompany(dbTransaction, loginUser, companyId, compSystemCode, compSystemRefId, accSystemCode) {
159
+ const financeCompany = new FinanceCompany(compSystemCode, compSystemRefId, accSystemCode);
160
+ const company = await FinanceCompany._financeCompanyRepository.findOne({
161
+ where: {
162
+ CompSystemCode: compSystemCode,
163
+ CompSystemRefId: compSystemRefId,
164
+ AccSystemCode: accSystemCode,
165
+ },
166
+ });
167
+ if (company) {
168
+ throw Error('There is already another Finance Company with the compSystemCode, CompSystemRefId and accSystemCode specified.');
169
+ }
170
+ financeCompany.ObjectId = companyId;
171
+ const accSystemRefId = config_1.ComponentConfig.getComponentConfigValue('finance-config.json', 'accountSystemRefId');
172
+ const postedToAccSystemYN = config_1.ComponentConfig.getComponentConfigValue('finance-config.json', 'postedToAccSystemYN');
173
+ financeCompany.PostedById = loginUser.ObjectId || null;
174
+ financeCompany.PostedDateTime = new Date();
175
+ await FinanceCompany._financeCompanyRepository.create({
176
+ CompanyId: financeCompany.CompanyId,
177
+ CompSystemCode: financeCompany.CompSystemCode,
178
+ CompSystemRefId: financeCompany.CompSystemRefId,
179
+ AccSystemCode: financeCompany.AccSystemCode,
180
+ AccSystemRefId: postedToAccSystemYN === 'Y'
181
+ ? accSystemRefId
182
+ : financeCompany.AccSystemRefId,
183
+ PostedToAccSystemYN: postedToAccSystemYN || financeCompany.PostedToAccSystemYN,
184
+ PostedById: financeCompany.PostedById,
185
+ PostedDateTime: financeCompany.PostedDateTime,
186
+ }, {
187
+ transaction: dbTransaction,
188
+ });
189
+ const sKey = `${compSystemCode}-${compSystemRefId}-${accSystemCode}`;
190
+ FinanceCompany._htFinanceCompanyIds.add(sKey, financeCompany.ObjectId);
191
+ FinanceCompany._htFinanceCompanies.add(financeCompany.ObjectId, financeCompany);
192
+ console.log('return from hash table');
193
+ return FinanceCompany._htFinanceCompanies.get(companyId);
194
+ }
195
+ static async findAccount(loginUser, dbTransaction, accountNo) {
196
+ try {
197
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
198
+ const isPrivileged = await loginUser.checkPrivileges(systemCode, 'FINANCECOMPANY_VIEW_ACCOUNT');
199
+ if (!isPrivileged) {
200
+ throw new general_1.ClassError('FinanceCompany', 'findAccountErrMsg0X', 'User not privileged to view finance company account');
201
+ }
202
+ const record = await FinanceCompany._AccountRepository.findOne({
203
+ where: {
204
+ AccountNo: accountNo,
205
+ },
206
+ transaction: dbTransaction,
207
+ });
208
+ if (record) {
209
+ const account = new account_1.default(dbTransaction);
210
+ account.init(record.get({ plain: true }));
211
+ return account;
212
+ }
213
+ return undefined;
214
+ }
215
+ catch (error) {
216
+ throw error;
217
+ }
218
+ }
219
+ async createCustomer(dbTransaction, custSystemCode, custSystemRefId, customer, loginUser) {
220
+ try {
221
+ if (!custSystemCode || !custSystemRefId) {
222
+ throw new Error('CustSystemCode and CustomerRefId are required fields.');
223
+ }
224
+ const financeCustomerData = await FinanceCompany._FinanceCustomerRepository.findOne({
225
+ where: {
226
+ CompanyId: this._CompanyId,
227
+ CustSystemCode: custSystemCode,
228
+ CustSystemRefId: custSystemRefId,
229
+ },
230
+ });
231
+ if (financeCustomerData) {
232
+ throw new Error('Customer already created previously.');
233
+ }
234
+ let AccCustomerRefId = 'REF';
235
+ if (this.AccountingSystem) {
236
+ AccCustomerRefId = await this.AccountingSystem.createCustomer(customer, dbTransaction);
237
+ }
238
+ customer.CompanyId = this._CompanyId;
239
+ const newCustomer = await customer.save(AccCustomerRefId, custSystemCode, custSystemRefId, dbTransaction);
240
+ const activity = new activity_history_1.Activity();
241
+ activity.ActivityId = this._createId().toUpperCase();
242
+ activity.Action = activity_history_1.ActionEnum.CREATE;
243
+ activity.Description = 'Add Finance Customer';
244
+ activity.EntityType = 'FinanceCustomer';
245
+ activity.EntityId = newCustomer.CustomerId;
246
+ activity.EntityValueBefore = JSON.stringify({});
247
+ activity.EntityValueAfter = JSON.stringify(newCustomer);
248
+ await activity.create(loginUser.ObjectId, dbTransaction);
249
+ return customer;
250
+ }
251
+ catch (error) {
252
+ throw error;
253
+ }
254
+ }
255
+ async postJournal(dbTransaction, journalEntry, loginUser) {
256
+ const debitTransactions = await journalEntry.DebitTransactions;
257
+ const creditTransactions = await journalEntry.CreditTransactions;
258
+ try {
259
+ if (creditTransactions.length < 1 || (debitTransactions === null || debitTransactions === void 0 ? void 0 : debitTransactions.length) < 1) {
260
+ throw new Error('There should be at least 1 debit ledger transaction and 1 credit ledger transaction in the journal entry');
261
+ }
262
+ let totalCreditAmount = creditTransactions.reduce((accumulator, currentValue) => accumulator + currentValue.CreditAmount, 0);
263
+ let totalDebitAmount = debitTransactions.reduce((accumulator, currentValue) => accumulator + currentValue.DebitAmount, 0);
264
+ console.log('totalCreditAmount: ', totalCreditAmount);
265
+ console.log('totalDebitAmount: ', totalDebitAmount);
266
+ if (typeof totalCreditAmount === 'string') {
267
+ totalCreditAmount = parseFloat(totalCreditAmount);
268
+ }
269
+ if (typeof totalDebitAmount === 'string') {
270
+ totalDebitAmount = parseFloat(totalDebitAmount);
271
+ }
272
+ if (totalCreditAmount.toFixed(2) !== totalDebitAmount.toFixed(2)) {
273
+ throw new Error('Credit ledger transaction and debit ledger transaction should the same amount');
274
+ }
275
+ const newJournalEntry = await journalEntry.save(loginUser.ObjectId, dbTransaction);
276
+ for (const ledgerTransaction of debitTransactions) {
277
+ ledgerTransaction.JournalEntryId = newJournalEntry.JournalEntryId;
278
+ await ledgerTransaction.save(dbTransaction);
279
+ }
280
+ for (const ledgerTransaction of creditTransactions) {
281
+ ledgerTransaction.JournalEntryId = newJournalEntry.JournalEntryId;
282
+ await ledgerTransaction.save(dbTransaction);
283
+ }
284
+ const payload = {
285
+ Action: 'Create',
286
+ Activity: 'Post Journal Entry',
287
+ Description: `Journal Entry (ID: ${newJournalEntry.JournalEntryId}) has been created`,
288
+ EntityType: 'JournalEntry',
289
+ EntityValueBefore: JSON.stringify({}),
290
+ EntityValueAfter: JSON.stringify(newJournalEntry),
291
+ PerformedById: loginUser.ObjectId,
292
+ PerformedAt: new Date(),
293
+ EntityId: newJournalEntry.JournalEntryId,
294
+ };
295
+ await axios_1.default.post(`${process.env.COMMON_API_URL}/activity-histories`, payload);
296
+ }
297
+ catch (error) {
298
+ throw error;
299
+ }
300
+ }
301
+ async createAccount(dbTransaction, account, loginUser) {
302
+ try {
303
+ let accSystemRefId;
304
+ if (!account.AccountType) {
305
+ throw new Error('AccountType is required.');
306
+ }
307
+ const accountNoLength = config_1.ComponentConfig.getComponentConfigValue('@tomei/finance', 'accountNoLength');
308
+ if (accountNoLength && account.AccountNo.length > accountNoLength) {
309
+ throw new Error(`Account No length should not exceed ${accountNoLength} characters.`);
310
+ }
311
+ let createAccountPayload = {
312
+ Name: account.Name,
313
+ AcctNum: account.AccountNo,
314
+ AccountType: account.AccountType,
315
+ AccountSubType: account.AccountSubtype,
316
+ };
317
+ if (this.AccountingSystem) {
318
+ accSystemRefId = await this.AccountingSystem.createAccount(account, dbTransaction);
319
+ }
320
+ if (account.isParentAccountExists()) {
321
+ createAccountPayload = Object.assign(Object.assign({}, createAccountPayload), { CurrencyRef: 'MYR', ParentRef: account.ParentAccountNo, SubAccount: true });
322
+ }
323
+ console.log('Finance Company Create Account: Before accSystemAccountId Create');
324
+ console.log('Finance Company Create Account: After accSystemAccountId Create');
325
+ console.log('Finance Company Create Account: Before new Account Create');
326
+ if (accSystemRefId) {
327
+ account.PostedToAccSystemYN = 'Y';
328
+ account.PostedById = loginUser.ObjectId;
329
+ account.PostedDateTime = new Date();
330
+ }
331
+ const newAccount = await account.save(this.CompanyId, accSystemRefId || 'REF', loginUser.ObjectId, dbTransaction);
332
+ console.log('Finance Company Create Account: After new Account Create');
333
+ const payload = {
334
+ Action: 'Create',
335
+ Activity: 'Account Created',
336
+ Description: `Account (ID: ${newAccount.AccountNo}) has been created`,
337
+ EntityType: 'Account',
338
+ EntityValueBefore: JSON.stringify({}),
339
+ EntityValueAfter: JSON.stringify(newAccount),
340
+ PerformedById: loginUser.ObjectId,
341
+ PerformedAt: new Date(),
342
+ EntityId: newAccount.AccountNo,
343
+ };
344
+ await axios_1.default.post(`${process.env.COMMON_API_URL}/activity-histories`, payload);
345
+ return account;
346
+ }
347
+ catch (error) {
348
+ throw error;
349
+ }
350
+ }
351
+ async issueInvoice(dbTransaction, invoice, loginUser, customer, dtAccountNo) {
352
+ try {
353
+ const duplicateInvoice = await FinanceCompany._DocumentRepository.findOne({
354
+ where: {
355
+ DocNo: invoice.DocNo,
356
+ },
357
+ transaction: dbTransaction,
358
+ });
359
+ if (duplicateInvoice) {
360
+ throw new Error('Invoice number already exists');
361
+ }
362
+ const documentItems = await invoice.getDocumentItems(dbTransaction);
363
+ if (!documentItems.length) {
364
+ throw new Error('Document must have at least 1 document item');
365
+ }
366
+ for (const invoiceItem of documentItems) {
367
+ if (!invoiceItem.CtAccountNo) {
368
+ throw new Error('Each document item should have CtAccountNo provided');
369
+ }
370
+ }
371
+ invoice.DocType = enum_1.DocType.INVOICE;
372
+ let invoiceMedia;
373
+ if (invoice.UseAccSystemDocYN === 'Y') {
374
+ const accInvoiceRefIdDetail = await this.AccountingSystem.createInvoice({
375
+ customer,
376
+ invoice,
377
+ paymentMode: 'credit',
378
+ }, dbTransaction);
379
+ invoice.DocNo = accInvoiceRefIdDetail.invoiceNo;
380
+ invoice.AccSystemRefId = accInvoiceRefIdDetail.invoiceRefId;
381
+ invoice.PostedToAccSystemYN = 'Y';
382
+ invoice.PostedById = loginUser.ObjectId;
383
+ invoice.PostedDateTime = new Date();
384
+ for (const documentItem of documentItems) {
385
+ const accItem = accInvoiceRefIdDetail.invoiceItems.find((item) => item.name === documentItem.Name);
386
+ if (accItem) {
387
+ documentItem.DocNo = accInvoiceRefIdDetail.invoiceNo;
388
+ documentItem.AccSystemRefId = accItem.itemRefId;
389
+ documentItem.PostedToAccSystemYN = 'Y';
390
+ documentItem.PostedById = loginUser.ObjectId;
391
+ documentItem.PostedDateTime = new Date();
392
+ }
393
+ }
394
+ }
395
+ else {
396
+ invoiceMedia = await invoice.generateInvoice(invoice.IssuedById, customer, dbTransaction);
397
+ }
398
+ await FinanceCompany._DocumentRepository.create({
399
+ DocNo: invoice.DocNo,
400
+ DocType: invoice.DocType,
401
+ DocDate: invoice.DocDate,
402
+ CompanyId: invoice.CompanyId,
403
+ Currency: invoice.Currency,
404
+ Amount: invoice.Amount,
405
+ Description: invoice.Description,
406
+ Status: invoice.Status,
407
+ IssuedById: invoice.IssuedById,
408
+ IssuedToId: invoice.IssuedToId,
409
+ IssuedToType: invoice.IssuedToType,
410
+ RelatedObjectId: invoice.RelatedObjectId,
411
+ RelatedObjectType: invoice.RelatedObjectType,
412
+ CreatedById: invoice.CreatedById,
413
+ CreatedAt: new Date(),
414
+ UpdatedById: invoice.UpdatedById,
415
+ UpdatedAt: new Date(),
416
+ DocPDFFileMediaId: invoice.UseAccSystemDocYN == 'N'
417
+ ? invoiceMedia.PDFMedia.MediaId
418
+ : null,
419
+ DocHTMLFileMediaId: invoice.UseAccSystemDocYN == 'N'
420
+ ? invoiceMedia.HTMLMedia.MediaId
421
+ : null,
422
+ AccSystemRefId: invoice.AccSystemRefId,
423
+ PostedToAccSystemYN: invoice.PostedToAccSystemYN,
424
+ PostedById: invoice.UseAccSystemDocYN == 'Y' ? invoice.PostedById : null,
425
+ PostedDateTime: new Date(),
426
+ UseAccSystemDocYN: invoice.UseAccSystemDocYN,
427
+ }, {
428
+ transaction: dbTransaction,
429
+ });
430
+ for (const documentItem of documentItems) {
431
+ await FinanceCompany._DocumentItemRepository.create({
432
+ DocumentItemId: this._createId().toUpperCase(),
433
+ DocNo: invoice.DocNo,
434
+ Name: documentItem.Name,
435
+ NameBM: documentItem.NameBM,
436
+ Description: documentItem.Description,
437
+ ItemId: documentItem.ItemId,
438
+ ItemType: documentItem.ItemType,
439
+ ItemSKU: documentItem.ItemSKU,
440
+ ItemSerialNo: documentItem.ItemSerialNo,
441
+ Currency: documentItem.Currency,
442
+ UnitPrice: documentItem.UnitPrice,
443
+ Quantity: documentItem.Quantity,
444
+ QuantityUOM: documentItem.QuantityUOM,
445
+ Amount: documentItem.Amount,
446
+ TaxCode: documentItem.TaxCode,
447
+ TaxAmount: documentItem.TaxAmount,
448
+ TaxRate: documentItem.TaxRate,
449
+ TaxInclusiveYN: documentItem.TaxInclusiveYN,
450
+ DtAccountNo: documentItem.DtAccountNo
451
+ ? documentItem.DtAccountNo
452
+ : null,
453
+ CtAccountNo: documentItem.CtAccountNo
454
+ ? documentItem.CtAccountNo
455
+ : null,
456
+ AccSystemRefId: documentItem.AccSystemRefId,
457
+ PostedToAccSystemYN: documentItem.PostedToAccSystemYN,
458
+ PostedById: documentItem.PostedById,
459
+ PostedDateTime: documentItem.PostedDateTime,
460
+ }, {
461
+ transaction: dbTransaction,
462
+ });
463
+ }
464
+ const transactionDate = new Date();
465
+ const htCreditAccountAmount = new general_1.HashTable();
466
+ const htCreditAccountCurrency = new general_1.HashTable();
467
+ const htCreditAccountPurpose = new general_1.HashTable();
468
+ documentItems.forEach((invoiceItem) => {
469
+ if (!htCreditAccountAmount.exists(invoiceItem.CtAccountNo)) {
470
+ htCreditAccountAmount.add(invoiceItem.CtAccountNo, invoiceItem.Amount);
471
+ htCreditAccountCurrency.add(invoiceItem.CtAccountNo, invoiceItem.Currency);
472
+ htCreditAccountPurpose.add(invoiceItem.CtAccountNo, invoiceItem.Name);
473
+ }
474
+ else {
475
+ const d = htCreditAccountAmount.get(invoiceItem.CtAccountNo);
476
+ htCreditAccountAmount.add(invoiceItem.CtAccountNo, d + invoiceItem.Amount);
477
+ }
478
+ });
479
+ const savedItems = htCreditAccountAmount.list();
480
+ for (const item of savedItems) {
481
+ const journalEntry = new journal_entry_1.default(dbTransaction);
482
+ journalEntry.init({
483
+ CompanyId: this.CompanyId,
484
+ Name: 'Issue Invoice ' + invoice.DocNo,
485
+ });
486
+ const creditAmount = item.value[1];
487
+ const currency = htCreditAccountCurrency.get(item.value[0]);
488
+ const purpose = htCreditAccountPurpose.get(item.value[0]);
489
+ const dt = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
490
+ if (dtAccountNo) {
491
+ dt.AccountNo = dtAccountNo;
492
+ }
493
+ else {
494
+ const arAccount = await customer.getAccountReceivable();
495
+ dt.AccountNo = arAccount.AccountNo;
496
+ }
497
+ dt.Currency = currency ? currency : 'MYR';
498
+ dt.DebitAmount = creditAmount ? creditAmount : 0.0;
499
+ dt.Date = transactionDate;
500
+ dt.Description = `${purpose}`;
501
+ dt.Name = `${purpose}`;
502
+ dt.RelatedDocNo = invoice.DocNo;
503
+ dt.RelatedObjectId = invoice.RelatedObjectId;
504
+ dt.RelatedObjectType = invoice.RelatedObjectType;
505
+ const ct = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
506
+ ct.AccountNo = item.value[0];
507
+ ct.Currency = currency ? currency : 'MYR';
508
+ ct.CreditAmount = creditAmount ? creditAmount : 0.0;
509
+ ct.Date = transactionDate;
510
+ ct.Description = customer.FullName;
511
+ ct.Name = customer.FullName;
512
+ ct.RelatedDocNo = invoice.DocNo;
513
+ ct.RelatedObjectId = invoice.RelatedObjectId;
514
+ ct.RelatedObjectType = invoice.RelatedObjectType;
515
+ await this.postJournal(dbTransaction, journalEntry, loginUser);
516
+ }
517
+ return invoice;
518
+ }
519
+ catch (err) {
520
+ console.log('Issue invoice err: ', err);
521
+ throw err;
522
+ }
523
+ }
524
+ static async findCustomer(custSystemRefId, dbTransaction) {
525
+ const data = await FinanceCompany._FinanceCustomerRepository.findOne({
526
+ where: {
527
+ CustSystemRefId: custSystemRefId,
528
+ },
529
+ transaction: dbTransaction,
530
+ });
531
+ return data;
532
+ }
533
+ async issueDebitNote(dbTransaction, loginUser, invoice, customer, dtAccountNo) {
534
+ try {
535
+ const duplicateInvoice = await FinanceCompany._DocumentRepository.findOne({
536
+ where: {
537
+ DocNo: invoice.DocNo,
538
+ },
539
+ transaction: dbTransaction,
540
+ });
541
+ if (duplicateInvoice) {
542
+ throw new Error('Invoice number already exists');
543
+ }
544
+ const documentItems = await invoice.getDocumentItems(dbTransaction);
545
+ if (!documentItems.length) {
546
+ throw new Error('Document must have at least 1 document item');
547
+ }
548
+ for (const invoiceItem of documentItems) {
549
+ if (!invoiceItem.CtAccountNo) {
550
+ throw new Error('Each document item should have CtAccountNo provided');
551
+ }
552
+ }
553
+ invoice.DocType = enum_1.DocType.DEBIT_NOTE;
554
+ if (invoice.UseAccSystemDocYN === 'Y') {
555
+ const accInvoiceRefIDetail = await this.AccountingSystem.createInvoice({
556
+ customer,
557
+ invoice,
558
+ paymentMode: 'credit',
559
+ }, dbTransaction);
560
+ invoice.AccSystemRefId = accInvoiceRefIDetail.invoiceRefId;
561
+ invoice.PostedToAccSystemYN = 'Y';
562
+ invoice.PostedById = loginUser.ObjectId;
563
+ invoice.PostedDateTime = new Date();
564
+ for (const documentItem of documentItems) {
565
+ const accItem = accInvoiceRefIDetail.invoiceItems.find((item) => item.name === documentItem.Name);
566
+ if (accItem) {
567
+ documentItem.AccSystemRefId = accItem.itemRefId;
568
+ documentItem.PostedToAccSystemYN = 'Y';
569
+ documentItem.PostedById = loginUser.ObjectId;
570
+ documentItem.PostedDateTime = new Date();
571
+ }
572
+ }
573
+ }
574
+ else {
575
+ invoice.generateInvoice(loginUser.IDNo, customer, dbTransaction);
576
+ }
577
+ await FinanceCompany._DocumentRepository.create({
578
+ DocNo: invoice.DocNo,
579
+ DocType: invoice.DocType,
580
+ DocDate: invoice.DocDate,
581
+ CompanyId: invoice.CompanyId,
582
+ Currency: invoice.Currency,
583
+ Amount: invoice.Amount,
584
+ Description: invoice.Description,
585
+ Status: invoice.Status,
586
+ IssuedById: loginUser.ObjectId,
587
+ IssuedToId: customer.ObjectId,
588
+ IssuedToType: invoice.IssuedToType,
589
+ RelatedObjectId: invoice.RelatedObjectId,
590
+ RelatedObjectType: invoice.RelatedObjectType,
591
+ CreatedById: loginUser.ObjectId,
592
+ CreatedAt: new Date(),
593
+ UpdatedById: loginUser.ObjectId,
594
+ UpdatedAt: new Date(),
595
+ DocPDFFileMediaId: invoice.DocPDFFileMediaId,
596
+ DocHTMLFileMediaId: invoice.DocHTMLFileMediaId,
597
+ AccSystemRefId: invoice.AccSystemRefId,
598
+ PostedToAccSystemYN: invoice.PostedToAccSystemYN,
599
+ PostedById: invoice.PostedToAccSystemYN == 'Y' ? invoice.PostedById : null,
600
+ PostedDateTime: new Date(),
601
+ UseAccSystemDocYN: invoice.UseAccSystemDocYN,
602
+ }, {
603
+ transaction: dbTransaction,
604
+ });
605
+ documentItems.forEach(async (documentItem) => {
606
+ await FinanceCompany._DocumentItemRepository.create({
607
+ DocumentItemId: this._createId().toUpperCase(),
608
+ DocNo: documentItem.DocNo,
609
+ Name: documentItem.Name,
610
+ NameBM: documentItem.NameBM,
611
+ Description: documentItem.Description,
612
+ ItemId: documentItem.ItemId,
613
+ ItemType: documentItem.ItemType,
614
+ ItemSKU: documentItem.ItemSKU,
615
+ ItemSerialNo: documentItem.ItemSerialNo,
616
+ Currency: documentItem.Currency,
617
+ UnitPrice: documentItem.UnitPrice,
618
+ Quantity: documentItem.Quantity,
619
+ QuantityUOM: documentItem.QuantityUOM,
620
+ Amount: documentItem.Amount,
621
+ TaxCode: documentItem.TaxCode,
622
+ TaxAmount: documentItem.TaxAmount,
623
+ TaxRate: documentItem.TaxRate,
624
+ TaxInclusiveYN: documentItem.TaxInclusiveYN,
625
+ DtAccountNo: documentItem.DtAccountNo,
626
+ CtAccountNo: documentItem.CtAccountNo,
627
+ AccSystemRefId: documentItem.AccSystemRefId,
628
+ PostedToAccSystemYN: documentItem.PostedToAccSystemYN,
629
+ PostedById: documentItem.PostedById,
630
+ PostedDateTime: documentItem.PostedDateTime,
631
+ }, {
632
+ transaction: dbTransaction,
633
+ });
634
+ });
635
+ const transactionDate = new Date();
636
+ const htCreditAccountAmount = new general_1.HashTable();
637
+ const htCreditAccountCurrency = new general_1.HashTable();
638
+ const htCreditAccountPurpose = new general_1.HashTable();
639
+ documentItems.forEach((invoiceItem) => {
640
+ if (!htCreditAccountAmount.exists(invoiceItem.CtAccountNo)) {
641
+ htCreditAccountAmount.add(invoiceItem.CtAccountNo, invoiceItem.Amount);
642
+ htCreditAccountCurrency.add(invoiceItem.CtAccountNo, invoiceItem.Currency);
643
+ htCreditAccountPurpose.add(invoiceItem.CtAccountNo, invoiceItem.Name);
644
+ }
645
+ else {
646
+ const d = htCreditAccountAmount.get(invoiceItem.CtAccountNo);
647
+ htCreditAccountAmount.add(invoiceItem.CtAccountNo, d + invoiceItem.Amount);
648
+ }
649
+ });
650
+ const savedItems = htCreditAccountAmount.list();
651
+ for (const item of savedItems) {
652
+ const journalEntry = new journal_entry_1.default(dbTransaction);
653
+ journalEntry.init({
654
+ CompanyId: this.CompanyId,
655
+ Name: 'issue Invoice ' + invoice.DocNo,
656
+ });
657
+ const creditAmount = item.value[1];
658
+ const currency = htCreditAccountCurrency.get(item.value[0]);
659
+ const purpose = htCreditAccountPurpose.get(item.value[0]);
660
+ const dt = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
661
+ if (dtAccountNo) {
662
+ dt.AccountNo = dtAccountNo;
663
+ }
664
+ else {
665
+ const arAccount = await customer.getAccountReceivable();
666
+ dt.AccountNo = arAccount.AccountNo;
667
+ }
668
+ dt.Currency = currency ? currency : 'MYR';
669
+ dt.DebitAmount = creditAmount ? creditAmount : 0.0;
670
+ dt.Date = transactionDate;
671
+ dt.Description = `${purpose}`;
672
+ dt.Name = `${purpose}`;
673
+ dt.RelatedDocNo = invoice.DocNo;
674
+ dt.RelatedObjectId = invoice.RelatedObjectId;
675
+ dt.RelatedObjectType = invoice.RelatedObjectType;
676
+ const ct = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
677
+ ct.AccountNo = item.value[0];
678
+ ct.Currency = currency ? currency : 'MYR';
679
+ ct.CreditAmount = creditAmount ? creditAmount : 0.0;
680
+ ct.Date = transactionDate;
681
+ ct.Description = customer.FullName;
682
+ ct.Name = customer.FullName;
683
+ ct.RelatedDocNo = invoice.DocNo;
684
+ ct.RelatedObjectId = invoice.RelatedObjectId;
685
+ ct.RelatedObjectType = invoice.RelatedObjectType;
686
+ await this.postJournal(dbTransaction, journalEntry, loginUser);
687
+ }
688
+ return invoice;
689
+ }
690
+ catch (err) {
691
+ console.log('Issue debit note err: ', err);
692
+ throw err;
693
+ }
694
+ }
695
+ async issueCreditNote(dbTransaction, loginUser, creditNote, customer, ctAccountNo) {
696
+ try {
697
+ const duplicateCreditNote = await FinanceCompany._DocumentRepository.findOne({
698
+ where: {
699
+ DocNo: creditNote.DocNo,
700
+ },
701
+ transaction: dbTransaction,
702
+ });
703
+ if (duplicateCreditNote) {
704
+ throw new Error('Invoice number already exists');
705
+ }
706
+ const documentItems = await creditNote.getDocumentItems(dbTransaction);
707
+ if (!documentItems.length) {
708
+ throw new Error('Document must have at least 1 document item');
709
+ }
710
+ for (const invoiceItem of documentItems) {
711
+ if (!invoiceItem.DtAccountNo) {
712
+ throw new Error('Each document item should have DtAccountNo provided');
713
+ }
714
+ const actualDocument = await document_1.default.initDocument(dbTransaction, invoiceItem.ItemId);
715
+ if (actualDocument.IssuedToId !== creditNote.IssuedToId) {
716
+ throw new general_1.ClassError('FinanceCompany', 'FinanceCompanyErrMsgOX', 'To issue credit note, all invoices must belong to same customer.');
717
+ }
718
+ }
719
+ creditNote.DocType = enum_1.DocType.CREDIT_NOTE;
720
+ creditNote.Status = enum_1.DocumentStatus.SETTLED;
721
+ await FinanceCompany._DocumentRepository.create({
722
+ DocNo: creditNote.DocNo,
723
+ DocType: creditNote.DocType,
724
+ DocDate: creditNote.DocDate,
725
+ CompanyId: creditNote.CompanyId,
726
+ Currency: creditNote.Currency,
727
+ Amount: creditNote.Amount,
728
+ Description: creditNote.Description,
729
+ Status: creditNote.Status,
730
+ IssuedById: loginUser.ObjectId,
731
+ IssuedToId: customer.ObjectId,
732
+ IssuedToType: creditNote.IssuedToType,
733
+ RelatedObjectId: creditNote.RelatedObjectId,
734
+ RelatedObjectType: creditNote.RelatedObjectType,
735
+ CreatedById: loginUser.ObjectId,
736
+ CreatedAt: new Date(),
737
+ UpdatedById: loginUser.ObjectId,
738
+ UpdatedAt: new Date(),
739
+ DocPDFFileMediaId: creditNote.DocPDFFileMediaId,
740
+ DocHTMLFileMediaId: creditNote.DocHTMLFileMediaId,
741
+ AccSystemRefId: creditNote.AccSystemRefId,
742
+ PostedToAccSystemYN: creditNote.PostedToAccSystemYN,
743
+ PostedById: creditNote.PostedToAccSystemYN == 'Y'
744
+ ? creditNote.PostedById
745
+ : null,
746
+ PostedDateTime: new Date(),
747
+ UseAccSystemDocYN: creditNote.UseAccSystemDocYN,
748
+ }, {
749
+ transaction: dbTransaction,
750
+ });
751
+ for (const docItem of documentItems) {
752
+ await FinanceCompany._DocumentItemRepository.create({
753
+ DocumentItemId: this._createId().toUpperCase(),
754
+ DocNo: docItem.DocNo,
755
+ Name: docItem.Name,
756
+ NameBM: docItem.NameBM,
757
+ Description: docItem.Description,
758
+ ItemId: docItem.ItemId,
759
+ ItemType: docItem.ItemType,
760
+ ItemSKU: docItem.ItemSKU,
761
+ ItemSerialNo: docItem.ItemSerialNo,
762
+ Currency: docItem.Currency,
763
+ UnitPrice: docItem.UnitPrice,
764
+ Quantity: docItem.Quantity,
765
+ QuantityUOM: docItem.QuantityUOM,
766
+ Amount: docItem.Amount,
767
+ TaxCode: docItem.TaxCode,
768
+ TaxAmount: docItem.TaxAmount,
769
+ TaxRate: docItem.TaxRate,
770
+ TaxInclusiveYN: docItem.TaxInclusiveYN,
771
+ DtAccountNo: docItem.DtAccountNo ? docItem.DtAccountNo : null,
772
+ CtAccountNo: docItem.CtAccountNo ? docItem.CtAccountNo : null,
773
+ }, {
774
+ transaction: dbTransaction,
775
+ });
776
+ await document_1.default.settleByCreditNote(loginUser, dbTransaction, docItem.ItemId, docItem.Amount);
777
+ }
778
+ if (creditNote.UseAccSystemDocYN === 'Y') {
779
+ }
780
+ else {
781
+ creditNote.generateCreditNote(loginUser.IDNo, customer);
782
+ }
783
+ const journalEntry = new journal_entry_1.default(dbTransaction);
784
+ journalEntry.init({
785
+ CompanyId: this.CompanyId,
786
+ Name: 'Issue Credit Note ' + creditNote.DocNo,
787
+ });
788
+ const transactionDate = new Date();
789
+ const creditTransaction = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
790
+ if (ctAccountNo) {
791
+ creditTransaction.AccountNo = ctAccountNo;
792
+ }
793
+ else {
794
+ const arAccount = await customer.getAccountPayable();
795
+ creditTransaction.AccountNo = arAccount.AccountNo;
796
+ }
797
+ creditTransaction.Currency = creditNote.Currency;
798
+ creditTransaction.CreditAmount = creditNote.Amount;
799
+ creditTransaction.Date = transactionDate;
800
+ creditTransaction.Description = creditNote.DocNo;
801
+ creditTransaction.Name = creditNote.DocNo;
802
+ creditTransaction.RelatedDocNo = creditNote.DocNo;
803
+ creditTransaction.RelatedObjectId = creditNote.RelatedObjectId;
804
+ creditTransaction.RelatedObjectType = creditNote.RelatedObjectType;
805
+ for (const invoiceItem of documentItems) {
806
+ const itemLedger = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
807
+ itemLedger.AccountNo = invoiceItem.DtAccountNo;
808
+ itemLedger.Currency = invoiceItem.Currency;
809
+ itemLedger.DebitAmount = invoiceItem.Amount;
810
+ itemLedger.Date = transactionDate;
811
+ itemLedger.Description = invoiceItem.Name;
812
+ itemLedger.RelatedDocNo = creditNote.DocNo;
813
+ itemLedger.RelatedObjectId = creditNote.RelatedObjectId;
814
+ itemLedger.RelatedObjectType = creditNote.RelatedObjectType;
815
+ }
816
+ await this.postJournal(dbTransaction, journalEntry, loginUser);
817
+ const entityValueAfter = {
818
+ LedgerNo: creditTransaction.LedgerNo,
819
+ TransactionType: creditTransaction.TransactionType,
820
+ JournalEntryId: creditTransaction.JournalEntryId,
821
+ AccountNo: creditTransaction.AccountNo,
822
+ Date: creditTransaction.Date,
823
+ Name: creditTransaction.Name,
824
+ Description: creditTransaction.Description,
825
+ Currency: creditTransaction.Currency,
826
+ DebitAmount: creditTransaction.DebitAmount,
827
+ CreditAmount: creditTransaction.CreditAmount,
828
+ RelatedObjectId: creditTransaction.RelatedObjectId,
829
+ RelatedObjectType: creditTransaction.RelatedObjectType,
830
+ RelatedDocNo: creditTransaction.RelatedDocNo,
831
+ RelatedPaymentId: creditTransaction.RelatedPaymentId,
832
+ };
833
+ const payload = {
834
+ Action: 'Create',
835
+ Activity: 'Issuing a Credit Note Transaction',
836
+ Description: `Credit Transaction (ID: ${creditTransaction.LedgerNo}) has been created`,
837
+ EntityType: 'CreditTransaction',
838
+ EntityValueBefore: JSON.stringify({}),
839
+ EntityValueAfter: JSON.stringify(entityValueAfter),
840
+ PerformedById: loginUser.ObjectId,
841
+ PerformedAt: transactionDate,
842
+ EntityId: creditTransaction.LedgerNo,
843
+ };
844
+ await axios_1.default.post(`${process.env.COMMON_API_URL}/activity-histories`, payload);
845
+ return creditNote;
846
+ }
847
+ catch (err) {
848
+ console.log('Issue credit note err: ', err);
849
+ throw err;
850
+ }
851
+ }
852
+ async collectPayment(dbTransaction, loginUser, payment, collectPaymentType = collect_payment_type_1.CollectPaymentType.AUTOMATIC) {
853
+ try {
854
+ const paymentItems = await payment.getPaymentItems();
855
+ if (paymentItems.length < 1) {
856
+ throw new Error('Atleast one payment item is required to identify what payment is being paid for.');
857
+ }
858
+ const paymentPaidWithItems = await payment.getPaymentPaidWith();
859
+ if (paymentPaidWithItems.length < 1) {
860
+ throw new Error('Atleast one payment paid with item is required to identify how the payment was made.');
861
+ }
862
+ payment.PaymentId = this._createId().toUpperCase();
863
+ payment.PaymentType = enum_1.PaymentType.PAYMENT_RECEIVED;
864
+ payment.ReceivedBy = loginUser.ObjectId;
865
+ payment.IssuedBy = loginUser.ObjectId;
866
+ await FinanceCompany._PaymentRepository.create({
867
+ PaymentId: payment.PaymentId,
868
+ PaymentType: payment.PaymentType,
869
+ PaymentDate: payment.PaymentDate,
870
+ Description: payment.Description,
871
+ Currency: payment.Currency,
872
+ Amount: payment.Amount,
873
+ Status: collectPaymentType === collect_payment_type_1.CollectPaymentType.AUTOMATIC
874
+ ? enum_1.PaymentStatus.CONFIRMED
875
+ : enum_1.PaymentStatus.PENDING,
876
+ PostedToAccSystemYN: 'N',
877
+ ReceivedBy: payment.ReceivedBy,
878
+ IssuedBy: payment.IssuedBy,
879
+ Remarks: payment.Remarks,
880
+ RelatedObjectId: payment.RelatedObjectId,
881
+ RelatedObjectType: payment.RelatedObjectType,
882
+ ReceiptDocNo: payment.ReceiptDocNo,
883
+ UpdatedAt: new Date(),
884
+ UpdatedBy: loginUser.ObjectId,
885
+ CreatedAt: new Date(),
886
+ CreatedBy: loginUser.ObjectId,
887
+ }, { transaction: dbTransaction });
888
+ for (const paymentItem of paymentItems) {
889
+ await FinanceCompany._PaymentItemRepository.create({
890
+ PaymentId: payment.PaymentId,
891
+ PayForObjectId: paymentItem.PayForObjectId,
892
+ PayForObjectType: paymentItem.PayForObjectType,
893
+ Currency: paymentItem.Currency,
894
+ Amount: paymentItem.Amount,
895
+ Name: paymentItem.Name,
896
+ Description: paymentItem.Description,
897
+ }, { transaction: dbTransaction });
898
+ }
899
+ for (const paymentPaidWithItem of paymentPaidWithItems) {
900
+ await payment_method_type_1.default.initMethodType(dbTransaction, paymentPaidWithItem.MethodTypeId);
901
+ await FinanceCompany._PaymentPaidWithRepository.create({
902
+ PaymentId: payment.PaymentId,
903
+ MethodTypeId: paymentPaidWithItem.MethodTypeId,
904
+ Currency: paymentPaidWithItem.Currency,
905
+ Amount: paymentPaidWithItem.Amount,
906
+ Status: paymentPaidWithItem.Status,
907
+ TransactionId: paymentPaidWithItem.TransactionId,
908
+ RefBank: paymentPaidWithItem.RefBank,
909
+ RefName: paymentPaidWithItem.RefName,
910
+ RefNo: paymentPaidWithItem.RefNo,
911
+ RefOther1: paymentPaidWithItem.RefOther1,
912
+ RefOther2: paymentPaidWithItem.RefOther2,
913
+ RefOther3: paymentPaidWithItem.RefOther3,
914
+ RefOther4: paymentPaidWithItem.RefOther4,
915
+ RefOther5: paymentPaidWithItem.RefOther5,
916
+ Remarks: paymentPaidWithItem.Remarks,
917
+ PaymentMediaId: paymentPaidWithItem.PaymentMediaId,
918
+ }, { transaction: dbTransaction });
919
+ }
920
+ return payment;
921
+ }
922
+ catch (error) {
923
+ throw error;
924
+ }
925
+ }
926
+ async makePayment(dbTransaction, loginUser, payment, customer, dtAccountNo) {
927
+ let paymentMethodType;
928
+ try {
929
+ const paymentPaidWith = await payment.getPaymentPaidWith();
930
+ if (paymentPaidWith.length < 1) {
931
+ throw new Error('Atleast one payment paid with item is required to identify how the payment was made.');
932
+ }
933
+ paymentMethodType = await payment_method_type_1.default.initMethodType(dbTransaction, paymentPaidWith[0].MethodTypeId);
934
+ const paymentItems = await payment.getPaymentItems();
935
+ if (paymentItems.length < 1) {
936
+ throw new Error('Atleast one payment item is required to identify what payment is being paid for');
937
+ }
938
+ payment.PaymentId = this._createId().toUpperCase();
939
+ payment.PaymentType = enum_1.PaymentType.PAYOUT;
940
+ payment.ReceivedBy = loginUser.ObjectId;
941
+ payment.IssuedBy = loginUser.ObjectId;
942
+ await FinanceCompany._PaymentRepository.create({
943
+ PaymentId: payment.PaymentId,
944
+ PaymentType: payment.PaymentType,
945
+ PaymentDate: payment.PaymentDate,
946
+ Description: payment.Description,
947
+ Currency: payment.Currency,
948
+ ReceivedBy: payment.ReceivedBy,
949
+ IssuedBy: payment.IssuedBy,
950
+ Remarks: payment.Remarks,
951
+ RelatedObjectId: payment.RelatedObjectId,
952
+ RelatedObjectType: payment.RelatedObjectType,
953
+ Amount: payment.Amount,
954
+ Status: enum_1.PaymentStatus.CONFIRMED,
955
+ PostedToAccSystemYN: 'N',
956
+ UpdatedAt: new Date(),
957
+ UpdatedBy: loginUser.ObjectId,
958
+ CreatedAt: new Date(),
959
+ CreatedBy: loginUser.ObjectId,
960
+ }, { transaction: dbTransaction });
961
+ paymentItems.forEach(async (paymentItem) => {
962
+ await FinanceCompany._PaymentItemRepository.create({
963
+ PaymentId: payment.PaymentId,
964
+ PayForObjectId: paymentItem.PayForObjectId,
965
+ PayForObjectType: paymentItem.PayForObjectType,
966
+ Currency: paymentItem.Currency,
967
+ Amount: paymentItem.Amount,
968
+ Name: paymentItem.Name,
969
+ Description: paymentItem.Description,
970
+ }, { transaction: dbTransaction });
971
+ await paymentItem.paid(dbTransaction);
972
+ });
973
+ for (const paymentPaidWithItem of paymentPaidWith) {
974
+ await FinanceCompany._PaymentPaidWithRepository.create({
975
+ PaymentId: payment.PaymentId,
976
+ MethodTypeId: paymentPaidWithItem.MethodTypeId,
977
+ Currency: paymentPaidWithItem.Currency,
978
+ Amount: paymentPaidWithItem.Amount,
979
+ Status: paymentPaidWithItem.Status,
980
+ TransactionId: paymentPaidWithItem.TransactionId,
981
+ RefBank: paymentPaidWithItem.RefBank,
982
+ RefName: paymentPaidWithItem.RefName,
983
+ RefNo: paymentPaidWithItem.RefNo,
984
+ RefOther1: paymentPaidWithItem.RefOther1,
985
+ RefOther2: paymentPaidWithItem.RefOther2,
986
+ RefOther3: paymentPaidWithItem.RefOther3,
987
+ RefOther4: paymentPaidWithItem.RefOther4,
988
+ RefOther5: paymentPaidWithItem.RefOther5,
989
+ Remarks: paymentPaidWithItem.Remarks,
990
+ PaymentMediaId: paymentPaidWithItem.PaymentMediaId,
991
+ }, { transaction: dbTransaction });
992
+ }
993
+ const transactionDate = new Date();
994
+ for (const paymentPaidWithItem of paymentPaidWith) {
995
+ try {
996
+ paymentMethodType = await payment_method_type_1.default.initMethodType(dbTransaction, paymentPaidWithItem.MethodTypeId);
997
+ const journalEntry = new journal_entry_1.default(dbTransaction);
998
+ journalEntry.init({
999
+ CompanyId: this.CompanyId,
1000
+ Name: 'Make Payment for ' + payment.PaymentId,
1001
+ });
1002
+ const creditLT = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
1003
+ creditLT.AccountNo = paymentMethodType.AccountNo;
1004
+ creditLT.Currency = paymentPaidWithItem.Currency;
1005
+ creditLT.CreditAmount = paymentPaidWithItem.Amount;
1006
+ creditLT.Date = transactionDate;
1007
+ creditLT.Description = customer.FullName;
1008
+ creditLT.Name = customer.FullName;
1009
+ creditLT.RelatedObjectId = payment.RelatedObjectId;
1010
+ creditLT.RelatedObjectType = payment.RelatedObjectType;
1011
+ const debitLT = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
1012
+ if (dtAccountNo) {
1013
+ debitLT.AccountNo = dtAccountNo;
1014
+ }
1015
+ else {
1016
+ const apAccount = await customer.getAccountPayable();
1017
+ debitLT.AccountNo = apAccount.AccountNo;
1018
+ }
1019
+ debitLT.Currency = paymentPaidWithItem.Currency;
1020
+ debitLT.DebitAmount = paymentPaidWithItem.Amount;
1021
+ debitLT.Date = transactionDate;
1022
+ debitLT.Description = paymentMethodType.Name;
1023
+ debitLT.Name = paymentMethodType.Name;
1024
+ debitLT.RelatedObjectId = payment.RelatedObjectId;
1025
+ debitLT.RelatedObjectType = payment.RelatedObjectType;
1026
+ await this.postJournal(dbTransaction, journalEntry, loginUser);
1027
+ }
1028
+ catch (error) {
1029
+ if (error instanceof general_1.RecordNotFoundError) {
1030
+ throw new Error('Invalid Payment Method Type Id');
1031
+ }
1032
+ else {
1033
+ throw error;
1034
+ }
1035
+ }
1036
+ }
1037
+ return payment;
1038
+ }
1039
+ catch (error) {
1040
+ if (error instanceof general_1.RecordNotFoundError) {
1041
+ throw new Error('Invalid PaymentMethodType id');
1042
+ }
1043
+ else {
1044
+ throw error;
1045
+ }
1046
+ }
1047
+ }
1048
+ get PaymentMethods() {
1049
+ return new Promise((resolve, reject) => {
1050
+ if (this.CompanyId !== 'New') {
1051
+ FinanceCompany._PaymentMethodRepository
1052
+ .findAll({
1053
+ where: {
1054
+ CompanyId: this.CompanyId,
1055
+ },
1056
+ })
1057
+ .then((paymentMethod) => {
1058
+ const paymentMethodObjects = paymentMethod.map((paymentMethodData) => {
1059
+ return new Promise((resolve, reject) => {
1060
+ FinanceCompany._PaymentMethodTypeRepository
1061
+ .findAll({
1062
+ where: {
1063
+ MethodId: paymentMethodData.MethodId,
1064
+ },
1065
+ raw: true,
1066
+ })
1067
+ .then((paymentMethodTypes) => {
1068
+ const paymentMethodObjects = Object.assign(Object.assign({}, paymentMethodData.get({ plain: true })), { Types: paymentMethodTypes });
1069
+ resolve(paymentMethodObjects);
1070
+ })
1071
+ .catch((err) => {
1072
+ reject(err);
1073
+ });
1074
+ }).then((paymentMethods) => paymentMethods);
1075
+ });
1076
+ return Promise.all(paymentMethodObjects);
1077
+ })
1078
+ .then((paymentMethodObjects) => {
1079
+ this._PaymentMethods = paymentMethodObjects;
1080
+ resolve(this._PaymentMethods);
1081
+ })
1082
+ .catch((err) => {
1083
+ reject(err);
1084
+ });
1085
+ }
1086
+ else {
1087
+ resolve(this._PaymentMethods);
1088
+ }
1089
+ });
1090
+ }
1091
+ get TaxCodes() {
1092
+ return new Promise((resolve, reject) => {
1093
+ if (this.CompanyId !== 'New') {
1094
+ FinanceCompany._TaxRepository
1095
+ .findAll({
1096
+ where: {
1097
+ CompanyId: this.CompanyId,
1098
+ },
1099
+ transaction: this._DbTransaction,
1100
+ })
1101
+ .then((taxes) => {
1102
+ const taxList = [];
1103
+ taxes.forEach((tax) => {
1104
+ taxList.push(new tax_1.Tax({
1105
+ TaxCode: tax.TaxCode,
1106
+ TaxRate: typeof tax.TaxRate === 'number'
1107
+ ? tax.TaxRate
1108
+ : parseFloat(tax.TaxRate),
1109
+ Description: tax.Description,
1110
+ CompanyId: tax.CompanyId,
1111
+ CreatedAt: tax.CreatedAt,
1112
+ CreatedById: tax.CreatedById,
1113
+ UpdatedAt: tax.UpdatedAt,
1114
+ UpdatedById: tax.UpdatedById,
1115
+ }));
1116
+ });
1117
+ this._Taxes = taxList;
1118
+ resolve(this._Taxes);
1119
+ })
1120
+ .catch((err) => {
1121
+ reject(err);
1122
+ });
1123
+ }
1124
+ else {
1125
+ resolve(this._Taxes);
1126
+ }
1127
+ });
1128
+ }
1129
+ async LoadPaymentMethods(companyId, paymentMethods, transaction) {
1130
+ const paymentMethod = new payment_method_1.default();
1131
+ for (const method in paymentMethods) {
1132
+ const paymentMethodData = await FinanceCompany._PaymentMethodRepository.findOne({
1133
+ where: {
1134
+ MethodId: paymentMethods[method].id,
1135
+ Name: paymentMethods[method].name,
1136
+ },
1137
+ transaction: transaction,
1138
+ });
1139
+ if (!paymentMethodData) {
1140
+ const newPaymentMethod = await FinanceCompany._PaymentMethodRepository.create({
1141
+ MethodId: paymentMethods[method].id,
1142
+ Name: paymentMethods[method].name,
1143
+ CompanyId: companyId,
1144
+ }, {
1145
+ transaction: transaction,
1146
+ });
1147
+ this._PaymentMethods.push(newPaymentMethod);
1148
+ }
1149
+ this._PaymentMethods.push(paymentMethodData);
1150
+ }
1151
+ this._PaymentMethods.forEach(async (item) => {
1152
+ var _a, _b;
1153
+ const p = item === null || item === void 0 ? void 0 : item.get({ plain: true });
1154
+ for (const method in paymentMethods) {
1155
+ if (!p) {
1156
+ continue;
1157
+ }
1158
+ if (p.MethodId === ((_a = paymentMethods[method]) === null || _a === void 0 ? void 0 : _a.id)) {
1159
+ const paymentMethodTypeData = await FinanceCompany._PaymentMethodTypeRepository.findOne({
1160
+ where: {
1161
+ MethodId: p.MethodId,
1162
+ },
1163
+ transaction: transaction,
1164
+ });
1165
+ if (!paymentMethodTypeData) {
1166
+ const configPaymentMethodTypes = (_b = paymentMethods[method]) === null || _b === void 0 ? void 0 : _b.types;
1167
+ for (const methodType in configPaymentMethodTypes) {
1168
+ const accountData = await FinanceCompany._AccountRepository.findOne({
1169
+ where: {
1170
+ AccountNo: configPaymentMethodTypes[methodType].accountNo,
1171
+ },
1172
+ transaction: transaction,
1173
+ });
1174
+ if (!accountData) {
1175
+ const accountPayload = {
1176
+ CompanyId: companyId,
1177
+ Name: configPaymentMethodTypes[methodType].name,
1178
+ AccountType: 'PaymentMethod',
1179
+ CreatedAt: new Date(),
1180
+ CreatedById: 'System',
1181
+ AccSystemRefId: 'REF',
1182
+ PostedToAccSystemYN: 'N',
1183
+ };
1184
+ try {
1185
+ await FinanceCompany._AccountRepository.create(Object.assign({ AccountNo: configPaymentMethodTypes[methodType].accountNo }, accountPayload), {
1186
+ transaction: transaction,
1187
+ });
1188
+ await FinanceCompany._AccountRepository.create(Object.assign({ AccountNo: configPaymentMethodTypes[methodType]
1189
+ .processingFeeAccountNo }, accountPayload), {
1190
+ transaction: transaction,
1191
+ });
1192
+ }
1193
+ catch (err) {
1194
+ throw err;
1195
+ }
1196
+ }
1197
+ const paymentMethodTypePayload = {
1198
+ MethodId: p.MethodId,
1199
+ MethodTypeId: configPaymentMethodTypes[methodType].id,
1200
+ Name: configPaymentMethodTypes[methodType].name,
1201
+ AccountNo: configPaymentMethodTypes[methodType].accountNo,
1202
+ ProcessingFeeRate: configPaymentMethodTypes[methodType].processingFeeRate,
1203
+ ProcessingFeeAccountNo: configPaymentMethodTypes[methodType].processingFeeAccountNo,
1204
+ };
1205
+ try {
1206
+ await paymentMethod.newPaymentMethodType(paymentMethodTypePayload, transaction);
1207
+ }
1208
+ catch (err) { }
1209
+ }
1210
+ }
1211
+ }
1212
+ }
1213
+ });
1214
+ }
1215
+ async LoadTaxCodes(companyId, companyTaxes, transaction) {
1216
+ for (const tax in companyTaxes) {
1217
+ let tx = await FinanceCompany._TaxRepository.findOne({
1218
+ where: {
1219
+ TaxCode: companyTaxes[tax].taxCode,
1220
+ },
1221
+ transaction: transaction,
1222
+ });
1223
+ if (!tx) {
1224
+ const newTx = await FinanceCompany._TaxRepository.create({
1225
+ TaxCode: companyTaxes[tax].taxCode,
1226
+ TaxRate: companyTaxes[tax].taxRate,
1227
+ Description: companyTaxes[tax].description,
1228
+ CompanyId: companyId,
1229
+ UpdatedAt: new Date(),
1230
+ CreatedById: 'System',
1231
+ CreatedAt: new Date(),
1232
+ UpdatedById: 'System',
1233
+ }, {
1234
+ transaction: transaction,
1235
+ });
1236
+ tx = newTx;
1237
+ }
1238
+ this._Taxes.push(new tax_1.Tax(tx.get({ plain: true })));
1239
+ }
1240
+ }
1241
+ async collectPaymentForMultipleCustomers(dbTransaction, loginUser, payment, creditTransaction, receiptNo, collectPaymentType = collect_payment_type_1.CollectPaymentType.AUTOMATIC) {
1242
+ try {
1243
+ const systemCode = await config_1.ApplicationConfig.getComponentConfigValue('system-code');
1244
+ const isPrivileged = await loginUser.checkPrivileges(systemCode, 'Collect Payment For Multiple Customers');
1245
+ if (!isPrivileged) {
1246
+ throw new Error('User is not authorized to perform this action');
1247
+ }
1248
+ const paymentItems = await payment.getPaymentItems();
1249
+ if (paymentItems.length < 1) {
1250
+ throw new Error('Atleast one payment item is required to identify what payment is being paid for.');
1251
+ }
1252
+ const paymentPaidWithItems = await payment.getPaymentPaidWith();
1253
+ if (paymentPaidWithItems.length < 1) {
1254
+ throw new Error('Atleast one payment paid with item is required to identify how the payment was made.');
1255
+ }
1256
+ if (paymentItems.length !== creditTransaction.length) {
1257
+ throw new Error('Payment items length is not equal to creditTransaction length');
1258
+ }
1259
+ let totalAmount = 0;
1260
+ paymentItems.forEach((paymentItem) => {
1261
+ totalAmount += paymentItem.Amount;
1262
+ });
1263
+ const totalCreditTransactionAmount = creditTransaction.reduce((accumulator, currentValue) => {
1264
+ return accumulator + currentValue.Amount;
1265
+ }, 0);
1266
+ if (totalAmount !== totalCreditTransactionAmount) {
1267
+ throw new Error('Payment items total Amount is dnot equal to credit transactions total Amount');
1268
+ }
1269
+ payment.PaymentId = this._createId().toUpperCase();
1270
+ payment.PaymentType = enum_1.PaymentType.PAYMENT_RECEIVED;
1271
+ payment.ReceivedBy = loginUser.ObjectId;
1272
+ payment.IssuedBy = loginUser.ObjectId;
1273
+ await FinanceCompany._PaymentRepository.create({
1274
+ PaymentId: payment.PaymentId,
1275
+ PaymentType: payment.PaymentType,
1276
+ PaymentDate: payment.PaymentDate,
1277
+ Description: payment.Description,
1278
+ Currency: payment.Currency,
1279
+ Amount: payment.Amount,
1280
+ Status: collectPaymentType === collect_payment_type_1.CollectPaymentType.MANUAL
1281
+ ? enum_1.PaymentStatus.PENDING
1282
+ : enum_1.PaymentStatus.CONFIRMED,
1283
+ PostedToAccSystemYN: 'N',
1284
+ ReceivedBy: payment.ReceivedBy,
1285
+ IssuedBy: payment.IssuedBy,
1286
+ Remarks: payment.Remarks,
1287
+ RelatedObjectId: payment.RelatedObjectId,
1288
+ RelatedObjectType: payment.RelatedObjectType,
1289
+ ReceiptDocNo: payment.ReceiptDocNo,
1290
+ UpdatedAt: new Date(),
1291
+ UpdatedBy: loginUser.ObjectId,
1292
+ CreatedAt: new Date(),
1293
+ CreatedBy: loginUser.ObjectId,
1294
+ }, { transaction: dbTransaction });
1295
+ paymentItems.forEach(async (paymentItem) => {
1296
+ await FinanceCompany._PaymentItemRepository.create({
1297
+ PaymentId: payment.PaymentId,
1298
+ PayForObjectId: paymentItem.PayForObjectId,
1299
+ PayForObjectType: paymentItem.PayForObjectType,
1300
+ Currency: paymentItem.Currency,
1301
+ Amount: paymentItem.Amount,
1302
+ Name: paymentItem.Name,
1303
+ Description: paymentItem.Description,
1304
+ }, { transaction: dbTransaction });
1305
+ });
1306
+ paymentPaidWithItems.forEach(async (paymentPaidWithItem) => {
1307
+ await FinanceCompany._PaymentPaidWithRepository.create({
1308
+ PaymentId: payment.PaymentId,
1309
+ MethodTypeId: paymentPaidWithItem.MethodTypeId,
1310
+ Currency: paymentPaidWithItem.Currency,
1311
+ Amount: paymentPaidWithItem.Amount,
1312
+ Status: paymentPaidWithItem.Status,
1313
+ LedgerNo: paymentPaidWithItem.TransactionId,
1314
+ RefBank: paymentPaidWithItem.RefBank,
1315
+ RefName: paymentPaidWithItem.RefName,
1316
+ RefNo: paymentPaidWithItem.RefNo,
1317
+ RefOther1: paymentPaidWithItem.RefOther1,
1318
+ RefOther2: paymentPaidWithItem.RefOther2,
1319
+ RefOther3: paymentPaidWithItem.RefOther3,
1320
+ RefOther4: paymentPaidWithItem.RefOther4,
1321
+ RefOther5: paymentPaidWithItem.RefOther5,
1322
+ Remarks: paymentPaidWithItem.Remarks,
1323
+ PaymentMediaId: paymentPaidWithItem.PaymentMediaId,
1324
+ }, { transaction: dbTransaction });
1325
+ });
1326
+ return payment;
1327
+ }
1328
+ catch (error) {
1329
+ throw error;
1330
+ }
1331
+ }
1332
+ async confirmPayment(dbTransaction, loginUser, customer, payment, status, remarks, ctAccountNo, receiptNo) {
1333
+ try {
1334
+ this._DbTransaction = dbTransaction;
1335
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1336
+ const isPrivileged = await loginUser.checkPrivileges(systemCode, 'FinanceCompany - Confirm Payment');
1337
+ if (!isPrivileged) {
1338
+ throw new general_1.ClassError('FinanceCompany', 'FinanceCompanyConfirmPaymentErrMsg00', `You do not have 'Payment - Confirm' privilege.`);
1339
+ }
1340
+ if (payment.PaymentId === 'New') {
1341
+ throw new general_1.ClassError('FinanceCompany', 'FinanceCompanyConfirmPaymentErrMsg01', `Payment not found.`);
1342
+ }
1343
+ if (payment.Status !== enum_1.PaymentStatus.PENDING) {
1344
+ throw new general_1.ClassError('Payment', 'PaymentConfirmPaymentErrMsg02', `Payment status is not 'Pending'.`);
1345
+ }
1346
+ payment.Remarks = remarks;
1347
+ let receiptDocNo = null;
1348
+ switch (status) {
1349
+ case enum_1.PaymentStatus.REJECTED:
1350
+ payment.Status = enum_1.PaymentStatus.REJECTED;
1351
+ break;
1352
+ case enum_1.PaymentStatus.FAILED:
1353
+ payment.Status = enum_1.PaymentStatus.FAILED;
1354
+ break;
1355
+ case enum_1.PaymentStatus.CONFIRMED:
1356
+ payment.Status = enum_1.PaymentStatus.CONFIRMED;
1357
+ const receiptDocuments = await FinanceCompany._DocumentRepository.findAll({
1358
+ where: {
1359
+ DocType: enum_1.DocType.RECEIPT,
1360
+ CompanyId: this.ObjectId,
1361
+ },
1362
+ });
1363
+ const receipt = new document_1.default(dbTransaction);
1364
+ if (receiptNo) {
1365
+ receipt.DocNo = receiptNo;
1366
+ }
1367
+ else {
1368
+ receipt.DocNo = `EZC-RCT-${receiptDocuments.length + 1}`;
1369
+ }
1370
+ receipt.DocType = enum_1.DocType.RECEIPT;
1371
+ receipt.DocDate = new Date();
1372
+ receipt.CompanyId = this.ObjectId;
1373
+ receipt.Currency = payment.Currency;
1374
+ receipt.Description = 'Payment Received';
1375
+ receipt.IssuedById = loginUser.ObjectId;
1376
+ receipt.IssuedToId = customer.CustomerId;
1377
+ receipt.IssuedToType = (0, typeof_1.type)(customer);
1378
+ receipt.RelatedObjectId = payment.RelatedObjectId;
1379
+ receipt.RelatedObjectType = payment.RelatedObjectType;
1380
+ receipt.UseAccSystemDocYN = 'N';
1381
+ receipt.CreatedById = loginUser.ObjectId;
1382
+ receipt.UpdatedById = loginUser.ObjectId;
1383
+ const paymentItems = await payment.getPaymentItems(dbTransaction);
1384
+ for (const paymentItem of paymentItems) {
1385
+ const receiptItem = new document_item_1.default(dbTransaction, receipt);
1386
+ receiptItem.Name = `Payment for ${paymentItem.PayForObjectType} No. ${paymentItem.PayForObjectId}`;
1387
+ receiptItem.NameBM = `Bayaran untuk ${paymentItem.PayForObjectType} No. ${paymentItem.PayForObjectId}`;
1388
+ receiptItem.Description = '-';
1389
+ receiptItem.Currency = paymentItem.Currency;
1390
+ receiptItem.UnitPrice = paymentItem.Amount;
1391
+ receiptItem.Quantity = 1;
1392
+ receiptItem.Amount = receiptItem.UnitPrice * receiptItem.Quantity;
1393
+ receiptItem.ItemId = receipt.DocNo;
1394
+ receiptItem.ItemType = (0, typeof_1.type)(payment);
1395
+ receiptItem.CtAccountNo = ctAccountNo;
1396
+ await paymentItem.paid(dbTransaction);
1397
+ await receipt.newDocumentItem(receiptItem);
1398
+ }
1399
+ const receiptMedia = await receipt.generateReceipt(receipt.IssuedById, customer, dbTransaction);
1400
+ await FinanceCompany._DocumentRepository.create({
1401
+ DocNo: receipt.DocNo,
1402
+ DocType: receipt.DocType,
1403
+ DocDate: receipt.DocDate,
1404
+ CompanyId: receipt.CompanyId,
1405
+ Currency: receipt.Currency,
1406
+ Amount: receipt.Amount,
1407
+ Description: receipt.Description,
1408
+ Status: receipt.Status,
1409
+ IssuedById: receipt.IssuedById,
1410
+ IssuedToId: receipt.IssuedToId,
1411
+ IssuedToType: receipt.IssuedToType,
1412
+ RelatedObjectId: receipt.RelatedObjectId,
1413
+ RelatedObjectType: receipt.RelatedObjectType,
1414
+ CreatedById: receipt.CreatedById,
1415
+ CreatedAt: new Date(),
1416
+ UpdatedById: receipt.UpdatedById,
1417
+ UpdatedAt: new Date(),
1418
+ DocPDFFileMediaId: receiptMedia.PDFMedia.MediaId,
1419
+ DocHTMLFileMediaId: receiptMedia.HTMLMedia.MediaId,
1420
+ AccSystemRefId: receipt.AccSystemRefId,
1421
+ PostedToAccSystemYN: receipt.PostedToAccSystemYN,
1422
+ PostedById: receipt.PostedToAccSystemYN == 'Y' ? receipt.PostedById : null,
1423
+ PostedDateTime: new Date(),
1424
+ UseAccSystemDocYN: receipt.UseAccSystemDocYN,
1425
+ }, {
1426
+ transaction: dbTransaction,
1427
+ });
1428
+ const receiptItems = await receipt.getDocumentItems(dbTransaction);
1429
+ for (const receiptItem of receiptItems) {
1430
+ await FinanceCompany._DocumentItemRepository.create({
1431
+ DocumentItemId: this._createId().toUpperCase(),
1432
+ DocNo: receipt.DocNo,
1433
+ Name: receiptItem.Name,
1434
+ NameBM: receiptItem.NameBM,
1435
+ Description: receiptItem.Description,
1436
+ ItemId: receiptItem.ItemId,
1437
+ ItemType: receiptItem.ItemType,
1438
+ ItemSKU: receiptItem.ItemSKU,
1439
+ ItemSerialNo: receiptItem.ItemSerialNo,
1440
+ Currency: receiptItem.Currency,
1441
+ UnitPrice: receiptItem.UnitPrice,
1442
+ Quantity: receiptItem.Quantity,
1443
+ QuantityUOM: receiptItem.QuantityUOM,
1444
+ Amount: receiptItem.Amount,
1445
+ TaxCode: receiptItem.TaxCode,
1446
+ TaxAmount: receiptItem.TaxAmount,
1447
+ TaxRate: receiptItem.TaxRate,
1448
+ TaxInclusiveYN: receiptItem.TaxInclusiveYN,
1449
+ DtAccountNo: receiptItem.DtAccountNo
1450
+ ? receiptItem.DtAccountNo
1451
+ : null,
1452
+ CtAccountNo: receiptItem.CtAccountNo
1453
+ ? receiptItem.CtAccountNo
1454
+ : null,
1455
+ }, {
1456
+ transaction: dbTransaction,
1457
+ });
1458
+ }
1459
+ payment.ReceiptDocNo = receipt.DocNo;
1460
+ receiptDocNo = receipt.DocNo;
1461
+ const transactionDate = new Date();
1462
+ const paymentPaidWithItems = await payment.getPaymentPaidWith(dbTransaction);
1463
+ for (const paymentPaidWith of paymentPaidWithItems) {
1464
+ let paymentMethodType = await payment_method_type_1.default.initMethodType(dbTransaction, paymentPaidWith.MethodTypeId);
1465
+ const journalEntry = new journal_entry_1.default(dbTransaction);
1466
+ journalEntry.init({
1467
+ CompanyId: this.CompanyId,
1468
+ Name: 'Collect-payments for ' + payment.PaymentId,
1469
+ });
1470
+ const debitLT = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.DEBIT);
1471
+ debitLT.AccountNo = paymentMethodType.AccountNo;
1472
+ debitLT.Currency = paymentPaidWith.Currency;
1473
+ debitLT.DebitAmount = paymentPaidWith.Amount;
1474
+ debitLT.Date = transactionDate;
1475
+ debitLT.Description = 'Payment Received';
1476
+ debitLT.Name = customer.FullName;
1477
+ debitLT.RelatedObjectId = payment.PaymentId;
1478
+ debitLT.RelatedObjectType = 'Payment';
1479
+ debitLT.RelatedPaymentId = payment.PaymentId;
1480
+ const creditLT = await journalEntry.newLedgerTransaction(enum_1.TransactionTypeOptions.CREDIT);
1481
+ if (ctAccountNo) {
1482
+ creditLT.AccountNo = ctAccountNo;
1483
+ }
1484
+ else {
1485
+ const arAccount = await customer.getAccountReceivable();
1486
+ creditLT.AccountNo = arAccount.AccountNo;
1487
+ }
1488
+ creditLT.Currency = paymentPaidWith.Currency;
1489
+ creditLT.CreditAmount = paymentPaidWith.Amount;
1490
+ creditLT.Date = transactionDate;
1491
+ creditLT.Description = 'Payment Received';
1492
+ creditLT.Name = paymentMethodType.Name;
1493
+ creditLT.RelatedObjectId = payment.PaymentId;
1494
+ creditLT.RelatedObjectType = (0, typeof_1.type)(payment);
1495
+ creditLT.RelatedPaymentId = payment.PaymentId;
1496
+ await this.postJournal(dbTransaction, journalEntry, loginUser);
1497
+ }
1498
+ break;
1499
+ default:
1500
+ throw new general_1.ClassError('FinanceCompany', 'FinanceCompanyConfirmPaymentErrMsg03', `Invalid status.`);
1501
+ }
1502
+ await FinanceCompany._PaymentRepository.update({
1503
+ ReceiptDocNo: receiptDocNo,
1504
+ Status: payment.Status,
1505
+ UpdatedAt: new Date(),
1506
+ UpdatedBy: loginUser.ObjectId,
1507
+ }, {
1508
+ where: {
1509
+ PaymentId: payment.PaymentId,
1510
+ },
1511
+ transaction: dbTransaction,
1512
+ });
1513
+ }
1514
+ catch (error) {
1515
+ throw error;
1516
+ }
1517
+ }
1518
+ }
1519
+ FinanceCompany._htFinanceCompanyIds = new general_1.HashTable();
1520
+ FinanceCompany._htFinanceCompanies = new general_1.HashTable();
1521
+ FinanceCompany._financeCompanyRepository = new finance_company_repository_1.FinanceCompanyRepository();
1522
+ FinanceCompany._PaymentRepository = new payment_repository_1.PaymentRepository();
1523
+ FinanceCompany._PaymentItemRepository = new payment_item_repository_1.PaymentItemRepository();
1524
+ FinanceCompany._PaymentPaidWithRepository = new payment_paid_with_repository_1.PaymentPaidWithRepository();
1525
+ FinanceCompany._PaymentMethodRepository = new payment_method_repository_1.PaymentMethodRepository();
1526
+ FinanceCompany._PaymentMethodTypeRepository = new payment_method_type_repository_1.PaymentMethodTypeRepository();
1527
+ FinanceCompany._DocumentRepository = new document_repository_1.DocumentRepository();
1528
+ FinanceCompany._DocumentItemRepository = new document_item_repository_1.DocumentItemRepository();
1529
+ FinanceCompany._FinanceCustomerRepository = new finance_customer_repository_1.FinanceCustomerRepository();
1530
+ FinanceCompany._LedgerTransactionRepository = new ledger_transaction_repository_1.LedgerTransactionRepository();
1531
+ FinanceCompany._AccountRepository = new account_repository_1.AccountRepository();
1532
+ FinanceCompany._TaxRepository = new tax_repository_1.TaxRepository();
1533
+ exports.default = FinanceCompany;
1577
1534
  //# sourceMappingURL=finance-company.js.map