refactor: migrate credit note and vendor credit services to nestjs

This commit is contained in:
Ahmed Bouhuolia
2024-12-29 18:37:33 +02:00
parent 9f9b75cd31
commit caf235e2b5
107 changed files with 7396 additions and 109 deletions

View File

@@ -0,0 +1,20 @@
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";
@Module({
imports: [
ApplyVendorCreditSyncBillsService,
ApplyVendorCreditSyncInvoicedService,
ApplyVendorCreditToBillsService,
DeleteApplyVendorCreditToBillService,
GetAppliedBillsToVendorCreditService
],
controllers: [],
})
export class VendorCreditApplyBillsModule {}

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,48 @@
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';
@Injectable()
export class ApplyVendorCreditSyncBillsService {
constructor(
@Inject(Bill.name)
private readonly billModel: 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,43 @@
import { Inject, Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
@Injectable()
export class ApplyVendorCreditSyncInvoicedService {
constructor(
@Inject(VendorCredit.name)
private readonly vendorCreditModel: 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,129 @@
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';
@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 {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,
private readonly billPaymentValidators: BillPaymentValidators,
private readonly vendorCreditAppliedBillModel: typeof VendorCreditAppliedBill,
@Inject(VendorCredit.name)
private readonly vendorCreditModel: 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.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,66 @@
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';
@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,
private readonly vendorCreditAppliedBillModel: typeof VendorCreditAppliedBill,
@Inject(VendorCredit.name)
private readonly vendorCreditModel: 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,40 @@
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';
@Injectable()
export class GetAppliedBillsToVendorCreditService {
constructor(
private readonly transformer: TransformerInjectable,
private readonly vendorCreditAppliedBillModel: typeof VendorCreditAppliedBill,
@Inject(VendorCredit.name)
private readonly vendorCreditModel: 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,47 @@
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';
@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: typeof Bill,
@Inject(VendorCredit.name)
private readonly vendorCreditModel: 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 '@/interfaces';
@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;
}