mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-22 07:40:32 +00:00
88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
import {
|
|
ICreditNoteOpenedPayload,
|
|
ICreditNoteOpeningPayload,
|
|
} from '../types/CreditNotes.types';
|
|
import { Knex } from 'knex';
|
|
import { Inject, Injectable } from '@nestjs/common';
|
|
import { ERRORS } from '../constants';
|
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
|
import { CreditNote } from '../models/CreditNote';
|
|
import { events } from '@/common/events/events';
|
|
import { ServiceError } from '@/modules/Items/ServiceError';
|
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
|
|
|
@Injectable()
|
|
export class OpenCreditNoteService {
|
|
/**
|
|
* @param {EventEmitter2} eventPublisher - The event publisher.
|
|
* @param {UnitOfWork} uow - The unit of work.
|
|
* @param {typeof CreditNote} creditNoteModel - The credit note model.
|
|
*/
|
|
constructor(
|
|
private readonly eventPublisher: EventEmitter2,
|
|
private readonly uow: UnitOfWork,
|
|
|
|
@Inject(CreditNote.name)
|
|
private readonly creditNoteModel: TenantModelProxy<typeof CreditNote>,
|
|
) {}
|
|
|
|
/**
|
|
* Opens the given credit note.
|
|
* @param {number} creditNoteId -
|
|
* @returns {Promise<CreditNote>}
|
|
*/
|
|
public openCreditNote = async (creditNoteId: number): Promise<CreditNote> => {
|
|
// Retrieve the sale invoice or throw not found service error.
|
|
const oldCreditNote = await this.creditNoteModel()
|
|
.query()
|
|
.findById(creditNoteId)
|
|
.throwIfNotFound();
|
|
|
|
// Throw service error if the credit note is already open.
|
|
this.throwErrorIfAlreadyOpen(oldCreditNote);
|
|
|
|
// Triggers `onCreditNoteOpen` event.
|
|
this.eventPublisher.emitAsync(events.creditNote.onOpen, {
|
|
creditNoteId,
|
|
oldCreditNote,
|
|
});
|
|
// Sales the credit note transactions with associated entries.
|
|
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
|
const eventPayload = {
|
|
oldCreditNote,
|
|
trx,
|
|
} as ICreditNoteOpeningPayload;
|
|
|
|
// Triggers `onCreditNoteOpening` event.
|
|
await this.eventPublisher.emitAsync(
|
|
events.creditNote.onOpening,
|
|
eventPayload,
|
|
);
|
|
// Saves the credit note graph to the storage.
|
|
const creditNote = await this.creditNoteModel()
|
|
.query(trx)
|
|
.updateAndFetchById(creditNoteId, {
|
|
openedAt: new Date(),
|
|
});
|
|
// Triggers `onCreditNoteOpened` event.
|
|
await this.eventPublisher.emitAsync(events.creditNote.onOpened, {
|
|
...eventPayload,
|
|
creditNote,
|
|
} as ICreditNoteOpenedPayload);
|
|
|
|
return creditNote;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Throws an error if the given credit note is already open.
|
|
* @param {CreditNote} creditNote -
|
|
*/
|
|
public throwErrorIfAlreadyOpen = (creditNote: CreditNote) => {
|
|
if (creditNote.openedAt) {
|
|
throw new ServiceError(ERRORS.CREDIT_NOTE_ALREADY_OPENED);
|
|
}
|
|
};
|
|
}
|