using luxon for datetimes to keep consistency when generating dates across timezones

This commit is contained in:
Alex Phillips 2022-02-22 09:38:09 -05:00
parent da9ba2ffe4
commit 79b2da18af
6 changed files with 209 additions and 35 deletions

View File

@ -1,12 +1,12 @@
{
"name": "BudgE",
"version": "1.0.0",
"version": "0.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "BudgE",
"version": "1.0.0",
"version": "0.0.1",
"license": "ISC",
"dependencies": {
"@dinero.js/currencies": "^2.0.0-alpha.8",
@ -19,6 +19,7 @@
"express": "^4.17.1",
"helmet": "^4.6.0",
"jsonwebtoken": "^8.5.1",
"luxon": "^2.3.0",
"morgan": "^1.10.0",
"mysql": "^2.18.1",
"pg": "^8.7.1",
@ -43,6 +44,7 @@
"@types/helmet": "^4.0.0",
"@types/jest": "^27.0.3",
"@types/jsonwebtoken": "^8.5.5",
"@types/luxon": "^2.0.9",
"@types/mongoose": "^5.11.96",
"@types/morgan": "^1.9.3",
"@types/node-geocoder": "^3.24.3",
@ -2911,6 +2913,12 @@
"@types/node": "*"
}
},
"node_modules/@types/luxon": {
"version": "2.0.9",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.9.tgz",
"integrity": "sha512-ZuzIc7aN+i2ZDMWIiSmMdubR9EMMSTdEzF6R+FckP4p6xdnOYKqknTo/k+xXQvciSXlNGIwA4OPU5X7JIFzYdA==",
"dev": true
},
"node_modules/@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@ -9970,6 +9978,14 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/luxon": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.3.0.tgz",
"integrity": "sha512-gv6jZCV+gGIrVKhO90yrsn8qXPKD8HYZJtrUDSfEbow8Tkw84T9OnCyJhWvnJIaIF/tBuiAjZuQHUt1LddX2mg==",
"engines": {
"node": ">=12"
}
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@ -16543,6 +16559,12 @@
"@types/node": "*"
}
},
"@types/luxon": {
"version": "2.0.9",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.9.tgz",
"integrity": "sha512-ZuzIc7aN+i2ZDMWIiSmMdubR9EMMSTdEzF6R+FckP4p6xdnOYKqknTo/k+xXQvciSXlNGIwA4OPU5X7JIFzYdA==",
"dev": true
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@ -21878,6 +21900,11 @@
}
}
},
"luxon": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.3.0.tgz",
"integrity": "sha512-gv6jZCV+gGIrVKhO90yrsn8qXPKD8HYZJtrUDSfEbow8Tkw84T9OnCyJhWvnJIaIF/tBuiAjZuQHUt1LddX2mg=="
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",

View File

@ -27,6 +27,7 @@
"@types/helmet": "^4.0.0",
"@types/jest": "^27.0.3",
"@types/jsonwebtoken": "^8.5.5",
"@types/luxon": "^2.0.9",
"@types/mongoose": "^5.11.96",
"@types/morgan": "^1.9.3",
"@types/node-geocoder": "^3.24.3",
@ -58,6 +59,7 @@
"express": "^4.17.1",
"helmet": "^4.6.0",
"jsonwebtoken": "^8.5.1",
"luxon": "^2.3.0",
"morgan": "^1.10.0",
"mysql": "^2.18.1",
"pg": "^8.7.1",

View File

@ -0,0 +1,150 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class initial1645274669158 implements MigrationInterface {
name = 'initial1645274669158'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "users" ("id" varchar PRIMARY KEY NOT NULL, "email" varchar NOT NULL, "password" varchar NOT NULL, "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_97672ac88f789774dd47f7c8be" ON "users" ("email") `);
await queryRunner.query(`CREATE TABLE "budget_months" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "month" varchar NOT NULL, "income" integer NOT NULL DEFAULT (0), "budgeted" integer NOT NULL DEFAULT (0), "activity" integer NOT NULL DEFAULT (0), "underfunded" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`CREATE INDEX "IDX_398c07457719d1899ba4f11914" ON "budget_months" ("budgetId") `);
await queryRunner.query(`CREATE INDEX "IDX_0c21df54422306fdf78621fc18" ON "budget_months" ("month") `);
await queryRunner.query(`CREATE TABLE "category_months" ("id" varchar PRIMARY KEY NOT NULL, "categoryId" varchar NOT NULL, "budgetMonthId" varchar NOT NULL, "month" varchar NOT NULL, "budgeted" integer NOT NULL DEFAULT (0), "activity" integer NOT NULL DEFAULT (0), "balance" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`CREATE INDEX "IDX_cba488e36ca6ff6eec83e91440" ON "category_months" ("categoryId") `);
await queryRunner.query(`CREATE INDEX "IDX_de0f1ed5fe7ad4f2254bb815be" ON "category_months" ("budgetMonthId") `);
await queryRunner.query(`CREATE INDEX "IDX_23f4c8894717fb764a2b88ff29" ON "category_months" ("month") `);
await queryRunner.query(`CREATE TABLE "categories" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "categoryGroupId" varchar NOT NULL, "trackingAccountId" varchar, "name" varchar NOT NULL, "inflow" boolean NOT NULL DEFAULT (0), "locked" boolean NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`CREATE INDEX "IDX_e6d5be2f8c1fbd283150e043a0" ON "categories" ("budgetId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_af173d6048d44da16b00e49e24" ON "categories" ("trackingAccountId") `);
await queryRunner.query(`CREATE TABLE "payees" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "transferAccountId" varchar, "name" varchar NOT NULL, "internal" boolean NOT NULL, "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "REL_f61fc1e67d3abfb79503cdd382" UNIQUE ("transferAccountId"))`);
await queryRunner.query(`CREATE TABLE "transactions" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "accountId" varchar NOT NULL, "payeeId" varchar NOT NULL, "transferAccountId" varchar, "transferTransactionId" varchar, "categoryId" varchar, "amount" integer NOT NULL DEFAULT (0), "date" datetime NOT NULL, "memo" varchar NOT NULL DEFAULT (''), "status" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`CREATE INDEX "IDX_7098ffeb5373b7d6344f4f1663" ON "transactions" ("transferTransactionId") `);
await queryRunner.query(`CREATE TABLE "accounts" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "transferPayeeId" varchar, "name" varchar NOT NULL, "type" integer NOT NULL, "balance" integer NOT NULL DEFAULT (0), "cleared" integer NOT NULL DEFAULT (0), "uncleared" integer NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "REL_c2a8be4512a377b0a8614170e3" UNIQUE ("transferPayeeId"))`);
await queryRunner.query(`CREATE TABLE "budgets" ("id" varchar PRIMARY KEY NOT NULL, "userId" varchar NOT NULL, "name" varchar NOT NULL, "toBeBudgeted" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`CREATE TABLE "category_groups" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "name" varchar NOT NULL, "internal" boolean NOT NULL DEFAULT (0), "locked" boolean NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`CREATE INDEX "IDX_0dcceebef7c019bc892be7b5d0" ON "category_groups" ("budgetId") `);
await queryRunner.query(`DROP INDEX "IDX_398c07457719d1899ba4f11914"`);
await queryRunner.query(`DROP INDEX "IDX_0c21df54422306fdf78621fc18"`);
await queryRunner.query(`CREATE TABLE "temporary_budget_months" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "month" varchar NOT NULL, "income" integer NOT NULL DEFAULT (0), "budgeted" integer NOT NULL DEFAULT (0), "activity" integer NOT NULL DEFAULT (0), "underfunded" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "FK_398c07457719d1899ba4f11914d" FOREIGN KEY ("budgetId") REFERENCES "budgets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`INSERT INTO "temporary_budget_months"("id", "budgetId", "month", "income", "budgeted", "activity", "underfunded", "created", "updated") SELECT "id", "budgetId", "month", "income", "budgeted", "activity", "underfunded", "created", "updated" FROM "budget_months"`);
await queryRunner.query(`DROP TABLE "budget_months"`);
await queryRunner.query(`ALTER TABLE "temporary_budget_months" RENAME TO "budget_months"`);
await queryRunner.query(`CREATE INDEX "IDX_398c07457719d1899ba4f11914" ON "budget_months" ("budgetId") `);
await queryRunner.query(`CREATE INDEX "IDX_0c21df54422306fdf78621fc18" ON "budget_months" ("month") `);
await queryRunner.query(`DROP INDEX "IDX_cba488e36ca6ff6eec83e91440"`);
await queryRunner.query(`DROP INDEX "IDX_de0f1ed5fe7ad4f2254bb815be"`);
await queryRunner.query(`DROP INDEX "IDX_23f4c8894717fb764a2b88ff29"`);
await queryRunner.query(`CREATE TABLE "temporary_category_months" ("id" varchar PRIMARY KEY NOT NULL, "categoryId" varchar NOT NULL, "budgetMonthId" varchar NOT NULL, "month" varchar NOT NULL, "budgeted" integer NOT NULL DEFAULT (0), "activity" integer NOT NULL DEFAULT (0), "balance" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "FK_cba488e36ca6ff6eec83e914409" FOREIGN KEY ("categoryId") REFERENCES "categories" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_de0f1ed5fe7ad4f2254bb815bef" FOREIGN KEY ("budgetMonthId") REFERENCES "budget_months" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`INSERT INTO "temporary_category_months"("id", "categoryId", "budgetMonthId", "month", "budgeted", "activity", "balance", "created", "updated") SELECT "id", "categoryId", "budgetMonthId", "month", "budgeted", "activity", "balance", "created", "updated" FROM "category_months"`);
await queryRunner.query(`DROP TABLE "category_months"`);
await queryRunner.query(`ALTER TABLE "temporary_category_months" RENAME TO "category_months"`);
await queryRunner.query(`CREATE INDEX "IDX_cba488e36ca6ff6eec83e91440" ON "category_months" ("categoryId") `);
await queryRunner.query(`CREATE INDEX "IDX_de0f1ed5fe7ad4f2254bb815be" ON "category_months" ("budgetMonthId") `);
await queryRunner.query(`CREATE INDEX "IDX_23f4c8894717fb764a2b88ff29" ON "category_months" ("month") `);
await queryRunner.query(`DROP INDEX "IDX_e6d5be2f8c1fbd283150e043a0"`);
await queryRunner.query(`DROP INDEX "IDX_af173d6048d44da16b00e49e24"`);
await queryRunner.query(`CREATE TABLE "temporary_categories" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "categoryGroupId" varchar NOT NULL, "trackingAccountId" varchar, "name" varchar NOT NULL, "inflow" boolean NOT NULL DEFAULT (0), "locked" boolean NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "FK_e6d5be2f8c1fbd283150e043a08" FOREIGN KEY ("budgetId") REFERENCES "budgets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_d05bb3b46b9b190eb9c20ad3c21" FOREIGN KEY ("categoryGroupId") REFERENCES "category_groups" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`INSERT INTO "temporary_categories"("id", "budgetId", "categoryGroupId", "trackingAccountId", "name", "inflow", "locked", "order", "created", "updated") SELECT "id", "budgetId", "categoryGroupId", "trackingAccountId", "name", "inflow", "locked", "order", "created", "updated" FROM "categories"`);
await queryRunner.query(`DROP TABLE "categories"`);
await queryRunner.query(`ALTER TABLE "temporary_categories" RENAME TO "categories"`);
await queryRunner.query(`CREATE INDEX "IDX_e6d5be2f8c1fbd283150e043a0" ON "categories" ("budgetId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_af173d6048d44da16b00e49e24" ON "categories" ("trackingAccountId") `);
await queryRunner.query(`CREATE TABLE "temporary_payees" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "transferAccountId" varchar, "name" varchar NOT NULL, "internal" boolean NOT NULL, "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "REL_f61fc1e67d3abfb79503cdd382" UNIQUE ("transferAccountId"), CONSTRAINT "FK_f61fc1e67d3abfb79503cdd3821" FOREIGN KEY ("transferAccountId") REFERENCES "accounts" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`INSERT INTO "temporary_payees"("id", "budgetId", "transferAccountId", "name", "internal", "created", "updated") SELECT "id", "budgetId", "transferAccountId", "name", "internal", "created", "updated" FROM "payees"`);
await queryRunner.query(`DROP TABLE "payees"`);
await queryRunner.query(`ALTER TABLE "temporary_payees" RENAME TO "payees"`);
await queryRunner.query(`DROP INDEX "IDX_7098ffeb5373b7d6344f4f1663"`);
await queryRunner.query(`CREATE TABLE "temporary_transactions" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "accountId" varchar NOT NULL, "payeeId" varchar NOT NULL, "transferAccountId" varchar, "transferTransactionId" varchar, "categoryId" varchar, "amount" integer NOT NULL DEFAULT (0), "date" datetime NOT NULL, "memo" varchar NOT NULL DEFAULT (''), "status" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "FK_9552f6354aafa8f1818aa571aaf" FOREIGN KEY ("budgetId") REFERENCES "budgets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_26d8aec71ae9efbe468043cd2b9" FOREIGN KEY ("accountId") REFERENCES "accounts" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_44075a45926dfce0379d2c81c83" FOREIGN KEY ("payeeId") REFERENCES "payees" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_86e965e74f9cc66149cf6c90f64" FOREIGN KEY ("categoryId") REFERENCES "categories" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`INSERT INTO "temporary_transactions"("id", "budgetId", "accountId", "payeeId", "transferAccountId", "transferTransactionId", "categoryId", "amount", "date", "memo", "status", "created", "updated") SELECT "id", "budgetId", "accountId", "payeeId", "transferAccountId", "transferTransactionId", "categoryId", "amount", "date", "memo", "status", "created", "updated" FROM "transactions"`);
await queryRunner.query(`DROP TABLE "transactions"`);
await queryRunner.query(`ALTER TABLE "temporary_transactions" RENAME TO "transactions"`);
await queryRunner.query(`CREATE INDEX "IDX_7098ffeb5373b7d6344f4f1663" ON "transactions" ("transferTransactionId") `);
await queryRunner.query(`CREATE TABLE "temporary_accounts" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "transferPayeeId" varchar, "name" varchar NOT NULL, "type" integer NOT NULL, "balance" integer NOT NULL DEFAULT (0), "cleared" integer NOT NULL DEFAULT (0), "uncleared" integer NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "REL_c2a8be4512a377b0a8614170e3" UNIQUE ("transferPayeeId"), CONSTRAINT "FK_81acfbf2205a3be5b1c41455329" FOREIGN KEY ("budgetId") REFERENCES "budgets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_c2a8be4512a377b0a8614170e33" FOREIGN KEY ("transferPayeeId") REFERENCES "payees" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`INSERT INTO "temporary_accounts"("id", "budgetId", "transferPayeeId", "name", "type", "balance", "cleared", "uncleared", "order", "created", "updated") SELECT "id", "budgetId", "transferPayeeId", "name", "type", "balance", "cleared", "uncleared", "order", "created", "updated" FROM "accounts"`);
await queryRunner.query(`DROP TABLE "accounts"`);
await queryRunner.query(`ALTER TABLE "temporary_accounts" RENAME TO "accounts"`);
await queryRunner.query(`CREATE TABLE "temporary_budgets" ("id" varchar PRIMARY KEY NOT NULL, "userId" varchar NOT NULL, "name" varchar NOT NULL, "toBeBudgeted" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "FK_27e688ddf1ff3893b43065899f9" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`INSERT INTO "temporary_budgets"("id", "userId", "name", "toBeBudgeted", "created", "updated") SELECT "id", "userId", "name", "toBeBudgeted", "created", "updated" FROM "budgets"`);
await queryRunner.query(`DROP TABLE "budgets"`);
await queryRunner.query(`ALTER TABLE "temporary_budgets" RENAME TO "budgets"`);
await queryRunner.query(`DROP INDEX "IDX_0dcceebef7c019bc892be7b5d0"`);
await queryRunner.query(`CREATE TABLE "temporary_category_groups" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "name" varchar NOT NULL, "internal" boolean NOT NULL DEFAULT (0), "locked" boolean NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "FK_0dcceebef7c019bc892be7b5d0e" FOREIGN KEY ("budgetId") REFERENCES "budgets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`INSERT INTO "temporary_category_groups"("id", "budgetId", "name", "internal", "locked", "order", "created", "updated") SELECT "id", "budgetId", "name", "internal", "locked", "order", "created", "updated" FROM "category_groups"`);
await queryRunner.query(`DROP TABLE "category_groups"`);
await queryRunner.query(`ALTER TABLE "temporary_category_groups" RENAME TO "category_groups"`);
await queryRunner.query(`CREATE INDEX "IDX_0dcceebef7c019bc892be7b5d0" ON "category_groups" ("budgetId") `);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP INDEX "IDX_0dcceebef7c019bc892be7b5d0"`);
await queryRunner.query(`ALTER TABLE "category_groups" RENAME TO "temporary_category_groups"`);
await queryRunner.query(`CREATE TABLE "category_groups" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "name" varchar NOT NULL, "internal" boolean NOT NULL DEFAULT (0), "locked" boolean NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`INSERT INTO "category_groups"("id", "budgetId", "name", "internal", "locked", "order", "created", "updated") SELECT "id", "budgetId", "name", "internal", "locked", "order", "created", "updated" FROM "temporary_category_groups"`);
await queryRunner.query(`DROP TABLE "temporary_category_groups"`);
await queryRunner.query(`CREATE INDEX "IDX_0dcceebef7c019bc892be7b5d0" ON "category_groups" ("budgetId") `);
await queryRunner.query(`ALTER TABLE "budgets" RENAME TO "temporary_budgets"`);
await queryRunner.query(`CREATE TABLE "budgets" ("id" varchar PRIMARY KEY NOT NULL, "userId" varchar NOT NULL, "name" varchar NOT NULL, "toBeBudgeted" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`INSERT INTO "budgets"("id", "userId", "name", "toBeBudgeted", "created", "updated") SELECT "id", "userId", "name", "toBeBudgeted", "created", "updated" FROM "temporary_budgets"`);
await queryRunner.query(`DROP TABLE "temporary_budgets"`);
await queryRunner.query(`ALTER TABLE "accounts" RENAME TO "temporary_accounts"`);
await queryRunner.query(`CREATE TABLE "accounts" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "transferPayeeId" varchar, "name" varchar NOT NULL, "type" integer NOT NULL, "balance" integer NOT NULL DEFAULT (0), "cleared" integer NOT NULL DEFAULT (0), "uncleared" integer NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "REL_c2a8be4512a377b0a8614170e3" UNIQUE ("transferPayeeId"))`);
await queryRunner.query(`INSERT INTO "accounts"("id", "budgetId", "transferPayeeId", "name", "type", "balance", "cleared", "uncleared", "order", "created", "updated") SELECT "id", "budgetId", "transferPayeeId", "name", "type", "balance", "cleared", "uncleared", "order", "created", "updated" FROM "temporary_accounts"`);
await queryRunner.query(`DROP TABLE "temporary_accounts"`);
await queryRunner.query(`DROP INDEX "IDX_7098ffeb5373b7d6344f4f1663"`);
await queryRunner.query(`ALTER TABLE "transactions" RENAME TO "temporary_transactions"`);
await queryRunner.query(`CREATE TABLE "transactions" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "accountId" varchar NOT NULL, "payeeId" varchar NOT NULL, "transferAccountId" varchar, "transferTransactionId" varchar, "categoryId" varchar, "amount" integer NOT NULL DEFAULT (0), "date" datetime NOT NULL, "memo" varchar NOT NULL DEFAULT (''), "status" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`INSERT INTO "transactions"("id", "budgetId", "accountId", "payeeId", "transferAccountId", "transferTransactionId", "categoryId", "amount", "date", "memo", "status", "created", "updated") SELECT "id", "budgetId", "accountId", "payeeId", "transferAccountId", "transferTransactionId", "categoryId", "amount", "date", "memo", "status", "created", "updated" FROM "temporary_transactions"`);
await queryRunner.query(`DROP TABLE "temporary_transactions"`);
await queryRunner.query(`CREATE INDEX "IDX_7098ffeb5373b7d6344f4f1663" ON "transactions" ("transferTransactionId") `);
await queryRunner.query(`ALTER TABLE "payees" RENAME TO "temporary_payees"`);
await queryRunner.query(`CREATE TABLE "payees" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "transferAccountId" varchar, "name" varchar NOT NULL, "internal" boolean NOT NULL, "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "REL_f61fc1e67d3abfb79503cdd382" UNIQUE ("transferAccountId"))`);
await queryRunner.query(`INSERT INTO "payees"("id", "budgetId", "transferAccountId", "name", "internal", "created", "updated") SELECT "id", "budgetId", "transferAccountId", "name", "internal", "created", "updated" FROM "temporary_payees"`);
await queryRunner.query(`DROP TABLE "temporary_payees"`);
await queryRunner.query(`DROP INDEX "IDX_af173d6048d44da16b00e49e24"`);
await queryRunner.query(`DROP INDEX "IDX_e6d5be2f8c1fbd283150e043a0"`);
await queryRunner.query(`ALTER TABLE "categories" RENAME TO "temporary_categories"`);
await queryRunner.query(`CREATE TABLE "categories" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "categoryGroupId" varchar NOT NULL, "trackingAccountId" varchar, "name" varchar NOT NULL, "inflow" boolean NOT NULL DEFAULT (0), "locked" boolean NOT NULL DEFAULT (0), "order" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`INSERT INTO "categories"("id", "budgetId", "categoryGroupId", "trackingAccountId", "name", "inflow", "locked", "order", "created", "updated") SELECT "id", "budgetId", "categoryGroupId", "trackingAccountId", "name", "inflow", "locked", "order", "created", "updated" FROM "temporary_categories"`);
await queryRunner.query(`DROP TABLE "temporary_categories"`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_af173d6048d44da16b00e49e24" ON "categories" ("trackingAccountId") `);
await queryRunner.query(`CREATE INDEX "IDX_e6d5be2f8c1fbd283150e043a0" ON "categories" ("budgetId") `);
await queryRunner.query(`DROP INDEX "IDX_23f4c8894717fb764a2b88ff29"`);
await queryRunner.query(`DROP INDEX "IDX_de0f1ed5fe7ad4f2254bb815be"`);
await queryRunner.query(`DROP INDEX "IDX_cba488e36ca6ff6eec83e91440"`);
await queryRunner.query(`ALTER TABLE "category_months" RENAME TO "temporary_category_months"`);
await queryRunner.query(`CREATE TABLE "category_months" ("id" varchar PRIMARY KEY NOT NULL, "categoryId" varchar NOT NULL, "budgetMonthId" varchar NOT NULL, "month" varchar NOT NULL, "budgeted" integer NOT NULL DEFAULT (0), "activity" integer NOT NULL DEFAULT (0), "balance" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`INSERT INTO "category_months"("id", "categoryId", "budgetMonthId", "month", "budgeted", "activity", "balance", "created", "updated") SELECT "id", "categoryId", "budgetMonthId", "month", "budgeted", "activity", "balance", "created", "updated" FROM "temporary_category_months"`);
await queryRunner.query(`DROP TABLE "temporary_category_months"`);
await queryRunner.query(`CREATE INDEX "IDX_23f4c8894717fb764a2b88ff29" ON "category_months" ("month") `);
await queryRunner.query(`CREATE INDEX "IDX_de0f1ed5fe7ad4f2254bb815be" ON "category_months" ("budgetMonthId") `);
await queryRunner.query(`CREATE INDEX "IDX_cba488e36ca6ff6eec83e91440" ON "category_months" ("categoryId") `);
await queryRunner.query(`DROP INDEX "IDX_0c21df54422306fdf78621fc18"`);
await queryRunner.query(`DROP INDEX "IDX_398c07457719d1899ba4f11914"`);
await queryRunner.query(`ALTER TABLE "budget_months" RENAME TO "temporary_budget_months"`);
await queryRunner.query(`CREATE TABLE "budget_months" ("id" varchar PRIMARY KEY NOT NULL, "budgetId" varchar NOT NULL, "month" varchar NOT NULL, "income" integer NOT NULL DEFAULT (0), "budgeted" integer NOT NULL DEFAULT (0), "activity" integer NOT NULL DEFAULT (0), "underfunded" integer NOT NULL DEFAULT (0), "created" datetime NOT NULL DEFAULT (datetime('now')), "updated" datetime NOT NULL DEFAULT (datetime('now')))`);
await queryRunner.query(`INSERT INTO "budget_months"("id", "budgetId", "month", "income", "budgeted", "activity", "underfunded", "created", "updated") SELECT "id", "budgetId", "month", "income", "budgeted", "activity", "underfunded", "created", "updated" FROM "temporary_budget_months"`);
await queryRunner.query(`DROP TABLE "temporary_budget_months"`);
await queryRunner.query(`CREATE INDEX "IDX_0c21df54422306fdf78621fc18" ON "budget_months" ("month") `);
await queryRunner.query(`CREATE INDEX "IDX_398c07457719d1899ba4f11914" ON "budget_months" ("budgetId") `);
await queryRunner.query(`DROP INDEX "IDX_0dcceebef7c019bc892be7b5d0"`);
await queryRunner.query(`DROP TABLE "category_groups"`);
await queryRunner.query(`DROP TABLE "budgets"`);
await queryRunner.query(`DROP TABLE "accounts"`);
await queryRunner.query(`DROP INDEX "IDX_7098ffeb5373b7d6344f4f1663"`);
await queryRunner.query(`DROP TABLE "transactions"`);
await queryRunner.query(`DROP TABLE "payees"`);
await queryRunner.query(`DROP INDEX "IDX_af173d6048d44da16b00e49e24"`);
await queryRunner.query(`DROP INDEX "IDX_e6d5be2f8c1fbd283150e043a0"`);
await queryRunner.query(`DROP TABLE "categories"`);
await queryRunner.query(`DROP INDEX "IDX_23f4c8894717fb764a2b88ff29"`);
await queryRunner.query(`DROP INDEX "IDX_de0f1ed5fe7ad4f2254bb815be"`);
await queryRunner.query(`DROP INDEX "IDX_cba488e36ca6ff6eec83e91440"`);
await queryRunner.query(`DROP TABLE "category_months"`);
await queryRunner.query(`DROP INDEX "IDX_0c21df54422306fdf78621fc18"`);
await queryRunner.query(`DROP INDEX "IDX_398c07457719d1899ba4f11914"`);
await queryRunner.query(`DROP TABLE "budget_months"`);
await queryRunner.query(`DROP INDEX "IDX_97672ac88f789774dd47f7c8be"`);
await queryRunner.query(`DROP TABLE "users"`);
}
}

View File

@ -26,12 +26,11 @@ export class BudgetMonthSubscriber implements EntitySubscriberInterface<BudgetMo
async afterInsert(event: InsertEvent<BudgetMonth>) {
const budgetMonth = event.entity
const manager = event.manager
const prevMonth = getDateFromString(budgetMonth.month)
prevMonth.setMonth(prevMonth.getMonth() - 1)
const prevMonth = getDateFromString(budgetMonth.month).minus({ month: 1 })
const prevBudgetMonth = await manager.findOne(BudgetMonth, {
budgetId: budgetMonth.budgetId,
month: formatMonthFromDateString(prevMonth),
month: formatMonthFromDateString(prevMonth.toJSDate()),
})
if (!prevBudgetMonth) {

View File

@ -20,11 +20,10 @@ export class CategoryMonthSubscriber implements EntitySubscriberInterface<Catego
const categoryMonth = event.entity
const manager = event.manager
const prevMonth = getDateFromString(categoryMonth.month)
prevMonth.setMonth(prevMonth.getMonth() - 1)
const prevMonth = getDateFromString(categoryMonth.month).minus({ month: 1 })
const prevCategoryMonth = await manager.findOne(CategoryMonth, {
categoryId: categoryMonth.categoryId,
month: formatMonthFromDateString(prevMonth),
month: formatMonthFromDateString(prevMonth.toJSDate()),
})
const category = await event.manager.findOne(Category, {
@ -55,6 +54,7 @@ export class CategoryMonthSubscriber implements EntitySubscriberInterface<Catego
* Also, cascade the new balance of this month into the next month to update the carry-over amount.
*/
private async bookkeeping(categoryMonth: CategoryMonth, manager: EntityManager) {
console.log(`bookeeping category month: ${categoryMonth.month}`)
const category = await manager.findOne(Category, categoryMonth.categoryId)
const originalCategoryMonth = CategoryMonthCache.get(categoryMonth.id)
@ -98,12 +98,11 @@ export class CategoryMonthSubscriber implements EntitySubscriberInterface<Catego
await manager.update(BudgetMonth, budgetMonth.id, budgetMonth.getUpdatePayload())
const nextMonth = getDateFromString(categoryMonth.month)
nextMonth.setMonth(nextMonth.getMonth() + 1)
const nextMonth = getDateFromString(categoryMonth.month).plus({ month: 1 })
const nextBudgetMonth = await manager.findOne(BudgetMonth, {
budgetId: category.budgetId,
month: formatMonthFromDateString(nextMonth),
month: formatMonthFromDateString(nextMonth.toJSDate()),
})
if (!nextBudgetMonth) {

View File

@ -1,42 +1,39 @@
import { DateTime } from 'luxon'
export async function sleep(duration: number): Promise<void> {
return new Promise(resolve => {
setTimeout(resolve, duration)
})
}
export function getDateFromString(date: string): Date {
let [year, month, day] = date.split('-').map(val => parseInt(val))
// Month is zero-indexed in JS...
month = month - 1
if (month < 0) {
month = 11
year = year - 1
}
return new Date(year, month, day)
export function getDateFromString(date: string): DateTime {
return DateTime.fromISO(date)
}
export function formatMonthFromDateString(date: Date): string {
let tempDate = new Date(date)
tempDate.setHours(0)
tempDate.setDate(1)
return tempDate.toISOString().split('T')[0]
let tempDate = DateTime.fromISO(date.toISOString())
tempDate = tempDate.set({ day: 1 })
return tempDate.toISO().split('T')[0]
}
export function getMonthDate(): Date {
const today = new Date()
const date = new Date(today.getFullYear(), today.getMonth(), 1)
return date
export function getMonthDate(): DateTime {
const today = DateTime.now()
return today.set({ day: 1 })
}
export function getMonthString(): string {
return getMonthDate().toISOString().split('T')[0]
return getMonthDate().toISO().split('T')[0]
}
export function getMonthStringFromNow(monthsAway: number): string {
const today = new Date()
const date = new Date(today.getFullYear(), today.getMonth(), 1)
date.setMonth(date.getMonth() + monthsAway)
return date.toISOString().split('T')[0]
let today: DateTime = DateTime.now()
today = today.set({ day: 1 })
if (monthsAway > 0) {
today = today.plus({ month: monthsAway })
} else {
today = today.minus({ month: monthsAway })
}
return today.toISO().split('T')[0]
}