diff --git a/packages/server/src/i18n/en/transaction_type.json b/packages/server/src/i18n/en/transaction_type.json new file mode 100644 index 000000000..5bd909d21 --- /dev/null +++ b/packages/server/src/i18n/en/transaction_type.json @@ -0,0 +1,24 @@ +{ + "sale_invoice": "Sale invoice", + "sale_receipt": "Sale receipt", + "payment_received": "Payment received", + "bill": "Bill", + "bill_payment": "Payment made", + "vendor_opening_balance": "Vendor opening balance", + "customer_opening_balance": "Customer opening balance", + "inventory_adjustment": "Inventory adjustment", + "manual_journal": "Manual journal", + "expense": "Expense", + "owner_contribution": "Owner contribution", + "transfer_to_account": "Transfer to account", + "transfer_from_account": "Transfer from account", + "other_income": "Other income", + "other_expense": "Other expense", + "owner_drawing": "Owner drawing", + "invoice_write_off": "Invoice write-off", + "credit_note": "Credit Note", + "vendor_credit": "Vendor Credit", + "refund_credit_note": "Refund Credit Note", + "refund_vendor_credit": "Refund Vendor Credit", + "landed_cost": "Landed Cost" +} \ No newline at end of file diff --git a/packages/server/src/main.ts b/packages/server/src/main.ts index 2bfe99fce..e9b404860 100644 --- a/packages/server/src/main.ts +++ b/packages/server/src/main.ts @@ -8,6 +8,7 @@ import { ServiceErrorFilter } from './common/filters/service-error.filter'; import { ValidationPipe } from './common/pipes/ClassValidation.pipe'; import { ToJsonInterceptor } from './common/interceptors/to-json.interceptor'; +global.__public_dirname = path.join(__dirname, '..', 'public'); global.__static_dirname = path.join(__dirname, '../static'); global.__views_dirname = path.join(global.__static_dirname, '/views'); global.__images_dirname = path.join(global.__static_dirname, '/images'); diff --git a/packages/server/src/modules/Accounts/models/AccountTransaction.model.ts b/packages/server/src/modules/Accounts/models/AccountTransaction.model.ts index 3ec4b2994..9319d383d 100644 --- a/packages/server/src/modules/Accounts/models/AccountTransaction.model.ts +++ b/packages/server/src/modules/Accounts/models/AccountTransaction.model.ts @@ -4,6 +4,7 @@ import { unitOfTime } from 'moment'; import { isEmpty, castArray } from 'lodash'; import { BaseModel } from '@/models/Model'; import { Account } from './Account.model'; +import { getTransactionTypeLabel } from '@/modules/BankingTransactions/utils'; // import { getTransactionTypeLabel } from '@/utils/transactions-types'; export class AccountTransaction extends BaseModel { @@ -19,7 +20,6 @@ export class AccountTransaction extends BaseModel { public readonly date: Date | string; public readonly transactionType: string; public readonly currencyCode: string; - public readonly referenceTypeFormatted: string; public readonly transactionNumber!: string; public readonly referenceNumber!: string; public readonly note!: string; @@ -72,13 +72,13 @@ export class AccountTransaction extends BaseModel { return this.debit * this.exchangeRate; } - // /** - // * Retrieve formatted reference type. - // * @return {string} - // */ - // get referenceTypeFormatted() { - // return getTransactionTypeLabel(this.referenceType, this.transactionType); - // } + /** + * Retrieve formatted reference type. + * @return {string} + */ + get referenceTypeFormatted() { + return getTransactionTypeLabel(this.referenceType, this.transactionType); + } /** * Model modifiers. diff --git a/packages/server/src/modules/App/App.module.ts b/packages/server/src/modules/App/App.module.ts index 59a9103ea..0123189f7 100644 --- a/packages/server/src/modules/App/App.module.ts +++ b/packages/server/src/modules/App/App.module.ts @@ -3,6 +3,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { EventEmitterModule } from '@nestjs/event-emitter'; import { APP_INTERCEPTOR } from '@nestjs/core'; import { join } from 'path'; +import { ServeStaticModule } from '@nestjs/serve-static'; import { RedisModule } from '@liaoliaots/nestjs-redis'; import { AcceptLanguageResolver, @@ -96,6 +97,10 @@ import { BillLandedCostsModule } from '../BillLandedCosts/BillLandedCosts.module @Module({ imports: [ + ServeStaticModule.forRoot({ + rootPath: join(__dirname, '../../..', 'public'), + serveRoot: '/public', + }), ConfigModule.forRoot({ envFilePath: '.env', load: config, @@ -220,7 +225,7 @@ import { BillLandedCostsModule } from '../BillLandedCosts/BillLandedCosts.module CurrenciesModule, MiscellaneousModule, UsersModule, - ContactsModule + ContactsModule, ], controllers: [AppController], providers: [ diff --git a/packages/server/src/modules/Auth/Auth.controller.ts b/packages/server/src/modules/Auth/Auth.controller.ts index 8ce4714e3..8b9193986 100644 --- a/packages/server/src/modules/Auth/Auth.controller.ts +++ b/packages/server/src/modules/Auth/Auth.controller.ts @@ -34,7 +34,10 @@ export class AuthController { @UseGuards(LocalAuthGuard) @ApiOperation({ summary: 'Sign in a user' }) @ApiBody({ type: AuthSigninDto }) - async signin(@Request() req: Request & { user: SystemUser }, @Body() signinDto: AuthSigninDto) { + async signin( + @Request() req: Request & { user: SystemUser }, + @Body() signinDto: AuthSigninDto, + ) { const { user } = req; const tenant = await this.tenantModel.query().findById(user.tenantId); @@ -68,7 +71,6 @@ export class AuthController { return this.authApp.signUpConfirm(email, token); } - @Post('/send_reset_password') @ApiOperation({ summary: 'Send reset password email' }) @ApiBody({ diff --git a/packages/server/src/modules/Auth/dtos/AuthSignin.dto.ts b/packages/server/src/modules/Auth/dtos/AuthSignin.dto.ts index 9d9922d7a..c8eb38312 100644 --- a/packages/server/src/modules/Auth/dtos/AuthSignin.dto.ts +++ b/packages/server/src/modules/Auth/dtos/AuthSignin.dto.ts @@ -1,10 +1,16 @@ import { IsNotEmpty, IsString } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; export class AuthSigninDto { + @ApiProperty({ example: 'password123', description: 'User password' }) @IsNotEmpty() @IsString() password: string; + @ApiProperty({ + example: 'user@example.com', + description: 'User email address', + }) @IsNotEmpty() @IsString() email: string; diff --git a/packages/server/src/modules/Auth/dtos/AuthSignup.dto.ts b/packages/server/src/modules/Auth/dtos/AuthSignup.dto.ts index 1830fca13..58a5eb483 100644 --- a/packages/server/src/modules/Auth/dtos/AuthSignup.dto.ts +++ b/packages/server/src/modules/Auth/dtos/AuthSignup.dto.ts @@ -1,19 +1,27 @@ import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; export class AuthSignupDto { + @ApiProperty({ example: 'John', description: 'User first name' }) @IsNotEmpty() @IsString() firstName: string; + @ApiProperty({ example: 'Doe', description: 'User last name' }) @IsNotEmpty() @IsString() lastName: string; + @ApiProperty({ + example: 'john.doe@example.com', + description: 'User email address', + }) @IsNotEmpty() @IsString() @IsEmail() email: string; + @ApiProperty({ example: 'password123', description: 'User password' }) @IsNotEmpty() @IsString() password: string; diff --git a/packages/server/src/modules/BankingPlaid/dtos/PlaidItem.dto.ts b/packages/server/src/modules/BankingPlaid/dtos/PlaidItem.dto.ts index f0b2c2f68..549dca706 100644 --- a/packages/server/src/modules/BankingPlaid/dtos/PlaidItem.dto.ts +++ b/packages/server/src/modules/BankingPlaid/dtos/PlaidItem.dto.ts @@ -1,26 +1,31 @@ +import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString } from 'class-validator'; export class PlaidItemDto { @IsString() @IsNotEmpty() + @ApiProperty({ example: '123', description: 'The public token' }) publicToken: string; @IsString() @IsNotEmpty() + @ApiProperty({ example: '123', description: 'The institution ID' }) institutionId: string; } export class PlaidWebhookDto { @IsString() @IsNotEmpty() + @ApiProperty({ example: '123', description: 'The Plaid item ID' }) itemId: string; @IsString() @IsNotEmpty() + @ApiProperty({ example: '123', description: 'The Plaid webhook type' }) webhookType: string; @IsString() @IsNotEmpty() + @ApiProperty({ example: '123', description: 'The Plaid webhook code' }) webhookCode: string; } - \ No newline at end of file diff --git a/packages/server/src/modules/BankingTransactions/constants.ts b/packages/server/src/modules/BankingTransactions/constants.ts index 4a80ca034..5f7f219b9 100644 --- a/packages/server/src/modules/BankingTransactions/constants.ts +++ b/packages/server/src/modules/BankingTransactions/constants.ts @@ -1,5 +1,4 @@ -import { ACCOUNT_TYPE } from "@/constants/accounts"; - +import { ACCOUNT_TYPE } from '@/constants/accounts'; export const ERRORS = { CASHFLOW_TRANSACTION_TYPE_INVALID: 'CASHFLOW_TRANSACTION_TYPE_INVALID', @@ -111,35 +110,34 @@ export const BankTransactionsSampleData = [ }, ]; - export const CashflowTransactionTypes = { - OtherIncome: 'Other income', - OtherExpense: 'Other expense', - OwnerDrawing: 'Owner drawing', - OwnerContribution: 'Owner contribution', - TransferToAccount: 'Transfer to account', - TransferFromAccount: 'Transfer from account', + OtherIncome: 'transaction_type.other_income', + OtherExpense: 'transaction_type.other_expense', + OwnerDrawing: 'transaction_type.owner_drawing', + OwnerContribution: 'transaction_type.owner_contribution', + TransferToAccount: 'transaction_type.transfer_to_account', + TransferFromAccount: 'transaction_type.transfer_from_account', }; export const TransactionTypes = { - SaleInvoice: 'Sale invoice', - SaleReceipt: 'Sale receipt', - PaymentReceive: 'Payment received', - Bill: 'Bill', - BillPayment: 'Payment made', - VendorOpeningBalance: 'Vendor opening balance', - CustomerOpeningBalance: 'Customer opening balance', - InventoryAdjustment: 'Inventory adjustment', - ManualJournal: 'Manual journal', - Journal: 'Manual journal', - Expense: 'Expense', - OwnerContribution: 'Owner contribution', - TransferToAccount: 'Transfer to account', - TransferFromAccount: 'Transfer from account', - OtherIncome: 'Other income', - OtherExpense: 'Other expense', - OwnerDrawing: 'Owner drawing', - InvoiceWriteOff: 'Invoice write-off', + SaleInvoice: 'transaction_type.sale_invoice', + SaleReceipt: 'transaction_type.sale_receipt', + PaymentReceive: 'transaction_type.payment_received', + Bill: 'transaction_type.bill', + BillPayment: 'transaction_type.payment_made', + VendorOpeningBalance: 'transaction_type.vendor_opening_balance', + CustomerOpeningBalance: 'transaction_type.customer_opening_balance', + InventoryAdjustment: 'transaction_type.inventory_adjustment', + ManualJournal: 'transaction_type.manual_journal', + Journal: 'transaction_type.manual_journal', + Expense: 'transaction_type.expense', + OwnerContribution: 'transaction_type.owner_contribution', + TransferToAccount: 'transaction_type.transfer_to_account', + TransferFromAccount: 'transaction_type.transfer_from_account', + OtherIncome: 'transaction_type.other_income', + OtherExpense: 'transaction_type.other_expense', + OwnerDrawing: 'transaction_type.owner_drawing', + InvoiceWriteOff: 'transaction_type.invoice_write_off', CreditNote: 'transaction_type.credit_note', VendorCredit: 'transaction_type.vendor_credit', RefundCreditNote: 'transaction_type.refund_credit_note', diff --git a/packages/server/src/modules/BankingTransactions/queries/GetBankAccountTransactions/GetBankAccountTransactions.service.ts b/packages/server/src/modules/BankingTransactions/queries/GetBankAccountTransactions/GetBankAccountTransactions.service.ts index 989ae1096..d3f943588 100644 --- a/packages/server/src/modules/BankingTransactions/queries/GetBankAccountTransactions/GetBankAccountTransactions.service.ts +++ b/packages/server/src/modules/BankingTransactions/queries/GetBankAccountTransactions/GetBankAccountTransactions.service.ts @@ -3,11 +3,13 @@ import { getBankAccountTransactionsDefaultQuery } from './_utils'; import { GetBankAccountTransactionsRepository } from './GetBankAccountTransactionsRepo.service'; import { GetBankAccountTransactions } from './GetBankAccountTransactions'; import { GetBankTransactionsQueryDto } from '../../dtos/GetBankTranasctionsQuery.dto'; +import { I18nService } from 'nestjs-i18n'; @Injectable() export class GetBankAccountTransactionsService { constructor( private readonly getBankAccountTransactionsRepository: GetBankAccountTransactionsRepository, + private readonly i18nService: I18nService ) {} /** @@ -30,6 +32,7 @@ export class GetBankAccountTransactionsService { const report = new GetBankAccountTransactions( this.getBankAccountTransactionsRepository, parsedQuery, + this.i18nService ); const transactions = report.reportData(); const pagination = this.getBankAccountTransactionsRepository.pagination; diff --git a/packages/server/src/modules/BankingTransactions/queries/GetBankAccountTransactions/GetBankAccountTransactions.ts b/packages/server/src/modules/BankingTransactions/queries/GetBankAccountTransactions/GetBankAccountTransactions.ts index b86310d2a..5af75485b 100644 --- a/packages/server/src/modules/BankingTransactions/queries/GetBankAccountTransactions/GetBankAccountTransactions.ts +++ b/packages/server/src/modules/BankingTransactions/queries/GetBankAccountTransactions/GetBankAccountTransactions.ts @@ -11,11 +11,13 @@ import { FinancialSheet } from '@/modules/FinancialStatements/common/FinancialSh import { formatBankTransactionsStatus } from './_utils'; import { GetBankAccountTransactionsRepository } from './GetBankAccountTransactionsRepo.service'; import { runningBalance } from '@/utils/running-balance'; +import { I18nService } from 'nestjs-i18n'; export class GetBankAccountTransactions extends FinancialSheet { private runningBalance: any; private query: ICashflowAccountTransactionsQuery; private repo: GetBankAccountTransactionsRepository; + private i18n: I18nService; /** * Constructor method. @@ -26,11 +28,14 @@ export class GetBankAccountTransactions extends FinancialSheet { constructor( repo: GetBankAccountTransactionsRepository, query: ICashflowAccountTransactionsQuery, + i18n: I18nService, ) { super(); this.repo = repo; this.query = query; + this.i18n = i18n; + this.runningBalance = runningBalance(this.repo.openingBalance); } @@ -104,7 +109,7 @@ export class GetBankAccountTransactions extends FinancialSheet { referenceId: transaction.referenceId, referenceType: transaction.referenceType, - formattedTransactionType: transaction.referenceTypeFormatted, + formattedTransactionType: this.i18n.t(transaction.referenceTypeFormatted), transactionNumber: transaction.transactionNumber, referenceNumber: transaction.referenceNumber, diff --git a/packages/server/src/modules/Bills/dtos/Bill.dto.ts b/packages/server/src/modules/Bills/dtos/Bill.dto.ts index e95ec383a..b62d7b2f3 100644 --- a/packages/server/src/modules/Bills/dtos/Bill.dto.ts +++ b/packages/server/src/modules/Bills/dtos/Bill.dto.ts @@ -1,6 +1,7 @@ import { ToNumber } from '@/common/decorators/Validators'; import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; import { Type } from 'class-transformer'; +import { ApiProperty } from '@nestjs/swagger'; import { ArrayMinSize, IsArray, @@ -23,93 +24,187 @@ enum DiscountType { } export class BillEntryDto extends ItemEntryDto { + @ApiProperty({ + description: 'Flag indicating whether the entry contributes to landed cost', + example: true, + required: false, + }) @IsOptional() @IsBoolean() landedCost?: boolean; } class AttachmentDto { + @ApiProperty({ + description: 'Storage key of the attachment file', + example: 'attachments/bills/receipt.pdf', + }) @IsString() @IsNotEmpty() key: string; } export class CommandBillDto { + @ApiProperty({ + description: 'Unique bill number', + example: 'BILL-0001', + required: false, + }) @IsOptional() @IsString() billNumber: string; + @ApiProperty({ + description: 'Reference number', + example: 'REF-12345', + required: false, + }) @IsOptional() @IsString() referenceNo?: string; + @ApiProperty({ + description: 'Date the bill was issued', + example: '2025-06-01', + }) @IsNotEmpty() @IsDateString() billDate: Date; + @ApiProperty({ + description: 'Date the bill is due', + example: '2025-07-01', + required: false, + }) @IsOptional() @IsDateString() dueDate?: Date; + @ApiProperty({ + description: 'Vendor identifier', + example: 10, + }) @IsInt() @IsNotEmpty() vendorId: number; + @ApiProperty({ + description: 'Exchange rate applied to bill amounts', + example: 3.67, + required: false, + }) @IsOptional() @ToNumber() @IsNumber() @IsPositive() exchangeRate?: number; + @ApiProperty({ + description: 'Warehouse identifier', + example: 4, + required: false, + }) @IsOptional() @ToNumber() @IsInt() warehouseId?: number; + @ApiProperty({ + description: 'Branch identifier', + example: 2, + required: false, + }) @IsOptional() @ToNumber() @IsInt() branchId?: number; + @ApiProperty({ + description: 'Project identifier', + example: 5, + required: false, + }) @IsOptional() @ToNumber() @IsInt() projectId?: number; + @ApiProperty({ + description: 'Additional notes about the bill', + example: 'Payment due next month', + required: false, + }) @IsOptional() @IsString() note?: string; + @ApiProperty({ + description: 'Indicates if the bill is open', + example: true, + required: false, + }) @IsBoolean() @IsOptional() open: boolean = false; + @ApiProperty({ + description: 'Indicates if tax is inclusive in prices', + example: false, + required: false, + }) @IsBoolean() @IsOptional() isInclusiveTax: boolean = false; + @ApiProperty({ + description: 'Bill line items', + type: () => BillEntryDto, + isArray: true, + }) @IsArray() @ValidateNested({ each: true }) @Type(() => BillEntryDto) @ArrayMinSize(1) entries: BillEntryDto[]; + @ApiProperty({ + description: 'File attachments associated with the bill', + type: () => AttachmentDto, + isArray: true, + required: false, + }) @IsOptional() @IsArray() @ValidateNested({ each: true }) @Type(() => AttachmentDto) attachments?: AttachmentDto[]; + @ApiProperty({ + description: 'Type of discount applied', + example: DiscountType.Amount, + enum: DiscountType, + required: false, + }) @IsEnum(DiscountType) @IsOptional() discountType: DiscountType = DiscountType.Amount; + @ApiProperty({ + description: 'Discount value', + example: 100, + required: false, + }) @IsOptional() @ToNumber() @IsNumber() @IsPositive() discount?: number; + @ApiProperty({ + description: 'Adjustment value', + example: 50, + required: false, + }) @IsOptional() @ToNumber() @IsNumber() diff --git a/packages/server/src/modules/ChromiumlyTenancy/utils.ts b/packages/server/src/modules/ChromiumlyTenancy/utils.ts index 5d031119f..33a501b23 100644 --- a/packages/server/src/modules/ChromiumlyTenancy/utils.ts +++ b/packages/server/src/modules/ChromiumlyTenancy/utils.ts @@ -9,5 +9,5 @@ export const getPdfFilesStorageDir = (filename: string) => { export const getPdfFilePath = (filename: string) => { const storageDir = getPdfFilesStorageDir(filename); - return path.join(global.__static_dirname, storageDir); + return path.join(global.__public_dirname, storageDir); }; diff --git a/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts b/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts index c6484f9d6..99a6d7a7d 100644 --- a/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts +++ b/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts @@ -6,7 +6,7 @@ import { RefundCreditNote } from './models/RefundCreditNote'; import { CreditNoteRefundDto } from './dto/CreditNoteRefund.dto'; @Controller('credit-notes') -@ApiTags('credit-notes-refunds') +@ApiTags('Credit Note Refunds') export class CreditNoteRefundsController { constructor( private readonly creditNotesRefundsApplication: CreditNotesRefundsApplication, diff --git a/packages/server/src/modules/CreditNotes/CreditNotes.controller.ts b/packages/server/src/modules/CreditNotes/CreditNotes.controller.ts index c759414c7..b4e590bcc 100644 --- a/packages/server/src/modules/CreditNotes/CreditNotes.controller.ts +++ b/packages/server/src/modules/CreditNotes/CreditNotes.controller.ts @@ -14,7 +14,7 @@ import { ICreditNotesQueryDTO } from './types/CreditNotes.types'; import { CreateCreditNoteDto, EditCreditNoteDto } from './dtos/CreditNote.dto'; @Controller('credit-notes') -@ApiTags('credit-notes') +@ApiTags('Credit Notes') export class CreditNotesController { /** * @param {CreditNoteApplication} creditNoteApplication - The credit note application service. diff --git a/packages/server/src/modules/Currencies/dtos/CreateCurrency.dto.ts b/packages/server/src/modules/Currencies/dtos/CreateCurrency.dto.ts index fb4f37fd4..6fafe7ef4 100644 --- a/packages/server/src/modules/Currencies/dtos/CreateCurrency.dto.ts +++ b/packages/server/src/modules/Currencies/dtos/CreateCurrency.dto.ts @@ -1,16 +1,20 @@ +import { ApiProperty } from "@nestjs/swagger"; import { IsNotEmpty } from "class-validator"; import { IsString } from "class-validator"; export class CreateCurrencyDto { @IsString() @IsNotEmpty() + @ApiProperty({ example: 'USD', description: 'The currency name' }) currencyName: string; @IsString() @IsNotEmpty() + @ApiProperty({ example: 'USD', description: 'The currency code' }) currencyCode: string; @IsString() @IsNotEmpty() + @ApiProperty({ example: '$', description: 'The currency sign' }) currencySign: string; } diff --git a/packages/server/src/modules/Currencies/dtos/EditCurrency.dto.ts b/packages/server/src/modules/Currencies/dtos/EditCurrency.dto.ts index 9179aeb7b..4c25248b9 100644 --- a/packages/server/src/modules/Currencies/dtos/EditCurrency.dto.ts +++ b/packages/server/src/modules/Currencies/dtos/EditCurrency.dto.ts @@ -1,12 +1,15 @@ +import { ApiProperty } from "@nestjs/swagger"; import { IsNotEmpty } from "class-validator"; import { IsString } from "class-validator"; export class EditCurrencyDto { @IsString() @IsNotEmpty() + @ApiProperty({ example: 'USD', description: 'The currency name' }) currencyName: string; @IsString() @IsNotEmpty() + @ApiProperty({ example: '$', description: 'The currency sign' }) currencySign: string; } diff --git a/packages/server/src/modules/Expenses/dtos/Expense.dto.ts b/packages/server/src/modules/Expenses/dtos/Expense.dto.ts index a9e8a6270..e1f536003 100644 --- a/packages/server/src/modules/Expenses/dtos/Expense.dto.ts +++ b/packages/server/src/modules/Expenses/dtos/Expense.dto.ts @@ -24,31 +24,52 @@ class AttachmentDto { export class ExpenseCategoryDto { @IsInt() @IsNotEmpty() + @ApiProperty({ example: 1, description: 'The index of the expense category' }) index: number; @IsNotEmpty() @ToNumber() @IsInt() + @ApiProperty({ + example: 1, + description: 'The expense account id of the expense category', + }) expenseAccountId: number; @ToNumber() @IsNumber() @IsOptional() + @ApiProperty({ + example: 100, + description: 'The amount of the expense category', + }) amount?: number; @IsString() @MaxLength(255) @IsOptional() + @ApiProperty({ + example: 'This is a description', + description: 'The description of the expense category', + }) description?: string; @IsBoolean() @Transform(({ value }) => parseBoolean(value, false)) @IsOptional() + @ApiProperty({ + example: true, + description: 'The landed cost of the expense category', + }) landedCost?: boolean; @ToNumber() @IsInt() @IsOptional() + @ApiProperty({ + example: 1, + description: 'The project id of the expense category', + }) projectId?: number; } diff --git a/packages/server/src/modules/FinancialStatements/common/TableSheetPdf.ts b/packages/server/src/modules/FinancialStatements/common/TableSheetPdf.ts index 17b96d7b4..92dd02030 100644 --- a/packages/server/src/modules/FinancialStatements/common/TableSheetPdf.ts +++ b/packages/server/src/modules/FinancialStatements/common/TableSheetPdf.ts @@ -38,7 +38,7 @@ export class TableSheetPdf { // Generate HTML content from the template const htmlContent = await this.templateInjectable.render( - 'modules/financial-sheet', + 'financial-sheet', { table: { rows, columns }, sheetName, diff --git a/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts index 6033a9df2..fbb3457aa 100644 --- a/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts +++ b/packages/server/src/modules/FinancialStatements/modules/CashFlowStatement/CashflowTablePdfInjectable.ts @@ -1,8 +1,10 @@ +import { Injectable } from '@nestjs/common'; import { TableSheetPdf } from '../../common/TableSheetPdf'; import { ICashFlowStatementQuery } from './Cashflow.types'; import { CashflowTableInjectable } from './CashflowTableInjectable'; import { HtmlTableCustomCss } from './constants'; +@Injectable() export class CashflowTablePdfInjectable { constructor( private readonly cashflowTable: CashflowTableInjectable, diff --git a/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts index a4395ac04..8c5cc77c9 100644 --- a/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/ProfitLossSheet/ProfitLossSheet.controller.ts @@ -49,7 +49,7 @@ export class ProfitLossSheetController { ); res.send(sheet); // Retrieves the json format. - } else if (acceptHeader.includes(AcceptType.ApplicationJson)) { + } else if (acceptHeader.includes(AcceptType.ApplicationPdf)) { const pdfContent = await this.profitLossSheetApp.pdf(query); res.set({ diff --git a/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts index 6fa2a9243..9f9164d20 100644 --- a/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts +++ b/packages/server/src/modules/FinancialStatements/modules/SalesByItems/SalesByItems.controller.ts @@ -7,7 +7,6 @@ import { Req, Res, } from '@nestjs/common'; -import { ISalesByItemsReportQuery } from './SalesByItems.types'; import { AcceptType } from '@/constants/accept-type'; import { SalesByItemsApplication } from './SalesByItemsApplication'; import { Response } from 'express'; @@ -21,7 +20,10 @@ export class SalesByItemsController { @Get() @ApiResponse({ status: 200, description: 'Sales by items report' }) - @ApiOperation({ summary: 'Get sales by items report' }) + @ApiOperation({ + summary: 'Sales by items report', + description: 'Retrieves the sales by items report.', + }) public async salesByitems( @Query() filter: SalesByItemsQueryDto, @Res({ passthrough: true }) res: Response, diff --git a/packages/server/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts b/packages/server/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts index 784b9b5a0..bb2214f0d 100644 --- a/packages/server/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts +++ b/packages/server/src/modules/InventoryAdjutments/commands/ledger/InventoryAdjustmentsGLEntries.ts @@ -46,8 +46,7 @@ export class InventoryAdjustmentsGLEntries { /** * Reverts the adjustment transactions GL entries. - * @param {number} tenantId - * @param {number} inventoryAdjustmentId + * @param {number} inventoryAdjustmentId * @returns {Promise} */ public revertAdjustmentGLEntries = ( @@ -63,7 +62,6 @@ export class InventoryAdjustmentsGLEntries { /** * Rewrite inventory adjustment GL entries. - * @param {number} tenantId * @param {number} inventoryAdjustmentId * @param {Knex.Transaction} trx */ diff --git a/packages/server/src/modules/Items/Item.controller.ts b/packages/server/src/modules/Items/Item.controller.ts index 8e1d8ca58..02783391a 100644 --- a/packages/server/src/modules/Items/Item.controller.ts +++ b/packages/server/src/modules/Items/Item.controller.ts @@ -21,13 +21,12 @@ import { ApiResponse, ApiTags, } from '@nestjs/swagger'; -import { IItemsFilter } from './types/Items.types'; import { CreateItemDto, EditItemDto } from './dtos/Item.dto'; import { GetItemsQueryDto } from './dtos/GetItemsQuery.dto'; @Controller('/items') @UseGuards(SubscriptionGuard) -@ApiTags('items') +@ApiTags('Items') export class ItemsController extends TenantController { constructor(private readonly itemsApplication: ItemsApplicationService) { super(); @@ -118,6 +117,12 @@ export class ItemsController extends TenantController { description: 'The item has been successfully updated.', }) @ApiResponse({ status: 404, description: 'The item not found.' }) + @ApiParam({ + name: 'id', + required: true, + type: Number, + description: 'The item id', + }) async editItem( @Param('id') id: string, @Body() editItemDto: EditItemDto, diff --git a/packages/server/src/modules/TaxRates/dtos/TaxRate.dto.ts b/packages/server/src/modules/TaxRates/dtos/TaxRate.dto.ts index 07cb69b91..678e81c94 100644 --- a/packages/server/src/modules/TaxRates/dtos/TaxRate.dto.ts +++ b/packages/server/src/modules/TaxRates/dtos/TaxRate.dto.ts @@ -14,10 +14,7 @@ export class CommandTaxRateDto { */ @IsString() @IsNotEmpty() - @ApiProperty({ - description: 'The name of the tax rate.', - example: 'VAT', - }) + @ApiProperty({ description: 'The name of the tax rate.', example: 'VAT' }) name: string; /** @@ -25,10 +22,7 @@ export class CommandTaxRateDto { */ @IsString() @IsNotEmpty() - @ApiProperty({ - description: 'The code of the tax rate.', - example: 'VAT', - }) + @ApiProperty({ description: 'The code of the tax rate.', example: 'VAT' }) code: string; /** diff --git a/packages/server/src/utils/template-render.ts b/packages/server/src/utils/template-render.ts index 9271c83fb..58935e7ee 100644 --- a/packages/server/src/utils/template-render.ts +++ b/packages/server/src/utils/template-render.ts @@ -2,6 +2,6 @@ import * as path from 'path'; import * as pug from 'pug'; export function templateRender(filePath: string, options: Record) { - const basePath = path.join(global.__resources_dir, '/views'); - return pug.renderFile(`${basePath}/${filePath}.pug`, options); + const templatePath = path.join(global.__views_dirname, `${filePath}.pug`); + return pug.renderFile(templatePath, options); } diff --git a/packages/webapp/src/hooks/query/FinancialReports/use-balance-sheet.ts b/packages/webapp/src/hooks/query/FinancialReports/use-balance-sheet.ts index c1cbec1e8..e389f5e7c 100644 --- a/packages/webapp/src/hooks/query/FinancialReports/use-balance-sheet.ts +++ b/packages/webapp/src/hooks/query/FinancialReports/use-balance-sheet.ts @@ -37,7 +37,7 @@ export function useBalanceSheet(query, props) { */ export const useBalanceSheetXlsxExport = (query, args) => { return useDownloadFile({ - url: '/reports/balance_sheet', + url: '/reports/balance-sheet', config: { headers: { accept: 'application/xlsx', @@ -57,7 +57,7 @@ export const useBalanceSheetXlsxExport = (query, args) => { */ export const useBalanceSheetCsvExport = (query, args) => { return useDownloadFile({ - url: '/reports/balance_sheet', + url: '/reports/balance-sheet', config: { headers: { accept: 'application/csv', @@ -76,7 +76,7 @@ export const useBalanceSheetCsvExport = (query, args) => { */ export function useBalanceSheetPdf(query = {}) { return useRequestPdf({ - url: `/reports/balance_sheet`, + url: `/reports/balance-sheet`, params: query, }); } diff --git a/packages/webapp/src/hooks/query/cashflowAccounts.tsx b/packages/webapp/src/hooks/query/cashflowAccounts.tsx index 25ce5cb2d..0e7302879 100644 --- a/packages/webapp/src/hooks/query/cashflowAccounts.tsx +++ b/packages/webapp/src/hooks/query/cashflowAccounts.tsx @@ -75,7 +75,7 @@ export function useCashflowTransaction(id, props) { [t.CASH_FLOW_TRANSACTIONS, id], { method: 'get', url: `banking/transactions/${id}` }, { - select: (res) => res.data.cashflow_transaction, + select: (res) => res.data, defaultData: [], ...props, }, diff --git a/packages/webapp/src/hooks/query/items.tsx b/packages/webapp/src/hooks/query/items.tsx index c415884a9..6ffdb636e 100644 --- a/packages/webapp/src/hooks/query/items.tsx +++ b/packages/webapp/src/hooks/query/items.tsx @@ -42,7 +42,7 @@ export function useEditItem(props) { const queryClient = useQueryClient(); const apiRequest = useApiRequest(); - return useMutation(([id, values]) => apiRequest.post(`items/${id}`, values), { + return useMutation(([id, values]) => apiRequest.put(`items/${id}`, values), { onSuccess: (res, [id, values]) => { // Invalidate specific item. queryClient.invalidateQueries([t.ITEM, id]);