@churchsoln/dbms 1.0.56 → 1.0.58

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.
@@ -64,6 +64,17 @@ const NORMAL_BALANCE = {
64
64
  CREDIT: "Credit",
65
65
  };
66
66
 
67
+ const JOURNAL_ENTRY_SOURCE_TYPE = {
68
+ CONTRIBUTION: "Contribution",
69
+ MANUAL: "Manual",
70
+ BILL: "Bill",
71
+ INVOICE: "Invoice",
72
+ };
73
+
74
+ const JOURNAL_ENTRY_STATUS = {
75
+ POSTED: "posted",
76
+ };
77
+
67
78
  const ACCOUNTING_ACCOUNT_TYPES = {
68
79
  ASSET: { name: "Asset", normalBalance: NORMAL_BALANCE.DEBIT },
69
80
  LIABILITY: { name: "Liability", normalBalance: NORMAL_BALANCE.CREDIT },
@@ -72,28 +83,128 @@ const ACCOUNTING_ACCOUNT_TYPES = {
72
83
  EXPENSE: { name: "Expense", normalBalance: NORMAL_BALANCE.DEBIT },
73
84
  };
74
85
 
86
+ const CHART_OF_ACCOUNTS = [
87
+ { code: "1000", name: "Assets", accountingAccountType: "Asset", parentCode: null, isPostingAccount: false },
88
+ { code: "1010", name: "Checking Account", accountingAccountType: "Asset", parentCode: "1000", isPostingAccount: true },
89
+ { code: "1020", name: "Cash on Hand", accountingAccountType: "Asset", parentCode: "1000", isPostingAccount: true },
90
+ { code: "2000", name: "Liabilities", accountingAccountType: "Liability", parentCode: null, isPostingAccount: false },
91
+ { code: "3000", name: "Equity", accountingAccountType: "Equity", parentCode: null, isPostingAccount: false },
92
+ { code: "4000", name: "Income", accountingAccountType: "Income", parentCode: null, isPostingAccount: false },
93
+ { code: "4010", name: "Members Subscription Income", accountingAccountType: "Income", parentCode: "4000", isPostingAccount: true },
94
+ { code: "4020", name: "Capital Fund Donation Income", accountingAccountType: "Income", parentCode: "4000", isPostingAccount: true },
95
+ { code: "4030", name: "Offering Income", accountingAccountType: "Income", parentCode: "4000", isPostingAccount: true },
96
+ { code: "4040", name: "Wedding Fees Income", accountingAccountType: "Income", parentCode: "4000", isPostingAccount: true },
97
+ { code: "4050", name: "Self Denial Cover Income", accountingAccountType: "Income", parentCode: "4000", isPostingAccount: true },
98
+ { code: "4051", name: "Passion Week Income", accountingAccountType: "Income", parentCode: "4000", isPostingAccount: true },
99
+ { code: "4060", name: "Special Donation Income", accountingAccountType: "Income", parentCode: "4000", isPostingAccount: true },
100
+ { code: "5000", name: "Expenses", accountingAccountType: "Expense", parentCode: null, isPostingAccount: false },
101
+ { code: "5010", name: "Utilities Expense", accountingAccountType: "Expense", parentCode: "5000", isPostingAccount: true },
102
+ { code: "5020", name: "Mortgage Expense", accountingAccountType: "Expense", parentCode: "5000", isPostingAccount: true },
103
+ { code: "5030", name: "Office Supplies Expense", accountingAccountType: "Expense", parentCode: "5000", isPostingAccount: true },
104
+ ];
105
+
75
106
  const ACCOUNTS = {
76
- MEMBERS_SUBSCRIPTION: "Members Subscription",
77
- CAPITAL_FUND_DONATION: "Capital Fund Donation",
78
- MONTHLY_MORTGAGE_CONTRIBUTION: "Monthly Mortgage Contribution",
79
- OFFERTORY_PLATE: "Offertory - Plate (Loose Plate)",
80
- OFFERTORY_COVER: "Offertory - Cover",
81
- BIRTHDAY_COVER: "Birthday Cover",
82
- WEDDING_ANNIVERSARY_COVER: "Wedding Anniversary Cover",
83
- REMEMBERANCE_PRAYER_DONATION: "Rememberance Prayer Donation",
84
- SELF_DENIAL_COVER: "Self Denial Cover",
85
- SPECIAL_DONATION: "Special Donation",
86
- PASSION_WEEK: "Passion Week",
87
- WEDDING_FEES: "Wedding Fees",
88
- BAPTISM_FEES: "Baptism Fees",
89
- CATHOLICATE_DAY_FUND: "Catholicate Day Fund",
90
- ARTICLE_DONATIONS: "Article Donations",
91
- HARVEST_FESTIVAL: "Harvest Festival",
92
- SUNDAY_SCHOOL_COLLECTION: "Sunday School - Collection",
93
- MMVS_COLLECTION: "MMVS Collection",
94
- CHRISTMAS_DONATIONS: "Christmas Donations",
95
- CHARITY_FUNDS: "Charity Funds",
96
- }
107
+ MEMBERS_SUBSCRIPTION: {
108
+ accountHead: "Members Subscription",
109
+ accountDescription: "Members Subscription",
110
+ chartOfAccountCode: "4010",
111
+ },
112
+ CAPITAL_FUND_DONATION: {
113
+ accountHead: "Capital Fund Donation",
114
+ accountDescription: "Capital Fund Donation",
115
+ chartOfAccountCode: "4020",
116
+ },
117
+ MONTHLY_MORTGAGE_CONTRIBUTION: {
118
+ accountHead: "Monthly Mortgage Contribution",
119
+ accountDescription: "Monthly Mortgage Contribution",
120
+ chartOfAccountCode: "4020",
121
+ },
122
+ OFFERTORY_PLATE: {
123
+ accountHead: "Offertory - Plate (Loose Plate)",
124
+ accountDescription: "Offertory - Plate (Loose Plate)",
125
+ chartOfAccountCode: "4030",
126
+ },
127
+ OFFERTORY_COVER: {
128
+ accountHead: "Offertory - Cover",
129
+ accountDescription: "Offertory - Cover",
130
+ chartOfAccountCode: "4030",
131
+ },
132
+ BIRTHDAY_COVER: {
133
+ accountHead: "Birthday Cover",
134
+ accountDescription: "Birthday Offering",
135
+ chartOfAccountCode: "4030",
136
+ },
137
+ WEDDING_ANNIVERSARY_COVER: {
138
+ accountHead: "Wedding Anniversary Cover",
139
+ accountDescription: "Wedding Anniversary Offering",
140
+ chartOfAccountCode: "4030",
141
+ },
142
+ REMEMBERANCE_PRAYER_DONATION: {
143
+ accountHead: "Rememberance Prayer Donation",
144
+ accountDescription: "Rememberance Prayer Offering",
145
+ chartOfAccountCode: "4030",
146
+ },
147
+ SELF_DENIAL_COVER: {
148
+ accountHead: "Self Denial Cover",
149
+ accountDescription: "Self Denial Cover",
150
+ chartOfAccountCode: "4050",
151
+ },
152
+ SPECIAL_DONATION: {
153
+ accountHead: "Special Donation",
154
+ accountDescription: "Special Donation",
155
+ chartOfAccountCode: "4060",
156
+ },
157
+ PASSION_WEEK: {
158
+ accountHead: "Passion Week",
159
+ accountDescription: "Passion Week",
160
+ chartOfAccountCode: "4051",
161
+ },
162
+ WEDDING_FEES: {
163
+ accountHead: "Wedding Fees",
164
+ accountDescription: "Wedding Fees",
165
+ chartOfAccountCode: "4040",
166
+ },
167
+ BAPTISM_FEES: {
168
+ accountHead: "Baptism Fees",
169
+ accountDescription: "Baptism Fees",
170
+ chartOfAccountCode: "4040",
171
+ },
172
+ CATHOLICATE_DAY_FUND: {
173
+ accountHead: "Catholicate Day Fund",
174
+ accountDescription: "Catholicate Day Fund",
175
+ chartOfAccountCode: null,
176
+ },
177
+ ARTICLE_DONATIONS: {
178
+ accountHead: "Article Donations",
179
+ accountDescription: "Article Donations",
180
+ chartOfAccountCode: null,
181
+ },
182
+ HARVEST_FESTIVAL: {
183
+ accountHead: "Harvest Festival",
184
+ accountDescription: "Harvest Festival",
185
+ chartOfAccountCode: null,
186
+ },
187
+ SUNDAY_SCHOOL_COLLECTION: {
188
+ accountHead: "Sunday School - Collection",
189
+ accountDescription: "Sunday School - Collection",
190
+ chartOfAccountCode: null,
191
+ },
192
+ MMVS_COLLECTION: {
193
+ accountHead: "MMVS Collection",
194
+ accountDescription: "MMVS Collection",
195
+ chartOfAccountCode: null,
196
+ },
197
+ CHRISTMAS_DONATIONS: {
198
+ accountHead: "Christmas Donations",
199
+ accountDescription: "Christmas Donations",
200
+ chartOfAccountCode: null,
201
+ },
202
+ CHARITY_FUNDS: {
203
+ accountHead: "Charity Funds",
204
+ accountDescription: "Charity Funds",
205
+ chartOfAccountCode: null,
206
+ },
207
+ };
97
208
 
98
209
  const GENDER = {
99
210
  MALE: "Male",
@@ -130,4 +241,7 @@ module.exports = {
130
241
  ACCOUNTS,
131
242
  NORMAL_BALANCE,
132
243
  ACCOUNTING_ACCOUNT_TYPES,
244
+ CHART_OF_ACCOUNTS,
245
+ JOURNAL_ENTRY_SOURCE_TYPE,
246
+ JOURNAL_ENTRY_STATUS,
133
247
  };
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "ChartOfAccounts",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ code: { type: DataTypes.STRING, allowNull: false, unique: true },
10
+ name: { type: DataTypes.STRING, allowNull: false },
11
+ accountingAccountTypeId: { type: DataTypes.INTEGER, allowNull: false },
12
+ parentAccountId: { type: DataTypes.INTEGER, allowNull: true },
13
+ isPostingAccount: { type: DataTypes.BOOLEAN, defaultValue: true },
14
+ status: { type: DataTypes.BOOLEAN, defaultValue: true },
15
+ createdAt: {
16
+ type: DataTypes.DATE,
17
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
18
+ },
19
+ updatedAt: {
20
+ type: DataTypes.DATE,
21
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
22
+ },
23
+ },
24
+ { timestamps: false }
25
+ )
26
+ .then(() =>
27
+ queryInterface.addConstraint("ChartOfAccounts", {
28
+ fields: ["accountingAccountTypeId"],
29
+ type: "foreign key",
30
+ name: "ChartOfAccounts_AccountingAccountTypeId_Fkey",
31
+ references: {
32
+ table: "AccountingAccountTypes",
33
+ field: "id",
34
+ },
35
+ onDelete: "restrict",
36
+ onUpdate: "cascade",
37
+ })
38
+ )
39
+ .then(() =>
40
+ queryInterface.addConstraint("ChartOfAccounts", {
41
+ fields: ["parentAccountId"],
42
+ type: "foreign key",
43
+ name: "ChartOfAccounts_ParentAccountId_Fkey",
44
+ references: {
45
+ table: "ChartOfAccounts",
46
+ field: "id",
47
+ },
48
+ onDelete: "restrict",
49
+ onUpdate: "cascade",
50
+ })
51
+ );
52
+ },
53
+ down: async (queryInterface) => {
54
+ await queryInterface.dropTable("ChartOfAccounts");
55
+ },
56
+ };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .addColumn("Accounts", "chartOfAccountId", {
6
+ type: DataTypes.INTEGER,
7
+ allowNull: true,
8
+ })
9
+ .then(() =>
10
+ queryInterface.addConstraint("Accounts", {
11
+ fields: ["chartOfAccountId"],
12
+ type: "foreign key",
13
+ name: "Accounts_ChartOfAccountId_Fkey",
14
+ references: {
15
+ table: "ChartOfAccounts",
16
+ field: "id",
17
+ },
18
+ onDelete: "restrict",
19
+ onUpdate: "cascade",
20
+ })
21
+ );
22
+ },
23
+ down: async (queryInterface) => {
24
+ await queryInterface.removeConstraint("Accounts", "Accounts_ChartOfAccountId_Fkey");
25
+ await queryInterface.removeColumn("Accounts", "chartOfAccountId");
26
+ },
27
+ };
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "JournalEntry",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ entryDate: { type: DataTypes.DATEONLY, allowNull: false },
10
+ sourceType: { type: DataTypes.STRING, allowNull: true },
11
+ contributionTransactionId: { type: DataTypes.INTEGER, allowNull: true },
12
+ description: { type: DataTypes.TEXT, allowNull: true },
13
+ status: { type: DataTypes.STRING, defaultValue: "posted" },
14
+ createdAt: {
15
+ type: DataTypes.DATE,
16
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
17
+ },
18
+ updatedAt: {
19
+ type: DataTypes.DATE,
20
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
21
+ },
22
+ },
23
+ { timestamps: false }
24
+ )
25
+ .then(() =>
26
+ queryInterface.addConstraint("JournalEntry", {
27
+ fields: ["contributionTransactionId"],
28
+ type: "foreign key",
29
+ name: "JournalEntry_ContributionTransactionId_Fkey",
30
+ references: {
31
+ table: "ContributionTransaction",
32
+ field: "id",
33
+ },
34
+ onDelete: "restrict",
35
+ onUpdate: "cascade",
36
+ })
37
+ );
38
+ },
39
+ down: async (queryInterface) => {
40
+ await queryInterface.dropTable("JournalEntry");
41
+ },
42
+ };
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "JournalEntryLine",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ journalEntryId: { type: DataTypes.INTEGER, allowNull: false },
10
+ chartOfAccountId: { type: DataTypes.INTEGER, allowNull: false },
11
+ debit: { type: DataTypes.DECIMAL(10, 2), defaultValue: 0 },
12
+ credit: { type: DataTypes.DECIMAL(10, 2), defaultValue: 0 },
13
+ memo: { type: DataTypes.TEXT, allowNull: true },
14
+ createdAt: {
15
+ type: DataTypes.DATE,
16
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
17
+ },
18
+ updatedAt: {
19
+ type: DataTypes.DATE,
20
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
21
+ },
22
+ },
23
+ { timestamps: false }
24
+ )
25
+ .then(() =>
26
+ queryInterface.addConstraint("JournalEntryLine", {
27
+ fields: ["journalEntryId"],
28
+ type: "foreign key",
29
+ name: "JournalEntryLine_JournalEntryId_Fkey",
30
+ references: {
31
+ table: "JournalEntry",
32
+ field: "id",
33
+ },
34
+ onDelete: "cascade",
35
+ onUpdate: "cascade",
36
+ })
37
+ )
38
+ .then(() =>
39
+ queryInterface.addConstraint("JournalEntryLine", {
40
+ fields: ["chartOfAccountId"],
41
+ type: "foreign key",
42
+ name: "JournalEntryLine_ChartOfAccountId_Fkey",
43
+ references: {
44
+ table: "ChartOfAccounts",
45
+ field: "id",
46
+ },
47
+ onDelete: "restrict",
48
+ onUpdate: "cascade",
49
+ })
50
+ );
51
+ },
52
+ down: async (queryInterface) => {
53
+ await queryInterface.dropTable("JournalEntryLine");
54
+ },
55
+ };
@@ -12,5 +12,11 @@ module.exports = (sequelize, DataTypes) => {
12
12
  { freezeTableName: true, timestamps: false }
13
13
  );
14
14
  accountingAccountTypes.selectedFields = ["id", "name", "normalBalance", "status"];
15
+ accountingAccountTypes.associate = function (models) {
16
+ accountingAccountTypes.hasMany(models.chartOfAccounts, {
17
+ foreignKey: "accountingAccountTypeId",
18
+ as: "chartOfAccounts",
19
+ });
20
+ };
15
21
  return accountingAccountTypes;
16
22
  };
@@ -6,6 +6,7 @@ module.exports = (sequelize, DataTypes) => {
6
6
  accountHead: { type: DataTypes.STRING },
7
7
  accountDescription: { type: DataTypes.STRING },
8
8
  isLinkedWithQB: { type: DataTypes.BOOLEAN },
9
+ chartOfAccountId: { type: DataTypes.INTEGER, allowNull: true },
9
10
  status: { type: DataTypes.BOOLEAN, defaultValue: true },
10
11
  createdAt: { type: DataTypes.DATE },
11
12
  updatedAt: { type: DataTypes.DATE },
@@ -13,6 +14,10 @@ module.exports = (sequelize, DataTypes) => {
13
14
  { freezeTableName: true, timestamps: false }
14
15
  );
15
16
  accounts.associate = function (models) {
17
+ accounts.belongsTo(models.chartOfAccounts, {
18
+ foreignKey: "chartOfAccountId",
19
+ as: "chartOfAccount",
20
+ });
16
21
  accounts.hasMany(models.pledgeAccount, {
17
22
  foreignKey: "accountId",
18
23
  as: "pledgeAccount",
@@ -22,6 +27,12 @@ module.exports = (sequelize, DataTypes) => {
22
27
  as: "contributionTransactionLine",
23
28
  });
24
29
  }
25
- accounts.selectedFields = ["id", "accountHead", "accountDescription", "isLinkedWithQB"];
30
+ accounts.selectedFields = [
31
+ "id",
32
+ "accountHead",
33
+ "accountDescription",
34
+ "isLinkedWithQB",
35
+ "chartOfAccountId",
36
+ ];
26
37
  return accounts;
27
38
  };
@@ -0,0 +1,49 @@
1
+ module.exports = (sequelize, DataTypes) => {
2
+ const chartOfAccounts = sequelize.define(
3
+ "ChartOfAccounts",
4
+ {
5
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
6
+ code: { type: DataTypes.STRING, allowNull: false, unique: true },
7
+ name: { type: DataTypes.STRING, allowNull: false },
8
+ accountingAccountTypeId: { type: DataTypes.INTEGER, allowNull: false },
9
+ parentAccountId: { type: DataTypes.INTEGER, allowNull: true },
10
+ isPostingAccount: { type: DataTypes.BOOLEAN, defaultValue: true },
11
+ status: { type: DataTypes.BOOLEAN, defaultValue: true },
12
+ createdAt: { type: DataTypes.DATE },
13
+ updatedAt: { type: DataTypes.DATE },
14
+ },
15
+ { freezeTableName: true, timestamps: false }
16
+ );
17
+ chartOfAccounts.associate = function (models) {
18
+ chartOfAccounts.belongsTo(models.accountingAccountTypes, {
19
+ foreignKey: "accountingAccountTypeId",
20
+ as: "accountingAccountType",
21
+ });
22
+ chartOfAccounts.belongsTo(models.chartOfAccounts, {
23
+ foreignKey: "parentAccountId",
24
+ as: "parentAccount",
25
+ });
26
+ chartOfAccounts.hasMany(models.chartOfAccounts, {
27
+ foreignKey: "parentAccountId",
28
+ as: "childAccounts",
29
+ });
30
+ chartOfAccounts.hasMany(models.accounts, {
31
+ foreignKey: "chartOfAccountId",
32
+ as: "accounts",
33
+ });
34
+ chartOfAccounts.hasMany(models.journalEntryLine, {
35
+ foreignKey: "chartOfAccountId",
36
+ as: "journalEntryLines",
37
+ });
38
+ };
39
+ chartOfAccounts.selectedFields = [
40
+ "id",
41
+ "code",
42
+ "name",
43
+ "accountingAccountTypeId",
44
+ "parentAccountId",
45
+ "isPostingAccount",
46
+ "status",
47
+ ];
48
+ return chartOfAccounts;
49
+ };
@@ -71,6 +71,10 @@ module.exports = (sequelize, DataTypes) => {
71
71
  foreignKey: "contributionTransactionId",
72
72
  as: "contributionTransactionLine",
73
73
  });
74
+ contributionTransaction.hasMany(models.journalEntry, {
75
+ foreignKey: "contributionTransactionId",
76
+ as: "journalEntries",
77
+ });
74
78
  }
75
79
  contributionTransaction.selectedFields = [
76
80
  "id",
@@ -0,0 +1,37 @@
1
+ module.exports = (sequelize, DataTypes) => {
2
+ const journalEntry = sequelize.define(
3
+ "JournalEntry",
4
+ {
5
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
6
+ entryDate: { type: DataTypes.DATEONLY, allowNull: false },
7
+ sourceType: { type: DataTypes.STRING, allowNull: true },
8
+ contributionTransactionId: { type: DataTypes.INTEGER, allowNull: true },
9
+ description: { type: DataTypes.TEXT, allowNull: true },
10
+ status: { type: DataTypes.STRING, defaultValue: "posted" },
11
+ createdAt: { type: DataTypes.DATE },
12
+ updatedAt: { type: DataTypes.DATE },
13
+ },
14
+ { freezeTableName: true, timestamps: false }
15
+ );
16
+ journalEntry.associate = function (models) {
17
+ journalEntry.belongsTo(models.contributionTransaction, {
18
+ foreignKey: "contributionTransactionId",
19
+ as: "contributionTransaction",
20
+ });
21
+ journalEntry.hasMany(models.journalEntryLine, {
22
+ foreignKey: "journalEntryId",
23
+ as: "journalEntryLines",
24
+ });
25
+ };
26
+ journalEntry.selectedFields = [
27
+ "id",
28
+ "entryDate",
29
+ "sourceType",
30
+ "contributionTransactionId",
31
+ "description",
32
+ "status",
33
+ "createdAt",
34
+ "updatedAt",
35
+ ];
36
+ return journalEntry;
37
+ };
@@ -0,0 +1,37 @@
1
+ module.exports = (sequelize, DataTypes) => {
2
+ const journalEntryLine = sequelize.define(
3
+ "JournalEntryLine",
4
+ {
5
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
6
+ journalEntryId: { type: DataTypes.INTEGER, allowNull: false },
7
+ chartOfAccountId: { type: DataTypes.INTEGER, allowNull: false },
8
+ debit: { type: DataTypes.DECIMAL(10, 2), defaultValue: 0 },
9
+ credit: { type: DataTypes.DECIMAL(10, 2), defaultValue: 0 },
10
+ memo: { type: DataTypes.TEXT, allowNull: true },
11
+ createdAt: { type: DataTypes.DATE },
12
+ updatedAt: { type: DataTypes.DATE },
13
+ },
14
+ { freezeTableName: true, timestamps: false }
15
+ );
16
+ journalEntryLine.associate = function (models) {
17
+ journalEntryLine.belongsTo(models.journalEntry, {
18
+ foreignKey: "journalEntryId",
19
+ as: "journalEntry",
20
+ });
21
+ journalEntryLine.belongsTo(models.chartOfAccounts, {
22
+ foreignKey: "chartOfAccountId",
23
+ as: "chartOfAccount",
24
+ });
25
+ };
26
+ journalEntryLine.selectedFields = [
27
+ "id",
28
+ "journalEntryId",
29
+ "chartOfAccountId",
30
+ "debit",
31
+ "credit",
32
+ "memo",
33
+ "createdAt",
34
+ "updatedAt",
35
+ ];
36
+ return journalEntryLine;
37
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@churchsoln/dbms",
3
- "version": "1.0.56",
3
+ "version": "1.0.58",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "prestart": "node db-setup.js",
@@ -3,10 +3,10 @@
3
3
  const { ACCOUNTS } = require("../../constants");
4
4
 
5
5
  module.exports = {
6
- up: async (queryInterface, Sequelize) => {
6
+ up: async (queryInterface) => {
7
7
  const accounts = Object.values(ACCOUNTS).map((account) => ({
8
- accountHead: account,
9
- accountDescription: account,
8
+ accountHead: account.accountHead,
9
+ accountDescription: account.accountDescription,
10
10
  isLinkedWithQB: false,
11
11
  status: true,
12
12
  }));
@@ -23,10 +23,10 @@ module.exports = {
23
23
  if (existingAccount) {
24
24
  await queryInterface.bulkUpdate(
25
25
  "Accounts",
26
- {
27
- status: account.status,
28
- isLinkedWithQB: account.isLinkedWithQB,
29
- accountDescription: account.accountDescription
26
+ {
27
+ status: account.status,
28
+ isLinkedWithQB: account.isLinkedWithQB,
29
+ accountDescription: account.accountDescription,
30
30
  },
31
31
  { accountHead: account.accountHead }
32
32
  );
@@ -36,5 +36,5 @@ module.exports = {
36
36
  }
37
37
  },
38
38
 
39
- down: async (queryInterface, Sequelize) => {},
39
+ down: async () => {},
40
40
  };
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ const { CHART_OF_ACCOUNTS } = require("../../constants");
4
+
5
+ module.exports = {
6
+ up: async (queryInterface) => {
7
+ const codeToId = {};
8
+
9
+ const getAccountTypeId = async (accountTypeName) =>
10
+ queryInterface.rawSelect(
11
+ "AccountingAccountTypes",
12
+ { where: { name: accountTypeName } },
13
+ ["id"]
14
+ );
15
+
16
+ for (const account of CHART_OF_ACCOUNTS) {
17
+ const accountingAccountTypeId = await getAccountTypeId(account.accountingAccountType);
18
+ if (!accountingAccountTypeId) continue;
19
+
20
+ const parentAccountId = account.parentCode ? codeToId[account.parentCode] || null : null;
21
+
22
+ const record = {
23
+ code: account.code,
24
+ name: account.name,
25
+ accountingAccountTypeId,
26
+ parentAccountId,
27
+ isPostingAccount: account.isPostingAccount,
28
+ status: true,
29
+ };
30
+
31
+ const existingId = await queryInterface.rawSelect(
32
+ "ChartOfAccounts",
33
+ { where: { code: account.code } },
34
+ ["id"]
35
+ );
36
+
37
+ if (existingId) {
38
+ await queryInterface.bulkUpdate("ChartOfAccounts", record, { code: account.code });
39
+ codeToId[account.code] = existingId;
40
+ } else {
41
+ await queryInterface.bulkInsert("ChartOfAccounts", [record], {});
42
+ codeToId[account.code] = await queryInterface.rawSelect(
43
+ "ChartOfAccounts",
44
+ { where: { code: account.code } },
45
+ ["id"]
46
+ );
47
+ }
48
+ }
49
+ },
50
+
51
+ down: async () => {},
52
+ };
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ const { ACCOUNTS } = require("../../constants");
4
+
5
+ module.exports = {
6
+ up: async (queryInterface) => {
7
+ for (const account of Object.values(ACCOUNTS)) {
8
+ if (!account.chartOfAccountCode) continue;
9
+
10
+ const chartOfAccountId = await queryInterface.rawSelect(
11
+ "ChartOfAccounts",
12
+ { where: { code: account.chartOfAccountCode } },
13
+ ["id"]
14
+ );
15
+ if (!chartOfAccountId) continue;
16
+
17
+ const existingAccountId = await queryInterface.rawSelect(
18
+ "Accounts",
19
+ { where: { accountHead: account.accountHead } },
20
+ ["id"]
21
+ );
22
+
23
+ if (existingAccountId) {
24
+ await queryInterface.bulkUpdate(
25
+ "Accounts",
26
+ {
27
+ accountDescription: account.accountDescription,
28
+ chartOfAccountId,
29
+ },
30
+ { accountHead: account.accountHead }
31
+ );
32
+ }
33
+ }
34
+ },
35
+
36
+ down: async () => {},
37
+ };