From 9b2382a1a8d43a35b2be77494a4c29247e95b584 Mon Sep 17 00:00:00 2001 From: Isaac GC Date: Tue, 30 Jan 2024 21:12:33 -0800 Subject: [PATCH 1/2] UTC Datetime inconsistency for LedgerPostings/Reports --- models/Transactional/LedgerPosting.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/models/Transactional/LedgerPosting.ts b/models/Transactional/LedgerPosting.ts index 1af625963..f1c80cdaa 100644 --- a/models/Transactional/LedgerPosting.ts +++ b/models/Transactional/LedgerPosting.ts @@ -90,12 +90,28 @@ export class LedgerPosting { return map[account]; } + // Timezone inconsistency fix (very ugly code for now) + let entryDateTime = this.refDoc.date as string | Date; + let dateTimeValue: Date; + if (typeof entryDateTime === 'string' || entryDateTime instanceof String) { + dateTimeValue = new Date(entryDateTime); + } else { + dateTimeValue = entryDateTime; + } + let dtFixedValue = dateTimeValue; + let dtMinutes = dtFixedValue.getTimezoneOffset() % 60; + let dtHours = (dtFixedValue.getTimezoneOffset() - dtMinutes) / 60; + dtFixedValue.setHours(dtFixedValue.getHours() - dtHours); + dtFixedValue.setMinutes(dtFixedValue.getMinutes() - dtMinutes); + + // end ugly timezone fix code + const ledgerEntry = this.fyo.doc.getNewDoc( ModelNameEnum.AccountingLedgerEntry, { account: account, party: (this.refDoc.party as string) ?? '', - date: this.refDoc.date as string | Date, + date: dtFixedValue, referenceType: this.refDoc.schemaName, referenceName: this.refDoc.name!, reverted: this.reverted, From 64ad73b3909197f1ccb8afd40f7ac252d88c134d Mon Sep 17 00:00:00 2001 From: Isaac GC Date: Tue, 30 Jan 2024 21:18:22 -0800 Subject: [PATCH 2/2] Changed how datetime was fixed for various timezones --- .prettierignore | 3 +- backend/patches/index.ts | 6 ++++ backend/patches/v0_21_0/fixLedgerDateTime.ts | 34 ++++++++++++++++++++ models/Transactional/LedgerPosting.ts | 15 +++++---- package.json | 2 +- 5 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 backend/patches/v0_21_0/fixLedgerDateTime.ts diff --git a/.prettierignore b/.prettierignore index 4da41445e..7e200f89d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ **/types.ts **/dist_electron **/dummy/*.json -**/.github/ISSUE_TEMPLATE/*.yml \ No newline at end of file +**/.github/ISSUE_TEMPLATE/*.yml +**/patches/v0_21_0/* \ No newline at end of file diff --git a/backend/patches/index.ts b/backend/patches/index.ts index 9e05d37e4..e22f94340 100644 --- a/backend/patches/index.ts +++ b/backend/patches/index.ts @@ -5,6 +5,7 @@ import fixRoundOffAccount from './fixRoundOffAccount'; import testPatch from './testPatch'; import updateSchemas from './updateSchemas'; import setPaymentReferenceType from './setPaymentReferenceType'; +import fixLedgerDateTime from './v0_21_0/fixLedgerDateTime'; export default [ { name: 'testPatch', version: '0.5.0-beta.0', patch: testPatch }, @@ -34,4 +35,9 @@ export default [ version: '0.20.1', patch: setPaymentReferenceType, }, + { + name: 'fixLedgerDateTime', + version: '0.21.1', + patch: fixLedgerDateTime, + }, ] as Patch[]; diff --git a/backend/patches/v0_21_0/fixLedgerDateTime.ts b/backend/patches/v0_21_0/fixLedgerDateTime.ts new file mode 100644 index 000000000..6f01cf009 --- /dev/null +++ b/backend/patches/v0_21_0/fixLedgerDateTime.ts @@ -0,0 +1,34 @@ +import { DatabaseManager } from '../../database/manager'; + +/* eslint-disable */ +async function execute(dm: DatabaseManager) { + await dm.db!.knex!('AccountingLedgerEntry') + .select('name', 'date') + .then((trx: Array<{name: string; date: Date;}> ) => { + trx.forEach(async entry => { + const entryDate = new Date(entry['date']); + const timeZoneOffset = entryDate.getTimezoneOffset(); + const offsetMinutes = timeZoneOffset % 60; + const offsetHours = (timeZoneOffset - offsetMinutes) / 60; + + let daysToAdd = 0; // If behind or at GMT/Zulu time, don't need to add a day + if (timeZoneOffset < 0) { + // If ahead of GMT/Zulu time, need to advance a day forward first + daysToAdd = 1; + } + + entryDate.setDate(entryDate.getDate() + daysToAdd); + entryDate.setHours(0 - offsetHours); + entryDate.setMinutes(0 - offsetMinutes); + entryDate.setSeconds(0); + entryDate.setMilliseconds(0); + + await dm.db!.knex!('AccountingLedgerEntry') + .where({ name: entry['name'] }) + .update({ date: entryDate.toISOString() }); + }); + }); +} + +export default { execute, beforeMigrate: true }; +/* eslint-enable */ \ No newline at end of file diff --git a/models/Transactional/LedgerPosting.ts b/models/Transactional/LedgerPosting.ts index f1c80cdaa..b342a0ce5 100644 --- a/models/Transactional/LedgerPosting.ts +++ b/models/Transactional/LedgerPosting.ts @@ -91,18 +91,21 @@ export class LedgerPosting { } // Timezone inconsistency fix (very ugly code for now) - let entryDateTime = this.refDoc.date as string | Date; + const entryDateTime = this.refDoc.date as string | Date; let dateTimeValue: Date; if (typeof entryDateTime === 'string' || entryDateTime instanceof String) { dateTimeValue = new Date(entryDateTime); } else { dateTimeValue = entryDateTime; } - let dtFixedValue = dateTimeValue; - let dtMinutes = dtFixedValue.getTimezoneOffset() % 60; - let dtHours = (dtFixedValue.getTimezoneOffset() - dtMinutes) / 60; - dtFixedValue.setHours(dtFixedValue.getHours() - dtHours); - dtFixedValue.setMinutes(dtFixedValue.getMinutes() - dtMinutes); + const dtFixedValue = dateTimeValue; + const dtMinutes = dtFixedValue.getTimezoneOffset() % 60; + const dtHours = (dtFixedValue.getTimezoneOffset() - dtMinutes) / 60; + // Forcing the time to always be set to 00:00.000 for locale time + dtFixedValue.setHours(0 - dtHours); + dtFixedValue.setMinutes(0 - dtMinutes); + dtFixedValue.setSeconds(0); + dtFixedValue.setMilliseconds(0); // end ugly timezone fix code diff --git a/package.json b/package.json index 49719ea35..4667e7e30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frappe-books", - "version": "0.21.0", + "version": "0.21.1", "description": "Simple book-keeping app for everyone", "author": { "name": "Frappe Technologies Pvt. Ltd.",