refactor: e2e tests for payment received

This commit is contained in:
Ahmed Bouhuolia
2024-12-30 20:58:56 +02:00
parent 515a984714
commit b046edf337
19 changed files with 237 additions and 76 deletions

View File

@@ -52,6 +52,7 @@ import { VendorCreditApplyBillsModule } from '../VendorCreditsApplyBills/VendorC
import { VendorCreditsRefundModule } from '../VendorCreditsRefund/VendorCreditsRefund.module';
import { CreditNoteRefundsModule } from '../CreditNoteRefunds/CreditNoteRefunds.module';
import { BillPaymentsModule } from '../BillPayments/BillPayments.module';
import { PaymentsReceivedModule } from '../PaymentReceived/PaymentsReceived.module';
@Module({
imports: [
@@ -128,6 +129,7 @@ import { BillPaymentsModule } from '../BillPayments/BillPayments.module';
VendorCreditsRefundModule,
CreditNoteRefundsModule,
BillPaymentsModule,
PaymentsReceivedModule,
],
controllers: [AppController],
providers: [

View File

@@ -0,0 +1,49 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { BillPaymentsApplication } from './BillPaymentsApplication.service';
import { IBillPaymentDTO } from './types/BillPayments.types';
@Controller('bill-payments')
export class BillPaymentsController {
constructor(private billPaymentsApplication: BillPaymentsApplication) {}
@Post()
public createBillPayment(@Body() billPaymentDTO: IBillPaymentDTO) {
return this.billPaymentsApplication.createBillPayment(billPaymentDTO);
}
@Delete(':billPaymentId')
public deleteBillPayment(@Param('billPaymentId') billPaymentId: string) {
return this.billPaymentsApplication.deleteBillPayment(
Number(billPaymentId),
);
}
@Put(':billPaymentId')
public editBillPayment(
@Param('billPaymentId') billPaymentId: string,
@Body() billPaymentDTO: IBillPaymentDTO,
) {
return this.billPaymentsApplication.editBillPayment(
Number(billPaymentId),
billPaymentDTO,
);
}
@Get(':billPaymentId')
public getBillPayment(@Param('billPaymentId') billPaymentId: string) {
return this.billPaymentsApplication.getBillPayment(Number(billPaymentId));
}
@Get(':billPaymentId/bills')
public getPaymentBills(@Param('billPaymentId') billPaymentId: string) {
return this.billPaymentsApplication.getPaymentBills(Number(billPaymentId));
}
}

View File

@@ -11,6 +11,7 @@ import { CommandBillPaymentDTOTransformer } from './commands/CommandBillPaymentD
import { TenancyContext } from '../Tenancy/TenancyContext.service';
import { BranchTransactionDTOTransformer } from '../Branches/integrations/BranchTransactionDTOTransform';
import { BranchesSettingsService } from '../Branches/BranchesSettings';
import { BillPaymentsController } from './BillPayments.controller';
@Module({
providers: [
@@ -28,6 +29,6 @@ import { BranchesSettingsService } from '../Branches/BranchesSettings';
TenancyContext,
],
exports: [BillPaymentValidators],
controllers: [],
controllers: [BillPaymentsController],
})
export class BillPaymentsModule {}

View File

@@ -15,11 +15,11 @@ import { IBillPaymentDTO } from './types/BillPayments.types';
export class BillPaymentsApplication {
constructor(
private createBillPaymentService: CreateBillPaymentService,
private deleteBillPaymentService: DeleteBillPayment,
private editBillPaymentService: EditBillPayment,
// private getBillPaymentsService: GetBillPayments,
private deleteBillPaymentService: DeleteBillPayment,
private getBillPaymentService: GetBillPayment,
private getPaymentBillsService: GetPaymentBills,
// private getBillPaymentsService: GetBillPayments,
) {}
/**

View File

@@ -3,8 +3,6 @@ import { sumBy, difference } from 'lodash';
import {
IBillPaymentDTO,
IBillPaymentEntryDTO,
IBillPayment,
IBillPaymentEntry,
} from '../types/BillPayments.types';
import { ERRORS } from '../constants';
import { Bill } from '../../Bills/models/Bill';
@@ -140,7 +138,7 @@ export class BillPaymentValidators {
*/
public async validateBillsDueAmount(
billPaymentEntries: IBillPaymentEntryDTO[],
oldPaymentEntries: IBillPaymentEntry[] = [],
oldPaymentEntries: BillPaymentEntry[] = [],
) {
const billsIds = billPaymentEntries.map(
(entry: IBillPaymentEntryDTO) => entry.billId,
@@ -187,7 +185,7 @@ export class BillPaymentValidators {
*/
public async validateEntriesIdsExistance(
billPaymentId: number,
billPaymentEntries: IBillPaymentEntry[],
billPaymentEntries: BillPaymentEntry[],
) {
const entriesIds = billPaymentEntries
.filter((entry: any) => entry.id)

View File

@@ -1,7 +1,6 @@
import { Knex } from 'knex';
import {
IBillPaymentDTO,
IBillPayment,
IBillPaymentEventCreatedPayload,
IBillPaymentCreatingPayload,
} from '../types/BillPayments.types';

View File

@@ -1,36 +1,7 @@
import { Knex } from 'knex';
import { Bill } from '@/modules/Bills/models/Bill';
import { BillPayment } from '../models/BillPayment';
import { AttachmentLinkDTO } from '@/modules/Attachments/Attachments.types';
export interface IBillPaymentEntry {
id?: number;
billPaymentId: number;
billId: number;
paymentAmount: number;
bill?: Bill;
}
export interface IBillPayment {
id?: number;
vendorId: number;
amount: number;
currencyCode: string;
reference: string;
paymentAccountId: number;
paymentNumber: string;
paymentDate: Date;
exchangeRate: number | null;
userId: number;
entries: IBillPaymentEntry[];
statement: string;
createdAt: Date;
updatedAt: Date;
localAmount?: number;
branchId?: number;
}
export interface IBillPaymentEntryDTO {
billId: number;
paymentAmount: number;
@@ -62,12 +33,7 @@ export interface IBillReceivePageEntry {
date: Date | string;
}
export interface IBillPaymentsService {
validateVendorHasNoPayments(tenantId: number, vendorId): Promise<void>;
}
export interface IBillPaymentEventCreatedPayload {
// tenantId: number;
billPayment: BillPayment;
billPaymentDTO: IBillPaymentDTO;
billPaymentId: number;
@@ -75,19 +41,16 @@ export interface IBillPaymentEventCreatedPayload {
}
export interface IBillPaymentCreatingPayload {
// tenantId: number;
billPaymentDTO: IBillPaymentDTO;
trx: Knex.Transaction;
}
export interface IBillPaymentEditingPayload {
// tenantId: number;
billPaymentDTO: IBillPaymentDTO;
oldBillPayment: BillPayment;
trx: Knex.Transaction;
}
export interface IBillPaymentEventEditedPayload {
// tenantId: number;
billPaymentId: number;
billPayment: BillPayment;
oldBillPayment: BillPayment;
@@ -96,7 +59,6 @@ export interface IBillPaymentEventEditedPayload {
}
export interface IBillPaymentEventDeletedPayload {
// tenantId: number;
billPaymentId: number;
oldBillPayment: BillPayment;
trx: Knex.Transaction;
@@ -108,7 +70,6 @@ export interface IBillPaymentDeletingPayload {
}
export interface IBillPaymentPublishingPayload {
// tenantId: number;
oldBillPayment: BillPayment;
trx: Knex.Transaction;
}

View File

@@ -8,29 +8,29 @@ import {
} from './types/PaymentReceived.types';
import { Injectable } from '@nestjs/common';
import { CreatePaymentReceivedService } from './commands/CreatePaymentReceived.serivce';
import { EditPaymentReceived } from './commands/EditPaymentReceived.service';
import { DeletePaymentReceived } from './commands/DeletePaymentReceived.service';
import { EditPaymentReceivedService } from './commands/EditPaymentReceived.service';
import { DeletePaymentReceivedService } from './commands/DeletePaymentReceived.service';
// import { GetPaymentReceives } from './queries/GetPaymentsReceived.service';
import { GetPaymentReceived } from './queries/GetPaymentReceived.service';
import { GetPaymentReceivedService } from './queries/GetPaymentReceived.service';
import { GetPaymentReceivedInvoices } from './queries/GetPaymentReceivedInvoices.service';
// import { PaymentReceiveNotifyBySms } from './PaymentReceivedSmsNotify';
import GetPaymentReceivedPdf from './queries/GetPaymentReceivedPdf.service';
// import { SendPaymentReceiveMailNotification } from './PaymentReceivedMailNotification';
import { GetPaymentReceivedState } from './queries/GetPaymentReceivedState.service';
import { GetPaymentReceivedStateService } from './queries/GetPaymentReceivedState.service';
@Injectable()
export class PaymentReceivesApplication {
constructor(
private createPaymentReceivedService: CreatePaymentReceivedService,
private editPaymentReceivedService: EditPaymentReceived,
private deletePaymentReceivedService: DeletePaymentReceived,
private editPaymentReceivedService: EditPaymentReceivedService,
private deletePaymentReceivedService: DeletePaymentReceivedService,
// private getPaymentsReceivedService: GetPaymentReceives,
private getPaymentReceivedService: GetPaymentReceived,
private getPaymentReceivedService: GetPaymentReceivedService,
private getPaymentReceiveInvoicesService: GetPaymentReceivedInvoices,
// private paymentSmsNotify: PaymentReceiveNotifyBySms,
// private paymentMailNotify: SendPaymentReceiveMailNotification,
private getPaymentReceivePdfService: GetPaymentReceivedPdf,
private getPaymentReceivedStateService: GetPaymentReceivedState,
private getPaymentReceivedStateService: GetPaymentReceivedStateService,
) {}
/**

View File

@@ -0,0 +1,82 @@
import {
Body,
Controller,
Delete,
Get,
Param,
ParseIntPipe,
Post,
Put,
} from '@nestjs/common';
import { PaymentReceivesApplication } from './PaymentReceived.application';
import {
IPaymentReceivedCreateDTO,
IPaymentReceivedEditDTO,
} from './types/PaymentReceived.types';
import { PublicRoute } from '../Auth/Jwt.guard';
@Controller('payments-received')
@PublicRoute()
export class PaymentReceivesController {
constructor(private paymentReceivesApplication: PaymentReceivesApplication) {}
@Post()
public createPaymentReceived(
@Body() paymentReceiveDTO: IPaymentReceivedCreateDTO,
) {
return this.paymentReceivesApplication.createPaymentReceived(
paymentReceiveDTO,
);
}
@Put(':id')
public editPaymentReceive(
@Param('id', ParseIntPipe) paymentReceiveId: number,
@Body() paymentReceiveDTO: IPaymentReceivedEditDTO,
) {
return this.paymentReceivesApplication.editPaymentReceive(
paymentReceiveId,
paymentReceiveDTO,
);
}
@Delete(':id')
public deletePaymentReceive(
@Param('id', ParseIntPipe) paymentReceiveId: number,
) {
return this.paymentReceivesApplication.deletePaymentReceive(
paymentReceiveId,
);
}
@Get('state')
public getPaymentReceivedState() {
return this.paymentReceivesApplication.getPaymentReceivedState();
}
@Get(':id/invoices')
public getPaymentReceiveInvoices(
@Param('id', ParseIntPipe) paymentReceiveId: number,
) {
return this.paymentReceivesApplication.getPaymentReceiveInvoices(
paymentReceiveId,
);
}
@Get(':id')
public getPaymentReceive(
@Param('id', ParseIntPipe) paymentReceiveId: number,
) {
return this.paymentReceivesApplication.getPaymentReceive(paymentReceiveId);
}
@Get(':id/pdf')
public getPaymentReceivePdf(
@Param('id', ParseIntPipe) paymentReceiveId: number,
) {
return this.paymentReceivesApplication.getPaymentReceivePdf(
1,
paymentReceiveId,
);
}
}

View File

@@ -0,0 +1,51 @@
import { Module } from '@nestjs/common';
import { PaymentReceivesController } from './PaymentsReceived.controller';
import { PaymentReceivesApplication } from './PaymentReceived.application';
import { CreatePaymentReceivedService } from './commands/CreatePaymentReceived.serivce';
import { DeletePaymentReceivedService } from './commands/DeletePaymentReceived.service';
import { EditPaymentReceivedService } from './commands/EditPaymentReceived.service';
import { GetPaymentReceivedStateService } from './queries/GetPaymentReceivedState.service';
import { GetPaymentReceivedService } from './queries/GetPaymentReceived.service';
import { GetPaymentReceivedInvoices } from './queries/GetPaymentReceivedInvoices.service';
import GetPaymentReceivedPdf from './queries/GetPaymentReceivedPdf.service';
import { PaymentReceivedValidators } from './commands/PaymentReceivedValidators.service';
import { PaymentReceiveDTOTransformer } from './commands/PaymentReceivedDTOTransformer';
import { TenancyContext } from '../Tenancy/TenancyContext.service';
import { ChromiumlyTenancyModule } from '../ChromiumlyTenancy/ChromiumlyTenancy.module';
import { TemplateInjectableModule } from '../TemplateInjectable/TemplateInjectable.module';
import { PaymentReceivedBrandingTemplate } from './queries/PaymentReceivedBrandingTemplate.service';
import { PaymentReceivedIncrement } from './commands/PaymentReceivedIncrement.service';
import { BranchesModule } from '../Branches/Branches.module';
import { WarehousesModule } from '../Warehouses/Warehouses.module';
import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module';
import { AutoIncrementOrdersModule } from '../AutoIncrementOrders/AutoIncrementOrders.module';
@Module({
controllers: [PaymentReceivesController],
providers: [
PaymentReceivesApplication,
CreatePaymentReceivedService,
DeletePaymentReceivedService,
EditPaymentReceivedService,
GetPaymentReceivedStateService,
GetPaymentReceivedService,
GetPaymentReceivedInvoices,
GetPaymentReceivedPdf,
PaymentReceivedValidators,
PaymentReceiveDTOTransformer,
PaymentReceivedBrandingTemplate,
PaymentReceivedIncrement,
TenancyContext,
],
exports: [PaymentReceivesApplication],
imports: [
ChromiumlyTenancyModule,
TemplateInjectableModule,
BranchesModule,
WarehousesModule,
PdfTemplatesModule,
AutoIncrementOrdersModule
],
})
export class PaymentsReceivedModule {}

View File

@@ -45,7 +45,6 @@ export class CreatePaymentReceivedService {
// Validate customer existance.
const paymentCustomer = await this.customer
.query()
.modify('customer')
.findById(paymentReceiveDTO.customerId)
.throwIfNotFound();

View File

@@ -2,14 +2,22 @@ import { Inject, Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
import { events } from '@/common/events/events';
import { PaymentReceived } from '../models/PaymentReceived';
import { PaymentReceivedEntry } from '../models/PaymentReceivedEntry';
import { events } from '@/common/events/events';
import { IPaymentReceivedDeletingPayload } from '../types/PaymentReceived.types';
import { IPaymentReceivedDeletedPayload } from '../types/PaymentReceived.types';
import {
IPaymentReceivedDeletingPayload,
IPaymentReceivedDeletedPayload,
} from '../types/PaymentReceived.types';
@Injectable()
export class DeletePaymentReceived {
export class DeletePaymentReceivedService {
/**
* @param {EventEmitter2} eventPublisher - Event emitter.
* @param {UnitOfWork} uow - Unit of work.
* @param {typeof PaymentReceived} paymentReceiveModel - Payment received model.
* @param {typeof PaymentReceivedEntry} paymentReceiveEntryModel - Payment received entry model.
*/
constructor(
private eventPublisher: EventEmitter2,
private uow: UnitOfWork,

View File

@@ -15,7 +15,7 @@ import { Customer } from '@/modules/Customers/models/Customer';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
@Injectable()
export class EditPaymentReceived {
export class EditPaymentReceivedService {
constructor(
private readonly transformer: PaymentReceiveDTOTransformer,
private readonly validators: PaymentReceivedValidators,
@@ -23,7 +23,7 @@ export class EditPaymentReceived {
private readonly uow: UnitOfWork,
private readonly tenancyContext: TenancyContext,
@Inject(PaymentReceived)
@Inject(PaymentReceived.name)
private readonly paymentReceiveModel: typeof PaymentReceived,
@Inject(Customer.name)

View File

@@ -243,6 +243,7 @@ export class PaymentReceivedValidators {
depositAccountId: number
): Promise<Account> {
const depositAccount = await this.accountModel.query().findById(depositAccountId);
if (!depositAccount) {
throw new ServiceError(ERRORS.DEPOSIT_ACCOUNT_NOT_FOUND);
}

View File

@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { ERRORS } from '../constants';
import { PaymentReceiveTransfromer } from './PaymentReceivedTransformer';
import { PaymentReceived } from '../models/PaymentReceived';
@@ -6,10 +6,12 @@ import { TransformerInjectable } from '../../Transformer/TransformerInjectable.s
import { ServiceError } from '../../Items/ServiceError';
@Injectable()
export class GetPaymentReceived {
export class GetPaymentReceivedService {
constructor(
private readonly paymentReceiveModel: typeof PaymentReceived,
private readonly transformer: TransformerInjectable,
@Inject(PaymentReceived.name)
private readonly paymentReceiveModel: typeof PaymentReceived,
) {}
/**

View File

@@ -8,6 +8,10 @@ export class GetPaymentReceivedInvoices {
constructor(
@Inject(PaymentReceived.name)
private paymentReceiveModel: typeof PaymentReceived,
@Inject(SaleInvoice.name)
private saleInvoiceModel: typeof SaleInvoice,
private validators: PaymentReceivedValidators,
) {}
@@ -28,10 +32,10 @@ export class GetPaymentReceivedInvoices {
const paymentReceiveInvoicesIds = paymentReceive.entries.map(
(entry) => entry.invoiceId,
);
const saleInvoices = await SaleInvoice.query().whereIn(
'id',
paymentReceiveInvoicesIds,
);
const saleInvoices = await this.saleInvoiceModel
.query()
.whereIn('id', paymentReceiveInvoicesIds);
return saleInvoices;
}
}

View File

@@ -1,5 +1,5 @@
import { Inject, Injectable } from '@nestjs/common';
import { GetPaymentReceived } from './GetPaymentReceived.service';
import { GetPaymentReceivedService } from './GetPaymentReceived.service';
import { PaymentReceivedBrandingTemplate } from './PaymentReceivedBrandingTemplate.service';
import { transformPaymentReceivedToPdfTemplate } from '../utils';
@@ -16,7 +16,7 @@ export default class GetPaymentReceivedPdf {
constructor(
private chromiumlyTenancy: ChromiumlyTenancy,
private templateInjectable: TemplateInjectable,
private getPaymentService: GetPaymentReceived,
private getPaymentService: GetPaymentReceivedService,
private paymentBrandingTemplateService: PaymentReceivedBrandingTemplate,
private eventPublisher: EventEmitter2,

View File

@@ -1,10 +1,13 @@
import { PdfTemplateModel } from '@/modules/PdfTemplate/models/PdfTemplate';
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { IPaymentReceivedState } from '../types/PaymentReceived.types';
@Injectable()
export class GetPaymentReceivedState {
constructor(private pdfTemplateModel: typeof PdfTemplateModel) {}
export class GetPaymentReceivedStateService {
constructor(
@Inject(PdfTemplateModel.name)
private pdfTemplateModel: typeof PdfTemplateModel,
) {}
/**
* Retrieves the create/edit initial state of the payment received.

View File

@@ -37,6 +37,7 @@ import { ManualJournalEntry } from '@/modules/ManualJournals/models/ManualJourna
import { RefundCreditNote } from '@/modules/CreditNoteRefunds/models/RefundCreditNote';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
import { RefundVendorCredit } from '@/modules/VendorCreditsRefund/models/RefundVendorCredit';
import { PaymentReceived } from '@/modules/PaymentReceived/models/PaymentReceived';
const models = [
Item,
@@ -64,7 +65,6 @@ const models = [
BillLandedCostEntry,
VendorCreditAppliedBill,
SaleInvoice,
PaymentReceivedEntry,
CreditNoteAppliedInvoice,
CreditNote,
RefundCreditNote,
@@ -75,7 +75,8 @@ const models = [
VendorCredit,
VendorCreditAppliedBill,
RefundVendorCredit,
PaymentReceived,
PaymentReceivedEntry
];
const modelProviders = models.map((model) => {