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 1af625963..b342a0ce5 100644 --- a/models/Transactional/LedgerPosting.ts +++ b/models/Transactional/LedgerPosting.ts @@ -90,12 +90,31 @@ export class LedgerPosting { return map[account]; } + // Timezone inconsistency fix (very ugly code for now) + 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; + } + 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 + 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, 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.",