mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
feat(nestjs): migrate to NestJS
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { CreditNote } from '../../CreditNotes/models/CreditNote';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class CreditNoteApplySyncCredit {
|
||||
constructor(
|
||||
@Inject(CreditNote.name)
|
||||
private creditNoteModel: TenantModelProxy<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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import Bluebird from 'bluebird';
|
||||
import { ICreditNoteAppliedToInvoice } from '../types/CreditNoteApplyInvoice.types';
|
||||
import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
|
||||
import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class CreditNoteApplySyncInvoicesCreditedAmount {
|
||||
/**
|
||||
* @param {typeof SaleInvoice} saleInvoiceModel - Sale invoice model.
|
||||
*/
|
||||
constructor(
|
||||
@Inject(SaleInvoice.name)
|
||||
private readonly saleInvoiceModel: TenantModelProxy<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: CreditNoteAppliedInvoice) => {
|
||||
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);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { sumBy } from 'lodash';
|
||||
import {
|
||||
ICreditNoteAppliedToInvoiceModel,
|
||||
IApplyCreditToInvoicesDTO,
|
||||
IApplyCreditToInvoicesCreatedPayload,
|
||||
} from '../types/CreditNoteApplyInvoice.types';
|
||||
import { ERRORS } from '../../CreditNotes/constants';
|
||||
import { PaymentReceivedValidators } from '@/modules/PaymentReceived/commands/PaymentReceivedValidators.service';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { events } from '@/common/events/events';
|
||||
import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { CreditNote } from '@/modules/CreditNotes/models/CreditNote';
|
||||
import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice';
|
||||
import { CommandCreditNoteDTOTransform } from '@/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@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,
|
||||
private readonly creditNoteDTOTransform: CommandCreditNoteDTOTransform,
|
||||
|
||||
@Inject(CreditNoteAppliedInvoice.name)
|
||||
private readonly creditNoteAppliedInvoiceModel: TenantModelProxy<
|
||||
typeof CreditNoteAppliedInvoice
|
||||
>,
|
||||
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: TenantModelProxy<typeof CreditNote>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Apply credit note to the given invoices.
|
||||
* @param {number} creditNoteId
|
||||
* @param {IApplyCreditToInvoicesDTO} applyCreditToInvoicesDTO
|
||||
*/
|
||||
public async applyCreditNoteToInvoices(
|
||||
creditNoteId: number,
|
||||
applyCreditToInvoicesDTO: IApplyCreditToInvoicesDTO,
|
||||
): Promise<CreditNoteAppliedInvoice[]> {
|
||||
// Saves the credit note or throw not found service error.
|
||||
const creditNote = await this.creditNoteModel()
|
||||
.query()
|
||||
.findById(creditNoteId)
|
||||
.throwIfNotFound();
|
||||
|
||||
// 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.creditNoteDTOTransform.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: CreditNote,
|
||||
): 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { IApplyCreditToInvoicesDeletedPayload } from '../types/CreditNoteApplyInvoice.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 '../../CreditNotes/models/CreditNote';
|
||||
import { ERRORS } from '../../CreditNotes/constants';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export default class DeleteCreditNoteApplyToInvoices {
|
||||
/**
|
||||
* @param {UnitOfWork} uow - Unit of work.
|
||||
* @param {EventEmitter2} eventPublisher - Event emitter.
|
||||
* @param {typeof CreditNoteAppliedInvoice} creditNoteAppliedInvoiceModel - Credit note applied invoice model.
|
||||
* @param {typeof CreditNote} creditNoteModel - Credit note model.
|
||||
*/
|
||||
constructor(
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly eventPublisher: EventEmitter2,
|
||||
|
||||
@Inject(CreditNoteAppliedInvoice.name)
|
||||
private readonly creditNoteAppliedInvoiceModel: TenantModelProxy<
|
||||
typeof CreditNoteAppliedInvoice
|
||||
>,
|
||||
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: TenantModelProxy<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,
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { CreditNote } from '../../CreditNotes/models/CreditNote';
|
||||
import { ERRORS } from '../../CreditNotes/constants';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class DeleteCustomerLinkedCreditNoteService {
|
||||
/**
|
||||
* @param {typeof CreditNote} creditNoteModel - Credit note model.
|
||||
*/
|
||||
constructor(
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: TenantModelProxy<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
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 '../../CreditNotes/models/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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
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'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Formatted amount.
|
||||
* @param {CreditNoteAppliedInvoice} item -
|
||||
* @returns {string}
|
||||
*/
|
||||
public formttedAmount = (item: CreditNoteAppliedInvoice) => {
|
||||
return this.formatNumber(item.amount, {
|
||||
currencyCode: item.creditNote.currencyCode,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Credit note number.
|
||||
* @param {CreditNoteAppliedInvoice} item -
|
||||
* @returns {string}
|
||||
*/
|
||||
public creditNoteNumber = (item: CreditNoteAppliedInvoice) => {
|
||||
return item.creditNote.creditNoteNumber;
|
||||
};
|
||||
|
||||
/**
|
||||
* Credit note date.
|
||||
* @param {CreditNoteAppliedInvoice} item -
|
||||
* @returns {string}
|
||||
*/
|
||||
public creditNoteDate = (item: CreditNoteAppliedInvoice) => {
|
||||
return item.creditNote.creditNoteDate;
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoice number.
|
||||
* @param {CreditNoteAppliedInvoice} item -
|
||||
* @returns {string}
|
||||
*/
|
||||
public invoiceNumber = (item: CreditNoteAppliedInvoice) => {
|
||||
return item.saleInvoice.invoiceNo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoice reference no.
|
||||
* @param {CreditNoteAppliedInvoice} item -
|
||||
* @returns {string}
|
||||
*/
|
||||
public invoiceReferenceNo = (item: CreditNoteAppliedInvoice) => {
|
||||
return item.saleInvoice.referenceNo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Formatted credit note date.
|
||||
* @param {CreditNoteAppliedInvoice} item -
|
||||
* @returns {string}
|
||||
*/
|
||||
public formattedCreditNoteDate = (item: CreditNoteAppliedInvoice) => {
|
||||
return this.formatDate(item.creditNote.creditNoteDate);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
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,
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { CreditNoteAppliedInvoiceTransformer } from './CreditNoteAppliedInvoiceTransformer';
|
||||
import { CreditNote } from '../../CreditNotes/models/CreditNote';
|
||||
import { TransformerInjectable } from '../../Transformer/TransformerInjectable.service';
|
||||
import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class GetCreditNoteAssociatedAppliedInvoices {
|
||||
constructor(
|
||||
private readonly transformer: TransformerInjectable,
|
||||
private readonly creditNoteAppliedInvoiceModel: typeof CreditNoteAppliedInvoice,
|
||||
|
||||
@Inject(CreditNote.name)
|
||||
private readonly creditNoteModel: TenantModelProxy<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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
|
||||
import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
|
||||
import { GetCreditNote } from '../../CreditNotes/queries/GetCreditNote.service';
|
||||
import { CreditNoteWithInvoicesToApplyTransformer } from './CreditNoteWithInvoicesToApplyTransformer';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class GetCreditNoteAssociatedInvoicesToApply {
|
||||
/**
|
||||
* @param {TransformerInjectable} transformer - Transformer service.
|
||||
* @param {GetCreditNote} getCreditNote - Get credit note service.
|
||||
* @param {typeof SaleInvoice} saleInvoiceModel - Sale invoice model.
|
||||
*/
|
||||
constructor(
|
||||
private transformer: TransformerInjectable,
|
||||
private getCreditNote: GetCreditNote,
|
||||
|
||||
@Inject(SaleInvoice.name)
|
||||
private saleInvoiceModel: TenantModelProxy<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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// 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
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
@@ -0,0 +1,61 @@
|
||||
// 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
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
@@ -0,0 +1,35 @@
|
||||
import { CreditNote } from '@/modules/CreditNotes/models/CreditNote';
|
||||
import { Knex } from 'knex';
|
||||
|
||||
export interface ICreditNoteApplyInvoiceDTO {
|
||||
entries: { invoiceId: number; amount: number }[];
|
||||
}
|
||||
|
||||
export interface IApplyCreditToInvoiceEntryDTO {
|
||||
amount: number;
|
||||
invoiceId: number;
|
||||
}
|
||||
|
||||
export interface IApplyCreditToInvoicesDTO {
|
||||
entries: IApplyCreditToInvoiceEntryDTO[];
|
||||
}
|
||||
|
||||
export interface IApplyCreditToInvoicesCreatedPayload {
|
||||
trx: Knex.Transaction;
|
||||
creditNote: CreditNote;
|
||||
creditNoteAppliedInvoices: ICreditNoteAppliedToInvoice[];
|
||||
}
|
||||
export interface IApplyCreditToInvoicesDeletedPayload {
|
||||
trx: Knex.Transaction;
|
||||
creditNote: CreditNote;
|
||||
creditNoteAppliedToInvoice: ICreditNoteAppliedToInvoice;
|
||||
}
|
||||
|
||||
export interface ICreditNoteAppliedToInvoice {
|
||||
amount: number;
|
||||
creditNoteId: number;
|
||||
}
|
||||
export interface ICreditNoteAppliedToInvoiceModel {
|
||||
amount: number;
|
||||
entries: ICreditNoteAppliedToInvoice[];
|
||||
}
|
||||
Reference in New Issue
Block a user