mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
refactor: credit notes and vendor credits to Nestjs
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CreateCreditNoteService } from './commands/CreateCreditNote.service';
|
||||
import { CreateRefundCreditNoteService } from './commands/CreateRefundCreditNote.service';
|
||||
import { DeleteCreditNoteService } from './commands/DeleteCreditNote.service';
|
||||
import { EditCreditNoteService } from './commands/EditCreditNote.service';
|
||||
import { OpenCreditNoteService } from './commands/OpenCreditNote.service';
|
||||
@@ -8,24 +7,33 @@ import { GetCreditNotePdf } from './queries/GetCreditNotePdf.serivce';
|
||||
import {
|
||||
ICreditNoteEditDTO,
|
||||
ICreditNoteNewDTO,
|
||||
ICreditNoteRefundDTO,
|
||||
} from './types/CreditNotes.types';
|
||||
|
||||
@Injectable()
|
||||
export class CreditNoteApplication {
|
||||
constructor(
|
||||
private createCreditNoteService: CreateCreditNoteService,
|
||||
private createRefundCreditNoteService: CreateRefundCreditNoteService,
|
||||
private editCreditNoteService: EditCreditNoteService,
|
||||
private openCreditNoteService: OpenCreditNoteService,
|
||||
private deleteCreditNoteService: DeleteCreditNoteService,
|
||||
private getCreditNotePdfService: GetCreditNotePdf,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Creates a new credit note.
|
||||
* @param {ICreditNoteNewDTO} creditNoteDTO
|
||||
* @returns {Promise<CreditNote>}
|
||||
*/
|
||||
createCreditNote(creditNoteDTO: ICreditNoteNewDTO) {
|
||||
return this.createCreditNoteService.creditCreditNote(creditNoteDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits a credit note.
|
||||
* @param {number} creditNoteId
|
||||
* @param {ICreditNoteEditDTO} creditNoteDTO
|
||||
* @returns {Promise<CreditNote>}
|
||||
*/
|
||||
editCreditNote(creditNoteId: number, creditNoteDTO: ICreditNoteEditDTO) {
|
||||
return this.editCreditNoteService.editCreditNote(
|
||||
creditNoteId,
|
||||
@@ -33,24 +41,29 @@ export class CreditNoteApplication {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a credit note.
|
||||
* @param {number} creditNoteId
|
||||
* @returns {Promise<CreditNote>}
|
||||
*/
|
||||
openCreditNote(creditNoteId: number) {
|
||||
return this.openCreditNoteService.openCreditNote(creditNoteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a credit note.
|
||||
* @param {number} creditNoteId
|
||||
* @returns {Promise<CreditNote>}
|
||||
*/
|
||||
deleteCreditNote(creditNoteId: number) {
|
||||
return this.deleteCreditNoteService.deleteCreditNote(creditNoteId);
|
||||
}
|
||||
|
||||
createRefundCreditNote(
|
||||
creditNoteId: number,
|
||||
creditNoteDTO: ICreditNoteRefundDTO,
|
||||
) {
|
||||
return this.createRefundCreditNoteService.createCreditNoteRefund(
|
||||
creditNoteId,
|
||||
creditNoteDTO,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the PDF for a credit note.
|
||||
* @param {number} creditNoteId
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
getCreditNotePdf(creditNoteId: number) {
|
||||
return this.getCreditNotePdfService.getCreditNotePdf(creditNoteId);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import { CreditNoteApplication } from './CreditNoteApplication.service';
|
||||
import {
|
||||
ICreditNoteEditDTO,
|
||||
ICreditNoteNewDTO,
|
||||
ICreditNoteRefundDTO,
|
||||
} from './types/CreditNotes.types';
|
||||
|
||||
@Controller('credit-notes')
|
||||
@@ -38,15 +37,4 @@ export class CreditNotesController {
|
||||
deleteCreditNote(@Param('id') creditNoteId: number) {
|
||||
return this.creditNoteApplication.deleteCreditNote(creditNoteId);
|
||||
}
|
||||
|
||||
@Post(':id/refund')
|
||||
createRefundCreditNote(
|
||||
@Param('id') creditNoteId: number,
|
||||
@Body() creditNoteDTO: ICreditNoteRefundDTO,
|
||||
) {
|
||||
return this.creditNoteApplication.createRefundCreditNote(
|
||||
creditNoteId,
|
||||
creditNoteDTO,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,59 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { CreateCreditNoteService } from './commands/CreateCreditNote.service';
|
||||
import { CommandCreditNoteDTOTransform } from './commands/CommandCreditNoteDTOTransform.service';
|
||||
import { CreateRefundCreditNoteService } from './commands/CreateRefundCreditNote.service';
|
||||
import { EditCreditNoteService } from './commands/EditCreditNote.service';
|
||||
import { OpenCreditNoteService } from './commands/OpenCreditNote.service';
|
||||
import { DeleteCreditNoteService } from './commands/DeleteCreditNote.service';
|
||||
import { CreditNoteApplySyncCredit } from './commands/CreditNoteApplySyncCredit.service';
|
||||
import { DeleteCustomerLinkedCreditNoteService } from './commands/DeleteCustomerLinkedCreditNote.service';
|
||||
import { CreditNoteAutoIncrementService } from './commands/CreditNoteAutoIncrement.service';
|
||||
import { CreditNoteApplication } from './CreditNoteApplication.service';
|
||||
import { CreditNotesController } from './CreditNotes.controller';
|
||||
import { GetCreditNoteState } from './queries/GetCreditNoteState.service';
|
||||
import { GetCreditNotePdf } from './queries/GetCreditNotePdf.serivce';
|
||||
import { ItemsModule } from '../Items/items.module';
|
||||
import { BranchesModule } from '../Branches/Branches.module';
|
||||
import { WarehousesModule } from '../Warehouses/Warehouses.module';
|
||||
import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module';
|
||||
import { ChromiumlyTenancyModule } from '../ChromiumlyTenancy/ChromiumlyTenancy.module';
|
||||
import { TemplateInjectableModule } from '../TemplateInjectable/TemplateInjectable.module';
|
||||
import { GetCreditNote } from './queries/GetCreditNote.service';
|
||||
import { CreditNoteBrandingTemplate } from './queries/CreditNoteBrandingTemplate.service';
|
||||
import { AutoIncrementOrdersModule } from '../AutoIncrementOrders/AutoIncrementOrders.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ItemsModule,
|
||||
BranchesModule,
|
||||
WarehousesModule,
|
||||
PdfTemplatesModule,
|
||||
ChromiumlyTenancyModule,
|
||||
TemplateInjectableModule,
|
||||
AutoIncrementOrdersModule
|
||||
],
|
||||
providers: [
|
||||
CreateCreditNoteService,
|
||||
GetCreditNote,
|
||||
CommandCreditNoteDTOTransform,
|
||||
CreateRefundCreditNoteService,
|
||||
EditCreditNoteService,
|
||||
OpenCreditNoteService,
|
||||
DeleteCreditNoteService,
|
||||
CreditNoteApplySyncCredit,
|
||||
DeleteCustomerLinkedCreditNoteService,
|
||||
GetCreditNotePdf,
|
||||
CreditNoteAutoIncrementService,
|
||||
CreditNoteApplication
|
||||
GetCreditNoteState,
|
||||
CreditNoteApplication,
|
||||
CreditNoteBrandingTemplate
|
||||
],
|
||||
exports: [
|
||||
CreateCreditNoteService,
|
||||
GetCreditNote,
|
||||
CommandCreditNoteDTOTransform,
|
||||
EditCreditNoteService,
|
||||
OpenCreditNoteService,
|
||||
DeleteCreditNoteService,
|
||||
GetCreditNotePdf,
|
||||
CreditNoteAutoIncrementService,
|
||||
GetCreditNoteState,
|
||||
CreditNoteApplication,
|
||||
CreditNoteBrandingTemplate
|
||||
],
|
||||
controllers: [CreditNotesController],
|
||||
})
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import BaseCreditNotes from '../CreditNotes';
|
||||
import { ISaleInvoice } from '@/interfaces';
|
||||
import { CreditNoteWithInvoicesToApplyTransformer } from './commands/CreditNoteWithInvoicesToApplyTransformer';
|
||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||
|
||||
@Service()
|
||||
export default class GetCreditNoteAssociatedInvoicesToApply extends BaseCreditNotes {
|
||||
@Inject()
|
||||
private transformer: TransformerInjectable;
|
||||
|
||||
/**
|
||||
* Retrieve credit note associated invoices to apply.
|
||||
* @param {number} tenantId
|
||||
* @param {number} creditNoteId
|
||||
* @returns {Promise<ISaleInvoice[]>}
|
||||
*/
|
||||
public getCreditAssociatedInvoicesToApply = async (
|
||||
tenantId: number,
|
||||
creditNoteId: number
|
||||
): Promise<ISaleInvoice[]> => {
|
||||
const { SaleInvoice } = this.tenancy.models(tenantId);
|
||||
|
||||
// Retireve credit note or throw not found service error.
|
||||
const creditNote = await this.getCreditNoteOrThrowError(
|
||||
tenantId,
|
||||
creditNoteId
|
||||
);
|
||||
// Retrieves the published due invoices that associated to the given customer.
|
||||
const saleInvoices = await SaleInvoice.query()
|
||||
.where('customerId', creditNote.customerId)
|
||||
.modify('dueInvoices')
|
||||
.modify('published');
|
||||
|
||||
// Transformes the sale invoices models to POJO.
|
||||
return this.transformer.transform(
|
||||
tenantId,
|
||||
saleInvoices,
|
||||
new CreditNoteWithInvoicesToApplyTransformer()
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -5,7 +5,6 @@ import * as R from 'ramda';
|
||||
import composeAsync from 'async/compose';
|
||||
import { ERRORS } from '../constants';
|
||||
import {
|
||||
ICreditNote,
|
||||
ICreditNoteEditDTO,
|
||||
ICreditNoteEntryNewDTO,
|
||||
ICreditNoteNewDTO,
|
||||
@@ -92,9 +91,9 @@ export class CommandCreditNoteDTOTransform {
|
||||
)(initialDTO);
|
||||
|
||||
return R.compose(
|
||||
this.branchDTOTransform.transformDTO<ICreditNote>,
|
||||
this.warehouseDTOTransform.transformDTO<ICreditNote>,
|
||||
)(initialAsyncDTO);
|
||||
this.branchDTOTransform.transformDTO<CreditNote>,
|
||||
this.warehouseDTOTransform.transformDTO<CreditNote>,
|
||||
)(initialAsyncDTO) as CreditNote;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import {
|
||||
ICreditNoteCreatedPayload,
|
||||
ICreditNoteCreatingPayload,
|
||||
@@ -15,13 +15,25 @@ import { events } from '@/common/events/events';
|
||||
|
||||
@Injectable()
|
||||
export class CreateCreditNoteService {
|
||||
/**
|
||||
* @param {UnitOfWork} uow - Unit of work.
|
||||
* @param {ItemsEntriesService} itemsEntriesService - Items entries service.
|
||||
* @param {EventEmitter2} eventPublisher - Event emitter.
|
||||
* @param {typeof CreditNote} creditNoteModel - Credit note model.
|
||||
* @param {typeof Contact} contactModel - Contact model.
|
||||
* @param {CommandCreditNoteDTOTransform} commandCreditNoteDTOTransform - Command credit note DTO transform service.
|
||||
*/
|
||||
constructor(
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly itemsEntriesService: ItemsEntriesService,
|
||||
private readonly eventPublisher: EventEmitter2,
|
||||
private readonly creditNoteModel: typeof CreditNote,
|
||||
private readonly contactModel: typeof Contact,
|
||||
private readonly commandCreditNoteDTOTransform: CommandCreditNoteDTOTransform,
|
||||
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: typeof CreditNote,
|
||||
|
||||
@Inject(Contact.name)
|
||||
private readonly contactModel: typeof Contact,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import {
|
||||
ICreditNoteRefundDTO,
|
||||
IRefundCreditNoteCreatedPayload,
|
||||
IRefundCreditNoteCreatingPayload,
|
||||
} from '../types/CreditNotes.types';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { RefundCreditNote } from '../models/RefundCreditNote';
|
||||
import { events } from '@/common/events/events';
|
||||
import { CommandCreditNoteDTOTransform } from './CommandCreditNoteDTOTransform.service';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
|
||||
@Injectable()
|
||||
export class CreateRefundCreditNoteService {
|
||||
/**
|
||||
* @param {UnitOfWork} uow - The unit of work service.
|
||||
* @param {EventEmitter2} eventPublisher - The event emitter service.
|
||||
* @param {CommandCreditNoteDTOTransform} commandCreditNoteDTOTransform - The command credit note DTO transform service.
|
||||
* @param {typeof RefundCreditNote} refundCreditNoteModel - The refund credit note model.
|
||||
* @param {typeof Account} accountModel - The account model.
|
||||
* @param {typeof CreditNote} creditNoteModel - The credit note model.
|
||||
*/
|
||||
constructor(
|
||||
private uow: UnitOfWork,
|
||||
private eventPublisher: EventEmitter2,
|
||||
private commandCreditNoteDTOTransform: CommandCreditNoteDTOTransform,
|
||||
|
||||
@Inject(RefundCreditNote.name)
|
||||
private refundCreditNoteModel: typeof RefundCreditNote,
|
||||
|
||||
@Inject(Account.name) private accountModel: typeof Account,
|
||||
@Inject(CreditNote.name) private creditNoteModel: typeof CreditNote,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieve the credit note graph.
|
||||
* @param {number} creditNoteId
|
||||
* @param {ICreditNoteRefundDTO} newCreditNoteDTO
|
||||
* @returns {Promise<IRefundCreditNote>}
|
||||
*/
|
||||
public async createCreditNoteRefund(
|
||||
creditNoteId: number,
|
||||
newCreditNoteDTO: ICreditNoteRefundDTO,
|
||||
): Promise<RefundCreditNote> {
|
||||
// Retrieve the credit note or throw not found service error.
|
||||
const creditNote = await this.creditNoteModel
|
||||
.query()
|
||||
.findById(creditNoteId)
|
||||
.throwIfNotFound();
|
||||
|
||||
// Retrieve the withdrawal account or throw not found service error.
|
||||
const fromAccount = await this.accountModel
|
||||
.query()
|
||||
.findById(newCreditNoteDTO.fromAccountId)
|
||||
.throwIfNotFound();
|
||||
|
||||
// Validate the credit note remaining amount.
|
||||
this.commandCreditNoteDTOTransform?.validateCreditRemainingAmount(
|
||||
creditNote,
|
||||
newCreditNoteDTO.amount,
|
||||
);
|
||||
// Validate the refund withdrawal account type.
|
||||
this.commandCreditNoteDTOTransform.validateRefundWithdrawwalAccountType(
|
||||
fromAccount,
|
||||
);
|
||||
// Creates a refund credit note transaction.
|
||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||
// Triggers `onCreditNoteRefundCreating` event.
|
||||
await this.eventPublisher.emitAsync(events.creditNote.onRefundCreating, {
|
||||
trx,
|
||||
creditNote,
|
||||
newCreditNoteDTO,
|
||||
} as IRefundCreditNoteCreatingPayload);
|
||||
|
||||
// Stores the refund credit note graph to the storage layer.
|
||||
const refundCreditNote = await this.refundCreditNoteModel
|
||||
.query(trx)
|
||||
.insertAndFetch({
|
||||
...this.transformDTOToModel(creditNote, newCreditNoteDTO),
|
||||
});
|
||||
|
||||
// Triggers `onCreditNoteRefundCreated` event.
|
||||
await this.eventPublisher.emitAsync(events.creditNote.onRefundCreated, {
|
||||
trx,
|
||||
refundCreditNote,
|
||||
creditNote,
|
||||
} as IRefundCreditNoteCreatedPayload);
|
||||
|
||||
return refundCreditNote;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transformes the refund credit note DTO to model.
|
||||
* @param {number} creditNoteId
|
||||
* @param {ICreditNoteRefundDTO} creditNoteDTO
|
||||
* @returns {ICreditNote}
|
||||
*/
|
||||
private transformDTOToModel = (
|
||||
creditNote: CreditNote,
|
||||
creditNoteDTO: ICreditNoteRefundDTO,
|
||||
): RefundCreditNote => {
|
||||
return {
|
||||
creditNoteId: creditNote.id,
|
||||
currencyCode: creditNote.currencyCode,
|
||||
...creditNoteDTO,
|
||||
exchangeRate: creditNoteDTO.exchangeRate || 1,
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
|
||||
@Injectable()
|
||||
export class CreditNoteApplySyncCredit {
|
||||
constructor(
|
||||
@Inject(CreditNote.name)
|
||||
private creditNoteModel: typeof CreditNote,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Increment credit note invoiced amount.
|
||||
* @param {number} creditNoteId
|
||||
* @param {number} invoicesAppliedAmount
|
||||
* @param {Knex.Transaction} [trx]
|
||||
*/
|
||||
public async incrementCreditNoteInvoicedAmount(
|
||||
creditNoteId: number,
|
||||
invoicesAppliedAmount: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> {
|
||||
await this.creditNoteModel
|
||||
.query(trx)
|
||||
.findById(creditNoteId)
|
||||
.increment('invoicesAmount', invoicesAppliedAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement credit note invoiced amount.
|
||||
* @param {number} creditNoteId
|
||||
* @param {number} invoicesAppliedAmount
|
||||
* @param {Knex.Transaction} [trx]
|
||||
*/
|
||||
public async decrementCreditNoteInvoicedAmount(
|
||||
creditNoteId: number,
|
||||
invoicesAppliedAmount: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> {
|
||||
await this.creditNoteModel
|
||||
.query(trx)
|
||||
.findById(creditNoteId)
|
||||
.decrement('invoicesAmount', invoicesAppliedAmount);
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import Bluebird from 'bluebird';
|
||||
import { ICreditNoteAppliedToInvoice } from '../types/CreditNotes.types';
|
||||
import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
|
||||
|
||||
@Injectable()
|
||||
export class CreditNoteApplySyncInvoicesCreditedAmount {
|
||||
constructor(
|
||||
@Inject(SaleInvoice.name)
|
||||
private readonly saleInvoiceModel: typeof SaleInvoice,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Increment invoices credited amount.
|
||||
* @param {ICreditNoteAppliedToInvoice[]} creditNoteAppliedInvoices -
|
||||
* @param {Knex.Transaction} trx -
|
||||
*/
|
||||
public incrementInvoicesCreditedAmount = async (
|
||||
creditNoteAppliedInvoices: ICreditNoteAppliedToInvoice[],
|
||||
trx?: Knex.Transaction
|
||||
) => {
|
||||
await Bluebird.each(
|
||||
creditNoteAppliedInvoices,
|
||||
(creditNoteAppliedInvoice: ICreditNoteAppliedToInvoice) => {
|
||||
return this.saleInvoiceModel.query(trx)
|
||||
.where('id', creditNoteAppliedInvoice.invoiceId)
|
||||
.increment('creditedAmount', creditNoteAppliedInvoice.amount);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} invoicesIds
|
||||
* @param {number} amount -
|
||||
* @param {Knex.Transaction} knex -
|
||||
*/
|
||||
public decrementInvoiceCreditedAmount = async (
|
||||
invoiceId: number,
|
||||
amount: number,
|
||||
trx?: Knex.Transaction
|
||||
) => {
|
||||
await this.saleInvoiceModel.query(trx)
|
||||
.findById(invoiceId)
|
||||
.decrement('creditedAmount', amount);
|
||||
};
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { sumBy } from 'lodash';
|
||||
import {
|
||||
ICreditNoteAppliedToInvoice,
|
||||
ICreditNoteAppliedToInvoiceModel,
|
||||
IApplyCreditToInvoicesDTO,
|
||||
IApplyCreditToInvoicesCreatedPayload,
|
||||
ICreditNote,
|
||||
} from '../types/CreditNotes.types';
|
||||
import { ERRORS } from '../constants';
|
||||
import { PaymentReceivedValidators } from '@/modules/PaymentReceived/commands/PaymentReceivedValidators.service';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice';
|
||||
import { events } from '@/common/events/events';
|
||||
import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
|
||||
@Injectable()
|
||||
export class CreditNoteApplyToInvoices {
|
||||
/**
|
||||
* @param {PaymentReceivedValidators} paymentReceiveValidators - The payment received validators service.
|
||||
* @param {UnitOfWork} uow - The unit of work service.
|
||||
* @param {EventEmitter2} eventPublisher - The event emitter service.
|
||||
* @param {typeof CreditNoteAppliedInvoice} creditNoteAppliedInvoiceModel - The credit note applied invoice model.
|
||||
*/
|
||||
constructor(
|
||||
private readonly paymentReceiveValidators: PaymentReceivedValidators,
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly eventPublisher: EventEmitter2,
|
||||
|
||||
@Inject(CreditNoteAppliedInvoice.name)
|
||||
private readonly creditNoteAppliedInvoiceModel: typeof CreditNoteAppliedInvoice,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Apply credit note to the given invoices.
|
||||
* @param {number} creditNoteId
|
||||
* @param {IApplyCreditToInvoicesDTO} applyCreditToInvoicesDTO
|
||||
*/
|
||||
public async applyCreditNoteToInvoices(
|
||||
creditNoteId: number,
|
||||
applyCreditToInvoicesDTO: IApplyCreditToInvoicesDTO,
|
||||
): Promise<ICreditNoteAppliedToInvoice[]> {
|
||||
// Saves the credit note or throw not found service error.
|
||||
const creditNote = await this.getCreditNoteOrThrowError(creditNoteId);
|
||||
|
||||
// Retrieve the applied invoices that associated to the credit note customer.
|
||||
const appliedInvoicesEntries =
|
||||
await this.paymentReceiveValidators.validateInvoicesIDsExistance(
|
||||
creditNote.customerId,
|
||||
applyCreditToInvoicesDTO.entries,
|
||||
);
|
||||
|
||||
// Transformes apply DTO to model.
|
||||
const creditNoteAppliedModel = this.transformApplyDTOToModel(
|
||||
applyCreditToInvoicesDTO,
|
||||
creditNote,
|
||||
);
|
||||
|
||||
// Validate invoices has remaining amount to apply.
|
||||
this.validateInvoicesRemainingAmount(
|
||||
appliedInvoicesEntries,
|
||||
creditNoteAppliedModel.amount,
|
||||
);
|
||||
// Validate the credit note remaining amount.
|
||||
this.validateCreditRemainingAmount(
|
||||
creditNote,
|
||||
creditNoteAppliedModel.amount,
|
||||
);
|
||||
|
||||
// Creates credit note apply to invoice transaction.
|
||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||
// Saves the credit note apply to invoice graph to the storage layer.
|
||||
const creditNoteAppliedInvoices = await this.creditNoteAppliedInvoiceModel
|
||||
.query()
|
||||
.insertGraph(creditNoteAppliedModel.entries);
|
||||
|
||||
// Triggers `onCreditNoteApplyToInvoiceCreated` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.creditNote.onApplyToInvoicesCreated,
|
||||
{
|
||||
creditNote,
|
||||
creditNoteAppliedInvoices,
|
||||
trx,
|
||||
} as IApplyCreditToInvoicesCreatedPayload,
|
||||
);
|
||||
|
||||
return creditNoteAppliedInvoices;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transformes apply DTO to model.
|
||||
* @param {IApplyCreditToInvoicesDTO} applyDTO
|
||||
* @param {ICreditNote} creditNote
|
||||
* @returns
|
||||
*/
|
||||
private transformApplyDTOToModel = (
|
||||
applyDTO: IApplyCreditToInvoicesDTO,
|
||||
creditNote: ICreditNote,
|
||||
): ICreditNoteAppliedToInvoiceModel => {
|
||||
const entries = applyDTO.entries.map((entry) => ({
|
||||
invoiceId: entry.invoiceId,
|
||||
amount: entry.amount,
|
||||
creditNoteId: creditNote.id,
|
||||
}));
|
||||
return {
|
||||
amount: sumBy(entries, 'amount'),
|
||||
entries,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate the invoice remaining amount.
|
||||
* @param {ISaleInvoice[]} invoices
|
||||
* @param {number} amount
|
||||
*/
|
||||
private validateInvoicesRemainingAmount = (
|
||||
invoices: SaleInvoice[],
|
||||
amount: number,
|
||||
) => {
|
||||
const invalidInvoices = invoices.filter(
|
||||
(invoice) => invoice.dueAmount < amount,
|
||||
);
|
||||
if (invalidInvoices.length > 0) {
|
||||
throw new ServiceError(ERRORS.INVOICES_HAS_NO_REMAINING_AMOUNT);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import { Transformer } from "@/modules/Transformer/Transformer";
|
||||
|
||||
export class CreditNoteWithInvoicesToApplyTransformer extends Transformer {
|
||||
/**
|
||||
* Include these attributes to sale invoice object.
|
||||
* @returns {Array}
|
||||
*/
|
||||
public includeAttributes = (): string[] => {
|
||||
return [
|
||||
'formattedInvoiceDate',
|
||||
'formattedDueDate',
|
||||
'formattedAmount',
|
||||
'formattedDueAmount',
|
||||
'formattedPaymentAmount',
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve formatted invoice date.
|
||||
* @param {ISaleInvoice} invoice
|
||||
* @returns {String}
|
||||
*/
|
||||
protected formattedInvoiceDate = (invoice): string => {
|
||||
return this.formatDate(invoice.invoiceDate);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve formatted due date.
|
||||
* @param {ISaleInvoice} invoice
|
||||
* @returns {string}
|
||||
*/
|
||||
protected formattedDueDate = (invoice): string => {
|
||||
return this.formatDate(invoice.dueDate);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve formatted invoice amount.
|
||||
* @param {ISaleInvoice} invoice
|
||||
* @returns {string}
|
||||
*/
|
||||
protected formattedAmount = (invoice): string => {
|
||||
return this.formatNumber(invoice.balance, {
|
||||
currencyCode: invoice.currencyCode,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve formatted invoice due amount.
|
||||
* @param {ISaleInvoice} invoice
|
||||
* @returns {string}
|
||||
*/
|
||||
protected formattedDueAmount = (invoice): string => {
|
||||
return this.formatNumber(invoice.dueAmount, {
|
||||
currencyCode: invoice.currencyCode,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve formatted payment amount.
|
||||
* @param {ISaleInvoice} invoice
|
||||
* @returns {string}
|
||||
*/
|
||||
protected formattedPaymentAmount = (invoice): string => {
|
||||
return this.formatNumber(invoice.paymentAmount, {
|
||||
currencyCode: invoice.currencyCode,
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import {
|
||||
} from '../types/CreditNotes.types';
|
||||
import { ERRORS } from '../constants';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice';
|
||||
import { CreditNoteAppliedInvoice } from '../../CreditNotesApplyInvoice/models/CreditNoteAppliedInvoice';
|
||||
import {
|
||||
RefundCreditNote as RefundCreditNoteModel,
|
||||
} from '../models/RefundCreditNote';
|
||||
} from '../../CreditNoteRefunds/models/RefundCreditNote';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { IApplyCreditToInvoicesDeletedPayload } from '../types/CreditNotes.types';
|
||||
import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { events } from '@/common/events/events';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
import { ERRORS } from '../constants';
|
||||
|
||||
@Injectable()
|
||||
export default class DeleteCreditNoteApplyToInvoices {
|
||||
constructor(
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly eventPublisher: EventEmitter2,
|
||||
private readonly creditNoteAppliedInvoiceModel: typeof CreditNoteAppliedInvoice,
|
||||
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: typeof CreditNote,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Apply credit note to the given invoices.
|
||||
* @param {number} creditNoteId
|
||||
* @param {IApplyCreditToInvoicesDTO} applyCreditToInvoicesDTO
|
||||
*/
|
||||
public deleteApplyCreditNoteToInvoices = async (
|
||||
applyCreditToInvoicesId: number,
|
||||
): Promise<void> => {
|
||||
const creditNoteAppliedToInvoice = await this.creditNoteAppliedInvoiceModel
|
||||
.query()
|
||||
.findById(applyCreditToInvoicesId);
|
||||
|
||||
if (!creditNoteAppliedToInvoice) {
|
||||
throw new ServiceError(ERRORS.CREDIT_NOTE_APPLY_TO_INVOICES_NOT_FOUND);
|
||||
}
|
||||
// Retrieve the credit note or throw not found service error.
|
||||
const creditNote = await this.creditNoteModel
|
||||
.query()
|
||||
.findById(creditNoteAppliedToInvoice.creditNoteId)
|
||||
.throwIfNotFound();
|
||||
|
||||
// Creates credit note apply to invoice transaction.
|
||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||
// Delete credit note applied to invoices.
|
||||
await this.creditNoteAppliedInvoiceModel
|
||||
.query(trx)
|
||||
.findById(applyCreditToInvoicesId)
|
||||
.delete();
|
||||
|
||||
// Triggers `onCreditNoteApplyToInvoiceDeleted` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.creditNote.onApplyToInvoicesDeleted,
|
||||
{
|
||||
creditNote,
|
||||
creditNoteAppliedToInvoice,
|
||||
trx,
|
||||
} as IApplyCreditToInvoicesDeletedPayload,
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
import { ERRORS } from '../constants';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
|
||||
@Injectable()
|
||||
export class DeleteCustomerLinkedCreditNoteService {
|
||||
constructor(
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: typeof CreditNote,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Validate the given customer has no linked credit note transactions.
|
||||
* @param {number} customerId - The customer identifier.
|
||||
*/
|
||||
public async validateCustomerHasNoCreditTransaction(customerId: number) {
|
||||
const associatedCredits = await this.creditNoteModel
|
||||
.query()
|
||||
.where('customerId', customerId);
|
||||
|
||||
if (associatedCredits.length > 0) {
|
||||
throw new ServiceError(ERRORS.CUSTOMER_HAS_LINKED_CREDIT_NOTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { Knex } from 'knex';
|
||||
import {
|
||||
IRefundCreditNoteDeletedPayload,
|
||||
IRefundCreditNoteDeletingPayload,
|
||||
IRefundVendorCreditDeletedPayload,
|
||||
} from '../types/CreditNotes.types';
|
||||
import { RefundCreditNote } from '../models/RefundCreditNote';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { events } from '@/common/events/events';
|
||||
|
||||
@Injectable()
|
||||
export default class DeleteRefundCreditNote {
|
||||
/**
|
||||
* @param {UnitOfWork} uow
|
||||
* @param {EventEmitter2} eventPublisher
|
||||
* @param {typeof RefundCreditNoteModel} refundCreditNoteModel
|
||||
*/
|
||||
constructor(
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly eventPublisher: EventEmitter2,
|
||||
|
||||
@Inject(RefundCreditNote.name)
|
||||
private readonly refundCreditNoteModel: typeof RefundCreditNote,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieve the credit note graph.
|
||||
* @param {number} refundCreditId
|
||||
* @returns
|
||||
*/
|
||||
public deleteCreditNoteRefund = async (refundCreditId: number) => {
|
||||
// Retrieve the old credit note or throw not found service error.
|
||||
const oldRefundCredit = await this.refundCreditNoteModel
|
||||
.query()
|
||||
.findById(refundCreditId)
|
||||
.throwIfNotFound();
|
||||
|
||||
// Triggers `onCreditNoteRefundDeleted` event.
|
||||
await this.eventPublisher.emitAsync(events.creditNote.onRefundDelete, {
|
||||
refundCreditId,
|
||||
oldRefundCredit,
|
||||
} as IRefundCreditNoteDeletedPayload);
|
||||
|
||||
// Deletes refund credit note transactions with associated entries.
|
||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||
const eventPayload = {
|
||||
trx,
|
||||
refundCreditId,
|
||||
oldRefundCredit,
|
||||
} as IRefundCreditNoteDeletedPayload | IRefundCreditNoteDeletingPayload;
|
||||
|
||||
// Triggers `onCreditNoteRefundDeleting` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.creditNote.onRefundDeleting,
|
||||
eventPayload,
|
||||
);
|
||||
|
||||
// Deletes the refund credit note graph from the storage.
|
||||
await this.refundCreditNoteModel
|
||||
.query(trx)
|
||||
.findById(refundCreditId)
|
||||
.delete();
|
||||
|
||||
// Triggers `onCreditNoteRefundDeleted` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.creditNote.onRefundDeleted,
|
||||
eventPayload as IRefundVendorCreditDeletedPayload,
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -49,7 +49,6 @@ export class OpenCreditNoteService {
|
||||
// Sales the credit note transactions with associated entries.
|
||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||
const eventPayload = {
|
||||
creditNoteId,
|
||||
oldCreditNote,
|
||||
trx,
|
||||
} as ICreditNoteOpeningPayload;
|
||||
@@ -62,8 +61,7 @@ export class OpenCreditNoteService {
|
||||
// Saves the credit note graph to the storage.
|
||||
const creditNote = await this.creditNoteModel
|
||||
.query(trx)
|
||||
.findById(creditNoteId)
|
||||
.update({
|
||||
.updateAndFetchById(creditNoteId, {
|
||||
openedAt: new Date(),
|
||||
});
|
||||
// Triggers `onCreditNoteOpened` event.
|
||||
@@ -77,10 +75,10 @@ export class OpenCreditNoteService {
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param creditNote
|
||||
* Throws an error if the given credit note is already open.
|
||||
* @param {CreditNote} creditNote -
|
||||
*/
|
||||
public throwErrorIfAlreadyOpen = (creditNote) => {
|
||||
public throwErrorIfAlreadyOpen = (creditNote: CreditNote) => {
|
||||
if (creditNote.openedAt) {
|
||||
throw new ServiceError(ERRORS.CREDIT_NOTE_ALREADY_OPENED);
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { ERRORS } from '../constants';
|
||||
import { RefundCreditNote } from '../models/RefundCreditNote';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||
|
||||
@Injectable()
|
||||
export class RefundCreditNoteService {
|
||||
/**
|
||||
* @param {typeof RefundCreditNote} refundCreditNoteModel - The refund credit note model.
|
||||
*/
|
||||
constructor(
|
||||
@Inject(RefundCreditNote.name)
|
||||
private readonly refundCreditNoteModel: typeof RefundCreditNote,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieve the credit note graph.
|
||||
* @param {number} refundCreditId
|
||||
* @returns {Promise<RefundCreditNote>}
|
||||
*/
|
||||
public getCreditNoteRefundOrThrowError = async (
|
||||
refundCreditId: number,
|
||||
): Promise<RefundCreditNote> => {
|
||||
const refundCreditNote = await this.refundCreditNoteModel
|
||||
.query()
|
||||
.findById(refundCreditId);
|
||||
if (!refundCreditNote) {
|
||||
throw new ServiceError(ERRORS.REFUND_CREDIT_NOTE_NOT_FOUND);
|
||||
}
|
||||
return refundCreditNote;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate the refund account type.
|
||||
* @param {Account} account
|
||||
*/
|
||||
public validateRefundWithdrawwalAccountType = (account: Account): void => {
|
||||
const supportedTypes = ['bank', 'cash', 'fixed-asset'];
|
||||
|
||||
if (supportedTypes.indexOf(account.accountType) === -1) {
|
||||
throw new ServiceError(ERRORS.ACCOUNT_INVALID_TYPE);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
// import { Inject, Service } from 'typedi';
|
||||
// import { Knex } from 'knex';
|
||||
// import { AccountNormal, ILedgerEntry, IRefundCreditNote } from '@/interfaces';
|
||||
// import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
// import LedgerStorageService from '@/services/Accounting/LedgerStorageService';
|
||||
// import Ledger from '@/services/Accounting/Ledger';
|
||||
|
||||
// @Service()
|
||||
// export default class RefundCreditNoteGLEntries {
|
||||
// @Inject()
|
||||
// ledgerStorage: LedgerStorageService;
|
||||
|
||||
// @Inject()
|
||||
// tenancy: HasTenancyService;
|
||||
|
||||
// /**
|
||||
// * Retrieves the refund credit common GL entry.
|
||||
// * @param {IRefundCreditNote} refundCreditNote
|
||||
// * @returns
|
||||
// */
|
||||
// private getRefundCreditCommonGLEntry = (
|
||||
// refundCreditNote: IRefundCreditNote
|
||||
// ) => {
|
||||
// return {
|
||||
// currencyCode: refundCreditNote.currencyCode,
|
||||
// exchangeRate: refundCreditNote.exchangeRate,
|
||||
|
||||
// transactionType: 'RefundCreditNote',
|
||||
// transactionId: refundCreditNote.id,
|
||||
// date: refundCreditNote.date,
|
||||
// userId: refundCreditNote.userId,
|
||||
|
||||
// referenceNumber: refundCreditNote.referenceNo,
|
||||
|
||||
// createdAt: refundCreditNote.createdAt,
|
||||
// indexGroup: 10,
|
||||
|
||||
// credit: 0,
|
||||
// debit: 0,
|
||||
|
||||
// note: refundCreditNote.description,
|
||||
// branchId: refundCreditNote.branchId,
|
||||
// };
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Retrieves the refudn credit receivable GL entry.
|
||||
// * @param {IRefundCreditNote} refundCreditNote
|
||||
// * @param {number} ARAccountId
|
||||
// * @returns {ILedgerEntry}
|
||||
// */
|
||||
// private getRefundCreditGLReceivableEntry = (
|
||||
// refundCreditNote: IRefundCreditNote,
|
||||
// ARAccountId: number
|
||||
// ): ILedgerEntry => {
|
||||
// const commonEntry = this.getRefundCreditCommonGLEntry(refundCreditNote);
|
||||
|
||||
// return {
|
||||
// ...commonEntry,
|
||||
// debit: refundCreditNote.amount,
|
||||
// accountId: ARAccountId,
|
||||
// contactId: refundCreditNote.creditNote.customerId,
|
||||
// index: 1,
|
||||
// accountNormal: AccountNormal.DEBIT,
|
||||
// };
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Retrieves the refund credit withdrawal GL entry.
|
||||
// * @param {number} refundCreditNote
|
||||
// * @returns {ILedgerEntry}
|
||||
// */
|
||||
// private getRefundCreditGLWithdrawalEntry = (
|
||||
// refundCreditNote: IRefundCreditNote
|
||||
// ): ILedgerEntry => {
|
||||
// const commonEntry = this.getRefundCreditCommonGLEntry(refundCreditNote);
|
||||
|
||||
// return {
|
||||
// ...commonEntry,
|
||||
// credit: refundCreditNote.amount,
|
||||
// accountId: refundCreditNote.fromAccountId,
|
||||
// index: 2,
|
||||
// accountNormal: AccountNormal.DEBIT,
|
||||
// };
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Retrieve the refund credit note GL entries.
|
||||
// * @param {IRefundCreditNote} refundCreditNote
|
||||
// * @param {number} receivableAccount
|
||||
// * @returns {ILedgerEntry[]}
|
||||
// */
|
||||
// public getRefundCreditGLEntries(
|
||||
// refundCreditNote: IRefundCreditNote,
|
||||
// ARAccountId: number
|
||||
// ): ILedgerEntry[] {
|
||||
// const receivableEntry = this.getRefundCreditGLReceivableEntry(
|
||||
// refundCreditNote,
|
||||
// ARAccountId
|
||||
// );
|
||||
// const withdrawalEntry =
|
||||
// this.getRefundCreditGLWithdrawalEntry(refundCreditNote);
|
||||
|
||||
// return [receivableEntry, withdrawalEntry];
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Creates refund credit GL entries.
|
||||
// * @param {number} tenantId
|
||||
// * @param {IRefundCreditNote} refundCreditNote
|
||||
// * @param {Knex.Transaction} trx
|
||||
// */
|
||||
// public createRefundCreditGLEntries = async (
|
||||
// tenantId: number,
|
||||
// refundCreditNoteId: number,
|
||||
// trx?: Knex.Transaction
|
||||
// ) => {
|
||||
// const { Account, RefundCreditNote } = this.tenancy.models(tenantId);
|
||||
|
||||
// // Retrieve the refund with associated credit note.
|
||||
// const refundCreditNote = await RefundCreditNote.query(trx)
|
||||
// .findById(refundCreditNoteId)
|
||||
// .withGraphFetched('creditNote');
|
||||
|
||||
// // Receivable account A/R.
|
||||
// const receivableAccount = await Account.query().findOne(
|
||||
// 'slug',
|
||||
// 'accounts-receivable'
|
||||
// );
|
||||
// // Retrieve refund credit GL entries.
|
||||
// const refundGLEntries = this.getRefundCreditGLEntries(
|
||||
// refundCreditNote,
|
||||
// receivableAccount.id
|
||||
// );
|
||||
// const ledger = new Ledger(refundGLEntries);
|
||||
|
||||
// // Saves refund ledger entries.
|
||||
// await this.ledgerStorage.commit(tenantId, ledger, trx);
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Reverts refund credit note GL entries.
|
||||
// * @param {number} tenantId
|
||||
// * @param {number} refundCreditNoteId
|
||||
// * @param {number} receivableAccount
|
||||
// * @param {Knex.Transaction} trx
|
||||
// */
|
||||
// public revertRefundCreditGLEntries = async (
|
||||
// tenantId: number,
|
||||
// refundCreditNoteId: number,
|
||||
// trx?: Knex.Transaction
|
||||
// ) => {
|
||||
// await this.ledgerStorage.deleteByReference(
|
||||
// tenantId,
|
||||
// refundCreditNoteId,
|
||||
// 'RefundCreditNote',
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
@@ -1,48 +0,0 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
|
||||
@Injectable()
|
||||
export class RefundSyncCreditNoteBalance {
|
||||
/**
|
||||
* @param {typeof CreditNote} creditNoteModel - The credit note model.
|
||||
*/
|
||||
constructor(
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: typeof CreditNote,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Increments the refund amount of the credit note.
|
||||
* @param {number} creditNoteId - The credit note ID.
|
||||
* @param {number} amount - The amount to increment.
|
||||
* @param {Knex.Transaction} trx - The knex transaction.
|
||||
*/
|
||||
public incrementCreditNoteRefundAmount = async (
|
||||
creditNoteId: number,
|
||||
amount: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> => {
|
||||
await this.creditNoteModel
|
||||
.query(trx)
|
||||
.findById(creditNoteId)
|
||||
.increment('refunded_amount', amount);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrements the refund amount of the credit note.
|
||||
* @param {number} creditNoteId - The credit note ID.
|
||||
* @param {number} amount - The amount to decrement.
|
||||
* @param {Knex.Transaction} trx - The knex transaction.
|
||||
*/
|
||||
public decrementCreditNoteRefundAmount = async (
|
||||
creditNoteId: number,
|
||||
amount: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> => {
|
||||
await this.creditNoteModel
|
||||
.query(trx)
|
||||
.findById(creditNoteId)
|
||||
.decrement('refunded_amount', amount);
|
||||
};
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
import { DiscountType } from '@/common/types/Discount';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { Branch } from '@/modules/Branches/models/Branch.model';
|
||||
import { Customer } from '@/modules/Customers/models/Customer';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model';
|
||||
import { mixin, Model, raw } from 'objection';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import ModelSetting from './ModelSetting';
|
||||
@@ -5,22 +11,32 @@ import { mixin, Model, raw } from 'objection';
|
||||
// import { DEFAULT_VIEWS } from '@/services/CreditNotes/constants';
|
||||
// import ModelSearchable from './ModelSearchable';
|
||||
// import CreditNoteMeta from './CreditNote.Meta';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
// import { DiscountType } from '@/interfaces';
|
||||
|
||||
export class CreditNote extends BaseModel {
|
||||
customerId: number;
|
||||
creditNoteDate: Date;
|
||||
creditNoteNumber: string;
|
||||
referenceNo: string;
|
||||
amount: number;
|
||||
exchangeRate: number;
|
||||
refundedAmount: number;
|
||||
invoicesAmount: number;
|
||||
currencyCode: string;
|
||||
note: string;
|
||||
termsConditions: string;
|
||||
openedAt: Date;
|
||||
userId: number;
|
||||
public amount: number;
|
||||
public exchangeRate: number;
|
||||
public openedAt: Date;
|
||||
public discount: number;
|
||||
public discountType: DiscountType;
|
||||
public adjustment: number;
|
||||
public refundedAmount: number;
|
||||
public invoicesAmount: number;
|
||||
public creditNoteDate: Date;
|
||||
public creditNoteNumber: string;
|
||||
public currencyCode: string;
|
||||
public customerId: number;
|
||||
|
||||
public branchId: number;
|
||||
public warehouseId: number;
|
||||
|
||||
public customer!: Customer;
|
||||
public entries!: ItemEntry[];
|
||||
|
||||
public branch!: Branch;
|
||||
public warehouse!: Warehouse;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Table name
|
||||
@@ -46,8 +62,21 @@ export class CreditNote extends BaseModel {
|
||||
'isPublished',
|
||||
'isOpen',
|
||||
'isClosed',
|
||||
|
||||
'creditsRemaining',
|
||||
'creditsUsed',
|
||||
|
||||
'subtotal',
|
||||
'subtotalLocal',
|
||||
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'total',
|
||||
'totalLocal',
|
||||
|
||||
'adjustmentLocal',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -59,6 +88,72 @@ export class CreditNote extends BaseModel {
|
||||
return this.amount * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit note subtotal.
|
||||
* @returns {number}
|
||||
*/
|
||||
get subtotal() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit note subtotal in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get subtotalLocal() {
|
||||
return this.subtotal * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount.
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmount() {
|
||||
return this.discountType === DiscountType.Amount
|
||||
? this.discount
|
||||
: this.subtotal * (this.discount / 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmountLocal() {
|
||||
return this.discountAmount ? this.discountAmount * this.exchangeRate : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount percentage.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get discountPercentage(): number | null {
|
||||
return this.discountType === DiscountType.Percentage ? this.discount : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjustment amount in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get adjustmentLocal() {
|
||||
return this.adjustment ? this.adjustment * this.exchangeRate : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit note total.
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.subtotal - this.discountAmount + this.adjustment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit note total in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get totalLocal() {
|
||||
return this.total * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detarmines whether the credit note is draft.
|
||||
* @returns {boolean}
|
||||
@@ -98,6 +193,9 @@ export class CreditNote extends BaseModel {
|
||||
return Math.max(this.amount - this.refundedAmount - this.invoicesAmount, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the credits used.
|
||||
*/
|
||||
get creditsUsed() {
|
||||
return this.refundedAmount + this.invoicesAmount;
|
||||
}
|
||||
@@ -128,7 +226,7 @@ export class CreditNote extends BaseModel {
|
||||
query
|
||||
.where(
|
||||
raw(`COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICES_AMOUNT) <
|
||||
COALESCE(AMOUNT)`)
|
||||
COALESCE(AMOUNT)`),
|
||||
)
|
||||
.modify('published');
|
||||
},
|
||||
@@ -140,7 +238,7 @@ export class CreditNote extends BaseModel {
|
||||
query
|
||||
.where(
|
||||
raw(`COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICES_AMOUNT) =
|
||||
COALESCE(AMOUNT)`)
|
||||
COALESCE(AMOUNT)`),
|
||||
)
|
||||
.modify('published');
|
||||
},
|
||||
@@ -171,7 +269,7 @@ export class CreditNote extends BaseModel {
|
||||
*/
|
||||
sortByStatus(query, order) {
|
||||
query.orderByRaw(
|
||||
`COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICES_AMOUNT) = COALESCE(AMOUNT) ${order}`
|
||||
`COALESCE(REFUNDED_AMOUNT) + COALESCE(INVOICES_AMOUNT) = COALESCE(AMOUNT) ${order}`,
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -181,12 +279,15 @@ export class CreditNote extends BaseModel {
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const { AccountTransaction } = require('../../Accounts/models/AccountTransaction.model');
|
||||
const { ItemEntry } = require('../../TransactionItemEntry/models/ItemEntry');
|
||||
const {
|
||||
AccountTransaction,
|
||||
} = require('../../Accounts/models/AccountTransaction.model');
|
||||
const { ItemEntry } = require('../../Items/models/ItemEntry');
|
||||
const { Customer } = require('../../Customers/models/Customer');
|
||||
const { Branch } = require('../../Branches/models/Branch.model');
|
||||
const { Document } = require('../../ChromiumlyTenancy/models/Document');
|
||||
const { Warehouse } = require('../../Warehouses/models/Warehouse.model');
|
||||
const { PdfTemplate } = require('../../PdfTemplate/models/PdfTemplate');
|
||||
|
||||
return {
|
||||
/**
|
||||
@@ -277,12 +378,24 @@ export class CreditNote extends BaseModel {
|
||||
query.where('model_ref', 'CreditNote');
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Credit note may belongs to pdf branding template.
|
||||
*/
|
||||
pdfTemplate: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: PdfTemplate,
|
||||
join: {
|
||||
from: 'credit_notes.pdfTemplateId',
|
||||
to: 'pdf_templates.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sale invoice meta.
|
||||
*/
|
||||
// /**
|
||||
// * Sale invoice meta.
|
||||
// */
|
||||
// static get meta() {
|
||||
// return CreditNoteMeta;
|
||||
// }
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import { mixin, 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 { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
|
||||
import { CreditNote } from './CreditNote';
|
||||
|
||||
export class CreditNoteAppliedInvoice extends BaseModel {
|
||||
public amount: number;
|
||||
public creditNoteId: number;
|
||||
public invoiceId: number;
|
||||
|
||||
public saleInvoice!: SaleInvoice;
|
||||
public creditNote!: CreditNote;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'credit_note_applied_invoice';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['created_at', 'updated_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const { SaleInvoice } = require('../../SaleInvoices/models/SaleInvoice');
|
||||
const { CreditNote } = require('../../CreditNotes/models/CreditNote');
|
||||
|
||||
return {
|
||||
saleInvoice: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: SaleInvoice,
|
||||
join: {
|
||||
from: 'credit_note_applied_invoice.invoiceId',
|
||||
to: 'sales_invoices.id',
|
||||
},
|
||||
},
|
||||
|
||||
creditNote: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: CreditNote,
|
||||
join: {
|
||||
from: 'credit_note_applied_invoice.creditNoteId',
|
||||
to: 'credit_notes.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import { Model, mixin } from 'objection';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import ModelSetting from './ModelSetting';
|
||||
// import CustomViewBaseModel from './CustomViewBaseModel';
|
||||
// import ModelSearchable from './ModelSearchable';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
|
||||
export class RefundCreditNote extends BaseModel{
|
||||
date: Date;
|
||||
referenceNo: string;
|
||||
amount: number;
|
||||
currencyCode: string;
|
||||
exchangeRate: number;
|
||||
fromAccountId: number;
|
||||
description: string;
|
||||
creditNoteId: number;
|
||||
|
||||
userId?: number;
|
||||
branchId?: number;
|
||||
|
||||
createdAt?: Date | null;
|
||||
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'refund_credit_note_transactions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['created_at', 'updated_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const { Account } = require('../../Accounts/models/Account.model');
|
||||
const { CreditNote } = require('../../CreditNotes/models/CreditNote');
|
||||
|
||||
return {
|
||||
fromAccount: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Account,
|
||||
join: {
|
||||
from: 'refund_credit_note_transactions.fromAccountId',
|
||||
to: 'accounts.id',
|
||||
},
|
||||
},
|
||||
creditNote: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: CreditNote,
|
||||
join: {
|
||||
from: 'refund_credit_note_transactions.creditNoteId',
|
||||
to: 'credit_notes.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import { Transformer } from '../../Transformer/Transformer';
|
||||
import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice';
|
||||
|
||||
export class CreditNoteAppliedInvoiceTransformer extends Transformer {
|
||||
/**
|
||||
* Includeded attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public includeAttributes = (): string[] => {
|
||||
return [
|
||||
'formttedAmount',
|
||||
'creditNoteNumber',
|
||||
'creditNoteDate',
|
||||
'invoiceNumber',
|
||||
'invoiceReferenceNo',
|
||||
'formattedCreditNoteDate',
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Exclude attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public excludeAttributes = (): string[] => {
|
||||
return ['saleInvoice', 'creditNote'];
|
||||
};
|
||||
|
||||
public formttedAmount = (item: CreditNoteAppliedInvoice) => {
|
||||
return this.formatNumber(item.amount, {
|
||||
currencyCode: item.creditNote.currencyCode,
|
||||
});
|
||||
};
|
||||
|
||||
public creditNoteNumber = (item: CreditNoteAppliedInvoice) => {
|
||||
return item.creditNote.creditNoteNumber;
|
||||
};
|
||||
|
||||
public creditNoteDate = (item: CreditNoteAppliedInvoice) => {
|
||||
return item.creditNote.creditNoteDate;
|
||||
};
|
||||
|
||||
public invoiceNumber = (item: CreditNoteAppliedInvoice) => {
|
||||
return item.saleInvoice.invoiceNo;
|
||||
};
|
||||
|
||||
public invoiceReferenceNo = (item: CreditNoteAppliedInvoice) => {
|
||||
return item.saleInvoice.referenceNo;
|
||||
};
|
||||
|
||||
public formattedCreditNoteDate = (item: CreditNoteAppliedInvoice) => {
|
||||
return this.formatDate(item.creditNote.creditNoteDate);
|
||||
};
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { CreditNoteAppliedInvoiceTransformer } from './CreditNoteAppliedInvoiceTransformer';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
import { TransformerInjectable } from '../../Transformer/TransformerInjectable.service';
|
||||
import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice';
|
||||
|
||||
@Injectable()
|
||||
export class GetCreditNoteAssociatedAppliedInvoices {
|
||||
constructor(
|
||||
private readonly transformer: TransformerInjectable,
|
||||
private readonly creditNoteAppliedInvoiceModel: typeof CreditNoteAppliedInvoice,
|
||||
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: typeof CreditNote
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve credit note associated invoices to apply.
|
||||
* @param {number} creditNoteId
|
||||
* @returns {Promise<CreditNoteAppliedInvoice[]>}
|
||||
*/
|
||||
public async getCreditAssociatedAppliedInvoices(
|
||||
creditNoteId: number
|
||||
): Promise<CreditNoteAppliedInvoice[]> {
|
||||
// Retrieve credit note or throw not found service error.
|
||||
const creditNote = await this.creditNoteModel.query()
|
||||
.findById(creditNoteId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const appliedToInvoices = await this.creditNoteAppliedInvoiceModel.query()
|
||||
.where('credit_note_id', creditNoteId)
|
||||
.withGraphFetched('saleInvoice')
|
||||
.withGraphFetched('creditNote');
|
||||
|
||||
// Transforms credit note applied to invoices.
|
||||
return this.transformer.transform(
|
||||
appliedToInvoices,
|
||||
new CreditNoteAppliedInvoiceTransformer()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { CreditNoteWithInvoicesToApplyTransformer } from '../commands/CreditNoteWithInvoicesToApplyTransformer';
|
||||
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
|
||||
import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
|
||||
import { GetCreditNote } from './GetCreditNote.service';
|
||||
|
||||
@Injectable()
|
||||
export class GetCreditNoteAssociatedInvoicesToApply {
|
||||
constructor(
|
||||
private transformer: TransformerInjectable,
|
||||
private getCreditNote: GetCreditNote,
|
||||
|
||||
@Inject(SaleInvoice.name)
|
||||
private saleInvoiceModel: typeof SaleInvoice,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieve credit note associated invoices to apply.
|
||||
* @param {number} creditNoteId
|
||||
* @returns {Promise<ISaleInvoice[]>}
|
||||
*/
|
||||
public async getCreditAssociatedInvoicesToApply(
|
||||
creditNoteId: number,
|
||||
): Promise<SaleInvoice[]> {
|
||||
// Retrieve credit note or throw not found service error.
|
||||
const creditNote = await this.getCreditNote.getCreditNote(creditNoteId);
|
||||
|
||||
// Retrieves the published due invoices that associated to the given customer.
|
||||
const saleInvoices = await this.saleInvoiceModel
|
||||
.query()
|
||||
.where('customerId', creditNote.customerId)
|
||||
.modify('dueInvoices')
|
||||
.modify('published');
|
||||
|
||||
// Transforms the sale invoices models to POJO.
|
||||
return this.transformer.transform(
|
||||
saleInvoices,
|
||||
new CreditNoteWithInvoicesToApplyTransformer(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,15 @@ import { events } from '@/common/events/events';
|
||||
|
||||
@Injectable()
|
||||
export class GetCreditNotePdf {
|
||||
/**
|
||||
* @param {ChromiumlyTenancy} chromiumlyTenancy - Chromiumly tenancy service.
|
||||
* @param {TemplateInjectable} templateInjectable - Template injectable service.
|
||||
* @param {GetCreditNote} getCreditNoteService - Get credit note service.
|
||||
* @param {CreditNoteBrandingTemplate} creditNoteBrandingTemplate - Credit note branding template service.
|
||||
* @param {EventEmitter2} eventPublisher - Event publisher service.
|
||||
* @param {typeof CreditNote} creditNoteModel - Credit note model.
|
||||
* @param {typeof PdfTemplateModel} pdfTemplateModel - Pdf template model.
|
||||
*/
|
||||
constructor(
|
||||
private readonly chromiumlyTenancy: ChromiumlyTenancy,
|
||||
private readonly templateInjectable: TemplateInjectable,
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import RefundCreditNoteTransformer from './RefundCreditNoteTransformer';
|
||||
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
|
||||
import { RefundCreditNote } from '../models/RefundCreditNote';
|
||||
import { IRefundCreditNotePOJO } from '../types/CreditNotes.types';
|
||||
|
||||
@Injectable()
|
||||
export class ListCreditNoteRefunds {
|
||||
constructor(
|
||||
private readonly transformer: TransformerInjectable,
|
||||
|
||||
@Inject(RefundCreditNote.name)
|
||||
private readonly refundCreditNoteModel: typeof RefundCreditNote,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieve the credit note graph.
|
||||
* @param {number} creditNoteId
|
||||
* @returns {Promise<IRefundCreditNotePOJO[]>}
|
||||
*/
|
||||
public async getCreditNoteRefunds(
|
||||
creditNoteId: number,
|
||||
): Promise<IRefundCreditNotePOJO[]> {
|
||||
// Retrieve refund credit notes associated to the given credit note.
|
||||
const refundCreditTransactions = await this.refundCreditNoteModel
|
||||
.query()
|
||||
.where('creditNoteId', creditNoteId)
|
||||
.withGraphFetched('creditNote')
|
||||
.withGraphFetched('fromAccount');
|
||||
|
||||
// Transforms refund credit note models to POJO objects.
|
||||
return this.transformer.transform(
|
||||
refundCreditTransactions,
|
||||
new RefundCreditNoteTransformer(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { IRefundCreditNote } from '../types/CreditNotes.types';
|
||||
import { RefundCreditNote } from '../models/RefundCreditNote';
|
||||
import { RefundCreditNoteTransformer } from './RefundCreditNoteTransformer';
|
||||
|
||||
@Injectable()
|
||||
export class GetRefundCreditNoteTransaction {
|
||||
/**
|
||||
* @param {RefundCreditNoteTransformer} transformer
|
||||
* @param {typeof RefundCreditNote} refundCreditNoteModel
|
||||
*/
|
||||
constructor(
|
||||
private readonly transformer: RefundCreditNoteTransformer,
|
||||
|
||||
@Inject(RefundCreditNote.name)
|
||||
private readonly refundCreditNoteModel: typeof RefundCreditNote,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve credit note associated invoices to apply.
|
||||
* @param {number} refundCreditId
|
||||
* @returns {Promise<IRefundCreditNote>}
|
||||
*/
|
||||
public async getRefundCreditTransaction(
|
||||
refundCreditId: number
|
||||
): Promise<IRefundCreditNote> {
|
||||
const refundCreditNote = await this.refundCreditNoteModel
|
||||
.query()
|
||||
.findById(refundCreditId)
|
||||
.withGraphFetched('fromAccount')
|
||||
.withGraphFetched('creditNote')
|
||||
.throwIfNotFound();
|
||||
|
||||
return this.transformer.transform(refundCreditNote);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import { sumBy } from 'lodash';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
IApplyCreditToInvoicesCreatedPayload,
|
||||
IApplyCreditToInvoicesDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import CreditNoteApplySyncCredit from '../commands/CreditNoteApplySyncCredit.service';
|
||||
|
||||
@Service()
|
||||
export default class CreditNoteApplySyncCreditSubscriber {
|
||||
@Inject()
|
||||
syncInvoicedAmountWithCredit: CreditNoteApplySyncCredit;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bus
|
||||
*/
|
||||
attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onApplyToInvoicesCreated,
|
||||
this.incrementCreditedAmountOnceApplyToInvoicesCreated
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onApplyToInvoicesDeleted,
|
||||
this.decrementCreditedAmountOnceApplyToInvoicesDeleted
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment credited amount of credit note transaction once the transaction created.
|
||||
* @param {IApplyCreditToInvoicesCreatedPayload} payload -
|
||||
*/
|
||||
private incrementCreditedAmountOnceApplyToInvoicesCreated = async ({
|
||||
trx,
|
||||
creditNote,
|
||||
tenantId,
|
||||
creditNoteAppliedInvoices,
|
||||
}: IApplyCreditToInvoicesCreatedPayload) => {
|
||||
const totalCredited = sumBy(creditNoteAppliedInvoices, 'amount');
|
||||
|
||||
await this.syncInvoicedAmountWithCredit.incrementCreditNoteInvoicedAmount(
|
||||
tenantId,
|
||||
creditNote.id,
|
||||
totalCredited,
|
||||
trx
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrement credited amount of credit note transaction once the transaction deleted.
|
||||
* @param {IApplyCreditToInvoicesDeletedPayload} payload -
|
||||
*/
|
||||
private decrementCreditedAmountOnceApplyToInvoicesDeleted = async ({
|
||||
tenantId,
|
||||
creditNote,
|
||||
creditNoteAppliedToInvoice,
|
||||
trx,
|
||||
}: IApplyCreditToInvoicesDeletedPayload) => {
|
||||
await this.syncInvoicedAmountWithCredit.decrementCreditNoteInvoicedAmount(
|
||||
tenantId,
|
||||
creditNote.id,
|
||||
creditNoteAppliedToInvoice.amount,
|
||||
trx
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
IApplyCreditToInvoicesCreatedPayload,
|
||||
IApplyCreditToInvoicesDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import CreditNoteApplySyncInvoicesCreditedAmount from '../commands/CreditNoteApplySyncInvoices.service';
|
||||
|
||||
@Service()
|
||||
export default class CreditNoteApplySyncInvoicesCreditedAmountSubscriber {
|
||||
@Inject()
|
||||
private syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount;
|
||||
|
||||
/**
|
||||
* Attaches events with handlers.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onApplyToInvoicesCreated,
|
||||
this.incrementAppliedInvoicesOnceCreditCreated
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onApplyToInvoicesDeleted,
|
||||
this.decrementAppliedInvoicesOnceCreditDeleted
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment invoices credited amount once the credit note apply to invoices transaction
|
||||
* @param {IApplyCreditToInvoicesCreatedPayload} payload -
|
||||
*/
|
||||
private incrementAppliedInvoicesOnceCreditCreated = async ({
|
||||
trx,
|
||||
tenantId,
|
||||
creditNoteAppliedInvoices,
|
||||
}: IApplyCreditToInvoicesCreatedPayload) => {
|
||||
await this.syncInvoicesWithCreditNote.incrementInvoicesCreditedAmount(
|
||||
tenantId,
|
||||
creditNoteAppliedInvoices,
|
||||
trx
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {IApplyCreditToInvoicesDeletedPayload} payload -
|
||||
*/
|
||||
private decrementAppliedInvoicesOnceCreditDeleted = async ({
|
||||
trx,
|
||||
creditNoteAppliedToInvoice,
|
||||
tenantId,
|
||||
}: IApplyCreditToInvoicesDeletedPayload) => {
|
||||
// Decrement invoice credited amount.
|
||||
await this.syncInvoicesWithCreditNote.decrementInvoiceCreditedAmount(
|
||||
tenantId,
|
||||
creditNoteAppliedToInvoice.invoiceId,
|
||||
creditNoteAppliedToInvoice.amount,
|
||||
trx
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1,30 +1,30 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import events from '@/subscribers/events';
|
||||
import BaseCreditNotes from '../commands/CommandCreditNoteDTOTransform.service';
|
||||
import { ICreditNoteCreatedPayload } from '@/interfaces';
|
||||
// import { Service, Inject } from 'typedi';
|
||||
// import events from '@/subscribers/events';
|
||||
// import BaseCreditNotes from '../commands/CommandCreditNoteDTOTransform.service';
|
||||
// import { ICreditNoteCreatedPayload } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
export default class CreditNoteAutoSerialSubscriber {
|
||||
@Inject()
|
||||
creditNotesService: BaseCreditNotes;
|
||||
// @Service()
|
||||
// export default class CreditNoteAutoSerialSubscriber {
|
||||
// @Inject()
|
||||
// creditNotesService: BaseCreditNotes;
|
||||
|
||||
/**
|
||||
* Attaches events with handlers.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onCreated,
|
||||
this.autoSerialIncrementOnceCreated
|
||||
);
|
||||
}
|
||||
// /**
|
||||
// * Attaches events with handlers.
|
||||
// */
|
||||
// public attach(bus) {
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onCreated,
|
||||
// this.autoSerialIncrementOnceCreated
|
||||
// );
|
||||
// }
|
||||
|
||||
/**
|
||||
* Auto serial increment once credit note created.
|
||||
* @param {ICreditNoteCreatedPayload} payload -
|
||||
*/
|
||||
private autoSerialIncrementOnceCreated = async ({
|
||||
tenantId,
|
||||
}: ICreditNoteCreatedPayload) => {
|
||||
await this.creditNotesService.incrementSerialNumber(tenantId);
|
||||
};
|
||||
}
|
||||
// /**
|
||||
// * Auto serial increment once credit note created.
|
||||
// * @param {ICreditNoteCreatedPayload} payload -
|
||||
// */
|
||||
// private autoSerialIncrementOnceCreated = async ({
|
||||
// tenantId,
|
||||
// }: ICreditNoteCreatedPayload) => {
|
||||
// await this.creditNotesService.incrementSerialNumber(tenantId);
|
||||
// };
|
||||
// }
|
||||
|
||||
@@ -1,113 +1,113 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
ICreditNoteCreatedPayload,
|
||||
ICreditNoteDeletedPayload,
|
||||
ICreditNoteEditedPayload,
|
||||
ICreditNoteOpenedPayload,
|
||||
} from '@/interfaces';
|
||||
import CreditNoteGLEntries from '../commands/CreditNoteGLEntries';
|
||||
// import { Service, Inject } from 'typedi';
|
||||
// import events from '@/subscribers/events';
|
||||
// import {
|
||||
// ICreditNoteCreatedPayload,
|
||||
// ICreditNoteDeletedPayload,
|
||||
// ICreditNoteEditedPayload,
|
||||
// ICreditNoteOpenedPayload,
|
||||
// } from '@/interfaces';
|
||||
// import CreditNoteGLEntries from '../commands/CreditNoteGLEntries';
|
||||
|
||||
@Service()
|
||||
export default class CreditNoteGLEntriesSubscriber {
|
||||
@Inject()
|
||||
private creditNoteGLEntries: CreditNoteGLEntries;
|
||||
// @Service()
|
||||
// export default class CreditNoteGLEntriesSubscriber {
|
||||
// @Inject()
|
||||
// private creditNoteGLEntries: CreditNoteGLEntries;
|
||||
|
||||
/**
|
||||
* Attaches events with handlers.
|
||||
* @param bus
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onCreated,
|
||||
this.writeGlEntriesOnceCreditNoteCreated
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onOpened,
|
||||
this.writeGLEntriesOnceCreditNoteOpened
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onEdited,
|
||||
this.editVendorCreditGLEntriesOnceEdited
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onDeleted,
|
||||
this.revertGLEntriesOnceCreditNoteDeleted
|
||||
);
|
||||
}
|
||||
// /**
|
||||
// * Attaches events with handlers.
|
||||
// * @param bus
|
||||
// */
|
||||
// public attach(bus) {
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onCreated,
|
||||
// this.writeGlEntriesOnceCreditNoteCreated
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onOpened,
|
||||
// this.writeGLEntriesOnceCreditNoteOpened
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onEdited,
|
||||
// this.editVendorCreditGLEntriesOnceEdited
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onDeleted,
|
||||
// this.revertGLEntriesOnceCreditNoteDeleted
|
||||
// );
|
||||
// }
|
||||
|
||||
/**
|
||||
* Writes the GL entries once the credit note transaction created or open.
|
||||
* @private
|
||||
* @param {ICreditNoteCreatedPayload|ICreditNoteOpenedPayload} payload -
|
||||
*/
|
||||
private writeGlEntriesOnceCreditNoteCreated = async ({
|
||||
tenantId,
|
||||
creditNote,
|
||||
creditNoteId,
|
||||
trx,
|
||||
}: ICreditNoteCreatedPayload | ICreditNoteOpenedPayload) => {
|
||||
// Can't continue if the credit note is not published yet.
|
||||
if (!creditNote.isPublished) return;
|
||||
// /**
|
||||
// * Writes the GL entries once the credit note transaction created or open.
|
||||
// * @private
|
||||
// * @param {ICreditNoteCreatedPayload|ICreditNoteOpenedPayload} payload -
|
||||
// */
|
||||
// private writeGlEntriesOnceCreditNoteCreated = async ({
|
||||
// tenantId,
|
||||
// creditNote,
|
||||
// creditNoteId,
|
||||
// trx,
|
||||
// }: ICreditNoteCreatedPayload | ICreditNoteOpenedPayload) => {
|
||||
// // Can't continue if the credit note is not published yet.
|
||||
// if (!creditNote.isPublished) return;
|
||||
|
||||
await this.creditNoteGLEntries.createVendorCreditGLEntries(
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
trx
|
||||
);
|
||||
};
|
||||
// await this.creditNoteGLEntries.createVendorCreditGLEntries(
|
||||
// tenantId,
|
||||
// creditNoteId,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Writes the GL entries once the vendor credit transaction opened.
|
||||
* @param {ICreditNoteOpenedPayload} payload
|
||||
*/
|
||||
private writeGLEntriesOnceCreditNoteOpened = async ({
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
trx,
|
||||
}: ICreditNoteOpenedPayload) => {
|
||||
await this.creditNoteGLEntries.createVendorCreditGLEntries(
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
trx
|
||||
);
|
||||
};
|
||||
// /**
|
||||
// * Writes the GL entries once the vendor credit transaction opened.
|
||||
// * @param {ICreditNoteOpenedPayload} payload
|
||||
// */
|
||||
// private writeGLEntriesOnceCreditNoteOpened = async ({
|
||||
// tenantId,
|
||||
// creditNoteId,
|
||||
// trx,
|
||||
// }: ICreditNoteOpenedPayload) => {
|
||||
// await this.creditNoteGLEntries.createVendorCreditGLEntries(
|
||||
// tenantId,
|
||||
// creditNoteId,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Reverts GL entries once credit note deleted.
|
||||
*/
|
||||
private revertGLEntriesOnceCreditNoteDeleted = async ({
|
||||
tenantId,
|
||||
oldCreditNote,
|
||||
creditNoteId,
|
||||
trx,
|
||||
}: ICreditNoteDeletedPayload) => {
|
||||
// Can't continue if the credit note is not published yet.
|
||||
if (!oldCreditNote.isPublished) return;
|
||||
// /**
|
||||
// * Reverts GL entries once credit note deleted.
|
||||
// */
|
||||
// private revertGLEntriesOnceCreditNoteDeleted = async ({
|
||||
// tenantId,
|
||||
// oldCreditNote,
|
||||
// creditNoteId,
|
||||
// trx,
|
||||
// }: ICreditNoteDeletedPayload) => {
|
||||
// // Can't continue if the credit note is not published yet.
|
||||
// if (!oldCreditNote.isPublished) return;
|
||||
|
||||
await this.creditNoteGLEntries.revertVendorCreditGLEntries(
|
||||
tenantId,
|
||||
creditNoteId
|
||||
);
|
||||
};
|
||||
// await this.creditNoteGLEntries.revertVendorCreditGLEntries(
|
||||
// tenantId,
|
||||
// creditNoteId
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Edits vendor credit associated GL entries once the transaction edited.
|
||||
* @param {ICreditNoteEditedPayload} payload -
|
||||
*/
|
||||
private editVendorCreditGLEntriesOnceEdited = async ({
|
||||
tenantId,
|
||||
creditNote,
|
||||
creditNoteId,
|
||||
trx,
|
||||
}: ICreditNoteEditedPayload) => {
|
||||
// Can't continue if the credit note is not published yet.
|
||||
if (!creditNote.isPublished) return;
|
||||
// /**
|
||||
// * Edits vendor credit associated GL entries once the transaction edited.
|
||||
// * @param {ICreditNoteEditedPayload} payload -
|
||||
// */
|
||||
// private editVendorCreditGLEntriesOnceEdited = async ({
|
||||
// tenantId,
|
||||
// creditNote,
|
||||
// creditNoteId,
|
||||
// trx,
|
||||
// }: ICreditNoteEditedPayload) => {
|
||||
// // Can't continue if the credit note is not published yet.
|
||||
// if (!creditNote.isPublished) return;
|
||||
|
||||
await this.creditNoteGLEntries.editVendorCreditGLEntries(
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
trx
|
||||
);
|
||||
};
|
||||
}
|
||||
// await this.creditNoteGLEntries.editVendorCreditGLEntries(
|
||||
// tenantId,
|
||||
// creditNoteId,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
|
||||
@@ -1,98 +1,98 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import events from '@/subscribers/events';
|
||||
import CreditNoteInventoryTransactions from '../commands/CreditNotesInventoryTransactions';
|
||||
import {
|
||||
ICreditNoteCreatedPayload,
|
||||
ICreditNoteDeletedPayload,
|
||||
ICreditNoteEditedPayload,
|
||||
} from '@/interfaces';
|
||||
// import { Service, Inject } from 'typedi';
|
||||
// import events from '@/subscribers/events';
|
||||
// import CreditNoteInventoryTransactions from '../commands/CreditNotesInventoryTransactions';
|
||||
// import {
|
||||
// ICreditNoteCreatedPayload,
|
||||
// ICreditNoteDeletedPayload,
|
||||
// ICreditNoteEditedPayload,
|
||||
// } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
export default class CreditNoteInventoryTransactionsSubscriber {
|
||||
@Inject()
|
||||
inventoryTransactions: CreditNoteInventoryTransactions;
|
||||
// @Service()
|
||||
// export default class CreditNoteInventoryTransactionsSubscriber {
|
||||
// @Inject()
|
||||
// inventoryTransactions: CreditNoteInventoryTransactions;
|
||||
|
||||
/**
|
||||
* Attaches events with publisher.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onCreated,
|
||||
this.writeInventoryTranscationsOnceCreated
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onEdited,
|
||||
this.rewriteInventoryTransactionsOnceEdited
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onDeleted,
|
||||
this.revertInventoryTransactionsOnceDeleted
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onOpened,
|
||||
this.writeInventoryTranscationsOnceCreated
|
||||
);
|
||||
}
|
||||
// /**
|
||||
// * Attaches events with publisher.
|
||||
// */
|
||||
// public attach(bus) {
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onCreated,
|
||||
// this.writeInventoryTranscationsOnceCreated
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onEdited,
|
||||
// this.rewriteInventoryTransactionsOnceEdited
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onDeleted,
|
||||
// this.revertInventoryTransactionsOnceDeleted
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onOpened,
|
||||
// this.writeInventoryTranscationsOnceCreated
|
||||
// );
|
||||
// }
|
||||
|
||||
/**
|
||||
* Writes inventory transactions once credit note created.
|
||||
* @param {ICreditNoteCreatedPayload} payload -
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public writeInventoryTranscationsOnceCreated = async ({
|
||||
tenantId,
|
||||
creditNote,
|
||||
trx,
|
||||
}: ICreditNoteCreatedPayload) => {
|
||||
// Can't continue if the credit note is open yet.
|
||||
if (!creditNote.isOpen) return;
|
||||
// /**
|
||||
// * Writes inventory transactions once credit note created.
|
||||
// * @param {ICreditNoteCreatedPayload} payload -
|
||||
// * @returns {Promise<void>}
|
||||
// */
|
||||
// public writeInventoryTranscationsOnceCreated = async ({
|
||||
// tenantId,
|
||||
// creditNote,
|
||||
// trx,
|
||||
// }: ICreditNoteCreatedPayload) => {
|
||||
// // Can't continue if the credit note is open yet.
|
||||
// if (!creditNote.isOpen) return;
|
||||
|
||||
await this.inventoryTransactions.createInventoryTransactions(
|
||||
tenantId,
|
||||
creditNote,
|
||||
trx
|
||||
);
|
||||
};
|
||||
// await this.inventoryTransactions.createInventoryTransactions(
|
||||
// tenantId,
|
||||
// creditNote,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Rewrites inventory transactions once credit note edited.
|
||||
* @param {ICreditNoteEditedPayload} payload -
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public rewriteInventoryTransactionsOnceEdited = async ({
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
creditNote,
|
||||
trx,
|
||||
}: ICreditNoteEditedPayload) => {
|
||||
// Can't continue if the credit note is open yet.
|
||||
if (!creditNote.isOpen) return;
|
||||
// /**
|
||||
// * Rewrites inventory transactions once credit note edited.
|
||||
// * @param {ICreditNoteEditedPayload} payload -
|
||||
// * @returns {Promise<void>}
|
||||
// */
|
||||
// public rewriteInventoryTransactionsOnceEdited = async ({
|
||||
// tenantId,
|
||||
// creditNoteId,
|
||||
// creditNote,
|
||||
// trx,
|
||||
// }: ICreditNoteEditedPayload) => {
|
||||
// // Can't continue if the credit note is open yet.
|
||||
// if (!creditNote.isOpen) return;
|
||||
|
||||
await this.inventoryTransactions.editInventoryTransactions(
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
creditNote,
|
||||
trx
|
||||
);
|
||||
};
|
||||
// await this.inventoryTransactions.editInventoryTransactions(
|
||||
// tenantId,
|
||||
// creditNoteId,
|
||||
// creditNote,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Reverts inventory transactions once credit note deleted.
|
||||
* @param {ICreditNoteDeletedPayload} payload -
|
||||
*/
|
||||
public revertInventoryTransactionsOnceDeleted = async ({
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
oldCreditNote,
|
||||
trx,
|
||||
}: ICreditNoteDeletedPayload) => {
|
||||
// Can't continue if the credit note is open yet.
|
||||
if (!oldCreditNote.isOpen) return;
|
||||
// /**
|
||||
// * Reverts inventory transactions once credit note deleted.
|
||||
// * @param {ICreditNoteDeletedPayload} payload -
|
||||
// */
|
||||
// public revertInventoryTransactionsOnceDeleted = async ({
|
||||
// tenantId,
|
||||
// creditNoteId,
|
||||
// oldCreditNote,
|
||||
// trx,
|
||||
// }: ICreditNoteDeletedPayload) => {
|
||||
// // Can't continue if the credit note is open yet.
|
||||
// if (!oldCreditNote.isOpen) return;
|
||||
|
||||
await this.inventoryTransactions.deleteInventoryTransactions(
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
trx
|
||||
);
|
||||
};
|
||||
}
|
||||
// await this.inventoryTransactions.deleteInventoryTransactions(
|
||||
// tenantId,
|
||||
// creditNoteId,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import TenancyService from '@/services/Tenancy/TenancyService';
|
||||
import events from '@/subscribers/events';
|
||||
import { ICustomerDeletingPayload } from '@/interfaces';
|
||||
import DeleteCustomerLinkedCreidtNote from '../commands/DeleteCustomerLinkedCreditNote.service';
|
||||
// import { Inject, Service } from 'typedi';
|
||||
// import { ServiceError } from '@/exceptions';
|
||||
// import TenancyService from '@/services/Tenancy/TenancyService';
|
||||
// import events from '@/subscribers/events';
|
||||
// import { ICustomerDeletingPayload } from '@/interfaces';
|
||||
// import DeleteCustomerLinkedCreidtNote from '../commands/DeleteCustomerLinkedCreditNote.service';
|
||||
|
||||
const ERRORS = {
|
||||
CUSTOMER_HAS_TRANSACTIONS: 'CUSTOMER_HAS_TRANSACTIONS',
|
||||
};
|
||||
// const ERRORS = {
|
||||
// CUSTOMER_HAS_TRANSACTIONS: 'CUSTOMER_HAS_TRANSACTIONS',
|
||||
// };
|
||||
|
||||
@Service()
|
||||
export default class DeleteCustomerLinkedCreditSubscriber {
|
||||
@Inject()
|
||||
tenancy: TenancyService;
|
||||
// @Service()
|
||||
// export default class DeleteCustomerLinkedCreditSubscriber {
|
||||
// @Inject()
|
||||
// tenancy: TenancyService;
|
||||
|
||||
@Inject()
|
||||
deleteCustomerLinkedCredit: DeleteCustomerLinkedCreidtNote;
|
||||
// @Inject()
|
||||
// deleteCustomerLinkedCredit: DeleteCustomerLinkedCreidtNote;
|
||||
|
||||
/**
|
||||
* Attaches events with handlers.
|
||||
* @param bus
|
||||
*/
|
||||
public attach = (bus) => {
|
||||
bus.subscribe(
|
||||
events.customers.onDeleting,
|
||||
this.validateCustomerHasNoLinkedCreditsOnDeleting
|
||||
);
|
||||
};
|
||||
// /**
|
||||
// * Attaches events with handlers.
|
||||
// * @param bus
|
||||
// */
|
||||
// public attach = (bus) => {
|
||||
// bus.subscribe(
|
||||
// events.customers.onDeleting,
|
||||
// this.validateCustomerHasNoLinkedCreditsOnDeleting
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Validate vendor has no associated credit transaction once the vendor deleting.
|
||||
* @param {IVendorEventDeletingPayload} payload -
|
||||
*/
|
||||
public validateCustomerHasNoLinkedCreditsOnDeleting = async ({
|
||||
tenantId,
|
||||
customerId,
|
||||
}: ICustomerDeletingPayload) => {
|
||||
try {
|
||||
await this.deleteCustomerLinkedCredit.validateCustomerHasNoCreditTransaction(
|
||||
tenantId,
|
||||
customerId
|
||||
);
|
||||
} catch (error) {
|
||||
throw new ServiceError(ERRORS.CUSTOMER_HAS_TRANSACTIONS);
|
||||
}
|
||||
};
|
||||
}
|
||||
// /**
|
||||
// * Validate vendor has no associated credit transaction once the vendor deleting.
|
||||
// * @param {IVendorEventDeletingPayload} payload -
|
||||
// */
|
||||
// public validateCustomerHasNoLinkedCreditsOnDeleting = async ({
|
||||
// tenantId,
|
||||
// customerId,
|
||||
// }: ICustomerDeletingPayload) => {
|
||||
// try {
|
||||
// await this.deleteCustomerLinkedCredit.validateCustomerHasNoCreditTransaction(
|
||||
// tenantId,
|
||||
// customerId
|
||||
// );
|
||||
// } catch (error) {
|
||||
// throw new ServiceError(ERRORS.CUSTOMER_HAS_TRANSACTIONS);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import events from '@/subscribers/events';
|
||||
import RefundCreditNoteGLEntries from '../commands/RefundCreditNoteGLEntries';
|
||||
import {
|
||||
IRefundCreditNoteCreatedPayload,
|
||||
IRefundCreditNoteDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
// import { Service, Inject } from 'typedi';
|
||||
// import events from '@/subscribers/events';
|
||||
// import RefundCreditNoteGLEntries from '../commands/RefundCreditNoteGLEntries';
|
||||
// import {
|
||||
// IRefundCreditNoteCreatedPayload,
|
||||
// IRefundCreditNoteDeletedPayload,
|
||||
// } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
export default class RefundCreditNoteGLEntriesSubscriber {
|
||||
@Inject()
|
||||
refundCreditGLEntries: RefundCreditNoteGLEntries;
|
||||
// @Service()
|
||||
// export default class RefundCreditNoteGLEntriesSubscriber {
|
||||
// @Inject()
|
||||
// refundCreditGLEntries: RefundCreditNoteGLEntries;
|
||||
|
||||
/**
|
||||
* Attaches events with handlers.
|
||||
*/
|
||||
public attach = (bus) => {
|
||||
bus.subscribe(
|
||||
events.creditNote.onRefundCreated,
|
||||
this.writeRefundCreditGLEntriesOnceCreated
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onRefundDeleted,
|
||||
this.revertRefundCreditGLEntriesOnceDeleted
|
||||
);
|
||||
};
|
||||
// /**
|
||||
// * Attaches events with handlers.
|
||||
// */
|
||||
// public attach = (bus) => {
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onRefundCreated,
|
||||
// this.writeRefundCreditGLEntriesOnceCreated
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onRefundDeleted,
|
||||
// this.revertRefundCreditGLEntriesOnceDeleted
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Writes refund credit note GL entries once the transaction created.
|
||||
* @param {IRefundCreditNoteCreatedPayload} payload -
|
||||
*/
|
||||
private writeRefundCreditGLEntriesOnceCreated = async ({
|
||||
trx,
|
||||
refundCreditNote,
|
||||
creditNote,
|
||||
tenantId,
|
||||
}: IRefundCreditNoteCreatedPayload) => {
|
||||
await this.refundCreditGLEntries.createRefundCreditGLEntries(
|
||||
tenantId,
|
||||
refundCreditNote.id,
|
||||
trx
|
||||
);
|
||||
};
|
||||
// /**
|
||||
// * Writes refund credit note GL entries once the transaction created.
|
||||
// * @param {IRefundCreditNoteCreatedPayload} payload -
|
||||
// */
|
||||
// private writeRefundCreditGLEntriesOnceCreated = async ({
|
||||
// trx,
|
||||
// refundCreditNote,
|
||||
// creditNote,
|
||||
// tenantId,
|
||||
// }: IRefundCreditNoteCreatedPayload) => {
|
||||
// await this.refundCreditGLEntries.createRefundCreditGLEntries(
|
||||
// tenantId,
|
||||
// refundCreditNote.id,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Reverts refund credit note GL entries once the transaction deleted.
|
||||
* @param {IRefundCreditNoteDeletedPayload} payload -
|
||||
*/
|
||||
private revertRefundCreditGLEntriesOnceDeleted = async ({
|
||||
trx,
|
||||
refundCreditId,
|
||||
oldRefundCredit,
|
||||
tenantId,
|
||||
}: IRefundCreditNoteDeletedPayload) => {
|
||||
await this.refundCreditGLEntries.revertRefundCreditGLEntries(
|
||||
tenantId,
|
||||
refundCreditId,
|
||||
trx
|
||||
);
|
||||
};
|
||||
}
|
||||
// /**
|
||||
// * Reverts refund credit note GL entries once the transaction deleted.
|
||||
// * @param {IRefundCreditNoteDeletedPayload} payload -
|
||||
// */
|
||||
// private revertRefundCreditGLEntriesOnceDeleted = async ({
|
||||
// trx,
|
||||
// refundCreditId,
|
||||
// oldRefundCredit,
|
||||
// tenantId,
|
||||
// }: IRefundCreditNoteDeletedPayload) => {
|
||||
// await this.refundCreditGLEntries.revertRefundCreditGLEntries(
|
||||
// tenantId,
|
||||
// refundCreditId,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
|
||||
@@ -1,62 +1,62 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import {
|
||||
IRefundCreditNoteCreatedPayload,
|
||||
IRefundCreditNoteDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import RefundSyncCreditNoteBalance from '../commands/RefundSyncCreditNoteBalance';
|
||||
// import { Inject, Service } from 'typedi';
|
||||
// import {
|
||||
// IRefundCreditNoteCreatedPayload,
|
||||
// IRefundCreditNoteDeletedPayload,
|
||||
// } from '@/interfaces';
|
||||
// import events from '@/subscribers/events';
|
||||
// import RefundSyncCreditNoteBalance from '../commands/RefundSyncCreditNoteBalance';
|
||||
|
||||
@Service()
|
||||
export default class RefundSyncCreditNoteBalanceSubscriber {
|
||||
@Inject()
|
||||
refundSyncCreditBalance: RefundSyncCreditNoteBalance;
|
||||
// @Service()
|
||||
// export default class RefundSyncCreditNoteBalanceSubscriber {
|
||||
// @Inject()
|
||||
// refundSyncCreditBalance: RefundSyncCreditNoteBalance;
|
||||
|
||||
/**
|
||||
* Attaches events with handlers.
|
||||
*/
|
||||
attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onRefundCreated,
|
||||
this.incrementRefundedAmountOnceRefundCreated
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onRefundDeleted,
|
||||
this.decrementRefundedAmountOnceRefundDeleted
|
||||
);
|
||||
return bus;
|
||||
}
|
||||
// /**
|
||||
// * Attaches events with handlers.
|
||||
// */
|
||||
// attach(bus) {
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onRefundCreated,
|
||||
// this.incrementRefundedAmountOnceRefundCreated
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.creditNote.onRefundDeleted,
|
||||
// this.decrementRefundedAmountOnceRefundDeleted
|
||||
// );
|
||||
// return bus;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Increment credit note refunded amount once associated refund transaction created.
|
||||
* @param {IRefundCreditNoteCreatedPayload} payload -
|
||||
*/
|
||||
private incrementRefundedAmountOnceRefundCreated = async ({
|
||||
trx,
|
||||
refundCreditNote,
|
||||
tenantId,
|
||||
}: IRefundCreditNoteCreatedPayload) => {
|
||||
await this.refundSyncCreditBalance.incrementCreditNoteRefundAmount(
|
||||
tenantId,
|
||||
refundCreditNote.creditNoteId,
|
||||
refundCreditNote.amount,
|
||||
trx
|
||||
);
|
||||
};
|
||||
// /**
|
||||
// * Increment credit note refunded amount once associated refund transaction created.
|
||||
// * @param {IRefundCreditNoteCreatedPayload} payload -
|
||||
// */
|
||||
// private incrementRefundedAmountOnceRefundCreated = async ({
|
||||
// trx,
|
||||
// refundCreditNote,
|
||||
// tenantId,
|
||||
// }: IRefundCreditNoteCreatedPayload) => {
|
||||
// await this.refundSyncCreditBalance.incrementCreditNoteRefundAmount(
|
||||
// tenantId,
|
||||
// refundCreditNote.creditNoteId,
|
||||
// refundCreditNote.amount,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
|
||||
/**
|
||||
* Decrement credit note refunded amount once associated refuned transaction deleted.
|
||||
* @param {IRefundCreditNoteDeletedPayload} payload -
|
||||
*/
|
||||
private decrementRefundedAmountOnceRefundDeleted = async ({
|
||||
trx,
|
||||
oldRefundCredit,
|
||||
tenantId,
|
||||
}: IRefundCreditNoteDeletedPayload) => {
|
||||
await this.refundSyncCreditBalance.decrementCreditNoteRefundAmount(
|
||||
tenantId,
|
||||
oldRefundCredit.creditNoteId,
|
||||
oldRefundCredit.amount,
|
||||
trx
|
||||
);
|
||||
};
|
||||
}
|
||||
// /**
|
||||
// * Decrement credit note refunded amount once associated refuned transaction deleted.
|
||||
// * @param {IRefundCreditNoteDeletedPayload} payload -
|
||||
// */
|
||||
// private decrementRefundedAmountOnceRefundDeleted = async ({
|
||||
// trx,
|
||||
// oldRefundCredit,
|
||||
// tenantId,
|
||||
// }: IRefundCreditNoteDeletedPayload) => {
|
||||
// await this.refundSyncCreditBalance.decrementCreditNoteRefundAmount(
|
||||
// tenantId,
|
||||
// oldRefundCredit.creditNoteId,
|
||||
// oldRefundCredit.amount,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
import { Knex } from 'knex';
|
||||
import { DiscountType, IDynamicListFilter, IItemEntry } from '@/interfaces';
|
||||
import { ILedgerEntry } from './Ledger';
|
||||
import { AttachmentLinkDTO } from './Attachments';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
import { RefundCreditNote } from '../models/RefundCreditNote';
|
||||
import { RefundCreditNote } from '../../CreditNoteRefunds/models/RefundCreditNote';
|
||||
import { AttachmentLinkDTO } from '@/modules/Attachments/Attachments.types';
|
||||
import { IItemEntryDTO } from '@/modules/TransactionItemEntry/ItemEntry.types';
|
||||
|
||||
export interface ICreditNoteEntryNewDTO extends IItemEntryDTO {}
|
||||
|
||||
export interface ICreditNoteEntryNewDTO {
|
||||
index?: number;
|
||||
itemId: number;
|
||||
rate: number;
|
||||
quantity: number;
|
||||
discount: number;
|
||||
description: string;
|
||||
warehouseId?: number;
|
||||
}
|
||||
export interface ICreditNoteNewDTO {
|
||||
customerId: number;
|
||||
exchangeRate?: number;
|
||||
@@ -26,7 +18,7 @@ export interface ICreditNoteNewDTO {
|
||||
warehouseId?: number;
|
||||
attachments?: AttachmentLinkDTO[];
|
||||
discount?: number;
|
||||
discountType?: DiscountType;
|
||||
// discountType?: DiscountType;
|
||||
adjustment?: number;
|
||||
}
|
||||
|
||||
@@ -43,34 +35,6 @@ export interface ICreditNoteEditDTO {
|
||||
attachments?: AttachmentLinkDTO[];
|
||||
}
|
||||
|
||||
export interface ICreditNoteEntry extends IItemEntry {}
|
||||
|
||||
export interface ICreditNote {
|
||||
id?: number;
|
||||
customerId: number;
|
||||
amount: number;
|
||||
refundedAmount: number;
|
||||
currencyCode: string;
|
||||
exchangeRate: number;
|
||||
creditNoteDate: Date;
|
||||
creditNoteNumber: string;
|
||||
referenceNo?: string;
|
||||
// note?: string;
|
||||
openedAt: Date | null;
|
||||
entries: ICreditNoteEntry[];
|
||||
isOpen: boolean;
|
||||
isClosed: boolean;
|
||||
isDraft: boolean;
|
||||
isPublished: boolean;
|
||||
creditsRemaining: number;
|
||||
localAmount?: number;
|
||||
branchId?: number;
|
||||
warehouseId: number;
|
||||
createdAt?: Date;
|
||||
termsConditions: string;
|
||||
note: string;
|
||||
}
|
||||
|
||||
export enum CreditNoteAction {
|
||||
Create = 'Create',
|
||||
Edit = 'Edit',
|
||||
@@ -102,37 +66,28 @@ export interface ICreditNoteEditingPayload {
|
||||
export interface ICreditNoteEditedPayload {
|
||||
trx: Knex.Transaction;
|
||||
oldCreditNote: CreditNote;
|
||||
// creditNoteId: number;
|
||||
creditNote: CreditNote;
|
||||
creditNoteEditDTO: ICreditNoteEditDTO;
|
||||
// tenantId: number;
|
||||
}
|
||||
|
||||
export interface ICreditNoteCreatedPayload {
|
||||
// tenantId: number;
|
||||
creditNoteDTO: ICreditNoteNewDTO;
|
||||
creditNote: CreditNote;
|
||||
// creditNoteId: number;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
|
||||
export interface ICreditNoteCreatingPayload {
|
||||
// tenantId: number;
|
||||
creditNoteDTO: ICreditNoteNewDTO;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
|
||||
export interface ICreditNoteOpeningPayload {
|
||||
tenantId: number;
|
||||
creditNoteId: number;
|
||||
oldCreditNote: CreditNote;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
|
||||
export interface ICreditNoteOpenedPayload {
|
||||
// tenantId: number;
|
||||
creditNote: CreditNote;
|
||||
// creditNoteId: number;
|
||||
oldCreditNote: CreditNote;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
@@ -141,11 +96,11 @@ export interface ICreditNotesQueryDTO {
|
||||
filterQuery?: (query: any) => void;
|
||||
}
|
||||
|
||||
export interface ICreditNotesQueryDTO extends IDynamicListFilter {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
searchKeyword?: string;
|
||||
}
|
||||
// export interface ICreditNotesQueryDTO extends IDynamicListFilter {
|
||||
// page: number;
|
||||
// pageSize: number;
|
||||
// searchKeyword?: string;
|
||||
// }
|
||||
|
||||
export interface ICreditNoteRefundDTO {
|
||||
fromAccountId: number;
|
||||
@@ -157,96 +112,22 @@ export interface ICreditNoteRefundDTO {
|
||||
branchId?: number;
|
||||
}
|
||||
|
||||
export interface ICreditNoteApplyInvoiceDTO {
|
||||
entries: { invoiceId: number; amount: number }[];
|
||||
}
|
||||
export interface IRefundCreditNotePOJO {
|
||||
formattedAmount: string;
|
||||
}
|
||||
|
||||
export interface IRefundCreditNoteDeletedPayload {
|
||||
trx: Knex.Transaction;
|
||||
refundCreditId: number;
|
||||
oldRefundCredit: RefundCreditNote;
|
||||
tenantId: number;
|
||||
}
|
||||
|
||||
export interface IRefundCreditNoteDeletingPayload {
|
||||
trx: Knex.Transaction;
|
||||
refundCreditId: number;
|
||||
oldRefundCredit: RefundCreditNote;
|
||||
// tenantId: number;
|
||||
}
|
||||
|
||||
export interface IRefundCreditNoteCreatingPayload {
|
||||
trx: Knex.Transaction;
|
||||
creditNote: CreditNote;
|
||||
newCreditNoteDTO: ICreditNoteRefundDTO;
|
||||
// tenantId: number;
|
||||
}
|
||||
|
||||
export interface IRefundCreditNoteCreatedPayload {
|
||||
trx: Knex.Transaction;
|
||||
refundCreditNote: RefundCreditNote;
|
||||
creditNote: CreditNote;
|
||||
// tenantId: number;
|
||||
}
|
||||
|
||||
export interface IRefundCreditNoteOpenedPayload {
|
||||
// tenantId: number;
|
||||
creditNoteId: number;
|
||||
oldCreditNote: CreditNote;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
|
||||
export interface IApplyCreditToInvoiceEntryDTO {
|
||||
amount: number;
|
||||
invoiceId: number;
|
||||
}
|
||||
|
||||
export interface IApplyCreditToInvoicesDTO {
|
||||
entries: IApplyCreditToInvoiceEntryDTO[];
|
||||
}
|
||||
|
||||
export interface IApplyCreditToInvoicesCreatedPayload {
|
||||
trx: Knex.Transaction;
|
||||
creditNote: ICreditNote;
|
||||
creditNoteAppliedInvoices: ICreditNoteAppliedToInvoice[];
|
||||
// tenantId: number;
|
||||
}
|
||||
export interface IApplyCreditToInvoicesDeletedPayload {
|
||||
trx: Knex.Transaction;
|
||||
creditNote: ICreditNote;
|
||||
creditNoteAppliedToInvoice: ICreditNoteAppliedToInvoice;
|
||||
// tenantId: number;
|
||||
}
|
||||
|
||||
export interface ICreditNoteAppliedToInvoice {
|
||||
invoiceId: number;
|
||||
amount: number;
|
||||
creditNoteId: number;
|
||||
}
|
||||
export interface ICreditNoteAppliedToInvoiceModel {
|
||||
amount: number;
|
||||
entries: ICreditNoteAppliedToInvoice[];
|
||||
}
|
||||
|
||||
export type ICreditNoteGLCommonEntry = Pick<
|
||||
ILedgerEntry,
|
||||
| 'date'
|
||||
| 'userId'
|
||||
| 'currencyCode'
|
||||
| 'exchangeRate'
|
||||
| 'transactionType'
|
||||
| 'transactionId'
|
||||
| 'transactionNumber'
|
||||
| 'referenceNumber'
|
||||
| 'createdAt'
|
||||
| 'indexGroup'
|
||||
| 'credit'
|
||||
| 'debit'
|
||||
| 'branchId'
|
||||
>;
|
||||
// export type ICreditNoteGLCommonEntry = Pick<
|
||||
// ILedgerEntry,
|
||||
// | 'date'
|
||||
// | 'userId'
|
||||
// | 'currencyCode'
|
||||
// | 'exchangeRate'
|
||||
// | 'transactionType'
|
||||
// | 'transactionId'
|
||||
// | 'transactionNumber'
|
||||
// | 'referenceNumber'
|
||||
// | 'createdAt'
|
||||
// | 'indexGroup'
|
||||
// | 'credit'
|
||||
// | 'debit'
|
||||
// | 'branchId'
|
||||
// >;
|
||||
|
||||
export interface CreditNotePdfTemplateAttributes {
|
||||
// # Primary color
|
||||
@@ -304,4 +185,4 @@ export interface CreditNotePdfTemplateAttributes {
|
||||
|
||||
export interface ICreditNoteState {
|
||||
defaultTemplateId: number;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import { CreditNotePdfTemplateAttributes, ICreditNote } from '@/interfaces';
|
||||
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user