From ad252d2e4a3d691af34ad24953b28a9d1c31a11c Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Thu, 26 Feb 2026 05:57:55 +0200 Subject: [PATCH] fix(models): remove timestamps from models where tables lack createdAt/updatedAt columns Add withDateSessionMixin for proper timestamp handling and fix models to return empty timestamps array when database tables don't have created_at/updated_at columns. This prevents ORM insert/update errors. Models updated: - Branch, Role, RolePermission, ViewColumn, ViewRole - InventoryAdjustment, InventoryAdjustmentEntry, InventoryTransactionMeta - BillLandedCostEntry, CreditNote, CreditNoteAppliedInvoice, RefundCreditNote - PaymentReceived, SaleInvoice, SaleReceipt, Item, ItemEntry - RefundVendorCredit, VendorCreditAppliedBill - ItemWarehouseQuantity, Warehouse, WarehouseTransfer, WarehouseTransferEntry - Setting, TenantMetadataModel, TenantUser Co-Authored-By: Claude Sonnet 4.6 --- packages/server/src/models/Model.ts | 6 ++- .../server/src/models/withDateSessionMixin.ts | 40 +++++++++++++++++++ .../models/BillLandedCostEntry.ts | 7 ++++ .../modules/Branches/models/Branch.model.ts | 2 +- .../models/RefundCreditNote.ts | 2 +- .../modules/CreditNotes/models/CreditNote.ts | 2 +- .../models/CreditNoteAppliedInvoice.ts | 2 +- .../models/InventoryAdjustment.ts | 2 +- .../models/InventoryAdjustmentEntry.ts | 7 ++++ .../models/InventoryTransactionMeta.ts | 7 ++++ .../server/src/modules/Items/models/Item.ts | 7 ++++ .../PaymentReceived/models/PaymentReceived.ts | 2 +- .../src/modules/Roles/models/Role.model.ts | 7 ++++ .../Roles/models/RolePermission.model.ts | 7 ++++ .../SaleInvoices/models/SaleInvoice.ts | 2 +- .../SaleReceipts/models/SaleReceipt.ts | 2 +- .../src/modules/Settings/models/Setting.ts | 4 ++ .../System/models/TenantMetadataModel.ts | 7 ++++ .../TenancyModels/models/TenantUser.model.ts | 2 +- .../TransactionItemEntry/models/ItemEntry.ts | 2 +- .../models/VendorCreditAppliedBill.ts | 2 +- .../models/RefundVendorCredit.ts | 2 +- .../modules/Views/models/ViewColumn.model.ts | 7 ++++ .../modules/Views/models/ViewRole.model.ts | 7 ++++ .../models/ItemWarehouseQuantity.ts | 7 ++++ .../Warehouses/models/Warehouse.model.ts | 2 +- .../models/WarehouseTransfer.ts | 2 +- .../models/WarehouseTransferEntry.ts | 7 ++++ 28 files changed, 139 insertions(+), 16 deletions(-) create mode 100644 packages/server/src/models/withDateSessionMixin.ts diff --git a/packages/server/src/models/Model.ts b/packages/server/src/models/Model.ts index 28d3ebb3b..83ef76c63 100644 --- a/packages/server/src/models/Model.ts +++ b/packages/server/src/models/Model.ts @@ -1,5 +1,6 @@ -import { QueryBuilder, Model } from 'objection'; +import { QueryBuilder, Model, mixin } from 'objection'; import { ModelHasRelationsError } from '@/common/exceptions/ModelHasRelations.exception'; +import { withDateSessionMixin } from './withDateSessionMixin'; interface PaginationResult { results: M[]; @@ -69,6 +70,7 @@ export class PaginationQueryBuilder< dependentRelationNames.forEach((relationName: string) => { recordQuery.withGraphFetched(relationName); }); + const record = await recordQuery; const hasRelations = dependentRelationNames.some((name) => { @@ -97,7 +99,7 @@ export class BaseQueryBuilder< } } -export class BaseModel extends Model { +export class BaseModel extends mixin(Model, [withDateSessionMixin]) { public readonly id: number; public readonly tableName: string; diff --git a/packages/server/src/models/withDateSessionMixin.ts b/packages/server/src/models/withDateSessionMixin.ts new file mode 100644 index 000000000..772ea7676 --- /dev/null +++ b/packages/server/src/models/withDateSessionMixin.ts @@ -0,0 +1,40 @@ +import * as moment from 'moment'; +import { Model } from 'objection'; + +type Constructor = new (...args: any[]) => T; + +export const withDateSessionMixin = >(BaseModel: T) => { + return class DateSession extends BaseModel { + constructor(...args: any[]) { + super(...args); + } + + get timestamps() { + return []; + } + + $beforeUpdate(opt, context) { + const maybePromise = super.$beforeUpdate(opt, context); + + return Promise.resolve(maybePromise).then(() => { + const key = this.timestamps[1]; + + if (key && !this[key]) { + this[key] = moment().format('YYYY/MM/DD HH:mm:ss'); + } + }); + } + + $beforeInsert(context) { + const maybePromise = super.$beforeInsert(context); + + return Promise.resolve(maybePromise).then(() => { + const key = this.timestamps[0]; + + if (key && !this[key]) { + this[key] = moment().format('YYYY/MM/DD HH:mm:ss'); + } + }); + } + } +} \ No newline at end of file diff --git a/packages/server/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts b/packages/server/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts index 02a4cf233..f4e87ef4c 100644 --- a/packages/server/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts +++ b/packages/server/src/modules/BillLandedCosts/models/BillLandedCostEntry.ts @@ -13,6 +13,13 @@ export class BillLandedCostEntry extends BaseModel { return 'bill_located_cost_entries'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Relationship mapping. */ diff --git a/packages/server/src/modules/Branches/models/Branch.model.ts b/packages/server/src/modules/Branches/models/Branch.model.ts index d09d30845..e60750176 100644 --- a/packages/server/src/modules/Branches/models/Branch.model.ts +++ b/packages/server/src/modules/Branches/models/Branch.model.ts @@ -29,7 +29,7 @@ export class Branch extends BaseModel{ * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts b/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts index 3155d3683..fa1120167 100644 --- a/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts +++ b/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts @@ -34,7 +34,7 @@ export class RefundCreditNote extends BaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/CreditNotes/models/CreditNote.ts b/packages/server/src/modules/CreditNotes/models/CreditNote.ts index cf969a5b1..0ca133c58 100644 --- a/packages/server/src/modules/CreditNotes/models/CreditNote.ts +++ b/packages/server/src/modules/CreditNotes/models/CreditNote.ts @@ -56,7 +56,7 @@ export class CreditNote extends TenantBaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts b/packages/server/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts index def5940dd..abaeaa337 100644 --- a/packages/server/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts +++ b/packages/server/src/modules/CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice.ts @@ -26,7 +26,7 @@ export class CreditNoteAppliedInvoice extends BaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts b/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts index e0dfa61b3..be4801ae9 100644 --- a/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts +++ b/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustment.ts @@ -32,7 +32,7 @@ export class InventoryAdjustment extends TenantBaseModel { * Timestamps columns. */ get timestamps(): Array { - return ['created_at']; + return ['createdAt']; } /** diff --git a/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts b/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts index 900ed8b1f..72009fa43 100644 --- a/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts +++ b/packages/server/src/modules/InventoryAdjutments/models/InventoryAdjustmentEntry.ts @@ -20,6 +20,13 @@ export class InventoryAdjustmentEntry extends BaseModel { return 'inventory_adjustments_entries'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Relationship mapping. */ diff --git a/packages/server/src/modules/InventoryCost/models/InventoryTransactionMeta.ts b/packages/server/src/modules/InventoryCost/models/InventoryTransactionMeta.ts index 30041855f..1da927d24 100644 --- a/packages/server/src/modules/InventoryCost/models/InventoryTransactionMeta.ts +++ b/packages/server/src/modules/InventoryCost/models/InventoryTransactionMeta.ts @@ -13,6 +13,13 @@ export class InventoryTransactionMeta extends BaseModel { return 'inventory_transaction_meta'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Relationship mapping. */ diff --git a/packages/server/src/modules/Items/models/Item.ts b/packages/server/src/modules/Items/models/Item.ts index 2d0e5fb9a..db8e0d965 100644 --- a/packages/server/src/modules/Items/models/Item.ts +++ b/packages/server/src/modules/Items/models/Item.ts @@ -44,6 +44,13 @@ export class Item extends TenantBaseModel { return 'items'; } + /** + * Timestamps columns. + */ + get timestamps() { + return ['createdAt', 'updatedAt']; + } + /** * Model modifiers. */ diff --git a/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts index 55edd254e..7a517e289 100644 --- a/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts +++ b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts @@ -43,7 +43,7 @@ export class PaymentReceived extends TenantBaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/Roles/models/Role.model.ts b/packages/server/src/modules/Roles/models/Role.model.ts index f9a5b1641..3ea987e4f 100644 --- a/packages/server/src/modules/Roles/models/Role.model.ts +++ b/packages/server/src/modules/Roles/models/Role.model.ts @@ -16,6 +16,13 @@ export class Role extends TenantBaseModel { return 'roles'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Relationship mapping. */ diff --git a/packages/server/src/modules/Roles/models/RolePermission.model.ts b/packages/server/src/modules/Roles/models/RolePermission.model.ts index 1f82b4fcc..1bd6dc313 100644 --- a/packages/server/src/modules/Roles/models/RolePermission.model.ts +++ b/packages/server/src/modules/Roles/models/RolePermission.model.ts @@ -13,6 +13,13 @@ export class RolePermission extends TenantBaseModel { return 'role_permissions'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Relationship mapping. */ diff --git a/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts b/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts index bf2168d0e..d827f20c1 100644 --- a/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts +++ b/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts @@ -74,7 +74,7 @@ export class SaleInvoice extends TenantBaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts b/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts index 87a840369..20fb18e09 100644 --- a/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts +++ b/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts @@ -72,7 +72,7 @@ export class SaleReceipt extends ExtendedModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/Settings/models/Setting.ts b/packages/server/src/modules/Settings/models/Setting.ts index ace76f31f..1dd0c016a 100644 --- a/packages/server/src/modules/Settings/models/Setting.ts +++ b/packages/server/src/modules/Settings/models/Setting.ts @@ -10,6 +10,10 @@ export class Setting extends BaseModel { return 'settings'; } + get timestamps() { + return []; + } + /** * Extra metadata query to query with the current authenticate user. * @param {Object} query diff --git a/packages/server/src/modules/System/models/TenantMetadataModel.ts b/packages/server/src/modules/System/models/TenantMetadataModel.ts index 22c0723f0..b16e6b61f 100644 --- a/packages/server/src/modules/System/models/TenantMetadataModel.ts +++ b/packages/server/src/modules/System/models/TenantMetadataModel.ts @@ -50,6 +50,13 @@ export class TenantMetadata extends BaseModel { */ static tableName = 'tenants_metadata'; + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Virtual attributes. */ diff --git a/packages/server/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts b/packages/server/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts index 3cc272fc4..619cd96d0 100644 --- a/packages/server/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts +++ b/packages/server/src/modules/Tenancy/TenancyModels/models/TenantUser.model.ts @@ -24,7 +24,7 @@ export class TenantUser extends TenantBaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/TransactionItemEntry/models/ItemEntry.ts b/packages/server/src/modules/TransactionItemEntry/models/ItemEntry.ts index 73b5fba37..5ce0268d1 100644 --- a/packages/server/src/modules/TransactionItemEntry/models/ItemEntry.ts +++ b/packages/server/src/modules/TransactionItemEntry/models/ItemEntry.ts @@ -53,7 +53,7 @@ export class ItemEntry extends BaseModel { * @returns {string[]} */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts b/packages/server/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts index 2a4ab9769..36f2a1af9 100644 --- a/packages/server/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts +++ b/packages/server/src/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill.ts @@ -26,7 +26,7 @@ export class VendorCreditAppliedBill extends BaseModel { * Timestamps columns. */ public get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts b/packages/server/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts index aabc2e48e..e3013994a 100644 --- a/packages/server/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts +++ b/packages/server/src/modules/VendorCreditsRefund/models/RefundVendorCredit.ts @@ -32,7 +32,7 @@ export class RefundVendorCredit extends BaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /* diff --git a/packages/server/src/modules/Views/models/ViewColumn.model.ts b/packages/server/src/modules/Views/models/ViewColumn.model.ts index 7a7b5c1a0..b93a5e619 100644 --- a/packages/server/src/modules/Views/models/ViewColumn.model.ts +++ b/packages/server/src/modules/Views/models/ViewColumn.model.ts @@ -8,6 +8,13 @@ export class ViewColumn extends BaseModel { return 'view_has_columns'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Relationship mapping. */ diff --git a/packages/server/src/modules/Views/models/ViewRole.model.ts b/packages/server/src/modules/Views/models/ViewRole.model.ts index 7af0a8f1a..0d6f3d024 100644 --- a/packages/server/src/modules/Views/models/ViewRole.model.ts +++ b/packages/server/src/modules/Views/models/ViewRole.model.ts @@ -25,6 +25,13 @@ export class ViewRole extends BaseModel { return 'view_roles'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Relationship mapping. */ diff --git a/packages/server/src/modules/Warehouses/models/ItemWarehouseQuantity.ts b/packages/server/src/modules/Warehouses/models/ItemWarehouseQuantity.ts index 5ff763dd3..8640e1bd3 100644 --- a/packages/server/src/modules/Warehouses/models/ItemWarehouseQuantity.ts +++ b/packages/server/src/modules/Warehouses/models/ItemWarehouseQuantity.ts @@ -9,6 +9,13 @@ export class ItemWarehouseQuantity extends BaseModel{ return 'items_warehouses_quantity'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Relation mappings. */ diff --git a/packages/server/src/modules/Warehouses/models/Warehouse.model.ts b/packages/server/src/modules/Warehouses/models/Warehouse.model.ts index b0b9683bf..be51d687b 100644 --- a/packages/server/src/modules/Warehouses/models/Warehouse.model.ts +++ b/packages/server/src/modules/Warehouses/models/Warehouse.model.ts @@ -24,7 +24,7 @@ export class Warehouse extends BaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts b/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts index 3146b91c1..071821a69 100644 --- a/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts +++ b/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransfer.ts @@ -28,7 +28,7 @@ export class WarehouseTransfer extends TenantBaseModel { * Timestamps columns. */ get timestamps() { - return ['created_at', 'updated_at']; + return ['createdAt', 'updatedAt']; } /** diff --git a/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts b/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts index 894bffcfb..7acfc3155 100644 --- a/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts +++ b/packages/server/src/modules/WarehousesTransfers/models/WarehouseTransferEntry.ts @@ -19,6 +19,13 @@ export class WarehouseTransferEntry extends TenantBaseModel { return 'warehouses_transfers_entries'; } + /** + * Timestamps columns. + */ + get timestamps() { + return []; + } + /** * Virtual attributes. */