From 8a12caf48d37d2108d24e321e54efa21fc6eaabe Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sat, 21 Dec 2024 15:07:01 +0200 Subject: [PATCH] refactor: warehouses to nestjs --- packages/server-nest/src/interfaces/Item.ts | 10 +-- .../server-nest/src/modules/App/App.module.ts | 2 + .../modules/Branches/Branches.controller.ts | 2 + .../src/modules/Branches/Branches.module.ts | 4 ++ .../src/modules/Branches/Branches.types.ts | 16 ++--- .../Branches/BranchesApplication.service.ts | 4 +- .../src/modules/Branches/BranchesSettings.ts | 26 +++---- .../ActivateBranchesFeature.service.ts | 4 +- .../Branches/commands/CreateBranch.service.ts | 7 +- .../Branches/commands/DeleteBranch.service.ts | 10 +-- .../Branches/commands/EditBranch.service.ts | 3 +- .../modules/Branches/models/Branch.model.ts | 14 ++-- .../Branches/subscribers/Validators/index.ts | 30 ++++---- .../src/modules/Items/ActivateItem.service.ts | 4 +- .../src/modules/Items/DeleteItem.service.ts | 9 ++- .../src/modules/Items/models/Item.ts | 3 + .../PdfTemplate/PdfTemplate.application.ts | 2 +- .../Tenancy/TenancyModels/Tenancy.module.ts | 8 ++- .../src/modules/Warehouses/Warehouse.types.ts | 1 - .../Warehouses/Warehouses.controller.ts | 64 +++++++++++++++++ .../modules/Warehouses/Warehouses.module.ts | 41 +++++++++++ .../WarehousesApplication.service.ts | 7 +- ...ouses.ts => ActivateWarehouses.service.ts} | 0 .../commands/DeleteWarehouse.service.ts | 8 +-- .../commands/EditWarehouse.service.ts | 2 +- .../commands/WarehouseMarkPrimary.service.ts | 3 +- .../Warehouses/models/Warehouse.model.ts | 22 +++--- .../server-nest/test/branches.e2e-spec.ts | 71 +++++++++++++++++++ .../server-nest/test/warehouses.e2e-spec.ts | 71 +++++++++++++++++++ 29 files changed, 348 insertions(+), 100 deletions(-) create mode 100644 packages/server-nest/src/modules/Warehouses/Warehouses.controller.ts create mode 100644 packages/server-nest/src/modules/Warehouses/Warehouses.module.ts rename packages/server-nest/src/modules/Warehouses/commands/{ActivateWarehouses.ts => ActivateWarehouses.service.ts} (100%) create mode 100644 packages/server-nest/test/branches.e2e-spec.ts create mode 100644 packages/server-nest/test/warehouses.e2e-spec.ts diff --git a/packages/server-nest/src/interfaces/Item.ts b/packages/server-nest/src/interfaces/Item.ts index 9f1e140cc..63816bdff 100644 --- a/packages/server-nest/src/interfaces/Item.ts +++ b/packages/server-nest/src/interfaces/Item.ts @@ -129,7 +129,7 @@ export interface IItemEditDTO extends IItemDTO {} // } export interface IItemEventCreatedPayload { - tenantId: number; + // tenantId: number; item: Item; itemId: number; trx: Knex.Transaction; @@ -143,15 +143,15 @@ export interface IItemEventEditedPayload { } export interface IItemEventDeletingPayload { - tenantId: number; + // tenantId: number; trx: Knex.Transaction; - oldItem: IItem; + oldItem: Item; } export interface IItemEventDeletedPayload { - tenantId: number; - oldItem: IItem; + // tenantId: number; itemId: number; + oldItem: Item; trx: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/App/App.module.ts b/packages/server-nest/src/modules/App/App.module.ts index 2f4f05022..c3483075f 100644 --- a/packages/server-nest/src/modules/App/App.module.ts +++ b/packages/server-nest/src/modules/App/App.module.ts @@ -37,6 +37,7 @@ import { ItemCategoryModule } from '../ItemCategories/ItemCategory.module'; import { TaxRatesModule } from '../TaxRates/TaxRate.module'; import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module'; import { BranchesModule } from '../Branches/Branches.module'; +import { WarehousesModule } from '../Warehouses/Warehouses.module'; @Module({ imports: [ @@ -97,6 +98,7 @@ import { BranchesModule } from '../Branches/Branches.module'; TaxRatesModule, PdfTemplatesModule, BranchesModule, + WarehousesModule, ], controllers: [AppController], providers: [ diff --git a/packages/server-nest/src/modules/Branches/Branches.controller.ts b/packages/server-nest/src/modules/Branches/Branches.controller.ts index 7b22da837..2df419591 100644 --- a/packages/server-nest/src/modules/Branches/Branches.controller.ts +++ b/packages/server-nest/src/modules/Branches/Branches.controller.ts @@ -9,8 +9,10 @@ import { } from '@nestjs/common'; import { BranchesApplication } from './BranchesApplication.service'; import { ICreateBranchDTO, IEditBranchDTO } from './Branches.types'; +import { PublicRoute } from '../Auth/Jwt.guard'; @Controller('branches') +@PublicRoute() export class BranchesController { constructor(private readonly branchesApplication: BranchesApplication) {} diff --git a/packages/server-nest/src/modules/Branches/Branches.module.ts b/packages/server-nest/src/modules/Branches/Branches.module.ts index d60a124d6..7f8b2fe0d 100644 --- a/packages/server-nest/src/modules/Branches/Branches.module.ts +++ b/packages/server-nest/src/modules/Branches/Branches.module.ts @@ -11,6 +11,8 @@ import { GetBranchService } from './queries/GetBranch.service'; import { GetBranchesService } from './queries/GetBranches.service'; import { ActivateBranches } from './commands/ActivateBranchesFeature.service'; import { BranchesApplication } from './BranchesApplication.service'; +import { BranchesSettingsService } from './BranchesSettings'; +import { BranchCommandValidator } from './commands/BranchCommandValidator.service'; @Module({ imports: [TenancyDatabaseModule], @@ -24,8 +26,10 @@ import { BranchesApplication } from './BranchesApplication.service'; MarkBranchAsPrimaryService, ActivateBranches, BranchesApplication, + BranchesSettingsService, TenancyContext, TransformerInjectable, + BranchCommandValidator ], }) export class BranchesModule {} diff --git a/packages/server-nest/src/modules/Branches/Branches.types.ts b/packages/server-nest/src/modules/Branches/Branches.types.ts index 99a04d42c..5e002169f 100644 --- a/packages/server-nest/src/modules/Branches/Branches.types.ts +++ b/packages/server-nest/src/modules/Branches/Branches.types.ts @@ -1,13 +1,9 @@ import { Knex } from 'knex'; - -export interface IBranch { - id?: number; -} +import { Branch } from './models/Branch.model'; export interface ICreateBranchDTO { name: string; code: string; - primary?: boolean; } export interface IEditBranchDTO { @@ -15,7 +11,7 @@ export interface IEditBranchDTO { } export interface IBranchCreatePayload { - tenantId: number; + // tenantId: number; createBranchDTO: ICreateBranchDTO; trx: Knex.Transaction; } @@ -33,18 +29,18 @@ export interface IBranchesActivatePayload { } export interface IBranchesActivatedPayload { // tenantId: number; - primaryBranch: IBranch; + primaryBranch: Branch; trx: Knex.Transaction; } export interface IBranchMarkAsPrimaryPayload { // tenantId: number; - oldBranch: IBranch; + oldBranch: Branch; trx: Knex.Transaction; } export interface IBranchMarkedAsPrimaryPayload { // tenantId: number; - oldBranch: IBranch; - markedBranch: IBranch; + oldBranch: Branch; + markedBranch: Branch; trx: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/Branches/BranchesApplication.service.ts b/packages/server-nest/src/modules/Branches/BranchesApplication.service.ts index f474eb7fd..1d012c2bf 100644 --- a/packages/server-nest/src/modules/Branches/BranchesApplication.service.ts +++ b/packages/server-nest/src/modules/Branches/BranchesApplication.service.ts @@ -1,4 +1,4 @@ -import { IBranch, ICreateBranchDTO, IEditBranchDTO } from './Branches.types'; +import { ICreateBranchDTO, IEditBranchDTO } from './Branches.types'; import { ActivateBranches } from './commands/ActivateBranchesFeature.service'; import { CreateBranchService, @@ -39,7 +39,7 @@ export class BranchesApplication { * @param {number} branchId - Branch id. * @returns {Promise} */ - public getBranch = (branchId: number): Promise => { + public getBranch = (branchId: number): Promise => { return this.getBranchService.getBranch(branchId); }; diff --git a/packages/server-nest/src/modules/Branches/BranchesSettings.ts b/packages/server-nest/src/modules/Branches/BranchesSettings.ts index ee1d6c1b9..e21ad895a 100644 --- a/packages/server-nest/src/modules/Branches/BranchesSettings.ts +++ b/packages/server-nest/src/modules/Branches/BranchesSettings.ts @@ -1,29 +1,23 @@ -import { Service, Inject } from 'typedi'; -import { Features } from '@/interfaces'; -import HasTenancyService from '@/services/Tenancy/TenancyService'; - -@Service() -export class BranchesSettings { - @Inject() - private tenancy: HasTenancyService; +import { Injectable } from '@nestjs/common'; +@Injectable() +export class BranchesSettingsService { /** * Marks multi-branches as activated. - * @param {number} tenantId - */ - public markMultiBranchesAsActivated = (tenantId: number) => { - const settings = this.tenancy.settings(tenantId); + public markMultiBranchesAsActivated = () => { + // const settings = this.tenancy.settings(tenantId); - settings.set({ group: 'features', key: Features.BRANCHES, value: 1 }); + // settings.set({ group: 'features', key: Features.BRANCHES, value: 1 }); }; /** * Retrieves whether multi-branches is active. - * @param {number} tenantId */ - public isMultiBranchesActive = (tenantId: number) => { - const settings = this.tenancy.settings(tenantId); + public isMultiBranchesActive = () => { + // const settings = this.tenancy.settings(tenantId); - return settings.get({ group: 'features', key: Features.BRANCHES }); + // return settings.get({ group: 'features', key: Features.BRANCHES }); + return false; }; } diff --git a/packages/server-nest/src/modules/Branches/commands/ActivateBranchesFeature.service.ts b/packages/server-nest/src/modules/Branches/commands/ActivateBranchesFeature.service.ts index a31060e90..617ae61ef 100644 --- a/packages/server-nest/src/modules/Branches/commands/ActivateBranchesFeature.service.ts +++ b/packages/server-nest/src/modules/Branches/commands/ActivateBranchesFeature.service.ts @@ -8,7 +8,7 @@ import { IBranchesActivatePayload, } from '../Branches.types'; import { CreateBranchService } from './CreateBranch.service'; -import { BranchesSettings } from '../BranchesSettings'; +import { BranchesSettingsService } from '../BranchesSettings'; import { ServiceError } from '@/modules/Items/ServiceError'; import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service'; import { Branch } from '../models/Branch.model'; @@ -20,7 +20,7 @@ export class ActivateBranches { private readonly uow: UnitOfWork, private readonly eventPublisher: EventEmitter2, private readonly createBranch: CreateBranchService, - private readonly branchesSettings: BranchesSettings, + private readonly branchesSettings: BranchesSettingsService, private readonly i18n: I18nService, @Inject(Branch.name) diff --git a/packages/server-nest/src/modules/Branches/commands/CreateBranch.service.ts b/packages/server-nest/src/modules/Branches/commands/CreateBranch.service.ts index 140994177..94b3824ae 100644 --- a/packages/server-nest/src/modules/Branches/commands/CreateBranch.service.ts +++ b/packages/server-nest/src/modules/Branches/commands/CreateBranch.service.ts @@ -5,7 +5,6 @@ import { IBranchCreatePayload, ICreateBranchDTO, } from '../Branches.types'; -import { BranchCommandValidator } from './BranchCommandValidator.service'; import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { Branch } from '../models/Branch.model'; @@ -13,10 +12,14 @@ import { events } from '@/common/events/events'; @Injectable() export class CreateBranchService { + /** + * @param {UnitOfWork} uow - Unit of Work for tenant database transactions. + * @param {EventEmitter2} eventPublisher - Event emitter for publishing branch creation events. + * @param {typeof Branch} branchModel - The Branch model class for database operations. + */ constructor( private readonly uow: UnitOfWork, private readonly eventPublisher: EventEmitter2, - private readonly validator: BranchCommandValidator, @Inject(Branch.name) private readonly branchModel: typeof Branch, diff --git a/packages/server-nest/src/modules/Branches/commands/DeleteBranch.service.ts b/packages/server-nest/src/modules/Branches/commands/DeleteBranch.service.ts index e55bb70f2..9af1293fa 100644 --- a/packages/server-nest/src/modules/Branches/commands/DeleteBranch.service.ts +++ b/packages/server-nest/src/modules/Branches/commands/DeleteBranch.service.ts @@ -1,6 +1,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { Knex } from 'knex'; -import { IBranchDeletedPayload, IBranchDeletePayload } from './Branch.types'; +import { IBranchDeletedPayload, IBranchDeletePayload } from '../Branches.types'; import { BranchCommandValidator } from './BranchCommandValidator.service'; import { ERRORS } from '../constants'; import { Branch } from '../models/Branch.model'; @@ -37,10 +37,10 @@ export class DeleteBranchService { const oldBranch = await this.branchModel .query() .findById(branchId) - .throwIfNotFound() - .queryAndThrowIfHasRelations({ - type: ERRORS.BRANCH_HAS_ASSOCIATED_TRANSACTIONS, - }); + .throwIfNotFound(); + // .queryAndThrowIfHasRelations({ + // type: ERRORS.BRANCH_HAS_ASSOCIATED_TRANSACTIONS, + // }); // Authorize the branch before deleting. await this.authorize(branchId); diff --git a/packages/server-nest/src/modules/Branches/commands/EditBranch.service.ts b/packages/server-nest/src/modules/Branches/commands/EditBranch.service.ts index fc430dd01..c4352e1c2 100644 --- a/packages/server-nest/src/modules/Branches/commands/EditBranch.service.ts +++ b/packages/server-nest/src/modules/Branches/commands/EditBranch.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { Knex } from 'knex'; import { IBranchEditedPayload, @@ -13,6 +13,7 @@ import { events } from '@/common/events/events'; @Injectable() export class EditBranchService { constructor( + @Inject(Branch.name) private readonly branchModel: typeof Branch, private readonly uow: UnitOfWork, private readonly eventPublisher: EventEmitter2, diff --git a/packages/server-nest/src/modules/Branches/models/Branch.model.ts b/packages/server-nest/src/modules/Branches/models/Branch.model.ts index a85dc7104..20f3aa593 100644 --- a/packages/server-nest/src/modules/Branches/models/Branch.model.ts +++ b/packages/server-nest/src/modules/Branches/models/Branch.model.ts @@ -1,7 +1,7 @@ -import { Model, mixin } from 'objection'; -import TenantModel from 'models/TenantModel'; -import BranchMetadata from './Branch.settings'; -import ModelSetting from './ModelSetting'; +// import { Model, mixin } from 'objection'; +// import TenantModel from 'models/TenantModel'; +// import BranchMetadata from './Branch.settings'; +// import ModelSetting from './ModelSetting'; import { BaseModel } from '@/models/Model'; export class Branch extends BaseModel{ @@ -186,7 +186,7 @@ export class Branch extends BaseModel{ /** * Model settings. */ - static get meta() { - return BranchMetadata; - } + // static get meta() { + // return BranchMetadata; + // } } diff --git a/packages/server-nest/src/modules/Branches/subscribers/Validators/index.ts b/packages/server-nest/src/modules/Branches/subscribers/Validators/index.ts index 8865dbfcb..f62b3ff7a 100644 --- a/packages/server-nest/src/modules/Branches/subscribers/Validators/index.ts +++ b/packages/server-nest/src/modules/Branches/subscribers/Validators/index.ts @@ -1,15 +1,15 @@ -export * from './BillBranchSubscriber'; -export * from './CashflowBranchDTOValidatorSubscriber'; -export * from './CreditNoteBranchesSubscriber'; -export * from './CreditNoteRefundBranchSubscriber'; -export * from './ExpenseBranchSubscriber'; -export * from './ManualJournalBranchSubscriber'; -export * from './PaymentMadeBranchSubscriber'; -export * from './PaymentReceiveBranchSubscriber'; -export * from './SaleEstimateMultiBranchesSubscriber'; -export * from './SaleReceiptBranchesSubscriber'; -export * from './VendorCreditBranchSubscriber'; -export * from './VendorCreditRefundBranchSubscriber'; -export * from './InvoiceBranchValidatorSubscriber'; -export * from './ContactOpeningBalanceBranchSubscriber'; -export * from './InventoryAdjustmentBranchValidatorSubscriber'; \ No newline at end of file +// export * from './BillBranchSubscriber'; +// export * from './CashflowBranchDTOValidatorSubscriber'; +// export * from './CreditNoteBranchesSubscriber'; +// export * from './CreditNoteRefundBranchSubscriber'; +// export * from './ExpenseBranchSubscriber'; +// export * from './ManualJournalBranchSubscriber'; +// export * from './PaymentMadeBranchSubscriber'; +// export * from './PaymentReceiveBranchSubscriber'; +// export * from './SaleEstimateMultiBranchesSubscriber'; +// export * from './SaleReceiptBranchesSubscriber'; +// export * from './VendorCreditBranchSubscriber'; +// export * from './VendorCreditRefundBranchSubscriber'; +// export * from './InvoiceBranchValidatorSubscriber'; +// export * from './ContactOpeningBalanceBranchSubscriber'; +// export * from './InventoryAdjustmentBranchValidatorSubscriber'; \ No newline at end of file diff --git a/packages/server-nest/src/modules/Items/ActivateItem.service.ts b/packages/server-nest/src/modules/Items/ActivateItem.service.ts index 10d3d78fc..8de6e529a 100644 --- a/packages/server-nest/src/modules/Items/ActivateItem.service.ts +++ b/packages/server-nest/src/modules/Items/ActivateItem.service.ts @@ -1,9 +1,9 @@ +import { Knex } from 'knex'; +import { EventEmitter2 } from '@nestjs/event-emitter'; import { Inject, Injectable } from '@nestjs/common'; import { Item } from './models/Item'; import { UnitOfWork } from '../Tenancy/TenancyDB/UnitOfWork.service'; -import { EventEmitter2 } from '@nestjs/event-emitter'; import { events } from '@/common/events/events'; -import { Knex } from 'knex'; @Injectable() export class ActivateItemService { diff --git a/packages/server-nest/src/modules/Items/DeleteItem.service.ts b/packages/server-nest/src/modules/Items/DeleteItem.service.ts index e1f51a785..8f3ac32a1 100644 --- a/packages/server-nest/src/modules/Items/DeleteItem.service.ts +++ b/packages/server-nest/src/modules/Items/DeleteItem.service.ts @@ -39,11 +39,10 @@ export class DeleteItemService { const oldItem = await this.itemModel .query() .findById(itemId) - .throwIfNotFound() - // @ts-expect-error - .queryAndThrowIfHasRelations({ - type: ERRORS.ITEM_HAS_ASSOCIATED_TRANSACTIONS, - }); + .throwIfNotFound(); + // .queryAndThrowIfHasRelations({ + // type: ERRORS.ITEM_HAS_ASSOCIATED_TRANSACTIONS, + // }); // Delete item in unit of work. return this.uow.withTransaction(async (trx: Knex.Transaction) => { diff --git a/packages/server-nest/src/modules/Items/models/Item.ts b/packages/server-nest/src/modules/Items/models/Item.ts index 045d613a7..6ee459981 100644 --- a/packages/server-nest/src/modules/Items/models/Item.ts +++ b/packages/server-nest/src/modules/Items/models/Item.ts @@ -2,6 +2,7 @@ import * as F from 'fp-ts/function'; import * as R from 'ramda'; import { SearchableModel } from '@/modules/Search/SearchableMdel'; import { BaseModel } from '@/models/Model'; +import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model'; // import { TenantModel } from '@/modules/System/models/TenantModel'; // const Extend = R.compose(SearchableModel)(TenantModel); @@ -21,6 +22,8 @@ export class Item extends BaseModel { public readonly inventoryAccountId: number; public readonly categoryId: number; + public readonly warehouse!: Warehouse; + static get tableName() { return 'items'; } diff --git a/packages/server-nest/src/modules/PdfTemplate/PdfTemplate.application.ts b/packages/server-nest/src/modules/PdfTemplate/PdfTemplate.application.ts index 459595ffa..62be396bb 100644 --- a/packages/server-nest/src/modules/PdfTemplate/PdfTemplate.application.ts +++ b/packages/server-nest/src/modules/PdfTemplate/PdfTemplate.application.ts @@ -11,8 +11,8 @@ import { GetOrganizationBrandingAttributesService } from './queries/GetOrganizat export class PdfTemplateApplication { constructor( private readonly createPdfTemplateService: CreatePdfTemplateService, - private readonly deletePdfTemplateService: DeletePdfTemplateService, private readonly getPdfTemplateService: GetPdfTemplateService, + private readonly deletePdfTemplateService: DeletePdfTemplateService, // private readonly getPdfTemplatesService: GetPdfTemplatesService, private readonly editPdfTemplateService: EditPdfTemplateService, private readonly assignPdfTemplateDefaultService: AssignPdfTemplateDefaultService, diff --git a/packages/server-nest/src/modules/Tenancy/TenancyModels/Tenancy.module.ts b/packages/server-nest/src/modules/Tenancy/TenancyModels/Tenancy.module.ts index 9829dccc3..8832e5cd2 100644 --- a/packages/server-nest/src/modules/Tenancy/TenancyModels/Tenancy.module.ts +++ b/packages/server-nest/src/modules/Tenancy/TenancyModels/Tenancy.module.ts @@ -11,6 +11,9 @@ import ExpenseCategory from '@/modules/Expenses/models/ExpenseCategory.model'; import { ItemCategory } from '@/modules/ItemCategories/models/ItemCategory.model'; import { TaxRateModel } from '@/modules/TaxRates/models/TaxRate.model'; import { PdfTemplateModel } from '@/modules/PdfTemplate/models/PdfTemplate'; +import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model'; +import { ItemWarehouseQuantity } from '@/modules/Warehouses/models/ItemWarehouseQuantity'; +import { Branch } from '@/modules/Branches/models/Branch.model'; const models = [ Item, @@ -21,7 +24,10 @@ const models = [ ExpenseCategory, ItemCategory, TaxRateModel, - PdfTemplateModel + PdfTemplateModel, + Warehouse, + ItemWarehouseQuantity, + Branch, ]; const modelProviders = models.map((model) => { diff --git a/packages/server-nest/src/modules/Warehouses/Warehouse.types.ts b/packages/server-nest/src/modules/Warehouses/Warehouse.types.ts index ca55aef8c..f00ff6b04 100644 --- a/packages/server-nest/src/modules/Warehouses/Warehouse.types.ts +++ b/packages/server-nest/src/modules/Warehouses/Warehouse.types.ts @@ -38,7 +38,6 @@ export interface ICreateWarehouseDTO { export interface IEditWarehouseDTO { name: string; code: string; - city: string; country: string; address: string; diff --git a/packages/server-nest/src/modules/Warehouses/Warehouses.controller.ts b/packages/server-nest/src/modules/Warehouses/Warehouses.controller.ts new file mode 100644 index 000000000..e24ee6b47 --- /dev/null +++ b/packages/server-nest/src/modules/Warehouses/Warehouses.controller.ts @@ -0,0 +1,64 @@ +import { + Body, + Controller, + Delete, + Get, + Param, + Post, + Put, +} from '@nestjs/common'; +import { WarehousesApplication } from './WarehousesApplication.service'; +import { ICreateWarehouseDTO, IEditWarehouseDTO } from './Warehouse.types'; +import { PublicRoute } from '../Auth/Jwt.guard'; + +@Controller('warehouses') +@PublicRoute() +export class WarehousesController { + constructor(private warehousesApplication: WarehousesApplication) {} + + @Post() + createWarehouse(@Body() createWarehouseDTO: ICreateWarehouseDTO) { + return this.warehousesApplication.createWarehouse(createWarehouseDTO); + } + + @Put(':id') + editWarehouse( + @Param('id') warehouseId: string, + @Body() editWarehouseDTO: IEditWarehouseDTO, + ) { + return this.warehousesApplication.editWarehouse( + Number(warehouseId), + editWarehouseDTO, + ); + } + + @Delete(':id') + deleteWarehouse(@Param('id') warehouseId: string) { + return this.warehousesApplication.deleteWarehouse(Number(warehouseId)); + } + + @Get(':id') + getWarehouse(@Param('id') warehouseId: string) { + return this.warehousesApplication.getWarehouse(Number(warehouseId)); + } + + @Get() + getWarehouses() { + return this.warehousesApplication.getWarehouses(); + } + + @Post('activate') + activateWarehouses() { + return this.warehousesApplication.activateWarehouses(); + } + + @Post(':id/mark-primary') + markWarehousePrimary(@Param('id') warehouseId: string) { + return this.warehousesApplication.markWarehousePrimary(Number(warehouseId)); + } + + @Get('items/:itemId') + getItemWarehouses(@Param('itemId') itemId: string) { + return this.warehousesApplication.getItemWarehouses(Number(itemId)); + } +} diff --git a/packages/server-nest/src/modules/Warehouses/Warehouses.module.ts b/packages/server-nest/src/modules/Warehouses/Warehouses.module.ts new file mode 100644 index 000000000..ebff07373 --- /dev/null +++ b/packages/server-nest/src/modules/Warehouses/Warehouses.module.ts @@ -0,0 +1,41 @@ +import { Module } from '@nestjs/common'; +import { TenancyDatabaseModule } from '../Tenancy/TenancyDB/TenancyDB.module'; +import { TenancyContext } from '../Tenancy/TenancyContext.service'; +import { TransformerInjectable } from '../Transformer/TransformerInjectable.service'; +import { CreateWarehouse } from './commands/CreateWarehouse.service'; +import { EditWarehouse } from './commands/EditWarehouse.service'; +import { DeleteWarehouseService } from './commands/DeleteWarehouse.service'; +import { WarehousesController } from './Warehouses.controller'; +import { GetWarehouse } from './queries/GetWarehouse'; +import { WarehouseMarkPrimary } from './commands/WarehouseMarkPrimary.service'; +import { GetWarehouses } from './queries/GetWarehouses'; +import { GetItemWarehouses } from './Items/GetItemWarehouses'; +import { WarehouseValidator } from './commands/WarehouseValidator.service'; +import { WarehousesApplication } from './WarehousesApplication.service'; +import { ActivateWarehousesService } from './commands/ActivateWarehouses.service'; +import { CreateInitialWarehouse } from './commands/CreateInitialWarehouse.service'; +import { WarehousesSettings } from './WarehousesSettings'; +import { I18nContext } from 'nestjs-i18n'; + +@Module({ + imports: [TenancyDatabaseModule], + controllers: [WarehousesController], + providers: [ + CreateWarehouse, + EditWarehouse, + DeleteWarehouseService, + GetWarehouse, + GetWarehouses, + GetItemWarehouses, + WarehouseMarkPrimary, + WarehouseValidator, + WarehousesApplication, + ActivateWarehousesService, + CreateInitialWarehouse, + WarehousesSettings, + I18nContext, + TenancyContext, + TransformerInjectable, + ], +}) +export class WarehousesModule {} diff --git a/packages/server-nest/src/modules/Warehouses/WarehousesApplication.service.ts b/packages/server-nest/src/modules/Warehouses/WarehousesApplication.service.ts index 22a410f8c..1ca6d0047 100644 --- a/packages/server-nest/src/modules/Warehouses/WarehousesApplication.service.ts +++ b/packages/server-nest/src/modules/Warehouses/WarehousesApplication.service.ts @@ -3,7 +3,7 @@ import { IEditWarehouseDTO, IWarehouse, } from './Warehouse.types'; -import { ActivateWarehousesService } from './commands/ActivateWarehouses'; +import { ActivateWarehousesService } from './commands/ActivateWarehouses.service'; import { CreateWarehouse } from './commands/CreateWarehouse.service'; import { DeleteWarehouseService } from './commands/DeleteWarehouse.service'; import { EditWarehouse } from './commands/EditWarehouse.service'; @@ -92,10 +92,7 @@ export class WarehousesApplication { * @param {number} tenantId - * @returns {Promise} */ - public markWarehousePrimary = ( - tenantId: number, - warehouseId: number, - ): Promise => { + public markWarehousePrimary = (warehouseId: number): Promise => { return this.markWarehousePrimaryService.markAsPrimary(warehouseId); }; diff --git a/packages/server-nest/src/modules/Warehouses/commands/ActivateWarehouses.ts b/packages/server-nest/src/modules/Warehouses/commands/ActivateWarehouses.service.ts similarity index 100% rename from packages/server-nest/src/modules/Warehouses/commands/ActivateWarehouses.ts rename to packages/server-nest/src/modules/Warehouses/commands/ActivateWarehouses.service.ts diff --git a/packages/server-nest/src/modules/Warehouses/commands/DeleteWarehouse.service.ts b/packages/server-nest/src/modules/Warehouses/commands/DeleteWarehouse.service.ts index 558e2ef9b..8a03dc127 100644 --- a/packages/server-nest/src/modules/Warehouses/commands/DeleteWarehouse.service.ts +++ b/packages/server-nest/src/modules/Warehouses/commands/DeleteWarehouse.service.ts @@ -47,10 +47,10 @@ export class DeleteWarehouseService { const oldWarehouse = await this.warehouseModel .query() .findById(warehouseId) - .throwIfNotFound() - .queryAndThrowIfHasRelations({ - type: ERRORS.WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS, - }); + .throwIfNotFound(); + // .queryAndThrowIfHasRelations({ + // type: ERRORS.WAREHOUSE_HAS_ASSOCIATED_TRANSACTIONS, + // }); // Validates the given warehouse before deleting. await this.authorize(warehouseId); diff --git a/packages/server-nest/src/modules/Warehouses/commands/EditWarehouse.service.ts b/packages/server-nest/src/modules/Warehouses/commands/EditWarehouse.service.ts index b9153a045..d8b06fd99 100644 --- a/packages/server-nest/src/modules/Warehouses/commands/EditWarehouse.service.ts +++ b/packages/server-nest/src/modules/Warehouses/commands/EditWarehouse.service.ts @@ -47,7 +47,7 @@ export class EditWarehouse { public editWarehouse = async ( warehouseId: number, warehouseDTO: IEditWarehouseDTO, - ): Promise => { + ): Promise => { // Authorize the warehouse DTO before editing. await this.authorize(warehouseDTO, warehouseId); diff --git a/packages/server-nest/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts b/packages/server-nest/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts index b73aaca52..269a9c7ac 100644 --- a/packages/server-nest/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts +++ b/packages/server-nest/src/modules/Warehouses/commands/WarehouseMarkPrimary.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { Knex } from 'knex'; import { IWarehouseMarkAsPrimaryPayload, @@ -12,6 +12,7 @@ import { events } from '@/common/events/events'; @Injectable() export class WarehouseMarkPrimary { constructor( + @Inject(Warehouse.name) private readonly warehouseModel: typeof Warehouse, private readonly uow: UnitOfWork, private readonly eventPublisher: EventEmitter2, diff --git a/packages/server-nest/src/modules/Warehouses/models/Warehouse.model.ts b/packages/server-nest/src/modules/Warehouses/models/Warehouse.model.ts index f484b30f0..94c078c72 100644 --- a/packages/server-nest/src/modules/Warehouses/models/Warehouse.model.ts +++ b/packages/server-nest/src/modules/Warehouses/models/Warehouse.model.ts @@ -1,23 +1,17 @@ // import { Model } from 'objection'; import { BaseModel } from '@/models/Model'; +import { Item } from '@/modules/Items/models/Item'; export class Warehouse extends BaseModel { - date!: Date; - - fromWarehouseId!: number; - toWarehouseId!: number; - - reason!: string; - transactionNumber!: string; - - transferInitiatedAt!: Date; - transferDeliveredAt!: Date; - - isInitiated!: boolean; - isTransferred!: boolean; - + name!: string; + code!: string; + city!: string; + country!: string; + address!: string; primary!: boolean; + items!: Item[]; + /** * Table name. */ diff --git a/packages/server-nest/test/branches.e2e-spec.ts b/packages/server-nest/test/branches.e2e-spec.ts new file mode 100644 index 000000000..d3444035c --- /dev/null +++ b/packages/server-nest/test/branches.e2e-spec.ts @@ -0,0 +1,71 @@ +import * as request from 'supertest'; +import { faker } from '@faker-js/faker'; +import { app } from './init-app-test'; + +describe('Branches (e2e)', () => { + it('/branches (POST)', () => { + return request(app.getHttpServer()) + .post('/branches') + .set('organization-id', '4064541lv40nhca') + .send({ + name: faker.commerce.productName(), + code: faker.string.alpha(4), + }) + .expect(201); + }); + + it('/branches/:id (DELETE)', async () => { + const response = await request(app.getHttpServer()) + .post('/branches') + .set('organization-id', '4064541lv40nhca') + .send({ + name: faker.commerce.productName(), + code: faker.string.alpha(4), + }); + const branchId = response.body.id; + + return request(app.getHttpServer()) + .delete(`/branches/${branchId}`) + .set('organization-id', '4064541lv40nhca') + .expect(200); + }); + + it('/branches/:id (PUT)', async () => { + const response = await request(app.getHttpServer()) + .post('/branches') + .set('organization-id', '4064541lv40nhca') + .send({ + name: faker.commerce.productName(), + code: faker.string.alpha(4), + }); + const branchId = response.body.id; + + return request(app.getHttpServer()) + .put(`/branches/${branchId}`) + .set('organization-id', '4064541lv40nhca') + .expect(200); + }); + + it('/branches/:id (GET)', async () => { + const response = await request(app.getHttpServer()) + .post('/branches') + .set('organization-id', '4064541lv40nhca') + .send({ + name: faker.commerce.productName(), + code: faker.string.alpha(4), + }); + const branchId = response.body.id; + + return request(app.getHttpServer()) + .get(`/branches/${branchId}`) + .set('organization-id', '4064541lv40nhca') + .expect(200); + }); + + it('/branches (GET)', async () => { + return request(app.getHttpServer()) + .get('/branches') + .set('organization-id', '4064541lv40nhca') + .expect(200); + }); +}); diff --git a/packages/server-nest/test/warehouses.e2e-spec.ts b/packages/server-nest/test/warehouses.e2e-spec.ts new file mode 100644 index 000000000..54d6e7555 --- /dev/null +++ b/packages/server-nest/test/warehouses.e2e-spec.ts @@ -0,0 +1,71 @@ +import * as request from 'supertest'; +import { faker } from '@faker-js/faker'; +import { app } from './init-app-test'; + +describe('Warehouses (e2e)', () => { + it('/warehouses (POST)', () => { + return request(app.getHttpServer()) + .post('/warehouses') + .set('organization-id', '4064541lv40nhca') + .send({ + name: faker.commerce.productName(), + code: faker.string.alpha(4), + }) + .expect(201); + }); + + it('/warehouses/:id (DELETE)', async () => { + const response = await request(app.getHttpServer()) + .post('/warehouses') + .set('organization-id', '4064541lv40nhca') + .send({ + name: faker.commerce.productName(), + code: faker.string.alpha(4), + }); + const warehouseId = response.body.id; + + return request(app.getHttpServer()) + .delete(`/warehouses/${warehouseId}`) + .set('organization-id', '4064541lv40nhca') + .expect(200); + }); + + it('/warehouses/:id (PUT)', async () => { + const response = await request(app.getHttpServer()) + .post('/warehouses') + .set('organization-id', '4064541lv40nhca') + .send({ + name: faker.commerce.productName(), + code: faker.string.alpha(4), + }); + const warehouseId = response.body.id; + + return request(app.getHttpServer()) + .put(`/warehouses/${warehouseId}`) + .set('organization-id', '4064541lv40nhca') + .expect(200); + }); + + it('/warehouses/:id (GET)', async () => { + const response = await request(app.getHttpServer()) + .post('/warehouses') + .set('organization-id', '4064541lv40nhca') + .send({ + name: faker.commerce.productName(), + code: faker.string.alpha(4), + }); + const warehouseId = response.body.id; + + return request(app.getHttpServer()) + .get(`/warehouses/${warehouseId}`) + .set('organization-id', '4064541lv40nhca') + .expect(200); + }); + + it('/warehouses (GET)', async () => { + return request(app.getHttpServer()) + .get('/warehouses') + .set('organization-id', '4064541lv40nhca') + .expect(200); + }); +});