From 04c25bd31a97fea07c2fefa899fbdb84087cbea1 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Tue, 8 Apr 2025 16:19:35 +0200 Subject: [PATCH] refactor(nestjs): export module --- .../src/common/constants/http.constants.ts | 8 ++ .../src/modules/Accounts/Accounts.module.ts | 2 + .../Accounts/AccountsExportable.service.ts | 8 ++ .../modules/Accounts/models/Account.model.ts | 3 +- packages/server/src/modules/App/App.module.ts | 4 +- .../BillPayments/BillPayments.module.ts | 2 + .../BillPaymentsApplication.service.ts | 15 +- .../commands/BillPaymentExportable.ts | 34 ----- .../queries/BillPaymentsExportable.ts | 42 ++++++ .../server/src/modules/Bills/Bills.module.ts | 2 + .../modules/Bills/commands/BillsExportable.ts | 66 +++++---- .../server/src/modules/Bills/models/Bill.ts | 2 + .../modules/Bills/queries/GetBillPayments.ts | 3 +- .../modules/CreditNotes/CreditNotes.module.ts | 2 + .../commands/CreditNotesExportable.ts | 63 +++++---- .../modules/CreditNotes/models/CreditNote.ts | 2 + .../src/modules/Customers/Customers.module.ts | 4 +- .../Customers/CustomersApplication.service.ts | 26 ++-- .../modules/Customers/CustomersExportable.ts | 58 ++++---- .../src/modules/Expenses/Expenses.module.ts | 2 + .../modules/Expenses/ExpensesExportable.ts | 66 ++++----- .../modules/Expenses/models/Expense.model.ts | 2 + .../src/modules/Export/Export.controller.ts | 12 +- .../server/src/modules/Export/Export.utils.ts | 13 ++ .../src/modules/Export/ExportResources.ts | 21 +-- .../src/modules/Export/ExportService.ts | 9 +- .../server/src/modules/Export/Exportable.ts | 2 +- .../decorators/ExportableModel.decorator.ts | 32 +++++ packages/server/src/modules/Import/_utils.ts | 6 +- .../src/modules/Import/models/Import.ts | 1 + .../ItemCategoriesExportable.ts | 52 +++---- .../ItemCategories/ItemCategory.module.ts | 2 + .../models/ItemCategory.model.ts | 2 + .../server/src/modules/Items/models/Item.ts | 2 + .../ManualJournals/ManualJournals.module.ts | 4 +- .../ManualJournalsApplication.service.ts | 29 ++-- .../commands/ManualJournalExportable.ts | 55 ++++---- .../ManualJournals/models/ManualJournal.ts | 2 + .../PaymentsReceived.module.ts | 2 + .../commands/PaymentsReceivedExportable.ts | 69 +++++---- .../PaymentReceived/models/PaymentReceived.ts | 2 + .../SaleEstimates/SaleEstimates.module.ts | 4 +- .../SaleEstimates/SaleEstimatesExportable.ts | 67 ++++----- .../SaleEstimates/models/SaleEstimate.ts | 3 +- .../SaleInvoices/SaleInvoices.module.ts | 2 + .../commands/SaleInvoicesExportable.ts | 68 ++++----- .../SaleInvoices/models/SaleInvoice.ts | 2 + .../SaleReceipts/SaleReceipts.module.ts | 2 + .../commands/SaleReceiptsExportable.ts | 64 ++++----- .../SaleReceipts/models/SaleReceipt.ts | 2 + .../src/modules/TaxRates/TaxRate.module.ts | 2 + .../modules/TaxRates/TaxRatesExportable.ts | 34 ++--- .../modules/TaxRates/models/TaxRate.model.ts | 2 + .../VendorCredit/VendorCredits.module.ts | 4 +- .../commands/VendorCreditsExportable.ts | 68 ++++----- .../VendorCredit/models/VendorCredit.ts | 2 + .../src/modules/Vendors/Vendors.module.ts | 2 + .../src/modules/Vendors/VendorsExportable.ts | 58 ++++---- .../src/modules/Vendors/models/Vendor.ts | 2 + .../server/src/utils/multi-number-parse.ts | 131 ++++++++++++++++++ 60 files changed, 748 insertions(+), 504 deletions(-) create mode 100644 packages/server/src/common/constants/http.constants.ts delete mode 100644 packages/server/src/modules/BillPayments/commands/BillPaymentExportable.ts create mode 100644 packages/server/src/modules/BillPayments/queries/BillPaymentsExportable.ts create mode 100644 packages/server/src/modules/Export/Export.utils.ts create mode 100644 packages/server/src/modules/Export/decorators/ExportableModel.decorator.ts create mode 100644 packages/server/src/utils/multi-number-parse.ts diff --git a/packages/server/src/common/constants/http.constants.ts b/packages/server/src/common/constants/http.constants.ts new file mode 100644 index 000000000..96022929a --- /dev/null +++ b/packages/server/src/common/constants/http.constants.ts @@ -0,0 +1,8 @@ +export const ACCEPT_TYPE = { + APPLICATION_PDF: 'application/pdf', + APPLICATION_JSON: 'application/json', + APPLICATION_JSON_TABLE: 'application/json+table', + APPLICATION_XLSX: 'application/xlsx', + APPLICATION_CSV: 'application/csv', + APPLICATION_TEXT_HTML: 'application/json+html', +}; \ No newline at end of file diff --git a/packages/server/src/modules/Accounts/Accounts.module.ts b/packages/server/src/modules/Accounts/Accounts.module.ts index 7ed6c4f12..41ae6bc11 100644 --- a/packages/server/src/modules/Accounts/Accounts.module.ts +++ b/packages/server/src/modules/Accounts/Accounts.module.ts @@ -17,6 +17,7 @@ import { RegisterTenancyModel } from '../Tenancy/TenancyModels/Tenancy.module'; import { BankAccount } from '../BankingTransactions/models/BankAccount'; import { GetAccountsService } from './GetAccounts.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; +import { AccountsExportable } from './AccountsExportable.service'; // import { GetAccountsService } from './GetAccounts.service'; const models = [RegisterTenancyModel(BankAccount)]; @@ -38,6 +39,7 @@ const models = [RegisterTenancyModel(BankAccount)]; GetAccountTypesService, GetAccountTransactionsService, GetAccountsService, + AccountsExportable ], exports: [AccountRepository, CreateAccountService, ...models], }) diff --git a/packages/server/src/modules/Accounts/AccountsExportable.service.ts b/packages/server/src/modules/Accounts/AccountsExportable.service.ts index 4c010806e..e05c2db0d 100644 --- a/packages/server/src/modules/Accounts/AccountsExportable.service.ts +++ b/packages/server/src/modules/Accounts/AccountsExportable.service.ts @@ -2,8 +2,16 @@ import { AccountsApplication } from './AccountsApplication.service'; import { Exportable } from '../Export/Exportable'; import { EXPORT_SIZE_LIMIT } from '../Export/constants'; import { IAccountsFilter, IAccountsStructureType } from './Accounts.types'; +import { Injectable } from '@nestjs/common'; +import { ExportableService } from '../Export/decorators/ExportableModel.decorator'; +import { Account } from './models/Account.model'; +@Injectable() +@ExportableService({ name: Account.name }) export class AccountsExportable extends Exportable { + /** + * @param {AccountsApplication} accountsApplication + */ constructor(private readonly accountsApplication: AccountsApplication) { super(); } diff --git a/packages/server/src/modules/Accounts/models/Account.model.ts b/packages/server/src/modules/Accounts/models/Account.model.ts index 92cef8f59..40f127ec5 100644 --- a/packages/server/src/modules/Accounts/models/Account.model.ts +++ b/packages/server/src/modules/Accounts/models/Account.model.ts @@ -15,12 +15,13 @@ import { Model } from 'objection'; import { PlaidItem } from '@/modules/BankingPlaid/models/PlaidItem'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { flatToNestedArray } from '@/utils/flat-to-nested-array'; +import { ExportableModel } from '../../Export/decorators/ExportableModel.decorator'; // import AccountSettings from './Account.Settings'; // import { DEFAULT_VIEWS } from '@/modules/Accounts/constants'; // import { buildFilterQuery, buildSortColumnQuery } from '@/lib/ViewRolesBuilder'; // import { flatToNestedArray } from 'utils'; - +@ExportableModel() export class Account extends TenantBaseModel { public name!: string; public slug!: string; diff --git a/packages/server/src/modules/App/App.module.ts b/packages/server/src/modules/App/App.module.ts index 2f31cb1fc..0e0d0dc1c 100644 --- a/packages/server/src/modules/App/App.module.ts +++ b/packages/server/src/modules/App/App.module.ts @@ -79,6 +79,7 @@ import { TenancyModule } from '../Tenancy/Tenancy.module'; import { LoopsModule } from '../Loops/Loops.module'; import { AttachmentsModule } from '../Attachments/Attachment.module'; import { S3Module } from '../S3/S3.module'; +import { ExportModule } from '../Export/Export.module'; @Module({ imports: [ @@ -192,7 +193,8 @@ import { S3Module } from '../S3/S3.module'; PaymentServicesModule, LoopsModule, AttachmentsModule, - S3Module + S3Module, + ExportModule ], controllers: [AppController], providers: [ diff --git a/packages/server/src/modules/BillPayments/BillPayments.module.ts b/packages/server/src/modules/BillPayments/BillPayments.module.ts index 2feb3c04a..e9f01f6e7 100644 --- a/packages/server/src/modules/BillPayments/BillPayments.module.ts +++ b/packages/server/src/modules/BillPayments/BillPayments.module.ts @@ -16,6 +16,7 @@ import { BillPaymentGLEntries } from './commands/BillPaymentGLEntries'; import { BillPaymentGLEntriesSubscriber } from './subscribers/BillPaymentGLEntriesSubscriber'; import { LedgerModule } from '../Ledger/Ledger.module'; import { AccountsModule } from '../Accounts/Accounts.module'; +import { BillPaymentsExportable } from './queries/BillPaymentsExportable'; @Module({ imports: [LedgerModule, AccountsModule], @@ -34,6 +35,7 @@ import { AccountsModule } from '../Accounts/Accounts.module'; TenancyContext, BillPaymentGLEntries, BillPaymentGLEntriesSubscriber, + BillPaymentsExportable ], exports: [BillPaymentValidators, CreateBillPaymentService], controllers: [BillPaymentsController], diff --git a/packages/server/src/modules/BillPayments/BillPaymentsApplication.service.ts b/packages/server/src/modules/BillPayments/BillPaymentsApplication.service.ts index 59959244d..29a551ad2 100644 --- a/packages/server/src/modules/BillPayments/BillPaymentsApplication.service.ts +++ b/packages/server/src/modules/BillPayments/BillPaymentsApplication.service.ts @@ -20,12 +20,12 @@ export class BillPaymentsApplication { private deleteBillPaymentService: DeleteBillPayment, private getBillPaymentService: GetBillPayment, private getPaymentBillsService: GetPaymentBills, - // private getBillPaymentsService: GetBillPayments, + private getBillPaymentsService: GetBillPayments, ) {} /** * Creates a bill payment with associated GL entries. - * @param {IBillPaymentDTO} billPaymentDTO + * @param {IBillPaymentDTO} billPaymentDTO - Create bill payment dto. * @returns {Promise} */ public createBillPayment(billPaymentDTO: CreateBillPaymentDto) { @@ -34,7 +34,7 @@ export class BillPaymentsApplication { /** * Delets the given bill payment with associated GL entries. - * @param {number} billPaymentId + * @param {number} billPaymentId - Bill payment id. */ public deleteBillPayment(billPaymentId: number) { return this.deleteBillPaymentService.deleteBillPayment(billPaymentId); @@ -58,13 +58,10 @@ export class BillPaymentsApplication { /** * Retrieves bill payments list. - * @param {number} tenantId - * @param filterDTO - * @returns */ - // public getBillPayments(filterDTO: IBillPaymentsFilter) { - // return this.getBillPaymentsService.getBillPayments(filterDTO); - // } + public getBillPayments(filterDTO: IBillPaymentsFilter) { + return this.getBillPaymentsService.getBillPayments(filterDTO); + } /** * Retrieve specific bill payment. diff --git a/packages/server/src/modules/BillPayments/commands/BillPaymentExportable.ts b/packages/server/src/modules/BillPayments/commands/BillPaymentExportable.ts deleted file mode 100644 index 44bf4b6cf..000000000 --- a/packages/server/src/modules/BillPayments/commands/BillPaymentExportable.ts +++ /dev/null @@ -1,34 +0,0 @@ -// import { Inject, Service } from 'typedi'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { BillPaymentsApplication } from './BillPaymentsApplication'; -// import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; - -// @Service() -// export class BillPaymentExportable extends Exportable { -// @Inject() -// private billPaymentsApplication: BillPaymentsApplication; - -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: any) { -// const filterQuery = (builder) => { -// builder.withGraphFetched('entries.bill'); -// builder.withGraphFetched('branch'); -// }; -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// filterQuery -// } as any; - -// return this.billPaymentsApplication -// .getBillPayments(tenantId, parsedQuery) -// .then((output) => output.billPayments); -// } -// } diff --git a/packages/server/src/modules/BillPayments/queries/BillPaymentsExportable.ts b/packages/server/src/modules/BillPayments/queries/BillPaymentsExportable.ts new file mode 100644 index 000000000..970730b75 --- /dev/null +++ b/packages/server/src/modules/BillPayments/queries/BillPaymentsExportable.ts @@ -0,0 +1,42 @@ +import { Injectable } from "@nestjs/common"; +import { BillPaymentsApplication } from "../BillPaymentsApplication.service"; +import { Exportable } from "@/modules/Export/Exportable"; +import { EXPORT_SIZE_LIMIT } from "@/modules/Export/constants"; +import { ExportableService } from "@/modules/Export/decorators/ExportableModel.decorator"; +import { BillPayment } from "../models/BillPayment"; + +@Injectable() +@ExportableService({ name: BillPayment.name }) +export class BillPaymentsExportable extends Exportable { + constructor( + private readonly billPaymentsApplication: BillPaymentsApplication + ) { + super(); + } + + /** + * Retrieves the accounts data to exportable sheet. + * @param {number} tenantId + * @returns + */ + public exportable(query: any) { + const filterQuery = (builder) => { + builder.withGraphFetched('entries.bill'); + builder.withGraphFetched('branch'); + }; + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + filterQuery + } as any; + + return []; + + // return this.billPaymentsApplication + // .billPayments(tenantId, parsedQuery) + // .then((output) => output.billPayments); + } +} diff --git a/packages/server/src/modules/Bills/Bills.module.ts b/packages/server/src/modules/Bills/Bills.module.ts index 87280de4c..a9f5549e1 100644 --- a/packages/server/src/modules/Bills/Bills.module.ts +++ b/packages/server/src/modules/Bills/Bills.module.ts @@ -26,6 +26,7 @@ import { BillInventoryTransactions } from './commands/BillInventoryTransactions' import { GetBillsService } from './queries/GetBills.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { InventoryCostModule } from '../InventoryCost/InventoryCost.module'; +import { BillsExportable } from './commands/BillsExportable'; @Module({ imports: [ @@ -57,6 +58,7 @@ import { InventoryCostModule } from '../InventoryCost/InventoryCost.module'; BillGLEntriesSubscriber, BillInventoryTransactions, BillWriteInventoryTransactionsSubscriber, + BillsExportable ], controllers: [BillsController], }) diff --git a/packages/server/src/modules/Bills/commands/BillsExportable.ts b/packages/server/src/modules/Bills/commands/BillsExportable.ts index e3dcf983f..df9d09b66 100644 --- a/packages/server/src/modules/Bills/commands/BillsExportable.ts +++ b/packages/server/src/modules/Bills/commands/BillsExportable.ts @@ -1,37 +1,35 @@ -// import { Inject, Service } from 'typedi'; -// import { Knex } from 'knex'; -// import { IBillsFilter } from '@/interfaces'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { BillsApplication } from '../Bills.application'; -// import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; -// import Objection from 'objection'; +import { Knex } from 'knex'; +import { BillsApplication } from '../Bills.application'; +import { Injectable } from '@nestjs/common'; +import { Exportable } from '@/modules/Export/Exportable'; +import { IBillsFilter } from '../Bills.types'; +import { EXPORT_SIZE_LIMIT } from '@/modules/Export/constants'; -// @Service() -// export class BillsExportable extends Exportable { -// @Inject() -// private billsApplication: BillsApplication; +@Injectable() +export class BillsExportable extends Exportable { + constructor(private readonly billsApplication: BillsApplication) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: IBillsFilter) { -// const filterQuery = (query) => { -// query.withGraphFetched('branch'); -// query.withGraphFetched('warehouse'); -// }; -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// filterQuery, -// } as IBillsFilter; + /** + * Retrieves the accounts data to exportable sheet. + */ + public exportable(query: IBillsFilter) { + const filterQuery = (query) => { + query.withGraphFetched('branch'); + query.withGraphFetched('warehouse'); + }; + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + filterQuery, + } as IBillsFilter; -// return this.billsApplication -// .getBills(tenantId, parsedQuery) -// .then((output) => output.bills); -// } -// } + return this.billsApplication + .getBills(parsedQuery) + .then((output) => output.bills); + } +} diff --git a/packages/server/src/modules/Bills/models/Bill.ts b/packages/server/src/modules/Bills/models/Bill.ts index 2b55f32ea..41da17fc3 100644 --- a/packages/server/src/modules/Bills/models/Bill.ts +++ b/packages/server/src/modules/Bills/models/Bill.ts @@ -14,7 +14,9 @@ import { BillLandedCost } from '@/modules/BillLandedCosts/models/BillLandedCost' import { DiscountType } from '@/common/types/Discount'; import type { Knex, QueryBuilder } from 'knex'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +@ExportableModel() export class Bill extends TenantBaseModel { public amount: number; public paymentAmount: number; diff --git a/packages/server/src/modules/Bills/queries/GetBillPayments.ts b/packages/server/src/modules/Bills/queries/GetBillPayments.ts index ef13ec272..6a1814bba 100644 --- a/packages/server/src/modules/Bills/queries/GetBillPayments.ts +++ b/packages/server/src/modules/Bills/queries/GetBillPayments.ts @@ -13,8 +13,7 @@ export class GetBillPayments { /** * Retrieve the specific bill associated payment transactions. - * @param {number} billId - * @returns {} + * @param {number} billId - Bill id. */ public getBillPayments = async (billId: number) => { const billsEntries = await this.billPaymentEntryModel diff --git a/packages/server/src/modules/CreditNotes/CreditNotes.module.ts b/packages/server/src/modules/CreditNotes/CreditNotes.module.ts index 0a1e5bafb..b7785488c 100644 --- a/packages/server/src/modules/CreditNotes/CreditNotes.module.ts +++ b/packages/server/src/modules/CreditNotes/CreditNotes.module.ts @@ -24,6 +24,7 @@ import { LedgerModule } from '../Ledger/Ledger.module'; import { AccountsModule } from '../Accounts/Accounts.module'; import { GetCreditNotesService } from './queries/GetCreditNotes.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; +import { CreditNotesExportable } from './commands/CreditNotesExportable'; @Module({ imports: [ @@ -53,6 +54,7 @@ import { DynamicListModule } from '../DynamicListing/DynamicList.module'; CreditNoteBrandingTemplate, CreditNoteGLEntries, CreditNoteGLEntriesSubscriber, + CreditNotesExportable ], exports: [ CreateCreditNoteService, diff --git a/packages/server/src/modules/CreditNotes/commands/CreditNotesExportable.ts b/packages/server/src/modules/CreditNotes/commands/CreditNotesExportable.ts index 8fd00ff7e..ac5c8b55a 100644 --- a/packages/server/src/modules/CreditNotes/commands/CreditNotesExportable.ts +++ b/packages/server/src/modules/CreditNotes/commands/CreditNotesExportable.ts @@ -1,35 +1,34 @@ -// import { Inject, Service } from 'typedi'; -// import { ICreditNotesQueryDTO } from '@/interfaces'; -// import { Exportable } from '@/services/Export/Exportable'; -// import ListCreditNotes from '../ListCreditNotes'; +import { Exportable } from '@/modules/Export/Exportable'; +import { CreditNoteApplication } from '../CreditNoteApplication.service'; +import { Injectable } from '@nestjs/common'; +import { ICreditNotesQueryDTO } from '../types/CreditNotes.types'; -// @Service() -// export class CreditNotesExportable extends Exportable { -// @Inject() -// private getCreditNotes: ListCreditNotes; +@Injectable() +export class CreditNotesExportable extends Exportable { + constructor(private readonly creditNotesApp: CreditNoteApplication) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId - -// * @param {IVendorCreditsQueryDTO} query - -// * @returns {} -// */ -// public exportable(tenantId: number, query: ICreditNotesQueryDTO) { -// const filterQuery = (query) => { -// query.withGraphFetched('branch'); -// query.withGraphFetched('warehouse'); -// }; -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: 12000, -// filterQuery, -// } as ICreditNotesQueryDTO; + /** + * Retrieves the accounts data to exportable sheet. + * @param {IVendorCreditsQueryDTO} query - + */ + public exportable(query: ICreditNotesQueryDTO) { + const filterQuery = (query) => { + query.withGraphFetched('branch'); + query.withGraphFetched('warehouse'); + }; + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: 12000, + filterQuery, + } as ICreditNotesQueryDTO; -// return this.getCreditNotes -// .getCreditNotesList(tenantId, parsedQuery) -// .then((output) => output.creditNotes); -// } -// } + return this.creditNotesApp + .getCreditNotes(parsedQuery) + .then((output) => output.creditNotes); + } +} diff --git a/packages/server/src/modules/CreditNotes/models/CreditNote.ts b/packages/server/src/modules/CreditNotes/models/CreditNote.ts index 482fef214..603338142 100644 --- a/packages/server/src/modules/CreditNotes/models/CreditNote.ts +++ b/packages/server/src/modules/CreditNotes/models/CreditNote.ts @@ -2,11 +2,13 @@ import { DiscountType } from '@/common/types/Discount'; import { BaseModel } from '@/models/Model'; import { Branch } from '@/modules/Branches/models/Branch.model'; import { Customer } from '@/modules/Customers/models/Customer'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry'; import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model'; import { mixin, Model, raw } from 'objection'; +@ExportableModel() export class CreditNote extends TenantBaseModel { public amount: number; public exchangeRate: number; diff --git a/packages/server/src/modules/Customers/Customers.module.ts b/packages/server/src/modules/Customers/Customers.module.ts index ab576eb0e..192e68d69 100644 --- a/packages/server/src/modules/Customers/Customers.module.ts +++ b/packages/server/src/modules/Customers/Customers.module.ts @@ -12,6 +12,7 @@ import { CreateEditCustomerDTO } from './commands/CreateEditCustomerDTO.service' import { CustomersController } from './Customers.controller'; import { CustomersApplication } from './CustomersApplication.service'; import { DeleteCustomer } from './commands/DeleteCustomer.service'; +import { CustomersExportable } from './CustomersExportable'; @Module({ imports: [TenancyDatabaseModule], @@ -29,7 +30,8 @@ import { DeleteCustomer } from './commands/DeleteCustomer.service'; DeleteCustomer, TenancyContext, TransformerInjectable, - GetCustomerService + GetCustomerService, + CustomersExportable ], }) export class CustomersModule {} diff --git a/packages/server/src/modules/Customers/CustomersApplication.service.ts b/packages/server/src/modules/Customers/CustomersApplication.service.ts index 4d1da82c7..161d0532c 100644 --- a/packages/server/src/modules/Customers/CustomersApplication.service.ts +++ b/packages/server/src/modules/Customers/CustomersApplication.service.ts @@ -4,9 +4,10 @@ import { CreateCustomer } from './commands/CreateCustomer.service'; import { EditCustomer } from './commands/EditCustomer.service'; import { DeleteCustomer } from './commands/DeleteCustomer.service'; import { EditOpeningBalanceCustomer } from './commands/EditOpeningBalanceCustomer.service'; -import { ICustomerOpeningBalanceEditDTO } from './types/Customers.types'; +import { ICustomerOpeningBalanceEditDTO, ICustomersFilter } from './types/Customers.types'; import { CreateCustomerDto } from './dtos/CreateCustomer.dto'; import { EditCustomerDto } from './dtos/EditCustomer.dto'; +import { GetCustomers } from './queries/GetCustomers.service'; @Injectable() export class CustomersApplication { @@ -16,13 +17,12 @@ export class CustomersApplication { private editCustomerService: EditCustomer, private deleteCustomerService: DeleteCustomer, private editOpeningBalanceService: EditOpeningBalanceCustomer, - // private getCustomersService: GetCustomers, + private getCustomersService: GetCustomers, ) {} /** * Retrieves the given customer details. - * @param {number} tenantId - * @param {number} customerId + * @param {number} customerId - Customer id. */ public getCustomer = (customerId: number) => { return this.getCustomerService.getCustomer(customerId); @@ -30,7 +30,7 @@ export class CustomersApplication { /** * Creates a new customer. - * @param {ICustomerNewDTO} customerDTO + * @param {ICustomerNewDTO} customerDTO - Create customer dto. * @returns {Promise} */ public createCustomer = (customerDTO: CreateCustomerDto) => { @@ -49,9 +49,7 @@ export class CustomersApplication { /** * Deletes the given customer and associated transactions. - * @param {number} tenantId - * @param {number} customerId - * @param {ISystemUser} authorizedUser + * @param {number} customerId - Customer id. * @returns {Promise} */ public deleteCustomer = (customerId: number) => { @@ -60,9 +58,8 @@ export class CustomersApplication { /** * Changes the opening balance of the given customer. - * @param {number} tenantId - * @param {number} customerId - * @param {Date|string} openingBalanceEditDTO + * @param {number} customerId - Customer id. + * @param {Date|string} openingBalanceEditDTO - Opening balance edit dto. * @returns {Promise} */ public editOpeningBalance = ( @@ -77,10 +74,9 @@ export class CustomersApplication { /** * Retrieve customers paginated list. - * @param {number} tenantId - Tenant id. * @param {ICustomersFilter} filter - Cusotmers filter. */ - // public getCustomers = (filterDTO: ICustomersFilter) => { - // return this.getCustomersService.getCustomersList(filterDTO); - // }; + public getCustomers = (filterDTO: ICustomersFilter) => { + return this.getCustomersService.getCustomersList(filterDTO); + }; } diff --git a/packages/server/src/modules/Customers/CustomersExportable.ts b/packages/server/src/modules/Customers/CustomersExportable.ts index 0384df0d1..849f2f767 100644 --- a/packages/server/src/modules/Customers/CustomersExportable.ts +++ b/packages/server/src/modules/Customers/CustomersExportable.ts @@ -1,30 +1,34 @@ -// import { Inject, Service } from 'typedi'; -// import { IItemsFilter } from '@/interfaces'; -// import { CustomersApplication } from './CustomersApplication'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; +import { Injectable } from '@nestjs/common'; +import { CustomersApplication } from './CustomersApplication.service'; +import { IItemsFilter } from '../Items/types/Items.types'; +import { EXPORT_SIZE_LIMIT } from '../Export/constants'; +import { Exportable } from '../Export/Exportable'; +import { ICustomersFilter } from './types/Customers.types'; +import { ExportableService } from '../Export/decorators/ExportableModel.decorator'; +import { Customer } from './models/Customer'; -// @Service() -// export class CustomersExportable extends Exportable { -// @Inject() -// private customersApplication: CustomersApplication; +@Injectable() +@ExportableService({ name: Customer.name }) +export class CustomersExportable extends Exportable { + constructor(private readonly customersApplication: CustomersApplication) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: IItemsFilter) { -// const parsedQuery = { -// sortOrder: 'DESC', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// } as IItemsFilter; + /** + * Retrieves the accounts data to exportable sheet. + * @param {ICustomersFilter} query - Customers query. + */ + public exportable(query: ICustomersFilter) { + const parsedQuery = { + sortOrder: 'DESC', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + } as IItemsFilter; -// return this.customersApplication -// .getCustomers(tenantId, parsedQuery) -// .then((output) => output.customers); -// } -// } + return this.customersApplication + .getCustomers(parsedQuery) + .then((output) => output.customers); + } +} diff --git a/packages/server/src/modules/Expenses/Expenses.module.ts b/packages/server/src/modules/Expenses/Expenses.module.ts index f00b75f14..3c6cb10cd 100644 --- a/packages/server/src/modules/Expenses/Expenses.module.ts +++ b/packages/server/src/modules/Expenses/Expenses.module.ts @@ -17,6 +17,7 @@ import { LedgerModule } from '../Ledger/Ledger.module'; import { BranchesModule } from '../Branches/Branches.module'; import { GetExpensesService } from './queries/GetExpenses.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; +import { ExpensesExportable } from './ExpensesExportable'; @Module({ imports: [LedgerModule, BranchesModule, DynamicListModule], @@ -37,6 +38,7 @@ import { DynamicListModule } from '../DynamicListing/DynamicList.module'; ExpenseGLEntriesStorageService, ExpenseGLEntriesService, GetExpensesService, + ExpensesExportable ], }) export class ExpensesModule {} diff --git a/packages/server/src/modules/Expenses/ExpensesExportable.ts b/packages/server/src/modules/Expenses/ExpensesExportable.ts index 7a1681506..902a2c91a 100644 --- a/packages/server/src/modules/Expenses/ExpensesExportable.ts +++ b/packages/server/src/modules/Expenses/ExpensesExportable.ts @@ -1,34 +1,38 @@ -// import { Inject, Service } from 'typedi'; -// import { Exportable } from '../Export/Exportable'; -// import { IExpensesFilter } from '@/interfaces'; -// import { ExpensesApplication } from './ExpensesApplication.service'; -// import { EXPORT_SIZE_LIMIT } from '../Export/constants'; +import { Exportable } from '../Export/Exportable'; +import { ExpensesApplication } from './ExpensesApplication.service'; +import { EXPORT_SIZE_LIMIT } from '../Export/constants'; +import { Injectable } from '@nestjs/common'; +import { IExpensesFilter } from './Expenses.types'; +import { ExportableService } from '../Export/decorators/ExportableModel.decorator'; +import { Expense } from './models/Expense.model'; -// @Service() -// export class ExpensesExportable extends Exportable { -// @Inject() -// private expensesApplication: ExpensesApplication; +@Injectable() +@ExportableService({ name: Expense.name }) +export class ExpensesExportable extends Exportable { + constructor( + private readonly expensesApplication: ExpensesApplication, + ) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: IExpensesFilter) { -// const filterQuery = (query) => { -// query.withGraphFetched('branch'); -// }; -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// filterQuery, -// } as IExpensesFilter; + /** + * Retrieves the accounts data to exportable sheet. + */ + public exportable(query: IExpensesFilter) { + const filterQuery = (query) => { + query.withGraphFetched('branch'); + }; + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + filterQuery, + } as IExpensesFilter; -// return this.expensesApplication -// .getExpenses(tenantId, parsedQuery) -// .then((output) => output.expenses); -// } -// } + return this.expensesApplication + .getExpenses(parsedQuery) + .then((output) => output.expenses); + } +} diff --git a/packages/server/src/modules/Expenses/models/Expense.model.ts b/packages/server/src/modules/Expenses/models/Expense.model.ts index 34630d9df..6dcc408d3 100644 --- a/packages/server/src/modules/Expenses/models/Expense.model.ts +++ b/packages/server/src/modules/Expenses/models/Expense.model.ts @@ -3,7 +3,9 @@ import * as moment from 'moment'; import { ExpenseCategory } from './ExpenseCategory.model'; import { Account } from '@/modules/Accounts/models/Account.model'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +@ExportableModel() export class Expense extends TenantBaseModel { totalAmount!: number; currencyCode!: string; diff --git a/packages/server/src/modules/Export/Export.controller.ts b/packages/server/src/modules/Export/Export.controller.ts index e13559948..4eff9b663 100644 --- a/packages/server/src/modules/Export/Export.controller.ts +++ b/packages/server/src/modules/Export/Export.controller.ts @@ -1,20 +1,24 @@ import { Response } from 'express'; -import { convertAcceptFormatToFormat } from './_utils'; -import { Controller, Headers, Query, Res } from '@nestjs/common'; +import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { Controller, Get, Headers, Query, Res } from '@nestjs/common'; +import { AcceptType } from '@/constants/accept-type'; import { ExportQuery } from './dtos/ExportQuery.dto'; import { ExportResourceService } from './ExportService'; -import { AcceptType } from '@/constants/accept-type'; +import { convertAcceptFormatToFormat } from './Export.utils'; @Controller('/export') +@ApiTags('export') export class ExportController { constructor(private readonly exportResourceApp: ExportResourceService) {} + @Get() + @ApiOperation({ summary: 'Retrieves exported the given resource.' }) async export( @Query() query: ExportQuery, @Res() res: Response, @Headers('accept') acceptHeader: string, ) { - const applicationFormat = convertAcceptFormatToFormat(acceptType); + const applicationFormat = convertAcceptFormatToFormat(acceptHeader); const data = await this.exportResourceApp.export( query.resource, diff --git a/packages/server/src/modules/Export/Export.utils.ts b/packages/server/src/modules/Export/Export.utils.ts new file mode 100644 index 000000000..97b31125e --- /dev/null +++ b/packages/server/src/modules/Export/Export.utils.ts @@ -0,0 +1,13 @@ +import { ACCEPT_TYPE } from '@/common/constants/http.constants'; +import { ExportFormat } from './common'; + +export const convertAcceptFormatToFormat = (accept: string): ExportFormat => { + switch (accept) { + case ACCEPT_TYPE.APPLICATION_CSV: + return ExportFormat.Csv; + case ACCEPT_TYPE.APPLICATION_PDF: + return ExportFormat.Pdf; + case ACCEPT_TYPE.APPLICATION_XLSX: + return ExportFormat.Xlsx; + } +}; \ No newline at end of file diff --git a/packages/server/src/modules/Export/ExportResources.ts b/packages/server/src/modules/Export/ExportResources.ts index 7033e34e6..660b02829 100644 --- a/packages/server/src/modules/Export/ExportResources.ts +++ b/packages/server/src/modules/Export/ExportResources.ts @@ -1,22 +1,3 @@ -// import Container, { Service } from 'typedi'; -// import { AccountsExportable } from '../Accounts/AccountsExportable'; -// import { ExportableRegistry } from './ExportRegistery'; -// import { ItemsExportable } from '../Items/ItemsExportable'; -// import { CustomersExportable } from '../Contacts/Customers/CustomersExportable'; -// import { VendorsExportable } from '../Contacts/Vendors/VendorsExportable'; -// import { ExpensesExportable } from '../Expenses/ExpensesExportable'; -// import { SaleInvoicesExportable } from '../Sales/Invoices/SaleInvoicesExportable'; -// import { SaleEstimatesExportable } from '../Sales/Estimates/SaleEstimatesExportable'; -// import { SaleReceiptsExportable } from '../Sales/Receipts/SaleReceiptsExportable'; -// import { BillsExportable } from '../Purchases/Bills/BillsExportable'; -// import { PaymentsReceivedExportable } from '../Sales/PaymentReceived/PaymentsReceivedExportable'; -// import { BillPaymentExportable } from '../Purchases/BillPayments/BillPaymentExportable'; -// import { ManualJournalsExportable } from '../ManualJournals/ManualJournalExportable'; -// import { CreditNotesExportable } from '../CreditNotes/CreditNotesExportable'; -// import { VendorCreditsExportable } from '../Purchases/VendorCredits/VendorCreditsExportable'; -// import { ItemCategoriesExportable } from '../ItemCategories/ItemCategoriesExportable'; -// import { TaxRatesExportable } from '../TaxRates/TaxRatesExportable'; - import { Injectable } from "@nestjs/common"; import { ExportableRegistry } from "./ExportRegistery"; import { AccountsExportable } from "../Accounts/AccountsExportable.service"; @@ -33,7 +14,7 @@ export class ExportableResources { * Importable instances. */ private importables = [ - { resource: 'Account', exportable: AccountsExportable }, + // { resource: 'Account', exportable: AccountsExportable }, // { resource: 'Item', exportable: ItemsExportable }, // { resource: 'ItemCategory', exportable: ItemCategoriesExportable }, // { resource: 'Customer', exportable: CustomersExportable }, diff --git a/packages/server/src/modules/Export/ExportService.ts b/packages/server/src/modules/Export/ExportService.ts index 3a7a5b461..a7b659172 100644 --- a/packages/server/src/modules/Export/ExportService.ts +++ b/packages/server/src/modules/Export/ExportService.ts @@ -22,7 +22,6 @@ export class ExportResourceService { ) {} /** - * * @param {string} resourceName * @param {ExportFormat} format * @returns @@ -46,15 +45,14 @@ export class ExportResourceService { format: ExportFormat = ExportFormat.Csv ) { const resource = sanitizeResourceName(resourceName); - const resourceMeta = this.getResourceMeta(tenantId, resource); + const resourceMeta = this.getResourceMeta(resource); const resourceColumns = this.resourceService.getResourceColumns( - tenantId, resource ); this.validateResourceMeta(resourceMeta); - const data = await this.getExportableData(tenantId, resource); - const transformed = this.transformExportedData(tenantId, resource, data); + const data = await this.getExportableData(resource); + const transformed = this.transformExportedData(resource, data); // Returns the csv, xlsx format. if (format === ExportFormat.Csv || format === ExportFormat.Xlsx) { @@ -67,7 +65,6 @@ export class ExportResourceService { const printableColumns = this.getPrintableColumns(resourceMeta); return this.exportPdf.pdf( - tenantId, printableColumns, transformed, resourceMeta?.print?.pageTitle diff --git a/packages/server/src/modules/Export/Exportable.ts b/packages/server/src/modules/Export/Exportable.ts index 0859ebd64..c83f94549 100644 --- a/packages/server/src/modules/Export/Exportable.ts +++ b/packages/server/src/modules/Export/Exportable.ts @@ -6,7 +6,7 @@ export class Exportable { */ public async exportable( query: Record, - ): Promise>> { + ): Promise { return []; } diff --git a/packages/server/src/modules/Export/decorators/ExportableModel.decorator.ts b/packages/server/src/modules/Export/decorators/ExportableModel.decorator.ts new file mode 100644 index 000000000..28a64e8ff --- /dev/null +++ b/packages/server/src/modules/Export/decorators/ExportableModel.decorator.ts @@ -0,0 +1,32 @@ +const exportableModels = new Map(); +const exportableService = new Map() + +/** + * Decorator that marks a model as exportable and registers its metadata. + * @param metadata Model metadata configuration for export + */ +export function ExportableModel() { + return function (target: any) { + const modelName = target.name; + exportableModels.set(modelName, true); + }; +} + +export function ExportableService({ name }: { name: string }) { + return function (target: any) { + exportableService.set(name, target); + }; +} + +/** + * Gets the registered exportable model metadata + * @param modelName Name of the model class + */ +export function getExportableModelMeta(modelName: string): boolean | undefined { + return exportableModels.get(modelName); +} + + +export function getExportableService(modelName: string) { + return exportableService.get(modelName); +} \ No newline at end of file diff --git a/packages/server/src/modules/Import/_utils.ts b/packages/server/src/modules/Import/_utils.ts index 43c80c912..a43d26737 100644 --- a/packages/server/src/modules/Import/_utils.ts +++ b/packages/server/src/modules/Import/_utils.ts @@ -20,9 +20,9 @@ import { } from 'lodash'; import pluralize from 'pluralize'; import { ResourceMetaFieldsMap } from './interfaces'; -import { IModelMetaField, IModelMetaField2 } from '@/interfaces'; -import { ServiceError } from '@/exceptions'; import { multiNumberParse } from '@/utils/multi-number-parse'; +import { ServiceError } from '../Items/ServiceError'; +import { IModelMetaField, IModelMetaField2 } from '@/interfaces/Model'; export const ERRORS = { RESOURCE_NOT_IMPORTABLE: 'RESOURCE_NOT_IMPORTABLE', @@ -336,7 +336,7 @@ export const valueParser = * @param {string} key - Mapped key path. formats: `group.key` or `key`. * @returns {string} */ -export const parseKey: R.Curry = R.curry( +export const parseKey = R.curry( (fields: { [key: string]: IModelMetaField2 }, key: string) => { const fieldKey = getFieldKey(key); const field = fields[fieldKey]; diff --git a/packages/server/src/modules/Import/models/Import.ts b/packages/server/src/modules/Import/models/Import.ts index 2d9d4f468..a34468005 100644 --- a/packages/server/src/modules/Import/models/Import.ts +++ b/packages/server/src/modules/Import/models/Import.ts @@ -8,6 +8,7 @@ export class Import extends BaseModel { mapping!: string; columns!: string; params!: string; + importId!: string; /** * Table name. diff --git a/packages/server/src/modules/ItemCategories/ItemCategoriesExportable.ts b/packages/server/src/modules/ItemCategories/ItemCategoriesExportable.ts index 3b0d16fd4..2b19d02ca 100644 --- a/packages/server/src/modules/ItemCategories/ItemCategoriesExportable.ts +++ b/packages/server/src/modules/ItemCategories/ItemCategoriesExportable.ts @@ -1,29 +1,29 @@ -// import { Inject, Service } from 'typedi'; -// import { Exportable } from '../Export/Exportable'; -// import { IAccountsFilter, IAccountsStructureType } from '@/interfaces'; -// import ItemCategoriesService from './ItemCategoriesService'; +import { Injectable } from '@nestjs/common'; +import { Exportable } from '../Export/Exportable'; +import { ItemCategoryApplication } from './ItemCategory.application'; +import { IItemCategoriesFilter } from './ItemCategory.interfaces'; +import { ExportableService } from '../Export/decorators/ExportableModel.decorator'; +import { ItemCategory } from './models/ItemCategory.model'; -// @Service() -// export class ItemCategoriesExportable extends Exportable { -// @Inject() -// private itemCategoriesApplication: ItemCategoriesService; +@Injectable() +@ExportableService({ name: ItemCategory.name }) +export class ItemCategoriesExportable extends Exportable { + constructor(private readonly itemCategoryApp: ItemCategoryApplication) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: IAccountsFilter) { -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// inactiveMode: false, -// ...query, -// structure: IAccountsStructureType.Flat, -// } as IAccountsFilter; + /** + * Retrieves the accounts data to exportable sheet. + * @param {number} tenantId + * @returns + */ + public exportable(query: Partial) { + const parsedQuery = { + ...query + } as IItemCategoriesFilter; -// return this.itemCategoriesApplication -// .getItemCategoriesList(tenantId, parsedQuery, {}) -// .then((output) => output.itemCategories); -// } -// } + return this.itemCategoryApp + .getItemCategories(parsedQuery) + .then((output) => output.itemCategories); + } +} diff --git a/packages/server/src/modules/ItemCategories/ItemCategory.module.ts b/packages/server/src/modules/ItemCategories/ItemCategory.module.ts index f78e46145..233ba1506 100644 --- a/packages/server/src/modules/ItemCategories/ItemCategory.module.ts +++ b/packages/server/src/modules/ItemCategories/ItemCategory.module.ts @@ -11,6 +11,7 @@ import { TransformerInjectable } from '../Transformer/TransformerInjectable.serv import { TenancyContext } from '../Tenancy/TenancyContext.service'; import { GetItemCategoriesService } from './queries/GetItemCategories.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; +import { ItemCategoriesExportable } from './ItemCategoriesExportable'; @Module({ imports: [TenancyDatabaseModule, DynamicListModule], @@ -23,6 +24,7 @@ import { DynamicListModule } from '../DynamicListing/DynamicList.module'; DeleteItemCategoryService, ItemCategoryApplication, CommandItemCategoryValidatorService, + ItemCategoriesExportable, TransformerInjectable, TenancyContext, ], diff --git a/packages/server/src/modules/ItemCategories/models/ItemCategory.model.ts b/packages/server/src/modules/ItemCategories/models/ItemCategory.model.ts index cb57c6d68..8fbfafbbb 100644 --- a/packages/server/src/modules/ItemCategories/models/ItemCategory.model.ts +++ b/packages/server/src/modules/ItemCategories/models/ItemCategory.model.ts @@ -1,6 +1,8 @@ +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { Model } from 'objection'; +@ExportableModel() export class ItemCategory extends TenantBaseModel { name!: string; description!: string; diff --git a/packages/server/src/modules/Items/models/Item.ts b/packages/server/src/modules/Items/models/Item.ts index 4a9960d97..3b7f33cd4 100644 --- a/packages/server/src/modules/Items/models/Item.ts +++ b/packages/server/src/modules/Items/models/Item.ts @@ -1,7 +1,9 @@ import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { Model } from 'objection'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +@ExportableModel() export class Item extends TenantBaseModel { public readonly quantityOnHand: number; public readonly name: string; diff --git a/packages/server/src/modules/ManualJournals/ManualJournals.module.ts b/packages/server/src/modules/ManualJournals/ManualJournals.module.ts index 112e513cf..bf217d88e 100644 --- a/packages/server/src/modules/ManualJournals/ManualJournals.module.ts +++ b/packages/server/src/modules/ManualJournals/ManualJournals.module.ts @@ -15,6 +15,7 @@ import { GetManualJournal } from './queries/GetManualJournal.service'; import { ManualJournalWriteGLSubscriber } from './commands/ManualJournalGLEntriesSubscriber'; import { ManualJournalGLEntries } from './commands/ManualJournalGLEntries'; import { LedgerModule } from '../Ledger/Ledger.module'; +import { ManualJournalsExportable } from './commands/ManualJournalExportable'; @Module({ imports: [BranchesModule, LedgerModule], @@ -33,7 +34,8 @@ import { LedgerModule } from '../Ledger/Ledger.module'; ManualJournalsApplication, GetManualJournal, ManualJournalGLEntries, - ManualJournalWriteGLSubscriber + ManualJournalWriteGLSubscriber, + ManualJournalsExportable ], }) export class ManualJournalsModule {} diff --git a/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts b/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts index 49ba23a93..a19a8f153 100644 --- a/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts +++ b/packages/server/src/modules/ManualJournals/ManualJournalsApplication.service.ts @@ -4,8 +4,12 @@ import { EditManualJournal } from './commands/EditManualJournal.service'; import { PublishManualJournal } from './commands/PublishManualJournal.service'; import { GetManualJournal } from './queries/GetManualJournal.service'; import { DeleteManualJournalService } from './commands/DeleteManualJournal.service'; -import { IManualJournalDTO, } from './types/ManualJournals.types'; -import { CreateManualJournalDto, EditManualJournalDto } from './dtos/ManualJournal.dto'; +import { IManualJournalsFilter } from './types/ManualJournals.types'; +import { + CreateManualJournalDto, + EditManualJournalDto, +} from './dtos/ManualJournal.dto'; +import { GetManualJournals } from './queries/GetManualJournals.service'; // import { GetManualJournals } from './queries/GetManualJournals'; @Injectable() @@ -16,7 +20,7 @@ export class ManualJournalsApplication { private deleteManualJournalService: DeleteManualJournalService, private publishManualJournalService: PublishManualJournal, private getManualJournalService: GetManualJournal, - // private getManualJournalsService: GetManualJournals, + private getManualJournalsService: GetManualJournals, ) {} /** @@ -50,9 +54,7 @@ export class ManualJournalsApplication { * @return {Promise} */ public deleteManualJournal = (manualJournalId: number) => { - return this.deleteManualJournalService.deleteManualJournal( - manualJournalId, - ); + return this.deleteManualJournalService.deleteManualJournal(manualJournalId); }; /** @@ -68,23 +70,16 @@ export class ManualJournalsApplication { /** * Retrieves the specific manual journal. * @param {number} manualJournalId - * @returns */ public getManualJournal = (manualJournalId: number) => { - return this.getManualJournalService.getManualJournal( - manualJournalId, - ); + return this.getManualJournalService.getManualJournal(manualJournalId); }; /** * Retrieves the paginated manual journals. - * @param {number} tenantId * @param {IManualJournalsFilter} filterDTO - * @returns */ - // public getManualJournals = ( - // filterDTO: IManualJournalsFilter, - // ) => { - // // return this.getManualJournalsService.getManualJournals(filterDTO); - // }; + public getManualJournals = (filterDTO: IManualJournalsFilter) => { + return this.getManualJournalsService.getManualJournals(filterDTO); + }; } diff --git a/packages/server/src/modules/ManualJournals/commands/ManualJournalExportable.ts b/packages/server/src/modules/ManualJournals/commands/ManualJournalExportable.ts index a91eee5b9..dc96bf0cd 100644 --- a/packages/server/src/modules/ManualJournals/commands/ManualJournalExportable.ts +++ b/packages/server/src/modules/ManualJournals/commands/ManualJournalExportable.ts @@ -1,30 +1,31 @@ -// import { Inject, Service } from 'typedi'; -// import { IManualJournalsFilter } from '@/interfaces'; -// import { Exportable } from '../../Export/Exportable'; -// import { ManualJournalsApplication } from '../ManualJournalsApplication'; -// import { EXPORT_SIZE_LIMIT } from '../../Export/constants'; +import { Exportable } from '../../Export/Exportable'; +import { EXPORT_SIZE_LIMIT } from '../../Export/constants'; +import { Injectable } from '@nestjs/common'; +import { IManualJournalsFilter } from '../types/ManualJournals.types'; +import { ManualJournalsApplication } from '../ManualJournalsApplication.service'; -// @Service() -// export class ManualJournalsExportable extends Exportable { -// @Inject() -// private manualJournalsApplication: ManualJournalsApplication; +@Injectable() +export class ManualJournalsExportable extends Exportable { + constructor( + private readonly manualJournalsApplication: ManualJournalsApplication, + ) { + super(); + } -// /** -// * Retrieves the manual journals data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: IManualJournalsFilter) { -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// } as IManualJournalsFilter; + /** + * Retrieves the manual journals data to exportable sheet. + */ + public exportable(query: IManualJournalsFilter) { + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + } as IManualJournalsFilter; -// return this.manualJournalsApplication -// .getManualJournals(tenantId, parsedQuery) -// .then((output) => output.manualJournals); -// } -// } + return this.manualJournalsApplication + .getManualJournals(parsedQuery) + .then((output) => output.manualJournals); + } +} diff --git a/packages/server/src/modules/ManualJournals/models/ManualJournal.ts b/packages/server/src/modules/ManualJournals/models/ManualJournal.ts index c7892eed3..e9e1b1077 100644 --- a/packages/server/src/modules/ManualJournals/models/ManualJournal.ts +++ b/packages/server/src/modules/ManualJournals/models/ManualJournal.ts @@ -9,7 +9,9 @@ import { Model, mixin } from 'objection'; import { ManualJournalEntry } from './ManualJournalEntry'; import { Document } from '@/modules/ChromiumlyTenancy/models/Document'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +@ExportableModel() export class ManualJournal extends TenantBaseModel { date: Date; journalNumber: string; diff --git a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts index d9709dd14..c6292691f 100644 --- a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts +++ b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts @@ -34,6 +34,7 @@ import { MailModule } from '../Mail/Mail.module'; import { SendPaymentReceivedMailProcessor } from './processors/PaymentReceivedMailNotification.processor'; import { BullModule } from '@nestjs/bull'; import { SEND_PAYMENT_RECEIVED_MAIL_QUEUE } from './constants'; +import { PaymentsReceivedExportable } from './commands/PaymentsReceivedExportable'; @Module({ controllers: [PaymentReceivesController], @@ -59,6 +60,7 @@ import { SEND_PAYMENT_RECEIVED_MAIL_QUEUE } from './constants'; GetPaymentsReceivedService, SendPaymentReceiveMailNotification, SendPaymentReceivedMailProcessor, + PaymentsReceivedExportable ], exports: [ PaymentReceivesApplication, diff --git a/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts b/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts index fdac2fda6..abdd81a95 100644 --- a/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts +++ b/packages/server/src/modules/PaymentReceived/commands/PaymentsReceivedExportable.ts @@ -1,39 +1,34 @@ -// import { Inject, Service } from 'typedi'; -// import { IAccountsStructureType, IPaymentsReceivedFilter } from '@/interfaces'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { PaymentReceivesApplication } from './PaymentReceived.application'; -// import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; +import { Injectable } from '@nestjs/common'; +import { PaymentReceivesApplication } from '../PaymentReceived.application'; +import { IPaymentsReceivedFilter } from '../types/PaymentReceived.types'; +import { EXPORT_SIZE_LIMIT } from '@/modules/Export/constants'; +import { Exportable } from '@/modules/Export/Exportable'; -// @Service() -// export class PaymentsReceivedExportable extends Exportable { -// @Inject() -// private paymentReceivedApp: PaymentReceivesApplication; +@Injectable() +export class PaymentsReceivedExportable extends Exportable { + constructor(private readonly paymentReceivedApp: PaymentReceivesApplication) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @param {IPaymentsReceivedFilter} query - -// * @returns -// */ -// public exportable(tenantId: number, query: IPaymentsReceivedFilter) { -// const filterQuery = (builder) => { -// builder.withGraphFetched('entries.invoice'); -// builder.withGraphFetched('branch'); -// }; - -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// inactiveMode: false, -// ...query, -// structure: IAccountsStructureType.Flat, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// filterQuery, -// } as IPaymentsReceivedFilter; - -// return this.paymentReceivedApp -// .getPaymentReceives(tenantId, parsedQuery) -// .then((output) => output.paymentReceives); -// } -// } + /** + * Retrieves the accounts data to exportable sheet. + * @param {number} tenantId + * @param {IPaymentsReceivedFilter} query - + * @returns + */ + public exportable(query: IPaymentsReceivedFilter) { + const filterQuery = (builder) => { + builder.withGraphFetched('entries.invoice'); + builder.withGraphFetched('branch'); + }; + const parsedQuery = { + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + filterQuery, + ...query + }; + return this.paymentReceivedApp + .getPaymentsReceived(parsedQuery) + .then((output) => output.paymentReceives); + } +} diff --git a/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts index a3f82f5c2..181a910e4 100644 --- a/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts +++ b/packages/server/src/modules/PaymentReceived/models/PaymentReceived.ts @@ -1,7 +1,9 @@ import { Model } from 'objection'; import { PaymentReceivedEntry } from './PaymentReceivedEntry'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +@ExportableModel() export class PaymentReceived extends TenantBaseModel { customerId: number; paymentDate: string; diff --git a/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts b/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts index 83a5e2bef..d310869ae 100644 --- a/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts +++ b/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts @@ -35,6 +35,7 @@ import { TemplateInjectableModule } from '../TemplateInjectable/TemplateInjectab import { SaleEstimatePdfTemplate } from '../SaleInvoices/queries/SaleEstimatePdfTemplate.service'; import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module'; import { SendSaleEstimateMailQueue } from './types/SaleEstimates.types'; +import { SaleEstimatesExportable } from './SaleEstimatesExportable'; @Module({ imports: [ @@ -74,7 +75,8 @@ import { SendSaleEstimateMailQueue } from './types/SaleEstimates.types'; SaleEstimatesApplication, SendSaleEstimateMail, GetSaleEstimatePdf, - SaleEstimatePdfTemplate + SaleEstimatePdfTemplate, + SaleEstimatesExportable ], }) export class SaleEstimatesModule {} diff --git a/packages/server/src/modules/SaleEstimates/SaleEstimatesExportable.ts b/packages/server/src/modules/SaleEstimates/SaleEstimatesExportable.ts index 889e7ca7a..4937223fe 100644 --- a/packages/server/src/modules/SaleEstimates/SaleEstimatesExportable.ts +++ b/packages/server/src/modules/SaleEstimates/SaleEstimatesExportable.ts @@ -1,35 +1,38 @@ -// import { Inject, Service } from 'typedi'; -// import { ISalesInvoicesFilter } from '@/interfaces'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { SaleEstimatesApplication } from './SaleEstimates.application'; -// import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; +import { Injectable } from '@nestjs/common'; +import { EXPORT_SIZE_LIMIT } from '../Export/constants'; +import { Exportable } from '../Export/Exportable'; +import { ISalesInvoicesFilter } from '../SaleInvoices/SaleInvoice.types'; +import { SaleEstimatesApplication } from './SaleEstimates.application'; +import { ISalesEstimatesFilter } from './types/SaleEstimates.types'; -// @Service() -// export class SaleEstimatesExportable extends Exportable { -// @Inject() -// private saleEstimatesApplication: SaleEstimatesApplication; +@Injectable() +export class SaleEstimatesExportable extends Exportable { + constructor( + private readonly saleEstimatesApplication: SaleEstimatesApplication, + ) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: ISalesInvoicesFilter) { -// const filterQuery = (query) => { -// query.withGraphFetched('branch'); -// query.withGraphFetched('warehouse'); -// }; -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// filterQuery, -// } as ISalesInvoicesFilter; + /** + * Retrieves the accounts data to exportable sheet. + * @param {ISalesEstimatesFilter} query - + */ + public exportable(query: ISalesEstimatesFilter) { + const filterQuery = (query) => { + query.withGraphFetched('branch'); + query.withGraphFetched('warehouse'); + }; + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + filterQuery, + } as ISalesInvoicesFilter; -// return this.saleEstimatesApplication -// .getSaleEstimates(tenantId, parsedQuery) -// .then((output) => output.salesEstimates); -// } -// } + return this.saleEstimatesApplication + .getSaleEstimates(parsedQuery) + .then((output) => output.salesEstimates); + } +} diff --git a/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts b/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts index 611881f8f..c772eb544 100644 --- a/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts +++ b/packages/server/src/modules/SaleEstimates/models/SaleEstimate.ts @@ -2,8 +2,9 @@ import * as moment from 'moment'; import { Model } from 'objection'; import { Injectable } from '@nestjs/common'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; -@Injectable() +@ExportableModel() export class SaleEstimate extends TenantBaseModel { exchangeRate!: number; amount!: number; diff --git a/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts b/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts index a4ac13327..3c5bcbfe3 100644 --- a/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts +++ b/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts @@ -56,6 +56,7 @@ import { SaleInvoiceCostGLEntries } from './SaleInvoiceCostGLEntries'; import { InvoicePaymentsGLEntriesRewrite } from './InvoicePaymentsGLRewrite'; import { PaymentsReceivedModule } from '../PaymentReceived/PaymentsReceived.module'; import { SaleInvoicesCost } from './SalesInvoicesCost'; +import { SaleInvoicesExportable } from './commands/SaleInvoicesExportable'; @Module({ imports: [ @@ -118,6 +119,7 @@ import { SaleInvoicesCost } from './SalesInvoicesCost'; SaleInvoiceWriteInventoryTransactionsSubscriber, InvoicePaymentsGLEntriesRewrite, SaleInvoicesCost, + SaleInvoicesExportable ], exports: [GetSaleInvoice, SaleInvoicesCost, SaleInvoicePdf], }) diff --git a/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts b/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts index 319c1d801..4d8df9c25 100644 --- a/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts +++ b/packages/server/src/modules/SaleInvoices/commands/SaleInvoicesExportable.ts @@ -1,35 +1,39 @@ -// import { Inject, Service } from 'typedi'; -// import { ISalesInvoicesFilter } from '@/interfaces'; -// import { SaleInvoiceApplication } from './SaleInvoices.application'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; +import { Exportable } from '@/modules/Export/Exportable'; +import { Injectable } from '@nestjs/common'; +import { SaleInvoiceApplication } from '../SaleInvoices.application'; +import { ISalesInvoicesFilter } from '../SaleInvoice.types'; +import { EXPORT_SIZE_LIMIT } from '@/modules/Export/constants'; +import { ExportableService } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { SaleInvoice } from '../models/SaleInvoice'; -// @Service() -// export class SaleInvoicesExportable extends Exportable { -// @Inject() -// private saleInvoicesApplication: SaleInvoiceApplication; +@Injectable() +@ExportableService({ name: SaleInvoice.name }) +export class SaleInvoicesExportable extends Exportable{ + constructor( + private readonly saleInvoicesApplication: SaleInvoiceApplication, + ) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: ISalesInvoicesFilter) { -// const filterQuery = (query) => { -// query.withGraphFetched('branch'); -// query.withGraphFetched('warehouse'); -// }; -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// filterQuery, -// } as ISalesInvoicesFilter; + /** + * Retrieves the accounts data to exportable sheet. + */ + public exportable(query: ISalesInvoicesFilter) { + const filterQuery = (query) => { + query.withGraphFetched('branch'); + query.withGraphFetched('warehouse'); + }; + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + filterQuery, + } as ISalesInvoicesFilter; -// return this.saleInvoicesApplication -// .getSaleInvoices(tenantId, parsedQuery) -// .then((output) => output.salesInvoices); -// } -// } + return this.saleInvoicesApplication + .getSaleInvoices(parsedQuery) + .then((output) => output.salesInvoices); + } +} diff --git a/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts b/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts index 3d64ba94b..c7d490eb8 100644 --- a/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts +++ b/packages/server/src/modules/SaleInvoices/models/SaleInvoice.ts @@ -14,8 +14,10 @@ import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; import { PaymentIntegrationTransactionLink } from '../SaleInvoice.types'; import { TransactionPaymentServiceEntry } from '@/modules/PaymentServices/models/TransactionPaymentServiceEntry.model'; import { InjectAttachable } from '@/modules/Attachments/decorators/InjectAttachable.decorator'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; @InjectAttachable() +@ExportableModel() export class SaleInvoice extends TenantBaseModel{ public taxAmountWithheld: number; public balance: number; diff --git a/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts b/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts index 255be3d42..bda6a185c 100644 --- a/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts +++ b/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts @@ -35,6 +35,7 @@ import { MailNotificationModule } from '../MailNotification/MailNotification.mod import { SendSaleReceiptMailProcess } from './processes/SendSaleReceiptMail.process'; import { MailModule } from '../Mail/Mail.module'; import { SendSaleReceiptMailQueue } from './constants'; +import { SaleReceiptsExportable } from './commands/SaleReceiptsExportable'; @Module({ controllers: [SaleReceiptsController], @@ -75,6 +76,7 @@ import { SendSaleReceiptMailQueue } from './constants'; SaleReceiptInventoryTransactions, SaleReceiptInventoryTransactionsSubscriber, SendSaleReceiptMailProcess, + SaleReceiptsExportable ], }) export class SaleReceiptsModule {} diff --git a/packages/server/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts index a8f91bea5..88d565f87 100644 --- a/packages/server/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts +++ b/packages/server/src/modules/SaleReceipts/commands/SaleReceiptsExportable.ts @@ -1,35 +1,35 @@ -// import { Inject, Service } from 'typedi'; -// import { ISalesReceiptsFilter } from '@/interfaces'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { SaleReceiptApplication } from './SaleReceiptApplication'; -// import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; +import { Exportable } from '@/modules/Export/Exportable'; +import { Injectable } from '@nestjs/common'; +import { SaleReceiptApplication } from '../SaleReceiptApplication.service'; +import { ISalesReceiptsFilter } from '../types/SaleReceipts.types'; +import { EXPORT_SIZE_LIMIT } from '@/modules/Export/constants'; -// @Service() -// export class SaleReceiptsExportable extends Exportable { -// @Inject() -// private saleReceiptsApp: SaleReceiptApplication; +@Injectable() +export class SaleReceiptsExportable extends Exportable { + constructor(private readonly saleReceiptsApp: SaleReceiptApplication) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: ISalesReceiptsFilter) { -// const filterQuery = (query) => { -// query.withGraphFetched('branch'); -// query.withGraphFetched('warehouse'); -// }; -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// filterQuery, -// } as ISalesReceiptsFilter; + /** + * Retrieves the accounts data to exportable sheet. + * @param {ISalesReceiptsFilter} query - + */ + public exportable(query: ISalesReceiptsFilter) { + const filterQuery = (query) => { + query.withGraphFetched('branch'); + query.withGraphFetched('warehouse'); + }; + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + filterQuery, + } as ISalesReceiptsFilter; -// return this.saleReceiptsApp -// .getSaleReceipts(tenantId, parsedQuery) -// .then((output) => output.data); -// } -// } + return this.saleReceiptsApp + .getSaleReceipts(parsedQuery) + .then((output) => output.data); + } +} diff --git a/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts b/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts index 9102075b9..80b880398 100644 --- a/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts +++ b/packages/server/src/modules/SaleReceipts/models/SaleReceipt.ts @@ -12,6 +12,7 @@ import { MetadataModelMixin } from '@/modules/DynamicListing/models/MetadataMode import { ResourceableModelMixin } from '@/modules/Resource/models/ResourcableModel'; import { CustomViewBaseModelMixin } from '@/modules/CustomViews/CustomViewBaseModel'; import { SearchableBaseModelMixin } from '@/modules/DynamicListing/models/SearchableBaseModel'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; const ExtendedModel = R.pipe( CustomViewBaseModelMixin, @@ -20,6 +21,7 @@ const ExtendedModel = R.pipe( MetadataModelMixin, )(BaseModel); +@ExportableModel() export class SaleReceipt extends ExtendedModel { public amount!: number; public exchangeRate!: number; diff --git a/packages/server/src/modules/TaxRates/TaxRate.module.ts b/packages/server/src/modules/TaxRates/TaxRate.module.ts index 97d62856f..38f886255 100644 --- a/packages/server/src/modules/TaxRates/TaxRate.module.ts +++ b/packages/server/src/modules/TaxRates/TaxRate.module.ts @@ -21,6 +21,7 @@ import { WriteTaxTransactionsItemEntries } from './WriteTaxTransactionsItemEntri import { SyncItemTaxRateOnEditTaxRate } from './SyncItemTaxRateOnEditTaxRate'; import { RegisterTenancyModel } from '../Tenancy/TenancyModels/Tenancy.module'; import { TaxRateTransaction } from './models/TaxRateTransaction.model'; +import { TaxRatesExportable } from './TaxRatesExportable'; const models = [RegisterTenancyModel(TaxRateTransaction)]; @@ -47,6 +48,7 @@ const models = [RegisterTenancyModel(TaxRateTransaction)]; SyncItemTaxRateOnEditTaxSubscriber, WriteTaxTransactionsItemEntries, SyncItemTaxRateOnEditTaxRate, + TaxRatesExportable ], exports: [ItemEntriesTaxTransactions, ...models], }) diff --git a/packages/server/src/modules/TaxRates/TaxRatesExportable.ts b/packages/server/src/modules/TaxRates/TaxRatesExportable.ts index 079a09637..ed2509840 100644 --- a/packages/server/src/modules/TaxRates/TaxRatesExportable.ts +++ b/packages/server/src/modules/TaxRates/TaxRatesExportable.ts @@ -1,18 +1,20 @@ -// import { Inject, Service } from 'typedi'; -// import { Exportable } from '../Export/Exportable'; -// import { TaxRatesApplication } from './TaxRate.application'; +import { ExportableService } from '../Export/decorators/ExportableModel.decorator'; +import { Exportable } from '../Export/Exportable'; +import { TaxRateModel } from './models/TaxRate.model'; +import { TaxRatesApplication } from './TaxRate.application'; +import { Injectable } from '@nestjs/common'; -// @Service() -// export class TaxRatesExportable extends Exportable { -// @Inject() -// private taxRatesApplication: TaxRatesApplication; +@Injectable() +@ExportableService({ name: TaxRateModel.name }) +export class TaxRatesExportable extends Exportable { + constructor(private readonly taxRatesApplication: TaxRatesApplication) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number) { -// return this.taxRatesApplication.getTaxRates(tenantId); -// } -// } + /** + * Retrieves the accounts data to exportable sheet. + */ + public exportable() { + return this.taxRatesApplication.getTaxRates(); + } +} diff --git a/packages/server/src/modules/TaxRates/models/TaxRate.model.ts b/packages/server/src/modules/TaxRates/models/TaxRate.model.ts index 4bdd9bab4..1442e7920 100644 --- a/packages/server/src/modules/TaxRates/models/TaxRate.model.ts +++ b/packages/server/src/modules/TaxRates/models/TaxRate.model.ts @@ -5,7 +5,9 @@ import { mixin, Model, raw } from 'objection'; // import TaxRateMeta from './TaxRate.settings'; // import ModelSetting from './ModelSetting'; import { BaseModel } from '@/models/Model'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +@ExportableModel() export class TaxRateModel extends BaseModel { active!: boolean; code!: string; diff --git a/packages/server/src/modules/VendorCredit/VendorCredits.module.ts b/packages/server/src/modules/VendorCredit/VendorCredits.module.ts index d7d81c3ec..915119f4a 100644 --- a/packages/server/src/modules/VendorCredit/VendorCredits.module.ts +++ b/packages/server/src/modules/VendorCredit/VendorCredits.module.ts @@ -25,6 +25,7 @@ import { VendorCreditInventoryTransactions } from './commands/VendorCreditInvent import { GetVendorCreditsService } from './queries/GetVendorCredits.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { InventoryCostModule } from '../InventoryCost/InventoryCost.module'; +import { VendorCreditsExportable } from './commands/VendorCreditsExportable'; @Module({ imports: [ @@ -54,7 +55,8 @@ import { InventoryCostModule } from '../InventoryCost/InventoryCost.module'; VendorCreditGLEntries, VendorCreditGlEntriesSubscriber, VendorCreditInventoryTransactions, - VendorCreditInventoryTransactionsSubscriber + VendorCreditInventoryTransactionsSubscriber, + VendorCreditsExportable ], exports: [ CreateVendorCreditService, diff --git a/packages/server/src/modules/VendorCredit/commands/VendorCreditsExportable.ts b/packages/server/src/modules/VendorCredit/commands/VendorCreditsExportable.ts index 39a688896..84291d10c 100644 --- a/packages/server/src/modules/VendorCredit/commands/VendorCreditsExportable.ts +++ b/packages/server/src/modules/VendorCredit/commands/VendorCreditsExportable.ts @@ -1,36 +1,38 @@ -// import { Inject, Service } from 'typedi'; -// import { IVendorCreditsQueryDTO } from '@/interfaces'; -// import ListVendorCredits from '../queries/ListVendorCredits'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { QueryBuilder } from 'knex'; +import { Injectable } from '@nestjs/common'; +import { VendorCreditsApplicationService } from '../VendorCreditsApplication.service'; +import { Exportable } from '@/modules/Export/Exportable'; +import { IVendorCreditsQueryDTO } from '../types/VendorCredit.types'; +import { ExportableService } from '@/modules/Export/decorators/ExportableModel.decorator'; +import { VendorCredit } from '../models/VendorCredit'; -// @Service() -// export class VendorCreditsExportable extends Exportable { -// @Inject() -// private getVendorCredits: ListVendorCredits; +@Injectable() +@ExportableService({ name: VendorCredit.name }) +export class VendorCreditsExportable extends Exportable { + constructor( + private readonly vendorCreditsApp: VendorCreditsApplicationService, + ) { + super(); + } -// /** -// * Retrieves the vendor credits data to exportable sheet. -// * @param {number} tenantId - -// * @param {IVendorCreditsQueryDTO} query - -// * @returns {} -// */ -// public exportable(tenantId: number, query: IVendorCreditsQueryDTO) { -// const filterQuery = (query) => { -// query.withGraphFetched('branch'); -// query.withGraphFetched('warehouse'); -// }; -// const parsedQuery = { -// sortOrder: 'desc', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: 12000, -// filterQuery, -// } as IVendorCreditsQueryDTO; + /** + * Retrieves the vendor credits data to exportable sheet. + */ + public exportable(query: IVendorCreditsQueryDTO) { + const filterQuery = (query) => { + query.withGraphFetched('branch'); + query.withGraphFetched('warehouse'); + }; + const parsedQuery = { + sortOrder: 'desc', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: 12000, + filterQuery, + } as IVendorCreditsQueryDTO; -// return this.getVendorCredits -// .getVendorCredits(tenantId, parsedQuery) -// .then((output) => output.vendorCredits); -// } -// } + return this.vendorCreditsApp + .getVendorCredits(parsedQuery) + .then((output) => output.vendorCredits); + } +} diff --git a/packages/server/src/modules/VendorCredit/models/VendorCredit.ts b/packages/server/src/modules/VendorCredit/models/VendorCredit.ts index bb6f5754d..1dfbbac29 100644 --- a/packages/server/src/modules/VendorCredit/models/VendorCredit.ts +++ b/packages/server/src/modules/VendorCredit/models/VendorCredit.ts @@ -5,7 +5,9 @@ import { Branch } from '@/modules/Branches/models/Branch.model'; import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry'; import { DiscountType } from '@/common/types/Discount'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; +@ExportableModel() export class VendorCredit extends TenantBaseModel { vendorId: number; amount: number; diff --git a/packages/server/src/modules/Vendors/Vendors.module.ts b/packages/server/src/modules/Vendors/Vendors.module.ts index 456fbe87e..88cf6efa0 100644 --- a/packages/server/src/modules/Vendors/Vendors.module.ts +++ b/packages/server/src/modules/Vendors/Vendors.module.ts @@ -14,6 +14,7 @@ import { TenancyContext } from '../Tenancy/TenancyContext.service'; import { VendorsController } from './Vendors.controller'; import { GetVendorsService } from './queries/GetVendors.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; +import { VendorsExportable } from './VendorsExportable'; @Module({ imports: [TenancyDatabaseModule, DynamicListModule], @@ -31,6 +32,7 @@ import { DynamicListModule } from '../DynamicListing/DynamicList.module'; VendorsApplication, TransformerInjectable, TenancyContext, + VendorsExportable ], }) export class VendorsModule {} diff --git a/packages/server/src/modules/Vendors/VendorsExportable.ts b/packages/server/src/modules/Vendors/VendorsExportable.ts index 4db7de1bd..9f9913954 100644 --- a/packages/server/src/modules/Vendors/VendorsExportable.ts +++ b/packages/server/src/modules/Vendors/VendorsExportable.ts @@ -1,30 +1,34 @@ -// import { Inject, Service } from 'typedi'; -// import { IItemsFilter } from '@/interfaces'; -// import { Exportable } from '@/services/Export/Exportable'; -// import { VendorsApplication } from './VendorsApplication'; -// import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants'; +import { Injectable } from '@nestjs/common'; +import { VendorsApplication } from './VendorsApplication.service'; +import { Exportable } from '../Export/Exportable'; +import { IVendorsFilter } from './types/Vendors.types'; +import { EXPORT_SIZE_LIMIT } from '../Export/constants'; +import { ExportableService } from '../Export/decorators/ExportableModel.decorator'; +import { Vendor } from './models/Vendor'; -// @Service() -// export class VendorsExportable extends Exportable { -// @Inject() -// private vendorsApplication: VendorsApplication; +@Injectable() +@ExportableService({ name: Vendor.name }) +export class VendorsExportable extends Exportable { + constructor( + private readonly vendorsApplication: VendorsApplication, + ) { + super(); + } -// /** -// * Retrieves the accounts data to exportable sheet. -// * @param {number} tenantId -// * @returns -// */ -// public exportable(tenantId: number, query: IItemsFilter) { -// const parsedQuery = { -// sortOrder: 'DESC', -// columnSortBy: 'created_at', -// ...query, -// page: 1, -// pageSize: EXPORT_SIZE_LIMIT, -// } as IItemsFilter; + /** + * Retrieves the vendors data to exportable sheet. + */ + public exportable(query: IVendorsFilter) { + const parsedQuery = { + sortOrder: 'DESC', + columnSortBy: 'created_at', + ...query, + page: 1, + pageSize: EXPORT_SIZE_LIMIT, + } as IVendorsFilter; -// return this.vendorsApplication -// .getVendors(tenantId, parsedQuery) -// .then((output) => output.vendors); -// } -// } + return this.vendorsApplication + .getVendors(parsedQuery) + .then((output) => output.vendors); + } +} diff --git a/packages/server/src/modules/Vendors/models/Vendor.ts b/packages/server/src/modules/Vendors/models/Vendor.ts index 0005a00db..194912df4 100644 --- a/packages/server/src/modules/Vendors/models/Vendor.ts +++ b/packages/server/src/modules/Vendors/models/Vendor.ts @@ -8,6 +8,7 @@ import { Model, mixin } from 'objection'; // import ModelSearchable from './ModelSearchable'; import { BaseModel } from '@/models/Model'; import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; +import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator'; // class VendorQueryBuilder extends PaginationQueryBuilder { // constructor(...args) { @@ -21,6 +22,7 @@ import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; // } // } +@ExportableModel() export class Vendor extends TenantBaseModel { contactService: string; contactType: string; diff --git a/packages/server/src/utils/multi-number-parse.ts b/packages/server/src/utils/multi-number-parse.ts new file mode 100644 index 000000000..72c3a291f --- /dev/null +++ b/packages/server/src/utils/multi-number-parse.ts @@ -0,0 +1,131 @@ +// @ts-nocheck +const validGrouping = (integerPart, sep) => + integerPart.split(sep).reduce((acc, group, idx) => { + if (idx > 0) { + return acc && group.length === 3; + } + + return acc && group.length; + }, true); + +export const multiNumberParse = (number: number | string, standardDecSep = '.') => { + // if it's a number already, this is going to be easy... + if (typeof number === 'number') { + return number; + } + + // check validity of parameters + if (!number || typeof number !== 'string') { + throw new TypeError('number must be a string'); + } + + if (typeof standardDecSep !== 'string' || standardDecSep.length !== 1) { + throw new TypeError('standardDecSep must be a single character string'); + } + + // check if negative + const negative = number[0] === '-'; + + // strip unnecessary chars + const stripped = number + // get rid of trailing non-numbers + .replace(/[^\d]+$/, '') + // get rid of the signal + .slice(negative ? 1 : 0); + + // analyze separators + const separators = (stripped.match(/[^\d]/g) || []).reduce( + (acc, sep, idx) => { + const sepChr = `str_${sep.codePointAt(0)}`; + const cnt = ((acc[sepChr] || {}).cnt || 0) + 1; + + return { + ...acc, + [sepChr]: { + sep, + cnt, + lastIdx: idx, + }, + }; + }, + {} + ); + + // check correctness of separators + const sepKeys = Object.keys(separators); + + if (!sepKeys.length) { + // no separator, that's easy-peasy + return parseInt(stripped, 10) * (negative ? -1 : 1); + } + + if (sepKeys.length > 2) { + // there's more than 2 separators, that's wrong + return Number.NaN; + } + + if (sepKeys.length > 1) { + // there's two separators, that's ok by now + let sep1 = separators[sepKeys[0]]; + let sep2 = separators[sepKeys[1]]; + + if (sep1.lastIdx > sep2.lastIdx) { + // swap + [sep1, sep2] = [sep2, sep1]; + } + + // if more than one separator appears more than once, that's wrong + if (sep1.cnt > 1 && sep2.cnt > 1) { + return Number.NaN; + } + + // check if the last separator is the single one + if (sep2.cnt > 1) { + return Number.NaN; + } + + // check the groupings + const [integerPart] = stripped.split(sep2.sep); + + if (!validGrouping(integerPart, sep1.sep)) { + return Number.NaN; + } + + // ok, we got here! let's handle it + return ( + parseFloat(stripped.split(sep1.sep).join('').replace(sep2.sep, '.')) * + (negative ? -1 : 1) + ); + } + + // ok, only one separator, which is nice + const sep = separators[sepKeys[0]]; + + if (sep.cnt > 1) { + // there's more than one separator, which means it's integer + // let's check the groupings + if (!validGrouping(stripped, sep.sep)) { + return Number.NaN; + } + + // it's valid, let's return an integer + return parseInt(stripped.split(sep.sep).join(''), 10) * (negative ? -1 : 1); + } + + // just one separator, let's check last group + const groups = stripped.split(sep.sep); + + if (groups[groups.length - 1].length === 3) { + // ok, we're in ambiguous territory here + + if (sep.sep !== standardDecSep) { + // it's an integer + return ( + parseInt(stripped.split(sep.sep).join(''), 10) * (negative ? -1 : 1) + ); + } + } + + // well, it looks like it's a simple float + return parseFloat(stripped.replace(sep.sep, '.')) * (negative ? -1 : 1); +}; \ No newline at end of file