mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14:20:31 +00:00
feat: deleteIfNoRelations
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
export class ModelHasRelationsError extends Error {
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
constructor(type: string = 'ModelHasRelations', message?: string) {
|
||||||
|
message = message || `Entity has relations`;
|
||||||
|
super(message);
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import {
|
||||||
|
ExceptionFilter,
|
||||||
|
Catch,
|
||||||
|
ArgumentsHost,
|
||||||
|
HttpStatus,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { Response } from 'express';
|
||||||
|
import { ModelHasRelationsError } from '../exceptions/ModelHasRelations.exception';
|
||||||
|
|
||||||
|
@Catch(ModelHasRelationsError)
|
||||||
|
export class ModelHasRelationsFilter implements ExceptionFilter {
|
||||||
|
catch(exception: ModelHasRelationsError, host: ArgumentsHost) {
|
||||||
|
const ctx = host.switchToHttp();
|
||||||
|
const response = ctx.getResponse<Response>();
|
||||||
|
const status = HttpStatus.CONFLICT;
|
||||||
|
|
||||||
|
response.status(status).json({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
statusCode: status,
|
||||||
|
type: exception.type || 'MODEL_HAS_RELATIONS',
|
||||||
|
message: exception.message,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
7
packages/server/src/common/types/Objection.d.ts
vendored
Normal file
7
packages/server/src/common/types/Objection.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { QueryBuilder, Model } from 'objection';
|
||||||
|
|
||||||
|
declare module 'objection' {
|
||||||
|
interface QueryBuilder<M extends Model, R = M[]> {
|
||||||
|
deleteIfNoRelations(this: QueryBuilder<M, R>, ...args: any[]): Promise<any>;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import * as path from 'path';
|
|||||||
import './utils/moment-mysql';
|
import './utils/moment-mysql';
|
||||||
import { AppModule } from './modules/App/App.module';
|
import { AppModule } from './modules/App/App.module';
|
||||||
import { ServiceErrorFilter } from './common/filters/service-error.filter';
|
import { ServiceErrorFilter } from './common/filters/service-error.filter';
|
||||||
|
import { ModelHasRelationsFilter } from './common/filters/model-has-relations.filter';
|
||||||
import { ValidationPipe } from './common/pipes/ClassValidation.pipe';
|
import { ValidationPipe } from './common/pipes/ClassValidation.pipe';
|
||||||
import { ToJsonInterceptor } from './common/interceptors/to-json.interceptor';
|
import { ToJsonInterceptor } from './common/interceptors/to-json.interceptor';
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ async function bootstrap() {
|
|||||||
SwaggerModule.setup('swagger', app, documentFactory);
|
SwaggerModule.setup('swagger', app, documentFactory);
|
||||||
|
|
||||||
app.useGlobalFilters(new ServiceErrorFilter());
|
app.useGlobalFilters(new ServiceErrorFilter());
|
||||||
|
app.useGlobalFilters(new ModelHasRelationsFilter());
|
||||||
|
|
||||||
await app.listen(process.env.PORT ?? 3000);
|
await app.listen(process.env.PORT ?? 3000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { QueryBuilder, Model } from 'objection';
|
import { QueryBuilder, Model } from 'objection';
|
||||||
|
import { ModelHasRelationsError } from '@/common/exceptions/ModelHasRelations.exception';
|
||||||
|
|
||||||
interface PaginationResult<M extends Model> {
|
interface PaginationResult<M extends Model> {
|
||||||
results: M[];
|
results: M[];
|
||||||
@@ -32,15 +33,44 @@ export class PaginationQueryBuilder<
|
|||||||
};
|
};
|
||||||
}) as unknown as PaginationQueryBuilderType<M>;
|
}) as unknown as PaginationQueryBuilderType<M>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteIfNoRelations({
|
||||||
|
type,
|
||||||
|
message,
|
||||||
|
}: {
|
||||||
|
type?: string;
|
||||||
|
message?: string;
|
||||||
|
}) {
|
||||||
|
const relationMappings = this.modelClass().relationMappings;
|
||||||
|
const relationNames = Object.keys(relationMappings || {});
|
||||||
|
|
||||||
|
if (relationNames.length === 0) {
|
||||||
|
// No relations defined
|
||||||
|
return this.delete();
|
||||||
|
}
|
||||||
|
const recordQuery = this.clone();
|
||||||
|
|
||||||
|
relationNames.forEach((relationName: string) => {
|
||||||
|
recordQuery.withGraphFetched(relationName);
|
||||||
|
});
|
||||||
|
const record = await recordQuery;
|
||||||
|
|
||||||
|
const hasRelations = relationNames.some((name) => {
|
||||||
|
const val = record[name];
|
||||||
|
return Array.isArray(val) ? val.length > 0 : val != null;
|
||||||
|
});
|
||||||
|
if (!hasRelations) {
|
||||||
|
return this.clone().delete();
|
||||||
|
} else {
|
||||||
|
throw new ModelHasRelationsError(type, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New BaseQueryBuilder extending PaginationQueryBuilder
|
|
||||||
export class BaseQueryBuilder<
|
export class BaseQueryBuilder<
|
||||||
M extends Model,
|
M extends Model,
|
||||||
R = M[],
|
R = M[],
|
||||||
> extends PaginationQueryBuilder<M, R> {
|
> extends PaginationQueryBuilder<M, R> {
|
||||||
// You can add more shared query methods here in the future
|
|
||||||
|
|
||||||
changeAmount(whereAttributes, attribute, amount) {
|
changeAmount(whereAttributes, attribute, amount) {
|
||||||
const changeMethod = amount > 0 ? 'increment' : 'decrement';
|
const changeMethod = amount > 0 ? 'increment' : 'decrement';
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,6 @@ export class DeleteBranchService {
|
|||||||
.query()
|
.query()
|
||||||
.findById(branchId)
|
.findById(branchId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
// .queryAndThrowIfHasRelations({
|
|
||||||
// type: ERRORS.BRANCH_HAS_ASSOCIATED_TRANSACTIONS,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Authorize the branch before deleting.
|
// Authorize the branch before deleting.
|
||||||
await this.authorize(branchId);
|
await this.authorize(branchId);
|
||||||
@@ -54,8 +51,10 @@ export class DeleteBranchService {
|
|||||||
trx,
|
trx,
|
||||||
} as IBranchDeletePayload);
|
} as IBranchDeletePayload);
|
||||||
|
|
||||||
await this.branchModel().query().findById(branchId).delete();
|
await this.branchModel().query().findById(branchId).deleteIfNoRelations({
|
||||||
|
type: ERRORS.BRANCH_HAS_ASSOCIATED_TRANSACTIONS,
|
||||||
|
message: 'Branch has associated transactions',
|
||||||
|
});
|
||||||
// Triggers `onBranchCreate` event.
|
// Triggers `onBranchCreate` event.
|
||||||
await this.eventPublisher.emitAsync(events.warehouse.onEdited, {
|
await this.eventPublisher.emitAsync(events.warehouse.onEdited, {
|
||||||
oldBranch,
|
oldBranch,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
|||||||
import { Customer } from '../models/Customer';
|
import { Customer } from '../models/Customer';
|
||||||
import { events } from '@/common/events/events';
|
import { events } from '@/common/events/events';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
|
import { ERRORS } from '../constants';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeleteCustomer {
|
export class DeleteCustomer {
|
||||||
@@ -36,9 +37,6 @@ export class DeleteCustomer {
|
|||||||
.query()
|
.query()
|
||||||
.findById(customerId)
|
.findById(customerId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
// .queryAndThrowIfHasRelations({
|
|
||||||
// type: ERRORS.CUSTOMER_HAS_TRANSACTIONS,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Triggers `onCustomerDeleting` event.
|
// Triggers `onCustomerDeleting` event.
|
||||||
await this.eventPublisher.emitAsync(events.customers.onDeleting, {
|
await this.eventPublisher.emitAsync(events.customers.onDeleting, {
|
||||||
@@ -49,8 +47,13 @@ export class DeleteCustomer {
|
|||||||
// Deletes the customer and associated entities under UOW transaction.
|
// Deletes the customer and associated entities under UOW transaction.
|
||||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||||
// Delete the customer from the storage.
|
// Delete the customer from the storage.
|
||||||
await this.customerModel().query(trx).findById(customerId).delete();
|
await this.customerModel()
|
||||||
|
.query(trx)
|
||||||
|
.findById(customerId)
|
||||||
|
.deleteIfNoRelations({
|
||||||
|
type: ERRORS.CUSTOMER_HAS_TRANSACTIONS,
|
||||||
|
message: 'Customer has associated transactions',
|
||||||
|
});
|
||||||
// Throws `onCustomerDeleted` event.
|
// Throws `onCustomerDeleted` event.
|
||||||
await this.eventPublisher.emitAsync(events.customers.onDeleted, {
|
await this.eventPublisher.emitAsync(events.customers.onDeleted, {
|
||||||
customerId,
|
customerId,
|
||||||
|
|||||||
@@ -39,11 +39,8 @@ export class DeleteItemService {
|
|||||||
// Retrieve the given item or throw not found service error.
|
// Retrieve the given item or throw not found service error.
|
||||||
const oldItem = await this.itemModel()
|
const oldItem = await this.itemModel()
|
||||||
.query()
|
.query()
|
||||||
.findById(itemId)
|
.findOne('id', itemId)
|
||||||
.throwIfNotFound();
|
.deleteIfNoRelations();
|
||||||
// .queryAndThrowIfHasRelations({
|
|
||||||
// type: ERRORS.ITEM_HAS_ASSOCIATED_TRANSACTIONS,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Delete item in unit of work.
|
// Delete item in unit of work.
|
||||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
IVendorEventDeletingPayload,
|
IVendorEventDeletingPayload,
|
||||||
} from '../types/Vendors.types';
|
} from '../types/Vendors.types';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
|
import { ERRORS } from '../constants';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeleteVendorService {
|
export class DeleteVendorService {
|
||||||
@@ -34,9 +35,6 @@ export class DeleteVendorService {
|
|||||||
.query()
|
.query()
|
||||||
.findById(vendorId)
|
.findById(vendorId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
// .queryAndThrowIfHasRelations({
|
|
||||||
// type: ERRORS.VENDOR_HAS_TRANSACTIONS,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Triggers `onVendorDeleting` event.
|
// Triggers `onVendorDeleting` event.
|
||||||
await this.eventPublisher.emitAsync(events.vendors.onDeleting, {
|
await this.eventPublisher.emitAsync(events.vendors.onDeleting, {
|
||||||
@@ -47,8 +45,13 @@ export class DeleteVendorService {
|
|||||||
// Deletes vendor contact under unit-of-work.
|
// Deletes vendor contact under unit-of-work.
|
||||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||||
// Deletes the vendor contact from the storage.
|
// Deletes the vendor contact from the storage.
|
||||||
await this.vendorModel().query(trx).findById(vendorId).delete();
|
await this.vendorModel()
|
||||||
|
.query(trx)
|
||||||
|
.findById(vendorId)
|
||||||
|
.deleteIfNoRelations({
|
||||||
|
type: ERRORS.VENDOR_HAS_TRANSACTIONS,
|
||||||
|
message: 'Vendor has associated transactions',
|
||||||
|
});
|
||||||
// Triggers `onVendorDeleted` event.
|
// Triggers `onVendorDeleted` event.
|
||||||
await this.eventPublisher.emitAsync(events.vendors.onDeleted, {
|
await this.eventPublisher.emitAsync(events.vendors.onDeleted, {
|
||||||
vendorId,
|
vendorId,
|
||||||
|
|||||||
@@ -49,9 +49,6 @@ export class DeleteWarehouseService {
|
|||||||
.query()
|
.query()
|
||||||
.findById(warehouseId)
|
.findById(warehouseId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
// .queryAndThrowIfHasRelations({
|
|
||||||
// type: ERRORS.WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Validates the given warehouse before deleting.
|
// Validates the given warehouse before deleting.
|
||||||
await this.authorize(warehouseId);
|
await this.authorize(warehouseId);
|
||||||
@@ -70,8 +67,13 @@ export class DeleteWarehouseService {
|
|||||||
eventPayload,
|
eventPayload,
|
||||||
);
|
);
|
||||||
// Deletes the given warehouse from the storage.
|
// Deletes the given warehouse from the storage.
|
||||||
await this.warehouseModel().query().findById(warehouseId).delete();
|
await this.warehouseModel()
|
||||||
|
.query()
|
||||||
|
.findById(warehouseId)
|
||||||
|
.deleteIfNoRelations({
|
||||||
|
type: ERRORS.WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS,
|
||||||
|
message: 'Warehouse has associated transactions',
|
||||||
|
});
|
||||||
// Triggers `onWarehouseCreated`.
|
// Triggers `onWarehouseCreated`.
|
||||||
await this.eventPublisher.emitAsync(
|
await this.eventPublisher.emitAsync(
|
||||||
events.warehouse.onDeleted,
|
events.warehouse.onDeleted,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// import { Model } from 'objection';
|
// import { Model } from 'objection';
|
||||||
import { BaseModel } from '@/models/Model';
|
import { BaseModel, BaseQueryBuilder } from '@/models/Model';
|
||||||
import { Item } from '@/modules/Items/models/Item';
|
import { Item } from '@/modules/Items/models/Item';
|
||||||
|
import { Model } from 'objection';
|
||||||
|
|
||||||
export class Warehouse extends BaseModel {
|
export class Warehouse extends BaseModel {
|
||||||
name!: string;
|
name!: string;
|
||||||
@@ -45,128 +46,134 @@ export class Warehouse extends BaseModel {
|
|||||||
/**
|
/**
|
||||||
* Relationship mapping.
|
* Relationship mapping.
|
||||||
*/
|
*/
|
||||||
// static get relationMappings() {
|
static get relationMappings() {
|
||||||
// const SaleInvoice = require('models/SaleInvoice');
|
const { SaleInvoice } = require('../../SaleInvoices/models/SaleInvoice');
|
||||||
// const SaleEstimate = require('models/SaleEstimate');
|
const { SaleEstimate } = require('../../SaleEstimates/models/SaleEstimate');
|
||||||
// const SaleReceipt = require('models/SaleReceipt');
|
const { SaleReceipt } = require('../../SaleReceipts/models/SaleReceipt');
|
||||||
// const Bill = require('models/Bill');
|
const { Bill } = require('../../Bills/models/Bill');
|
||||||
// const VendorCredit = require('models/VendorCredit');
|
const { VendorCredit } = require('../../VendorCredit/models/VendorCredit');
|
||||||
// const CreditNote = require('models/CreditNote');
|
const { CreditNote } = require('../../CreditNotes/models/CreditNote');
|
||||||
// const InventoryTransaction = require('models/InventoryTransaction');
|
const {
|
||||||
// const WarehouseTransfer = require('models/WarehouseTransfer');
|
InventoryTransaction,
|
||||||
// const InventoryAdjustment = require('models/InventoryAdjustment');
|
} = require('../../InventoryCost/models/InventoryTransaction');
|
||||||
|
const {
|
||||||
|
WarehouseTransfer,
|
||||||
|
} = require('../../WarehousesTransfers/models/WarehouseTransfer');
|
||||||
|
const {
|
||||||
|
InventoryAdjustment,
|
||||||
|
} = require('../../InventoryAdjutments/models/InventoryAdjustment');
|
||||||
|
|
||||||
// return {
|
return {
|
||||||
// /**
|
/**
|
||||||
// * Warehouse may belongs to associated sale invoices.
|
* Warehouse may belongs to associated sale invoices.
|
||||||
// */
|
*/
|
||||||
// invoices: {
|
invoices: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: SaleInvoice.default,
|
modelClass: SaleInvoice,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'sales_invoices.warehouseId',
|
to: 'sales_invoices.warehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Warehouse may belongs to associated sale estimates.
|
* Warehouse may belongs to associated sale estimates.
|
||||||
// */
|
*/
|
||||||
// estimates: {
|
estimates: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: SaleEstimate.default,
|
modelClass: SaleEstimate,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'sales_estimates.warehouseId',
|
to: 'sales_estimates.warehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Warehouse may belongs to associated sale receipts.
|
* Warehouse may belongs to associated sale receipts.
|
||||||
// */
|
*/
|
||||||
// receipts: {
|
receipts: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: SaleReceipt.default,
|
modelClass: SaleReceipt,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'sales_receipts.warehouseId',
|
to: 'sales_receipts.warehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Warehouse may belongs to associated bills.
|
* Warehouse may belongs to associated bills.
|
||||||
// */
|
*/
|
||||||
// bills: {
|
bills: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: Bill.default,
|
modelClass: Bill,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'bills.warehouseId',
|
to: 'bills.warehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Warehouse may belongs to associated credit notes.
|
* Warehouse may belongs to associated credit notes.
|
||||||
// */
|
*/
|
||||||
// creditNotes: {
|
creditNotes: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: CreditNote.default,
|
modelClass: CreditNote,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'credit_notes.warehouseId',
|
to: 'credit_notes.warehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Warehouse may belongs to associated to vendor credits.
|
* Warehouse may belongs to associated to vendor credits.
|
||||||
// */
|
*/
|
||||||
// vendorCredit: {
|
vendorCredit: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: VendorCredit.default,
|
modelClass: VendorCredit,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'vendor_credits.warehouseId',
|
to: 'vendor_credits.warehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Warehouse may belongs to associated to inventory transactions.
|
* Warehouse may belongs to associated to inventory transactions.
|
||||||
// */
|
*/
|
||||||
// inventoryTransactions: {
|
inventoryTransactions: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: InventoryTransaction.default,
|
modelClass: InventoryTransaction,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'inventory_transactions.warehouseId',
|
to: 'inventory_transactions.warehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// warehouseTransferTo: {
|
warehouseTransferTo: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: WarehouseTransfer.default,
|
modelClass: WarehouseTransfer,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'warehouses_transfers.toWarehouseId',
|
to: 'warehouses_transfers.toWarehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// warehouseTransferFrom: {
|
warehouseTransferFrom: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: WarehouseTransfer.default,
|
modelClass: WarehouseTransfer,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'warehouses_transfers.fromWarehouseId',
|
to: 'warehouses_transfers.fromWarehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
// inventoryAdjustment: {
|
inventoryAdjustment: {
|
||||||
// relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
// modelClass: InventoryAdjustment.default,
|
modelClass: InventoryAdjustment,
|
||||||
// join: {
|
join: {
|
||||||
// from: 'warehouses.id',
|
from: 'warehouses.id',
|
||||||
// to: 'inventory_adjustments.warehouseId',
|
to: 'inventory_adjustments.warehouseId',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user