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 <noreply@anthropic.com>
This commit is contained in:
Ahmed Bouhuolia
2026-02-26 05:57:55 +02:00
parent 12eb8c32dc
commit ad252d2e4a
28 changed files with 139 additions and 16 deletions

View File

@@ -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<M extends Model> {
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;

View File

@@ -0,0 +1,40 @@
import * as moment from 'moment';
import { Model } from 'objection';
type Constructor<T = {}> = new (...args: any[]) => T;
export const withDateSessionMixin = <T extends Constructor<Model>>(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');
}
});
}
}
}