@churchsoln/dbms 1.0.63 → 1.0.65

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 (26) hide show
  1. package/constants/index.js +47 -0
  2. package/migrations/church/20261017170648-create-vendor.js +46 -0
  3. package/migrations/church/20261017170649-create-bill.js +73 -0
  4. package/migrations/church/20261017170650-create-billLine.js +61 -0
  5. package/migrations/church/20261017170651-create-billAttachment.js +43 -0
  6. package/migrations/church/20261017170652-create-billPayment.js +72 -0
  7. package/migrations/church/20261023090000-create-customer.js +46 -0
  8. package/migrations/church/20261023090001-create-invoice.js +71 -0
  9. package/migrations/church/20261023090002-create-invoiceLine.js +57 -0
  10. package/migrations/church/20261023090003-create-invoicePayment.js +72 -0
  11. package/migrations/church/20261026170653-create-bankReconciliation.js +47 -0
  12. package/migrations/church/20261026170654-update-journalEntryLine-add-reconciliation.js +35 -0
  13. package/models/church/bankReconciliation.js +48 -0
  14. package/models/church/bill.js +83 -0
  15. package/models/church/billAttachment.js +34 -0
  16. package/models/church/billLine.js +47 -0
  17. package/models/church/billPayment.js +48 -0
  18. package/models/church/customer.js +45 -0
  19. package/models/church/invoice.js +75 -0
  20. package/models/church/invoiceLine.js +39 -0
  21. package/models/church/invoicePayment.js +48 -0
  22. package/models/church/journalEntryLine.js +10 -0
  23. package/models/church/vendor.js +45 -0
  24. package/package.json +1 -1
  25. package/seeders/church/20261017170653-chartOfAccounts-accountsPayable.js +44 -0
  26. package/seeders/church/20261023090004-chartOfAccounts-accountsReceivable.js +44 -0
@@ -84,6 +84,44 @@ const JOURNAL_ENTRY_STATUS = {
84
84
  DRAFT: "draft",
85
85
  };
86
86
 
87
+ const BILL_STATUS = {
88
+ DRAFT: "Draft",
89
+ UNPAID: "Unpaid",
90
+ PARTIALLY_PAID: "PartiallyPaid",
91
+ PAID: "Paid",
92
+ };
93
+
94
+ const BILL_TAX_MODE = {
95
+ EXCLUSIVE: "exclusive",
96
+ INCLUSIVE: "inclusive",
97
+ };
98
+
99
+ const BILL_PAYMENT_METHOD = {
100
+ CASH: "Cash",
101
+ CHECK: "Check",
102
+ BANK_TRANSFER: "BankTransfer",
103
+ CARD: "Card",
104
+ OTHER: "Other",
105
+ };
106
+
107
+ const ACCOUNTS_PAYABLE_CODE = "2010";
108
+
109
+ // Invoices share the bill lifecycle (Draft -> Unpaid -> PartiallyPaid -> Paid; Overdue is derived).
110
+ const INVOICE_STATUS = {
111
+ DRAFT: "Draft",
112
+ UNPAID: "Unpaid",
113
+ PARTIALLY_PAID: "PartiallyPaid",
114
+ PAID: "Paid",
115
+ };
116
+
117
+ // An asset account, but not cash: excluded wherever "posting asset" means a bank/cash account.
118
+ const ACCOUNTS_RECEIVABLE_CODE = "1100";
119
+
120
+ const BANK_RECONCILIATION_STATUS = {
121
+ IN_PROGRESS: "InProgress",
122
+ COMPLETED: "Completed",
123
+ };
124
+
87
125
  const ACCOUNTING_ACCOUNT_TYPES = {
88
126
  ASSET: { name: "Asset", normalBalance: NORMAL_BALANCE.DEBIT },
89
127
  LIABILITY: { name: "Liability", normalBalance: NORMAL_BALANCE.CREDIT },
@@ -96,7 +134,9 @@ const CHART_OF_ACCOUNTS = [
96
134
  { code: "1000", name: "Assets", accountingAccountType: "Asset", parentCode: null, isPostingAccount: false },
97
135
  { code: "1010", name: "Checking Account", accountingAccountType: "Asset", parentCode: "1000", isPostingAccount: true },
98
136
  { code: "1020", name: "Cash on Hand", accountingAccountType: "Asset", parentCode: "1000", isPostingAccount: true },
137
+ { code: "1100", name: "Accounts Receivable", accountingAccountType: "Asset", parentCode: "1000", isPostingAccount: true },
99
138
  { code: "2000", name: "Liabilities", accountingAccountType: "Liability", parentCode: null, isPostingAccount: false },
139
+ { code: "2010", name: "Accounts Payable", accountingAccountType: "Liability", parentCode: "2000", isPostingAccount: true },
100
140
  { code: "3000", name: "Equity", accountingAccountType: "Equity", parentCode: null, isPostingAccount: false },
101
141
  { code: "4000", name: "Income", accountingAccountType: "Income", parentCode: null, isPostingAccount: false },
102
142
  { code: "4010", name: "Members Subscription Income", accountingAccountType: "Income", parentCode: "4000", isPostingAccount: true },
@@ -253,4 +293,11 @@ module.exports = {
253
293
  CHART_OF_ACCOUNTS,
254
294
  JOURNAL_ENTRY_SOURCE_TYPE,
255
295
  JOURNAL_ENTRY_STATUS,
296
+ BILL_STATUS,
297
+ BILL_TAX_MODE,
298
+ BILL_PAYMENT_METHOD,
299
+ ACCOUNTS_PAYABLE_CODE,
300
+ INVOICE_STATUS,
301
+ ACCOUNTS_RECEIVABLE_CODE,
302
+ BANK_RECONCILIATION_STATUS,
256
303
  };
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "Vendor",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ name: { type: DataTypes.STRING, allowNull: false, unique: true },
10
+ email: { type: DataTypes.STRING, allowNull: true },
11
+ phone: { type: DataTypes.STRING, allowNull: true },
12
+ addressLine1: { type: DataTypes.STRING, allowNull: true },
13
+ addressLine2: { type: DataTypes.STRING, allowNull: true },
14
+ defaultTerms: { type: DataTypes.STRING, allowNull: true },
15
+ defaultChartOfAccountId: { type: DataTypes.INTEGER, allowNull: true },
16
+ notes: { type: DataTypes.TEXT, allowNull: true },
17
+ status: { type: DataTypes.BOOLEAN, defaultValue: true },
18
+ createdAt: {
19
+ type: DataTypes.DATE,
20
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
21
+ },
22
+ updatedAt: {
23
+ type: DataTypes.DATE,
24
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
25
+ },
26
+ },
27
+ { timestamps: false }
28
+ )
29
+ .then(() =>
30
+ queryInterface.addConstraint("Vendor", {
31
+ fields: ["defaultChartOfAccountId"],
32
+ type: "foreign key",
33
+ name: "Vendor_DefaultChartOfAccountId_Fkey",
34
+ references: {
35
+ table: "ChartOfAccounts",
36
+ field: "id",
37
+ },
38
+ onDelete: "set null",
39
+ onUpdate: "cascade",
40
+ })
41
+ );
42
+ },
43
+ down: async (queryInterface) => {
44
+ await queryInterface.dropTable("Vendor");
45
+ },
46
+ };
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "Bill",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ billNo: { type: DataTypes.STRING, allowNull: false, unique: true },
10
+ vendorId: { type: DataTypes.INTEGER, allowNull: false },
11
+ reference: { type: DataTypes.STRING, allowNull: true },
12
+ description: { type: DataTypes.TEXT, allowNull: true },
13
+ billDate: { type: DataTypes.DATEONLY, allowNull: true },
14
+ dueDate: { type: DataTypes.DATEONLY, allowNull: true },
15
+ terms: { type: DataTypes.STRING, allowNull: true },
16
+ currency: { type: DataTypes.STRING, defaultValue: "USD" },
17
+ memo: { type: DataTypes.TEXT, allowNull: true },
18
+ notes: { type: DataTypes.TEXT, allowNull: true },
19
+ status: { type: DataTypes.STRING, defaultValue: "Draft" },
20
+ taxMode: { type: DataTypes.STRING, defaultValue: "exclusive" },
21
+ subtotal: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
22
+ tax: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
23
+ discount: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
24
+ amount: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
25
+ amountPaid: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
26
+ amountDue: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
27
+ paidDate: { type: DataTypes.DATEONLY, allowNull: true },
28
+ journalEntryId: { type: DataTypes.INTEGER, allowNull: true },
29
+ createdBy: { type: DataTypes.INTEGER, allowNull: true },
30
+ createdAt: {
31
+ type: DataTypes.DATE,
32
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
33
+ },
34
+ updatedAt: {
35
+ type: DataTypes.DATE,
36
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
37
+ },
38
+ },
39
+ { timestamps: false }
40
+ )
41
+ .then(() =>
42
+ queryInterface.addConstraint("Bill", {
43
+ fields: ["vendorId"],
44
+ type: "foreign key",
45
+ name: "Bill_VendorId_Fkey",
46
+ references: {
47
+ table: "Vendor",
48
+ field: "id",
49
+ },
50
+ onDelete: "restrict",
51
+ onUpdate: "cascade",
52
+ })
53
+ )
54
+ .then(() =>
55
+ queryInterface.addConstraint("Bill", {
56
+ fields: ["journalEntryId"],
57
+ type: "foreign key",
58
+ name: "Bill_JournalEntryId_Fkey",
59
+ references: {
60
+ table: "JournalEntry",
61
+ field: "id",
62
+ },
63
+ onDelete: "set null",
64
+ onUpdate: "cascade",
65
+ })
66
+ )
67
+ .then(() => queryInterface.addIndex("Bill", ["status"]))
68
+ .then(() => queryInterface.addIndex("Bill", ["dueDate"]));
69
+ },
70
+ down: async (queryInterface) => {
71
+ await queryInterface.dropTable("Bill");
72
+ },
73
+ };
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "BillLine",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ billId: { type: DataTypes.INTEGER, allowNull: false },
10
+ chartOfAccountId: { type: DataTypes.INTEGER, allowNull: true },
11
+ description: { type: DataTypes.TEXT, allowNull: true },
12
+ className: { type: DataTypes.STRING, allowNull: true },
13
+ amount: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
14
+ taxRate: { type: DataTypes.DECIMAL(6, 4), defaultValue: 0 },
15
+ taxLabel: { type: DataTypes.STRING, allowNull: true },
16
+ netAmount: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
17
+ taxAmount: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
18
+ total: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
19
+ sortOrder: { type: DataTypes.INTEGER, defaultValue: 0 },
20
+ createdAt: {
21
+ type: DataTypes.DATE,
22
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
23
+ },
24
+ updatedAt: {
25
+ type: DataTypes.DATE,
26
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
27
+ },
28
+ },
29
+ { timestamps: false }
30
+ )
31
+ .then(() =>
32
+ queryInterface.addConstraint("BillLine", {
33
+ fields: ["billId"],
34
+ type: "foreign key",
35
+ name: "BillLine_BillId_Fkey",
36
+ references: {
37
+ table: "Bill",
38
+ field: "id",
39
+ },
40
+ onDelete: "cascade",
41
+ onUpdate: "cascade",
42
+ })
43
+ )
44
+ .then(() =>
45
+ queryInterface.addConstraint("BillLine", {
46
+ fields: ["chartOfAccountId"],
47
+ type: "foreign key",
48
+ name: "BillLine_ChartOfAccountId_Fkey",
49
+ references: {
50
+ table: "ChartOfAccounts",
51
+ field: "id",
52
+ },
53
+ onDelete: "restrict",
54
+ onUpdate: "cascade",
55
+ })
56
+ );
57
+ },
58
+ down: async (queryInterface) => {
59
+ await queryInterface.dropTable("BillLine");
60
+ },
61
+ };
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "BillAttachment",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ billId: { type: DataTypes.INTEGER, allowNull: false },
10
+ name: { type: DataTypes.STRING, allowNull: false },
11
+ fileName: { type: DataTypes.STRING, allowNull: false },
12
+ url: { type: DataTypes.STRING, allowNull: false },
13
+ mimeType: { type: DataTypes.STRING, allowNull: true },
14
+ size: { type: DataTypes.INTEGER, allowNull: 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("BillAttachment", {
28
+ fields: ["billId"],
29
+ type: "foreign key",
30
+ name: "BillAttachment_BillId_Fkey",
31
+ references: {
32
+ table: "Bill",
33
+ field: "id",
34
+ },
35
+ onDelete: "cascade",
36
+ onUpdate: "cascade",
37
+ })
38
+ );
39
+ },
40
+ down: async (queryInterface) => {
41
+ await queryInterface.dropTable("BillAttachment");
42
+ },
43
+ };
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "BillPayment",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ billId: { type: DataTypes.INTEGER, allowNull: false },
10
+ paymentDate: { type: DataTypes.DATEONLY, allowNull: false },
11
+ amount: { type: DataTypes.DECIMAL(12, 2), allowNull: false },
12
+ paidFromAccountId: { type: DataTypes.INTEGER, allowNull: false },
13
+ method: { type: DataTypes.STRING, allowNull: true },
14
+ reference: { type: DataTypes.STRING, allowNull: true },
15
+ memo: { type: DataTypes.TEXT, allowNull: true },
16
+ journalEntryId: { type: DataTypes.INTEGER, allowNull: true },
17
+ createdBy: { type: DataTypes.INTEGER, allowNull: true },
18
+ createdAt: {
19
+ type: DataTypes.DATE,
20
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
21
+ },
22
+ updatedAt: {
23
+ type: DataTypes.DATE,
24
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
25
+ },
26
+ },
27
+ { timestamps: false }
28
+ )
29
+ .then(() =>
30
+ queryInterface.addConstraint("BillPayment", {
31
+ fields: ["billId"],
32
+ type: "foreign key",
33
+ name: "BillPayment_BillId_Fkey",
34
+ references: {
35
+ table: "Bill",
36
+ field: "id",
37
+ },
38
+ onDelete: "restrict",
39
+ onUpdate: "cascade",
40
+ })
41
+ )
42
+ .then(() =>
43
+ queryInterface.addConstraint("BillPayment", {
44
+ fields: ["paidFromAccountId"],
45
+ type: "foreign key",
46
+ name: "BillPayment_PaidFromAccountId_Fkey",
47
+ references: {
48
+ table: "ChartOfAccounts",
49
+ field: "id",
50
+ },
51
+ onDelete: "restrict",
52
+ onUpdate: "cascade",
53
+ })
54
+ )
55
+ .then(() =>
56
+ queryInterface.addConstraint("BillPayment", {
57
+ fields: ["journalEntryId"],
58
+ type: "foreign key",
59
+ name: "BillPayment_JournalEntryId_Fkey",
60
+ references: {
61
+ table: "JournalEntry",
62
+ field: "id",
63
+ },
64
+ onDelete: "set null",
65
+ onUpdate: "cascade",
66
+ })
67
+ );
68
+ },
69
+ down: async (queryInterface) => {
70
+ await queryInterface.dropTable("BillPayment");
71
+ },
72
+ };
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "Customer",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ name: { type: DataTypes.STRING, allowNull: false, unique: true },
10
+ email: { type: DataTypes.STRING, allowNull: true },
11
+ phone: { type: DataTypes.STRING, allowNull: true },
12
+ addressLine1: { type: DataTypes.STRING, allowNull: true },
13
+ addressLine2: { type: DataTypes.STRING, allowNull: true },
14
+ defaultTerms: { type: DataTypes.STRING, allowNull: true },
15
+ defaultChartOfAccountId: { type: DataTypes.INTEGER, allowNull: true },
16
+ notes: { type: DataTypes.TEXT, allowNull: true },
17
+ status: { type: DataTypes.BOOLEAN, defaultValue: true },
18
+ createdAt: {
19
+ type: DataTypes.DATE,
20
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
21
+ },
22
+ updatedAt: {
23
+ type: DataTypes.DATE,
24
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
25
+ },
26
+ },
27
+ { timestamps: false }
28
+ )
29
+ .then(() =>
30
+ queryInterface.addConstraint("Customer", {
31
+ fields: ["defaultChartOfAccountId"],
32
+ type: "foreign key",
33
+ name: "Customer_DefaultChartOfAccountId_Fkey",
34
+ references: {
35
+ table: "ChartOfAccounts",
36
+ field: "id",
37
+ },
38
+ onDelete: "set null",
39
+ onUpdate: "cascade",
40
+ })
41
+ );
42
+ },
43
+ down: async (queryInterface) => {
44
+ await queryInterface.dropTable("Customer");
45
+ },
46
+ };
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "Invoice",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ invoiceNo: { type: DataTypes.STRING, allowNull: false, unique: true },
10
+ customerId: { type: DataTypes.INTEGER, allowNull: false },
11
+ reference: { type: DataTypes.STRING, allowNull: true },
12
+ description: { type: DataTypes.TEXT, allowNull: true },
13
+ invoiceDate: { type: DataTypes.DATEONLY, allowNull: true },
14
+ dueDate: { type: DataTypes.DATEONLY, allowNull: true },
15
+ terms: { type: DataTypes.STRING, allowNull: true },
16
+ currency: { type: DataTypes.STRING, defaultValue: "USD" },
17
+ memo: { type: DataTypes.TEXT, allowNull: true },
18
+ notes: { type: DataTypes.TEXT, allowNull: true },
19
+ status: { type: DataTypes.STRING, defaultValue: "Draft" },
20
+ subtotal: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
21
+ discount: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
22
+ amount: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
23
+ amountPaid: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
24
+ amountDue: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
25
+ paidDate: { type: DataTypes.DATEONLY, allowNull: true },
26
+ journalEntryId: { type: DataTypes.INTEGER, allowNull: true },
27
+ createdBy: { type: DataTypes.INTEGER, allowNull: true },
28
+ createdAt: {
29
+ type: DataTypes.DATE,
30
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
31
+ },
32
+ updatedAt: {
33
+ type: DataTypes.DATE,
34
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
35
+ },
36
+ },
37
+ { timestamps: false }
38
+ )
39
+ .then(() =>
40
+ queryInterface.addConstraint("Invoice", {
41
+ fields: ["customerId"],
42
+ type: "foreign key",
43
+ name: "Invoice_CustomerId_Fkey",
44
+ references: {
45
+ table: "Customer",
46
+ field: "id",
47
+ },
48
+ onDelete: "restrict",
49
+ onUpdate: "cascade",
50
+ })
51
+ )
52
+ .then(() =>
53
+ queryInterface.addConstraint("Invoice", {
54
+ fields: ["journalEntryId"],
55
+ type: "foreign key",
56
+ name: "Invoice_JournalEntryId_Fkey",
57
+ references: {
58
+ table: "JournalEntry",
59
+ field: "id",
60
+ },
61
+ onDelete: "set null",
62
+ onUpdate: "cascade",
63
+ })
64
+ )
65
+ .then(() => queryInterface.addIndex("Invoice", ["status"]))
66
+ .then(() => queryInterface.addIndex("Invoice", ["dueDate"]));
67
+ },
68
+ down: async (queryInterface) => {
69
+ await queryInterface.dropTable("Invoice");
70
+ },
71
+ };
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "InvoiceLine",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ invoiceId: { type: DataTypes.INTEGER, allowNull: false },
10
+ chartOfAccountId: { type: DataTypes.INTEGER, allowNull: true },
11
+ description: { type: DataTypes.TEXT, allowNull: true },
12
+ quantity: { type: DataTypes.DECIMAL(12, 2), defaultValue: 1 },
13
+ rate: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
14
+ amount: { type: DataTypes.DECIMAL(12, 2), defaultValue: 0 },
15
+ sortOrder: { type: DataTypes.INTEGER, defaultValue: 0 },
16
+ createdAt: {
17
+ type: DataTypes.DATE,
18
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
19
+ },
20
+ updatedAt: {
21
+ type: DataTypes.DATE,
22
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
23
+ },
24
+ },
25
+ { timestamps: false }
26
+ )
27
+ .then(() =>
28
+ queryInterface.addConstraint("InvoiceLine", {
29
+ fields: ["invoiceId"],
30
+ type: "foreign key",
31
+ name: "InvoiceLine_InvoiceId_Fkey",
32
+ references: {
33
+ table: "Invoice",
34
+ field: "id",
35
+ },
36
+ onDelete: "cascade",
37
+ onUpdate: "cascade",
38
+ })
39
+ )
40
+ .then(() =>
41
+ queryInterface.addConstraint("InvoiceLine", {
42
+ fields: ["chartOfAccountId"],
43
+ type: "foreign key",
44
+ name: "InvoiceLine_ChartOfAccountId_Fkey",
45
+ references: {
46
+ table: "ChartOfAccounts",
47
+ field: "id",
48
+ },
49
+ onDelete: "restrict",
50
+ onUpdate: "cascade",
51
+ })
52
+ );
53
+ },
54
+ down: async (queryInterface) => {
55
+ await queryInterface.dropTable("InvoiceLine");
56
+ },
57
+ };
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "InvoicePayment",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ invoiceId: { type: DataTypes.INTEGER, allowNull: false },
10
+ paymentDate: { type: DataTypes.DATEONLY, allowNull: false },
11
+ amount: { type: DataTypes.DECIMAL(12, 2), allowNull: false },
12
+ depositToAccountId: { type: DataTypes.INTEGER, allowNull: false },
13
+ method: { type: DataTypes.STRING, allowNull: true },
14
+ reference: { type: DataTypes.STRING, allowNull: true },
15
+ memo: { type: DataTypes.TEXT, allowNull: true },
16
+ journalEntryId: { type: DataTypes.INTEGER, allowNull: true },
17
+ createdBy: { type: DataTypes.INTEGER, allowNull: true },
18
+ createdAt: {
19
+ type: DataTypes.DATE,
20
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
21
+ },
22
+ updatedAt: {
23
+ type: DataTypes.DATE,
24
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
25
+ },
26
+ },
27
+ { timestamps: false }
28
+ )
29
+ .then(() =>
30
+ queryInterface.addConstraint("InvoicePayment", {
31
+ fields: ["invoiceId"],
32
+ type: "foreign key",
33
+ name: "InvoicePayment_InvoiceId_Fkey",
34
+ references: {
35
+ table: "Invoice",
36
+ field: "id",
37
+ },
38
+ onDelete: "restrict",
39
+ onUpdate: "cascade",
40
+ })
41
+ )
42
+ .then(() =>
43
+ queryInterface.addConstraint("InvoicePayment", {
44
+ fields: ["depositToAccountId"],
45
+ type: "foreign key",
46
+ name: "InvoicePayment_DepositToAccountId_Fkey",
47
+ references: {
48
+ table: "ChartOfAccounts",
49
+ field: "id",
50
+ },
51
+ onDelete: "restrict",
52
+ onUpdate: "cascade",
53
+ })
54
+ )
55
+ .then(() =>
56
+ queryInterface.addConstraint("InvoicePayment", {
57
+ fields: ["journalEntryId"],
58
+ type: "foreign key",
59
+ name: "InvoicePayment_JournalEntryId_Fkey",
60
+ references: {
61
+ table: "JournalEntry",
62
+ field: "id",
63
+ },
64
+ onDelete: "set null",
65
+ onUpdate: "cascade",
66
+ })
67
+ );
68
+ },
69
+ down: async (queryInterface) => {
70
+ await queryInterface.dropTable("InvoicePayment");
71
+ },
72
+ };
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ module.exports = {
3
+ up: async (queryInterface, DataTypes) => {
4
+ await queryInterface
5
+ .createTable(
6
+ "BankReconciliation",
7
+ {
8
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
9
+ chartOfAccountId: { type: DataTypes.INTEGER, allowNull: false },
10
+ statementDate: { type: DataTypes.DATEONLY, allowNull: false },
11
+ statementEndingBalance: { type: DataTypes.DECIMAL(12, 2), allowNull: false },
12
+ beginningBalance: { type: DataTypes.DECIMAL(12, 2), allowNull: false },
13
+ clearedBalance: { type: DataTypes.DECIMAL(12, 2), allowNull: true },
14
+ difference: { type: DataTypes.DECIMAL(12, 2), allowNull: true },
15
+ status: { type: DataTypes.STRING, allowNull: false },
16
+ startedAt: { type: DataTypes.DATE, allowNull: false },
17
+ completedAt: { type: DataTypes.DATE, allowNull: true },
18
+ createdBy: { type: DataTypes.INTEGER, allowNull: true },
19
+ createdAt: {
20
+ type: DataTypes.DATE,
21
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
22
+ },
23
+ updatedAt: {
24
+ type: DataTypes.DATE,
25
+ defaultValue: DataTypes.literal("CURRENT_TIMESTAMP"),
26
+ },
27
+ },
28
+ { timestamps: false }
29
+ )
30
+ .then(() =>
31
+ queryInterface.addConstraint("BankReconciliation", {
32
+ fields: ["chartOfAccountId"],
33
+ type: "foreign key",
34
+ name: "BankReconciliation_ChartOfAccountId_Fkey",
35
+ references: {
36
+ table: "ChartOfAccounts",
37
+ field: "id",
38
+ },
39
+ onDelete: "restrict",
40
+ onUpdate: "cascade",
41
+ })
42
+ );
43
+ },
44
+ down: async (queryInterface) => {
45
+ await queryInterface.dropTable("BankReconciliation");
46
+ },
47
+ };