feat(nestjs): migrate to NestJS

This commit is contained in:
Ahmed Bouhuolia
2025-04-07 11:51:24 +02:00
parent f068218a16
commit 55fcc908ef
3779 changed files with 631 additions and 195332 deletions

View File

@@ -0,0 +1,50 @@
import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common';
import { VendorCreditApplyBillsApplicationService } from './VendorCreditApplyBillsApplication.service';
import { IVendorCreditApplyToInvoicesDTO } from './types/VendorCreditApplyBills.types';
import { ApiTags } from '@nestjs/swagger';
@Controller('vendor-credits')
@ApiTags('vendor-credits-apply-bills')
export class VendorCreditApplyBillsController {
constructor(
private readonly vendorCreditApplyBillsApplication: VendorCreditApplyBillsApplicationService,
) {}
@Get(':vendorCreditId/bills-to-apply')
async getVendorCreditToApplyBills(
@Param('vendorCreditId') vendorCreditId: number,
) {
return this.vendorCreditApplyBillsApplication.getVendorCreditToApplyBills(
vendorCreditId,
);
}
@Post(':vendorCreditId/apply-to-bills')
async applyVendorCreditToBills(
@Param('vendorCreditId') vendorCreditId: number,
@Body() applyCreditToBillsDTO: IVendorCreditApplyToInvoicesDTO,
) {
return this.vendorCreditApplyBillsApplication.applyVendorCreditToBills(
vendorCreditId,
applyCreditToBillsDTO,
);
}
@Delete('applied-bills/:vendorCreditAppliedBillId')
async deleteAppliedBillToVendorCredit(
@Param('vendorCreditAppliedBillId') vendorCreditAppliedBillId: number,
) {
return this.vendorCreditApplyBillsApplication.deleteAppliedBillToVendorCredit(
vendorCreditAppliedBillId,
);
}
@Get(':vendorCreditId/applied-bills')
async getAppliedBillsToVendorCredit(
@Param('vendorCreditId') vendorCreditId: number,
) {
return this.vendorCreditApplyBillsApplication.getAppliedBillsToVendorCredit(
vendorCreditId,
);
}
}

View File

@@ -0,0 +1,38 @@
import { Module } from '@nestjs/common';
import { ApplyVendorCreditSyncBillsService } from './command/ApplyVendorCreditSyncBills.service';
import { ApplyVendorCreditSyncInvoicedService } from './command/ApplyVendorCreditSyncInvoiced.service';
import { DeleteApplyVendorCreditToBillService } from './command/DeleteApplyVendorCreditToBill.service';
import { ApplyVendorCreditToBillsService } from './command/ApplyVendorCreditToBills.service';
import { GetAppliedBillsToVendorCreditService } from './queries/GetAppliedBillsToVendorCredit.service';
import { GetVendorCreditToApplyBills } from './queries/GetVendorCreditToApplyBills.service';
import { VendorCreditApplyBillsApplicationService } from './VendorCreditApplyBillsApplication.service';
import { VendorCreditApplyBillsController } from './VendorCreditApplyBills.controller';
import { BillsModule } from '../Bills/Bills.module';
import { BillPaymentsModule } from '../BillPayments/BillPayments.module';
import { VendorCreditDTOTransformService } from '../VendorCredit/commands/VendorCreditDTOTransform.service';
import { ItemsModule } from '../Items/items.module';
import { BranchesModule } from '../Branches/Branches.module';
import { WarehousesModule } from '../Warehouses/Warehouses.module';
import { VendorCreditsModule } from '../VendorCredit/VendorCredits.module';
@Module({
imports: [
BillsModule,
BillPaymentsModule,
ItemsModule,
BranchesModule,
WarehousesModule,
VendorCreditsModule
],
providers: [
ApplyVendorCreditSyncBillsService,
ApplyVendorCreditSyncInvoicedService,
ApplyVendorCreditToBillsService,
DeleteApplyVendorCreditToBillService,
GetAppliedBillsToVendorCreditService,
GetVendorCreditToApplyBills,
VendorCreditApplyBillsApplicationService,
],
controllers: [VendorCreditApplyBillsController],
})
export class VendorCreditApplyBillsModule {}

View File

@@ -0,0 +1,67 @@
import { ApplyVendorCreditToBillsService } from './command/ApplyVendorCreditToBills.service';
import { DeleteApplyVendorCreditToBillService } from './command/DeleteApplyVendorCreditToBill.service';
import { GetAppliedBillsToVendorCreditService } from './queries/GetAppliedBillsToVendorCredit.service';
import { GetVendorCreditToApplyBills } from './queries/GetVendorCreditToApplyBills.service';
import { IVendorCreditApplyToInvoicesDTO } from './types/VendorCreditApplyBills.types';
export class VendorCreditApplyBillsApplicationService {
/**
* @param {ApplyVendorCreditToBillsService} applyVendorCreditToBillsService
* @param {DeleteApplyVendorCreditToBillService} deleteApplyVendorCreditToBillService
* @param {GetVendorCreditToApplyBills} getVendorCreditToApplyBillsService
* @param {GetAppliedBillsToVendorCreditService} getAppliedBillsToVendorCreditService
*/
constructor(
private readonly applyVendorCreditToBillsService: ApplyVendorCreditToBillsService,
private readonly deleteApplyVendorCreditToBillService: DeleteApplyVendorCreditToBillService,
private readonly getVendorCreditToApplyBillsService: GetVendorCreditToApplyBills,
private readonly getAppliedBillsToVendorCreditService: GetAppliedBillsToVendorCreditService,
) {}
/**
* Retrieve bills that valid apply to the given vendor credit.
* @param {number} vendorCreditId
* @returns {Promise<any[]>}
*/
async getVendorCreditToApplyBills(vendorCreditId: number) {
return this.getVendorCreditToApplyBillsService.getCreditToApplyBills(
vendorCreditId,
);
}
/**
* Apply credit note to the given bills.
* @param {number} vendorCreditId
* @param {IVendorCreditApplyToInvoicesDTO} applyCreditToBillsDTO
*/
async applyVendorCreditToBills(
vendorCreditId: number,
applyCreditToBillsDTO: IVendorCreditApplyToInvoicesDTO,
) {
return this.applyVendorCreditToBillsService.applyVendorCreditToBills(
vendorCreditId,
applyCreditToBillsDTO,
);
}
/**
* Delete applied bill to the given vendor credit.
* @param {number} vendorCreditAppliedBillId
*/
async deleteAppliedBillToVendorCredit(vendorCreditAppliedBillId: number) {
return this.deleteApplyVendorCreditToBillService.deleteApplyVendorCreditToBills(
vendorCreditAppliedBillId,
);
}
/**
* Retrieve applied bills to the given vendor credit.
* @param {number} vendorCreditId
* @returns {Promise<any[]>}
*/
async getAppliedBillsToVendorCredit(vendorCreditId: number) {
return this.getAppliedBillsToVendorCreditService.getAppliedBills(
vendorCreditId,
);
}
}

View File

@@ -0,0 +1,12 @@
export const ERRORS = {
VENDOR_CREDIT_NOT_FOUND: 'VENDOR_CREDIT_NOT_FOUND',
VENDOR_CREDIT_ALREADY_OPENED: 'VENDOR_CREDIT_ALREADY_OPENED',
VENDOR_CREDIT_HAS_NO_REMAINING_AMOUNT:
'VENDOR_CREDIT_HAS_NO_REMAINING_AMOUNT',
VENDOR_CREDIT_APPLY_TO_BILLS_NOT_FOUND:
'VENDOR_CREDIT_APPLY_TO_BILLS_NOT_FOUND',
BILLS_HAS_NO_REMAINING_AMOUNT: 'BILLS_HAS_NO_REMAINING_AMOUNT',
VENDOR_CREDIT_HAS_REFUND_TRANSACTIONS:
'VENDOR_CREDIT_HAS_REFUND_TRANSACTIONS',
VENDOR_CREDIT_HAS_APPLIED_BILLS: 'VENDOR_CREDIT_HAS_APPLIED_BILLS',
};

View File

@@ -0,0 +1,49 @@
import Bluebird from 'bluebird';
import { Inject, Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import { IVendorCreditAppliedBill } from '../types/VendorCreditApplyBills.types';
import { Bill } from '@/modules/Bills/models/Bill';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class ApplyVendorCreditSyncBillsService {
constructor(
@Inject(Bill.name)
private readonly billModel: TenantModelProxy<typeof Bill>,
) {}
/**
* Increment bills credited amount.
* @param {IVendorCreditAppliedBill[]} vendorCreditAppliedBills
* @param {Knex.Transaction} trx
*/
public incrementBillsCreditedAmount = async (
vendorCreditAppliedBills: IVendorCreditAppliedBill[],
trx?: Knex.Transaction,
) => {
await Bluebird.each(
vendorCreditAppliedBills,
(vendorCreditAppliedBill: IVendorCreditAppliedBill) => {
return this.billModel()
.query(trx)
.where('id', vendorCreditAppliedBill.billId)
.increment('creditedAmount', vendorCreditAppliedBill.amount);
},
);
};
/**
* Decrement bill credited amount.
* @param {IVendorCreditAppliedBill} vendorCreditAppliedBill
* @param {Knex.Transaction} trx
*/
public decrementBillCreditedAmount = async (
vendorCreditAppliedBill: IVendorCreditAppliedBill,
trx?: Knex.Transaction,
) => {
await this.billModel()
.query(trx)
.findById(vendorCreditAppliedBill.billId)
.decrement('creditedAmount', vendorCreditAppliedBill.amount);
};
}

View File

@@ -0,0 +1,49 @@
import { Inject, Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class ApplyVendorCreditSyncInvoicedService {
/**
* @param {TenantModelProxy<typeof VendorCredit>} vendorCreditModel - The vendor credit model.
*/
constructor(
@Inject(VendorCredit.name)
private readonly vendorCreditModel: TenantModelProxy<typeof VendorCredit>,
) {}
/**
* Increment vendor credit invoiced amount.
* @param {number} vendorCreditId - Vendor credit id.
* @param {number} amount - Amount to increment.
* @param {Knex.Transaction} trx - Knex transaction.
*/
public incrementVendorCreditInvoicedAmount = async (
vendorCreditId: number,
amount: number,
trx?: Knex.Transaction,
) => {
await this.vendorCreditModel()
.query(trx)
.findById(vendorCreditId)
.increment('invoicedAmount', amount);
};
/**
* Decrement credit note invoiced amount.
* @param {number} vendorCreditId - Vendor credit id.
* @param {number} amount - Amount to decrement.
* @param {Knex.Transaction} trx - Knex transaction.
*/
public decrementVendorCreditInvoicedAmount = async (
vendorCreditId: number,
amount: number,
trx?: Knex.Transaction,
) => {
await this.vendorCreditModel()
.query(trx)
.findById(vendorCreditId)
.decrement('invoicedAmount', amount);
};
}

View File

@@ -0,0 +1,136 @@
import { Inject, Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import { sumBy } from 'lodash';
import {
IVendorCreditApplyToBillsCreatedPayload,
IVendorCreditApplyToInvoicesDTO,
IVendorCreditApplyToInvoicesModel,
} from '../types/VendorCreditApplyBills.types';
import { ERRORS } from '../VendorCreditsApplyBills.constants';
import { VendorCreditAppliedBill } from '../models/VendorCreditAppliedBill';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
import { BillPaymentValidators } from '@/modules/BillPayments/commands/BillPaymentValidators.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
import { Bill } from '@/modules/Bills/models/Bill';
import { ServiceError } from '@/modules/Items/ServiceError';
import { events } from '@/common/events/events';
import { VendorCreditDTOTransformService } from '@/modules/VendorCredit/commands/VendorCreditDTOTransform.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class ApplyVendorCreditToBillsService {
/**
* @param {UnitOfWork} uow - The unit of work service.
* @param {EventEmitter2} eventPublisher - The event emitter service.
* @param {BillPaymentValidators} billPaymentValidators - The bill payment validators service.
* @param {TenantModelProxy<typeof VendorCreditAppliedBill>} vendorCreditAppliedBillModel - The vendor credit applied bill model.
* @param {TenantModelProxy<typeof VendorCredit>} vendorCreditModel - The vendor credit model.
*/
constructor(
private readonly uow: UnitOfWork,
private readonly eventPublisher: EventEmitter2,
private readonly billPaymentValidators: BillPaymentValidators,
private readonly vendorCreditDTOTransform: VendorCreditDTOTransformService,
@Inject(VendorCreditAppliedBill.name)
private readonly vendorCreditAppliedBillModel: TenantModelProxy<
typeof VendorCreditAppliedBill
>,
@Inject(VendorCredit.name)
private readonly vendorCreditModel: TenantModelProxy<typeof VendorCredit>,
) {}
/**
* Apply credit note to the given invoices.
* @param {number} creditNoteId
* @param {IApplyCreditToInvoicesDTO} applyCreditToInvoicesDTO
*/
public applyVendorCreditToBills = async (
vendorCreditId: number,
applyCreditToBillsDTO: IVendorCreditApplyToInvoicesDTO,
): Promise<void> => {
// Retrieves the vendor credit or throw not found service error.
const vendorCredit = await this.vendorCreditModel()
.query()
.findById(vendorCreditId)
.throwIfNotFound();
// Transfomes credit apply to bills DTO to model object.
const vendorCreditAppliedModel = this.transformApplyDTOToModel(
applyCreditToBillsDTO,
vendorCredit,
);
// Validate bills entries existance.
const appliedBills =
await this.billPaymentValidators.validateBillsExistance(
vendorCreditAppliedModel.entries,
vendorCredit.vendorId,
);
// Validate bills has remaining amount to apply.
this.validateBillsRemainingAmount(
appliedBills,
vendorCreditAppliedModel.amount,
);
// Validate vendor credit remaining credit amount.
this.vendorCreditDTOTransform.validateCreditRemainingAmount(
vendorCredit,
vendorCreditAppliedModel.amount,
);
// Saves vendor credit applied to bills under unit-of-work envirement.
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
// Inserts vendor credit applied to bills graph to the storage layer.
const vendorCreditAppliedBills = await this.vendorCreditAppliedBillModel()
.query(trx)
.insertGraph(vendorCreditAppliedModel.entries);
// Triggers `IVendorCreditApplyToBillsCreatedPayload` event.
await this.eventPublisher.emitAsync(
events.vendorCredit.onApplyToInvoicesCreated,
{
trx,
vendorCredit,
vendorCreditAppliedBills,
} as IVendorCreditApplyToBillsCreatedPayload,
);
});
};
/**
* Transformes apply DTO to model.
* @param {IApplyCreditToInvoicesDTO} applyDTO
* @param {ICreditNote} creditNote
* @returns {IVendorCreditApplyToInvoicesModel}
*/
private transformApplyDTOToModel = (
applyDTO: IVendorCreditApplyToInvoicesDTO,
vendorCredit: VendorCredit,
): IVendorCreditApplyToInvoicesModel => {
const entries = applyDTO.entries.map((entry) => ({
billId: entry.billId,
amount: entry.amount,
vendorCreditId: vendorCredit.id,
}));
const amount = sumBy(applyDTO.entries, 'amount');
return {
amount,
entries,
};
};
/**
* Validate bills remaining amount.
* @param {IBill[]} bills
* @param {number} amount
*/
private validateBillsRemainingAmount = (bills: Bill[], amount: number) => {
const invalidBills = bills.filter((bill) => bill.dueAmount < amount);
if (invalidBills.length > 0) {
throw new ServiceError(ERRORS.BILLS_HAS_NO_REMAINING_AMOUNT);
}
};
}

View File

@@ -0,0 +1,71 @@
import { Inject, Injectable } from '@nestjs/common';
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { ServiceError } from '@/modules/Items/ServiceError';
import { events } from '@/common/events/events';
import { IVendorCreditApplyToBillDeletedPayload } from '../types/VendorCreditApplyBills.types';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
import { ERRORS } from '../VendorCreditsApplyBills.constants';
import { VendorCreditAppliedBill } from '../models/VendorCreditAppliedBill';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class DeleteApplyVendorCreditToBillService {
/**
* @param {UnitOfWork} uow - The unit of work service.
* @param {EventEmitter2} eventPublisher - The event emitter service.
* @param {typeof VendorCreditAppliedBill} vendorCreditAppliedBillModel - The vendor credit applied bill model.
* @param {typeof VendorCredit} vendorCreditModel - The vendor credit model.
*/
constructor(
private readonly uow: UnitOfWork,
private readonly eventPublisher: EventEmitter2,
@Inject(VendorCreditAppliedBill.name)
private readonly vendorCreditAppliedBillModel: TenantModelProxy<
typeof VendorCreditAppliedBill
>,
@Inject(VendorCredit.name)
private readonly vendorCreditModel: TenantModelProxy<typeof VendorCredit>,
) {}
/**
* Delete apply vendor credit to bill transaction.
* @param {number} appliedCreditToBillId
* @returns {Promise<void>}
*/
public async deleteApplyVendorCreditToBills(appliedCreditToBillId: number) {
const oldCreditAppliedToBill = await this.vendorCreditAppliedBillModel()
.query()
.findById(appliedCreditToBillId);
if (!oldCreditAppliedToBill) {
throw new ServiceError(ERRORS.VENDOR_CREDIT_APPLY_TO_BILLS_NOT_FOUND);
}
// Retrieve the vendor credit or throw not found service error.
const vendorCredit = await this.vendorCreditModel()
.query()
.findById(oldCreditAppliedToBill.vendorCreditId)
.throwIfNotFound();
// Deletes vendor credit apply under unit-of-work environment.
return this.uow.withTransaction(async (trx) => {
// Delete vendor credit applied to bill transaction.
await this.vendorCreditAppliedBillModel()
.query(trx)
.findById(appliedCreditToBillId)
.delete();
// Triggers `onVendorCreditApplyToInvoiceDeleted` event.
await this.eventPublisher.emitAsync(
events.vendorCredit.onApplyToInvoicesDeleted,
{
vendorCredit,
oldCreditAppliedToBill,
trx,
} as IVendorCreditApplyToBillDeletedPayload,
);
});
}
}

View File

@@ -0,0 +1,59 @@
import { Model } from 'objection';
// import TenantModel from 'models/TenantModel';
// import ModelSetting from './ModelSetting';
// import CustomViewBaseModel from './CustomViewBaseModel';
// import ModelSearchable from './ModelSearchable';
import { BaseModel } from '@/models/Model';
import { VendorCredit } from '../../VendorCredit/models/VendorCredit';
import { Bill } from '@/modules/Bills/models/Bill';
export class VendorCreditAppliedBill extends BaseModel {
public amount!: number;
public billId!: number;
public vendorCreditId!: number;
public vendorCredit!: VendorCredit;
public bill!: Bill;
/**
* Table name
*/
static get tableName() {
return 'vendor_credit_applied_bill';
}
/**
* Timestamps columns.
*/
public get timestamps() {
return ['created_at', 'updated_at'];
}
/**
* Relationship mapping.
*/
static get relationMappings() {
const { Bill } = require('../../Bills/models/Bill');
const { VendorCredit } = require('../../VendorCredit/models/VendorCredit');
return {
bill: {
relation: Model.BelongsToOneRelation,
modelClass: Bill,
join: {
from: 'vendor_credit_applied_bill.billId',
to: 'bills.id',
},
},
vendorCredit: {
relation: Model.BelongsToOneRelation,
modelClass: VendorCredit,
join: {
from: 'vendor_credit_applied_bill.vendorCreditId',
to: 'vendor_credits.id',
},
},
};
}
}

View File

@@ -0,0 +1,45 @@
import { Inject, Injectable } from '@nestjs/common';
import { VendorCreditAppliedBillTransformer } from './VendorCreditAppliedBillTransformer';
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
import { VendorCreditAppliedBill } from '@/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class GetAppliedBillsToVendorCreditService {
constructor(
private readonly transformer: TransformerInjectable,
@Inject(VendorCreditAppliedBill.name)
private readonly vendorCreditAppliedBillModel: TenantModelProxy<
typeof VendorCreditAppliedBill
>,
@Inject(VendorCredit.name)
private readonly vendorCreditModel: TenantModelProxy<typeof VendorCredit>,
) {}
/**
* Get applied bills to vendor credit.
* @param {number} vendorCreditId
* @returns
*/
public getAppliedBills = async (vendorCreditId: number) => {
const vendorCredit = await this.vendorCreditModel()
.query()
.findById(vendorCreditId)
.throwIfNotFound();
const appliedToBills = await this.vendorCreditAppliedBillModel()
.query()
.where('vendorCreditId', vendorCreditId)
.withGraphFetched('bill')
.withGraphFetched('vendorCredit');
// Transforms the models to POJO.
return this.transformer.transform(
appliedToBills,
new VendorCreditAppliedBillTransformer(),
);
};
}

View File

@@ -0,0 +1,49 @@
import { Inject, Injectable } from '@nestjs/common';
import { VendorCreditToApplyBillTransformer } from './VendorCreditToApplyBillTransformer';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
import { Bill } from '@/modules/Bills/models/Bill';
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class GetVendorCreditToApplyBills {
/**
* @param {TransformerService} transformerService - The transformer service.
* @param {typeof Bill} billModel - The bill model.
* @param {typeof VendorCredit} vendorCreditModel - The vendor credit model.
*/
constructor(
private readonly transformerService: TransformerInjectable,
@Inject(Bill.name)
private readonly billModel: TenantModelProxy<typeof Bill>,
@Inject(VendorCredit.name)
private readonly vendorCreditModel: TenantModelProxy<typeof VendorCredit>,
) {}
/**
* Retrieve bills that valid apply to the given vendor credit.
* @param {number} vendorCreditId
* @returns {Promise<any[]>}
*/
public async getCreditToApplyBills(vendorCreditId: number) {
// Retrieve vendor credit or throw not found service error.
const vendorCredit = await this.vendorCreditModel()
.query()
.findById(vendorCreditId)
.throwIfNotFound();
// Retrieve open bills associated to the given vendor.
const openBills = await this.billModel()
.query()
.where('vendor_id', vendorCredit.vendorId)
.modify('dueBills')
.modify('published');
// Transform the bills to POJO.
return this.transformerService.transform(
openBills,
new VendorCreditToApplyBillTransformer(),
);
}
}

View File

@@ -0,0 +1,67 @@
import { Transformer } from "@/modules/Transformer/Transformer";
import { VendorCreditAppliedBill } from "@/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill";
export class VendorCreditAppliedBillTransformer extends Transformer {
/**
* Includeded attributes.
* @returns {string[]}
*/
public includeAttributes = (): string[] => {
return [
'formattedAmount',
'vendorCreditNumber',
'vendorCreditDate',
'billNumber',
'billReferenceNo',
'formattedVendorCreditDate',
'formattedBillDate',
];
};
/**
* Exclude attributes.
* @returns {string[]}
*/
public excludeAttributes = (): string[] => {
return ['bill', 'vendorCredit'];
};
/**
*
* @param item
* @returns
*/
protected formattedAmount = (item: VendorCreditAppliedBill) => {
return this.formatNumber(item.amount, {
currencyCode: item.vendorCredit.currencyCode,
});
};
protected vendorCreditNumber = (item) => {
return item.vendorCredit.vendorCreditNumber;
};
protected vendorCreditDate = (item) => {
return item.vendorCredit.vendorCreditDate;
};
protected formattedVendorCreditDate = (item) => {
return this.formatDate(item.vendorCredit.vendorCreditDate);
};
protected billNumber = (item) => {
return item.bill.billNo;
};
protected billReferenceNo = (item) => {
return item.bill.referenceNo;
};
protected BillDate = (item) => {
return item.bill.billDate;
};
protected formattedBillDate = (item) => {
return this.formatDate(item.bill.billDate);
};
}

View File

@@ -0,0 +1,69 @@
import { Bill } from '@/modules/Bills/models/Bill';
import { Transformer } from '@/modules/Transformer/Transformer';
export class VendorCreditToApplyBillTransformer extends Transformer {
/**
* Include these attributes to sale invoice object.
* @returns {Array}
*/
public includeAttributes = (): string[] => {
return [
'formattedBillDate',
'formattedDueDate',
'formattedAmount',
'formattedDueAmount',
'formattedPaymentAmount',
];
};
/**
* Retrieve formatted bill date.
* @param {Bill} bill
* @returns {String}
*/
protected formattedBillDate = (bill: Bill): string => {
return this.formatDate(bill.billDate);
};
/**
* Retrieve formatted due date.
* @param {Bill} bill
* @returns {string}
*/
protected formattedDueDate = (bill: Bill): string => {
return this.formatDate(bill.dueDate);
};
/**
* Retrieve formatted bill amount.
* @param {Bill} bill
* @returns {string}
*/
protected formattedAmount = (bill: Bill): string => {
return this.formatNumber(bill.amount, {
currencyCode: bill.currencyCode,
});
};
/**
* Retrieve formatted bill due amount.
* @param {Bill} bill
* @returns {string}
*/
protected formattedDueAmount = (bill: Bill): string => {
return this.formatNumber(bill.dueAmount, {
currencyCode: bill.currencyCode,
});
};
/**
* Retrieve formatted payment amount.
* @param {Bill} bill
* @returns {string}
*/
protected formattedPaymentAmount = (bill: Bill): string => {
return this.formatNumber(bill.paymentAmount, {
currencyCode: bill.currencyCode,
});
};
}

View File

@@ -0,0 +1,61 @@
// import { Injectable } from '@nestjs/common';
// import { InjectModel } from '@nestjs/objection';
// import events from '@/subscribers/events';
// import {
// IVendorCreditApplyToBillDeletedPayload,
// IVendorCreditApplyToBillsCreatedPayload,
// } from '@/interfaces';
// import { ApplyVendorCreditSyncBillsService } from '../command/ApplyVendorCreditSyncBills.service';
// import { VendorCreditApplyToBill } from '../models/VendorCreditApplyToBill';
// @Injectable()
// export default class ApplyVendorCreditSyncBillsSubscriber {
// constructor(
// private readonly syncBillsWithVendorCredit: ApplyVendorCreditSyncBillsService,
// @InjectModel(VendorCreditApplyToBill)
// private readonly vendorCreditApplyToBillModel: typeof VendorCreditApplyToBill,
// ) {}
// /**
// * Attaches events with handlers.
// */
// attach(bus) {
// bus.subscribe(
// events.vendorCredit.onApplyToInvoicesCreated,
// this.incrementAppliedBillsOnceCreditCreated
// );
// bus.subscribe(
// events.vendorCredit.onApplyToInvoicesDeleted,
// this.decrementAppliedBillsOnceCreditDeleted
// );
// }
// /**
// * Increment credited amount of applied bills once the vendor credit transaction created.
// * @param {IVendorCreditApplyToBillsCreatedPayload} paylaod -
// */
// private incrementAppliedBillsOnceCreditCreated = async ({
// vendorCreditAppliedBills,
// trx,
// }: IVendorCreditApplyToBillsCreatedPayload) => {
// await this.syncBillsWithVendorCredit.incrementBillsCreditedAmount(
// vendorCreditAppliedBills,
// trx
// );
// };
// /**
// * Decrement credited amount of applied bills once the vendor credit
// * transaction delted.
// * @param {IVendorCreditApplyToBillDeletedPayload} payload
// */
// private decrementAppliedBillsOnceCreditDeleted = async ({
// oldCreditAppliedToBill,
// trx,
// }: IVendorCreditApplyToBillDeletedPayload) => {
// await this.syncBillsWithVendorCredit.decrementBillCreditedAmount(
// oldCreditAppliedToBill,
// trx
// );
// };
// }

View File

@@ -0,0 +1,70 @@
// import { Service, Inject } from 'typedi';
// import { sumBy } from 'lodash';
// import HasTenancyService from '@/services/Tenancy/TenancyService';
// import ApplyVendorCreditSyncInvoiced from '../command/ApplyVendorCreditSyncInvoiced.service';
// import events from '@/subscribers/events';
// import {
// IVendorCreditApplyToBillDeletedPayload,
// IVendorCreditApplyToBillsCreatedPayload,
// } from '../types/VendorCreditApplyBills.types';
// @Service()
// export default class ApplyVendorCreditSyncInvoicedSubscriber {
// @Inject()
// tenancy: HasTenancyService;
// @Inject()
// syncCreditWithInvoiced: ApplyVendorCreditSyncInvoiced;
// /**
// * Attaches events with handlers.
// */
// attach(bus) {
// bus.subscribe(
// events.vendorCredit.onApplyToInvoicesCreated,
// this.incrementBillInvoicedOnceCreditApplied
// );
// bus.subscribe(
// events.vendorCredit.onApplyToInvoicesDeleted,
// this.decrementBillInvoicedOnceCreditApplyDeleted
// );
// }
// /**
// * Increment vendor credit invoiced amount once the apply transaction created.
// * @param {IVendorCreditApplyToBillsCreatedPayload} payload -
// */
// private incrementBillInvoicedOnceCreditApplied = async ({
// vendorCredit,
// tenantId,
// vendorCreditAppliedBills,
// trx,
// }: IVendorCreditApplyToBillsCreatedPayload) => {
// const amount = sumBy(vendorCreditAppliedBills, 'amount');
// await this.syncCreditWithInvoiced.incrementVendorCreditInvoicedAmount(
// tenantId,
// vendorCredit.id,
// amount,
// trx
// );
// };
// /**
// * Decrement vendor credit invoiced amount once the apply transaction deleted.
// * @param {IVendorCreditApplyToBillDeletedPayload} payload -
// */
// private decrementBillInvoicedOnceCreditApplyDeleted = async ({
// tenantId,
// vendorCredit,
// oldCreditAppliedToBill,
// trx,
// }: IVendorCreditApplyToBillDeletedPayload) => {
// await this.syncCreditWithInvoiced.decrementVendorCreditInvoicedAmount(
// tenantId,
// oldCreditAppliedToBill.vendorCreditId,
// oldCreditAppliedToBill.amount,
// trx
// );
// };
// }

View File

@@ -0,0 +1,48 @@
import { Knex } from 'knex';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
export interface IVendorCreditApplyToBillsCreatedPayload {
vendorCredit: VendorCredit;
vendorCreditAppliedBills: IVendorCreditAppliedBill[];
trx: Knex.Transaction;
}
export interface IVendorCreditApplyToBillsCreatingPayload {
trx: Knex.Transaction;
}
export interface IVendorCreditApplyToBillsCreatePayload {
trx: Knex.Transaction;
}
export interface IVendorCreditApplyToBillDeletedPayload {
vendorCredit: VendorCredit;
oldCreditAppliedToBill: IVendorCreditAppliedBill;
trx: Knex.Transaction;
}
export interface IVendorCreditApplyToInvoiceDTO {
amount: number;
billId: number;
}
export interface IVendorCreditApplyToInvoicesDTO {
entries: IVendorCreditApplyToInvoiceDTO[];
}
export interface IVendorCreditApplyToInvoiceModel {
billId: number;
amount: number;
vendorCreditId: number;
}
export interface IVendorCreditApplyToInvoicesModel {
entries: IVendorCreditApplyToInvoiceModel[];
amount: number;
}
export interface IVendorCreditAppliedBill {
billId: number;
amount: number;
vendorCreditId: number;
}