Files
bigcapital/packages/server/src/services/CreditNotes/EditCreditNote.ts

101 lines
2.9 KiB
TypeScript

import {
ICreditNoteEditDTO,
ICreditNoteEditedPayload,
ICreditNoteEditingPayload,
} from '@/interfaces';
import { Knex } from 'knex';
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
import ItemsEntriesService from '@/services/Items/ItemsEntriesService';
import UnitOfWork from '@/services/UnitOfWork';
import events from '@/subscribers/events';
import { Inject, Service } from 'typedi';
import BaseCreditNotes from './CreditNotes';
@Service()
export default class EditCreditNote extends BaseCreditNotes {
@Inject()
itemsEntriesService: ItemsEntriesService;
@Inject()
eventPublisher: EventPublisher;
@Inject()
uow: UnitOfWork;
/**
* Edits the given credit note.
* @param {number} tenantId -
* @param {ICreditNoteEditDTO} creditNoteEditDTO -
*/
public editCreditNote = async (
tenantId: number,
creditNoteId: number,
creditNoteEditDTO: ICreditNoteEditDTO
) => {
const { CreditNote, Contact } = this.tenancy.models(tenantId);
// Retrieve the sale invoice or throw not found service error.
const oldCreditNote = await this.getCreditNoteOrThrowError(
tenantId,
creditNoteId
);
// Validate customer existance.
const customer = await Contact.query()
.modify('customer')
.findById(creditNoteEditDTO.customerId)
.throwIfNotFound();
// Validate items ids existance.
await this.itemsEntriesService.validateItemsIdsExistance(
tenantId,
creditNoteEditDTO.entries
);
// Validate non-sellable entries items.
await this.itemsEntriesService.validateNonSellableEntriesItems(
tenantId,
creditNoteEditDTO.entries
);
// Validate the items entries existance.
await this.itemsEntriesService.validateEntriesIdsExistance(
tenantId,
creditNoteId,
'CreditNote',
creditNoteEditDTO.entries
);
// Transformes the given DTO to storage layer data.
const creditNoteModel = this.transformCreateEditDTOToModel(
tenantId,
creditNoteEditDTO,
customer.currencyCode,
oldCreditNote
);
// Sales the credit note transactions with associated entries.
return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => {
// Triggers `onCreditNoteEditing` event.
await this.eventPublisher.emitAsync(events.creditNote.onEditing, {
creditNoteEditDTO,
oldCreditNote,
trx,
tenantId,
} as ICreditNoteEditingPayload);
// Saves the credit note graph to the storage.
const creditNote = await CreditNote.query(trx).upsertGraphAndFetch({
id: creditNoteId,
...creditNoteModel,
});
// Triggers `onCreditNoteEdited` event.
await this.eventPublisher.emitAsync(events.creditNote.onEdited, {
trx,
oldCreditNote,
creditNoteId,
creditNote,
creditNoteEditDTO,
tenantId,
} as ICreditNoteEditedPayload);
return creditNote;
});
};
}