mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
feat: wip attach attachments to resource models
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||
|
||||
export class AttachmentTransformer extends Transformer {
|
||||
/**
|
||||
* Exclude attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public excludeAttributes = (): string[] => {
|
||||
return ['*'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Includeded attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public includeAttributes = (): string[] => {
|
||||
return ['extension', 'key'];
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import bluebird from 'bluebird';
|
||||
import { Knex } from 'knex';
|
||||
import {
|
||||
validateLinkModelEntryExists,
|
||||
validateLinkModelExists,
|
||||
@@ -12,38 +14,68 @@ export class LinkAttachment {
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
*
|
||||
* Links the given file key to the given model type and id.
|
||||
* @param {number} tenantId
|
||||
* @param {string} filekey
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async link(
|
||||
tenantId: number,
|
||||
filekey: string,
|
||||
modelRef: string,
|
||||
modelId: number
|
||||
modelId: number,
|
||||
trx?: Knex.Transaction
|
||||
) {
|
||||
const { DocumentLink, Document, ...models } = this.tenancy.models(tenantId);
|
||||
const LinkModel = models[modelRef];
|
||||
validateLinkModelExists(LinkModel);
|
||||
|
||||
const foundLinkModel = await LinkModel.query().findById(modelId);
|
||||
const foundLinkModel = await LinkModel.query(trx).findById(modelId);
|
||||
validateLinkModelEntryExists(foundLinkModel);
|
||||
|
||||
const foundLinks = await DocumentLink.query()
|
||||
const foundLinks = await DocumentLink.query(trx)
|
||||
.where('modelRef', modelRef)
|
||||
.where('modelId', modelId);
|
||||
|
||||
if (foundLinks.length > 0) {
|
||||
throw new ServiceError('');
|
||||
throw new ServiceError('DOCUMENT_LINK_ALREADY_LINKED');
|
||||
}
|
||||
const foundFile = await Document.query().findOne('key', filekey);
|
||||
const foundFile = await Document.query(trx).findOne('key', filekey);
|
||||
|
||||
await DocumentLink.query().insert({
|
||||
await DocumentLink.query(trx).insert({
|
||||
modelRef,
|
||||
modelId,
|
||||
documentId: foundFile.id,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Links the given file keys to the given model type and id.
|
||||
* @param {number} tenantId
|
||||
* @param {string[]} filekeys
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
* @param {Knex.Transaction} trx
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async bulkLink(
|
||||
tenantId: number,
|
||||
filekeys: string[],
|
||||
modelRef: string,
|
||||
modelId: number,
|
||||
trx?: Knex.Transaction
|
||||
) {
|
||||
await bluebird.map(
|
||||
filekeys,
|
||||
(fieldKey: string) =>
|
||||
this.link(tenantId, fieldKey, modelRef, modelId, trx),
|
||||
{
|
||||
concurrency: CONCURRENCY_ASYNC,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const CONCURRENCY_ASYNC = 10;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import bluebird from 'bluebird';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import {
|
||||
validateLinkModelEntryExists,
|
||||
validateLinkModelExists,
|
||||
} from './_utils';
|
||||
import { Knex } from 'knex';
|
||||
import { difference } from 'lodash';
|
||||
|
||||
@Service()
|
||||
export class UnlinkAttachment {
|
||||
@@ -11,7 +14,7 @@ export class UnlinkAttachment {
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
*
|
||||
* Unlink the attachments from the model entry.
|
||||
* @param {number} tenantId
|
||||
* @param {string} filekey
|
||||
* @param {string} modelRef
|
||||
@@ -21,19 +24,105 @@ export class UnlinkAttachment {
|
||||
tenantId: number,
|
||||
filekey: string,
|
||||
modelRef: string,
|
||||
modelId: number
|
||||
) {
|
||||
const { DocumentLink, ...models } = this.tenancy.models(tenantId);
|
||||
modelId: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> {
|
||||
const { DocumentLink, Document, ...models } = this.tenancy.models(tenantId);
|
||||
const LinkModel = models[modelRef];
|
||||
validateLinkModelExists(LinkModel);
|
||||
|
||||
const foundLinkModel = await LinkModel.query().findById(modelId);
|
||||
const foundLinkModel = await LinkModel.query(trx).findById(modelId);
|
||||
validateLinkModelEntryExists(foundLinkModel);
|
||||
|
||||
const document = await Document.query().findOne('key', filekey);
|
||||
|
||||
// Delete the document link.
|
||||
await DocumentLink.query()
|
||||
await DocumentLink.query(trx)
|
||||
.where('modelRef', modelRef)
|
||||
.where('modelId', modelId)
|
||||
.where('documentId', document.id)
|
||||
.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk unlink the attachments from the model entry.
|
||||
* @param {number} tenantId
|
||||
* @param {string} fieldkey
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async bulkUnlink(
|
||||
tenantId: number,
|
||||
filekeys: string[],
|
||||
modelRef: string,
|
||||
modelId: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> {
|
||||
await bluebird.map(
|
||||
filekeys,
|
||||
(fieldKey: string) =>
|
||||
this.unlink(tenantId, fieldKey, modelRef, modelId, trx),
|
||||
{
|
||||
concurrency: CONCURRENCY_ASYNC,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all the unpresented keys of the given model type and id.
|
||||
* @param {number} tenantId
|
||||
* @param {string[]} presentedKeys
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
* @param {Knex.Transaction} trx
|
||||
*/
|
||||
async unlinkUnpresentedKeys(
|
||||
tenantId: number,
|
||||
presentedKeys: string[],
|
||||
modelRef: string,
|
||||
modelId: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> {
|
||||
const { DocumentLink } = this.tenancy.models(tenantId);
|
||||
|
||||
const modelLinks = await DocumentLink.query(trx)
|
||||
.where('modelRef', modelRef)
|
||||
.where('modelId', modelId)
|
||||
.withGraphFetched('document');
|
||||
|
||||
const modelLinkKeys = modelLinks.map((link) => link.document.key);
|
||||
const unpresentedKeys = difference(modelLinkKeys, presentedKeys);
|
||||
|
||||
await this.bulkUnlink(tenantId, unpresentedKeys, modelRef, modelId, trx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments of the given model type and id.
|
||||
* @param {number} tenantId
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
* @param {Knex.Transaction} trx
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async unlinkAllModelKeys(
|
||||
tenantId: number,
|
||||
modelRef: string,
|
||||
modelId: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<void> {
|
||||
const { DocumentLink } = this.tenancy.models(tenantId);
|
||||
|
||||
// Get all the keys of the modelRef and modelId.
|
||||
const modelLinks = await DocumentLink.query(trx)
|
||||
.where('modelRef', modelRef)
|
||||
.where('modelId', modelId)
|
||||
.withGraphFetched('document');
|
||||
|
||||
const modelLinkKeys = modelLinks.map((link) => link.document.key);
|
||||
|
||||
await this.bulkUnlink(tenantId, modelLinkKeys, modelRef, modelId, trx);
|
||||
}
|
||||
}
|
||||
|
||||
const CONCURRENCY_ASYNC = 10;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { castArray, difference } from 'lodash';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { Inject, Service } from 'typedi';
|
||||
|
||||
@Service()
|
||||
export class ValidateAttachments {
|
||||
@Inject()
|
||||
tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
* Validates the given file keys existance.
|
||||
* @param {number} tenantId
|
||||
* @param {string|string[]} key
|
||||
*/
|
||||
async validate(tenantId: number, key: string | string[]) {
|
||||
const { Document } = this.tenancy.models(tenantId);
|
||||
|
||||
const keys = castArray(key);
|
||||
const documents = await Document.query().whereIn('key', key);
|
||||
const documentKeys = documents.map((document) => document.key);
|
||||
|
||||
const notFoundKeys = difference(keys, documentKeys);
|
||||
|
||||
if (notFoundKeys.length > 0) {
|
||||
throw new ServiceError('DOCUMENT_KEYS_INVALID');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
IBIllEventDeletedPayload,
|
||||
IBillCreatedPayload,
|
||||
IBillCreatingPayload,
|
||||
IBillEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnBills {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.bill.onCreating,
|
||||
this.validateAttachmentsOnBillCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.bill.onCreated,
|
||||
this.handleAttachmentsOnBillCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.bill.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnBillEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.bill.onEdited,
|
||||
this.handleLinkPresentedKeysOnBillEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.bill.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnBillDeleted.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating bill.
|
||||
* @param {ISaleInvoiceCreatingPaylaod}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnBillCreate({
|
||||
billDTO,
|
||||
tenantId,
|
||||
}: IBillCreatingPayload): Promise<void> {
|
||||
if (isEmpty(billDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = billDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created bill.
|
||||
* @param {ISaleInvoiceCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnBillCreated({
|
||||
tenantId,
|
||||
bill,
|
||||
billDTO,
|
||||
trx,
|
||||
}: IBillCreatedPayload): Promise<void> {
|
||||
if (isEmpty(billDTO.attachments)) return;
|
||||
|
||||
const keys = billDTO.attachments?.map((attachment) => attachment.key);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'Bill',
|
||||
bill.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited bill.
|
||||
* @param {IBillEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnBillEdited({
|
||||
tenantId,
|
||||
billDTO,
|
||||
bill,
|
||||
}: IBillEditedPayload) {
|
||||
const keys = billDTO.attachments?.map((attachment) => attachment.key);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'Bill',
|
||||
bill.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited bill.
|
||||
* @param {ISaleInvoiceEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnBillEdited({
|
||||
tenantId,
|
||||
billDTO,
|
||||
oldBill,
|
||||
trx,
|
||||
}: IBillEditedPayload) {
|
||||
if (isEmpty(billDTO.attachments)) return;
|
||||
|
||||
const keys = billDTO.attachments?.map((attachment) => attachment.key);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'Bill',
|
||||
oldBill.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the bill deleted.
|
||||
* @param {ISaleInvoiceDeletedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnBillDeleted({
|
||||
tenantId,
|
||||
oldBill,
|
||||
trx,
|
||||
}: IBIllEventDeletedPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'Bill',
|
||||
oldBill.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
ICreditNoteCreatedPayload,
|
||||
ICreditNoteCreatingPayload,
|
||||
ICreditNoteDeletingPayload,
|
||||
ICreditNoteEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnCreditNote {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onCreating,
|
||||
this.validateAttachmentsOnCreditNoteCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onCreated,
|
||||
this.handleAttachmentsOnCreditNoteCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnCreditNoteEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onEdited,
|
||||
this.handleLinkPresentedKeysOnCreditNoteEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.creditNote.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnCreditNoteDeleted.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating credit note.
|
||||
* @param {ICreditNoteCreatingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnCreditNoteCreate({
|
||||
creditNoteDTO,
|
||||
tenantId,
|
||||
}: ICreditNoteCreatingPayload): Promise<void> {
|
||||
if (isEmpty(creditNoteDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = creditNoteDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created credit note.
|
||||
* @param {ICreditNoteCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnCreditNoteCreated({
|
||||
tenantId,
|
||||
creditNote,
|
||||
creditNoteDTO,
|
||||
trx,
|
||||
}: ICreditNoteCreatedPayload): Promise<void> {
|
||||
if (isEmpty(creditNoteDTO.attachments)) return;
|
||||
|
||||
const keys = creditNoteDTO.attachments?.map((attachment) => attachment.key);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'CreditNote',
|
||||
creditNote.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited credit note.
|
||||
* @param {ICreditNoteEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnCreditNoteEdited({
|
||||
tenantId,
|
||||
creditNoteEditDTO,
|
||||
oldCreditNote,
|
||||
}: ICreditNoteEditedPayload) {
|
||||
const keys = creditNoteEditDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'CreditNote',
|
||||
oldCreditNote.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited credit note.
|
||||
* @param {ICreditNoteEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnCreditNoteEdited({
|
||||
tenantId,
|
||||
creditNoteEditDTO,
|
||||
oldCreditNote,
|
||||
trx,
|
||||
}: ICreditNoteEditedPayload) {
|
||||
if (isEmpty(creditNoteEditDTO.attachments)) return;
|
||||
|
||||
const keys = creditNoteEditDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'CreditNote',
|
||||
oldCreditNote.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the credit note deleted.
|
||||
* @param {ICreditNoteDeletingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnCreditNoteDeleted({
|
||||
tenantId,
|
||||
oldCreditNote,
|
||||
trx,
|
||||
}: ICreditNoteDeletingPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'CreditNote',
|
||||
oldCreditNote.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
IExpenseCreatedPayload,
|
||||
IExpenseCreatingPayload,
|
||||
IExpenseDeletingPayload,
|
||||
IExpenseEventEditPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnExpenses {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.expenses.onCreating,
|
||||
this.validateAttachmentsOnExpenseCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.expenses.onCreated,
|
||||
this.handleAttachmentsOnExpenseCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.expenses.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnExpenseEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.expenses.onEdited,
|
||||
this.handleLinkPresentedKeysOnExpenseEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.expenses.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnExpenseDeleted.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating expense.
|
||||
* @param {ISaleInvoiceCreatingPaylaod}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnExpenseCreate({
|
||||
expenseDTO,
|
||||
tenantId,
|
||||
}: IExpenseCreatingPayload): Promise<void> {
|
||||
if (isEmpty(expenseDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = expenseDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created expense.
|
||||
* @param {ISaleInvoiceCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnExpenseCreated({
|
||||
tenantId,
|
||||
expenseDTO,
|
||||
expense,
|
||||
trx,
|
||||
}: IExpenseCreatedPayload): Promise<void> {
|
||||
if (isEmpty(expenseDTO.attachments)) return;
|
||||
|
||||
const keys = expenseDTO.attachments?.map((attachment) => attachment.key);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'Expense',
|
||||
expense.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited expense.
|
||||
* @param {ISaleInvoiceEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnExpenseEdited({
|
||||
tenantId,
|
||||
expenseDTO,
|
||||
expense,
|
||||
}: IExpenseEventEditPayload) {
|
||||
const keys = expenseDTO.attachments?.map((attachment) => attachment.key);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'Expense',
|
||||
expense.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited expense.
|
||||
* @param {ISaleInvoiceEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnExpenseEdited({
|
||||
tenantId,
|
||||
expenseDTO,
|
||||
oldExpense,
|
||||
trx,
|
||||
}: IExpenseEventEditPayload) {
|
||||
if (isEmpty(expenseDTO.attachments)) return;
|
||||
|
||||
const keys = expenseDTO.attachments?.map((attachment) => attachment.key);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'Expense',
|
||||
oldExpense.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the expense deleted.
|
||||
* @param {ISaleInvoiceDeletedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnExpenseDeleted({
|
||||
tenantId,
|
||||
oldExpense,
|
||||
trx,
|
||||
}: IExpenseDeletingPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'Expense',
|
||||
oldExpense.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
IManualJournalCreatingPayload,
|
||||
IManualJournalEventCreatedPayload,
|
||||
IManualJournalEventDeletedPayload,
|
||||
IManualJournalEventEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnManualJournals {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.manualJournals.onCreating,
|
||||
this.validateAttachmentsOnManualJournalCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.manualJournals.onCreated,
|
||||
this.handleAttachmentsOnManualJournalCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.manualJournals.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnManualJournalEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.manualJournals.onEdited,
|
||||
this.handleLinkPresentedKeysOnManualJournalEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.manualJournals.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnManualJournalDeleted.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating manual journal.
|
||||
* @param {IManualJournalCreatingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnManualJournalCreate({
|
||||
manualJournalDTO,
|
||||
tenantId,
|
||||
}: IManualJournalCreatingPayload): Promise<void> {
|
||||
if (isEmpty(manualJournalDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = manualJournalDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created manual journal.
|
||||
* @param {IManualJournalEventCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnManualJournalCreated({
|
||||
tenantId,
|
||||
manualJournalDTO,
|
||||
manualJournal,
|
||||
trx,
|
||||
}: IManualJournalEventCreatedPayload): Promise<void> {
|
||||
if (isEmpty(manualJournalDTO.attachments)) return;
|
||||
|
||||
const keys = manualJournalDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'ManualJournal',
|
||||
manualJournal.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited manual journal.
|
||||
* @param {ISaleInvoiceEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnManualJournalEdited({
|
||||
tenantId,
|
||||
manualJournalDTO,
|
||||
manualJournal,
|
||||
}: IManualJournalEventEditedPayload) {
|
||||
// if (isEmpty(saleInvoiceDTO.attachments)) return;
|
||||
|
||||
const keys = manualJournalDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleInvoice',
|
||||
manualJournal.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited manual journal.
|
||||
* @param {ISaleInvoiceEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnManualJournalEdited({
|
||||
tenantId,
|
||||
manualJournalDTO,
|
||||
oldManualJournal,
|
||||
trx,
|
||||
}: IManualJournalEventEditedPayload) {
|
||||
if (isEmpty(manualJournalDTO.attachments)) return;
|
||||
|
||||
const keys = manualJournalDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'ManualJournal',
|
||||
oldManualJournal.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the manual journal deleted.
|
||||
* @param {ISaleInvoiceDeletedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnManualJournalDeleted({
|
||||
tenantId,
|
||||
oldManualJournal,
|
||||
trx,
|
||||
}: IManualJournalEventDeletedPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'SaleInvoice',
|
||||
oldManualJournal.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
IBillPaymentCreatingPayload,
|
||||
IBillPaymentDeletingPayload,
|
||||
IBillPaymentEventCreatedPayload,
|
||||
IBillPaymentEventEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnBillPayments{
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.billPayment.onCreating,
|
||||
this.validateAttachmentsOnBillPaymentCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.billPayment.onCreated,
|
||||
this.handleAttachmentsOnBillPaymentCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.billPayment.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnBillPaymentEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.billPayment.onEdited,
|
||||
this.handleLinkPresentedKeysOnBillPaymentEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.billPayment.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnBillPaymentDeleted.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating bill payment.
|
||||
* @param {IBillPaymentCreatingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnBillPaymentCreate({
|
||||
billPaymentDTO,
|
||||
tenantId,
|
||||
}: IBillPaymentCreatingPayload): Promise<void> {
|
||||
if (isEmpty(billPaymentDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = billPaymentDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created bill payment.
|
||||
* @param {IBillPaymentEventCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnBillPaymentCreated({
|
||||
tenantId,
|
||||
billPaymentDTO,
|
||||
billPayment,
|
||||
trx,
|
||||
}: IBillPaymentEventCreatedPayload): Promise<void> {
|
||||
if (isEmpty(billPaymentDTO.attachments)) return;
|
||||
|
||||
const keys = billPaymentDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'BillPayment',
|
||||
billPayment.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited bill payment.
|
||||
* @param {IBillPaymentEventEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnBillPaymentEdited({
|
||||
tenantId,
|
||||
billPaymentDTO,
|
||||
oldBillPayment,
|
||||
}: IBillPaymentEventEditedPayload) {
|
||||
const keys = billPaymentDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'BillPayment',
|
||||
oldBillPayment.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited bill payment.
|
||||
* @param {IBillPaymentEventEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnBillPaymentEdited({
|
||||
tenantId,
|
||||
billPaymentDTO,
|
||||
oldBillPayment,
|
||||
trx,
|
||||
}: IBillPaymentEventEditedPayload) {
|
||||
if (isEmpty(billPaymentDTO.attachments)) return;
|
||||
|
||||
const keys = billPaymentDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'BillPayment',
|
||||
oldBillPayment.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the bill payment deleted.
|
||||
* @param {IBillPaymentDeletingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnBillPaymentDeleted({
|
||||
tenantId,
|
||||
oldBillPayment,
|
||||
trx,
|
||||
}: IBillPaymentDeletingPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'BillPayment',
|
||||
oldBillPayment.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
IPaymentReceiveCreatedPayload,
|
||||
IPaymentReceiveCreatingPayload,
|
||||
IPaymentReceiveDeletingPayload,
|
||||
IPaymentReceiveEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnPaymentsReceived {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.paymentReceive.onCreating,
|
||||
this.validateAttachmentsOnPaymentCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.paymentReceive.onCreated,
|
||||
this.handleAttachmentsOnPaymentCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.paymentReceive.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnPaymentEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.paymentReceive.onEdited,
|
||||
this.handleLinkPresentedKeysOnPaymentEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.paymentReceive.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnPaymentDelete.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating payment.
|
||||
* @param {IPaymentReceiveCreatingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnPaymentCreate({
|
||||
paymentReceiveDTO,
|
||||
tenantId,
|
||||
}: IPaymentReceiveCreatingPayload): Promise<void> {
|
||||
if (isEmpty(paymentReceiveDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = paymentReceiveDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created payment.
|
||||
* @param {IPaymentReceiveCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnPaymentCreated({
|
||||
tenantId,
|
||||
paymentReceiveDTO,
|
||||
paymentReceive,
|
||||
trx,
|
||||
}: IPaymentReceiveCreatedPayload): Promise<void> {
|
||||
if (isEmpty(paymentReceiveDTO.attachments)) return;
|
||||
|
||||
const keys = paymentReceiveDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'PaymentReceive',
|
||||
paymentReceive.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited payment.
|
||||
* @param {IPaymentReceiveEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnPaymentEdited({
|
||||
tenantId,
|
||||
paymentReceiveDTO,
|
||||
oldPaymentReceive,
|
||||
}: IPaymentReceiveEditedPayload) {
|
||||
const keys = paymentReceiveDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'PaymentReceive',
|
||||
oldPaymentReceive.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited payment.
|
||||
* @param {IPaymentReceiveEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnPaymentEdited({
|
||||
tenantId,
|
||||
paymentReceiveDTO,
|
||||
oldPaymentReceive,
|
||||
trx,
|
||||
}: IPaymentReceiveEditedPayload) {
|
||||
if (isEmpty(paymentReceiveDTO.attachments)) return;
|
||||
|
||||
const keys = paymentReceiveDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'PaymentReceive',
|
||||
oldPaymentReceive.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the payment deleted.
|
||||
* @param {ISaleInvoiceDeletedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnPaymentDelete({
|
||||
tenantId,
|
||||
oldPaymentReceive,
|
||||
trx,
|
||||
}: IPaymentReceiveDeletingPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'PaymentReceive',
|
||||
oldPaymentReceive.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
ISaleEstimateCreatedPayload,
|
||||
ISaleEstimateCreatingPayload,
|
||||
ISaleEstimateDeletingPayload,
|
||||
ISaleEstimateEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnSaleEstimates {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.saleEstimate.onCreating,
|
||||
this.validateAttachmentsOnSaleEstimateCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleEstimate.onCreated,
|
||||
this.handleAttachmentsOnSaleEstimateCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleEstimate.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnSaleEstimateEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleEstimate.onEdited,
|
||||
this.handleLinkPresentedKeysOnSaleEstimateEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleEstimate.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnSaleEstimateDelete.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating sale estimate.
|
||||
* @param {ISaleEstimateCreatingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnSaleEstimateCreated({
|
||||
estimateDTO,
|
||||
tenantId,
|
||||
}: ISaleEstimateCreatingPayload): Promise<void> {
|
||||
if (isEmpty(estimateDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = estimateDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created sale estimate.
|
||||
* @param {ISaleEstimateCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnSaleEstimateCreated({
|
||||
tenantId,
|
||||
saleEstimateDTO,
|
||||
saleEstimate,
|
||||
trx,
|
||||
}: ISaleEstimateCreatedPayload): Promise<void> {
|
||||
if (isEmpty(saleEstimateDTO.attachments)) return;
|
||||
|
||||
const keys = saleEstimateDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleEstimate',
|
||||
saleEstimate.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited sale estimate.
|
||||
* @param {ISaleEstimateEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnSaleEstimateEdited({
|
||||
tenantId,
|
||||
estimateDTO,
|
||||
oldSaleEstimate,
|
||||
}: ISaleEstimateEditedPayload) {
|
||||
const keys = estimateDTO.attachments?.map((attachment) => attachment.key);
|
||||
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleEstimate',
|
||||
oldSaleEstimate.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited sale estimate.
|
||||
* @param {ISaleEstimateEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnSaleEstimateEdited({
|
||||
tenantId,
|
||||
estimateDTO,
|
||||
oldSaleEstimate,
|
||||
trx,
|
||||
}: ISaleEstimateEditedPayload) {
|
||||
if (isEmpty(estimateDTO.attachments)) return;
|
||||
|
||||
const keys = estimateDTO.attachments?.map((attachment) => attachment.key);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleEstimate',
|
||||
oldSaleEstimate.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the estimate deleted.
|
||||
* @param {ISaleEstimateDeletingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnSaleEstimateDelete({
|
||||
tenantId,
|
||||
oldSaleEstimate,
|
||||
trx,
|
||||
}: ISaleEstimateDeletingPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'SaleEstimate',
|
||||
oldSaleEstimate.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
ISaleInvoiceCreatedPayload,
|
||||
ISaleInvoiceCreatingPaylaod,
|
||||
ISaleInvoiceDeletePayload,
|
||||
ISaleInvoiceEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnSaleInvoiceCreated {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onCreating,
|
||||
this.validateAttachmentsOnSaleInvoiceCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onCreated,
|
||||
this.handleAttachmentsOnSaleInvoiceCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnInvoiceEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onEdited,
|
||||
this.handleLinkPresentedKeysOnInvoiceEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnInvoiceDeleted.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating sale invoice.
|
||||
* @param {ISaleInvoiceCreatingPaylaod}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnSaleInvoiceCreate({
|
||||
saleInvoiceDTO,
|
||||
tenantId,
|
||||
}: ISaleInvoiceCreatingPaylaod): Promise<void> {
|
||||
if (isEmpty(saleInvoiceDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = saleInvoiceDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created sale invoice.
|
||||
* @param {ISaleInvoiceCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnSaleInvoiceCreated({
|
||||
tenantId,
|
||||
saleInvoiceDTO,
|
||||
saleInvoice,
|
||||
trx,
|
||||
}: ISaleInvoiceCreatedPayload): Promise<void> {
|
||||
if (isEmpty(saleInvoiceDTO.attachments)) return;
|
||||
|
||||
const keys = saleInvoiceDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleInvoice',
|
||||
saleInvoice.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited sale invoice.
|
||||
* @param {ISaleInvoiceEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnInvoiceEdited({
|
||||
tenantId,
|
||||
saleInvoiceDTO,
|
||||
saleInvoice,
|
||||
}: ISaleInvoiceEditedPayload) {
|
||||
// if (isEmpty(saleInvoiceDTO.attachments)) return;
|
||||
|
||||
const keys = saleInvoiceDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleInvoice',
|
||||
saleInvoice.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited sale invoice.
|
||||
* @param {ISaleInvoiceEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnInvoiceEdited({
|
||||
tenantId,
|
||||
saleInvoiceDTO,
|
||||
oldSaleInvoice,
|
||||
trx,
|
||||
}: ISaleInvoiceEditedPayload) {
|
||||
if (isEmpty(saleInvoiceDTO.attachments)) return;
|
||||
|
||||
const keys = saleInvoiceDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleInvoice',
|
||||
oldSaleInvoice.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the invoice deleted.
|
||||
* @param {ISaleInvoiceDeletedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnInvoiceDeleted({
|
||||
tenantId,
|
||||
saleInvoice,
|
||||
trx,
|
||||
}: ISaleInvoiceDeletePayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'SaleInvoice',
|
||||
saleInvoice.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
ISaleReceiptCreatedPayload,
|
||||
ISaleReceiptCreatingPayload,
|
||||
ISaleReceiptDeletingPayload,
|
||||
ISaleReceiptEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnSaleReceipt {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.saleReceipt.onCreating,
|
||||
this.validateAttachmentsOnSaleInvoiceCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleReceipt.onCreated,
|
||||
this.handleAttachmentsOnSaleInvoiceCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleReceipt.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnInvoiceEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleReceipt.onEdited,
|
||||
this.handleLinkPresentedKeysOnInvoiceEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleReceipt.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnReceiptDeleted.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating sale receipt.
|
||||
* @param {ISaleReceiptCreatingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnSaleInvoiceCreate({
|
||||
saleReceiptDTO,
|
||||
tenantId,
|
||||
}: ISaleReceiptCreatingPayload): Promise<void> {
|
||||
if (isEmpty(saleReceiptDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = saleReceiptDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created sale receipt.
|
||||
* @param {ISaleReceiptCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnSaleInvoiceCreated({
|
||||
tenantId,
|
||||
saleReceiptDTO,
|
||||
saleReceipt,
|
||||
trx,
|
||||
}: ISaleReceiptCreatedPayload): Promise<void> {
|
||||
if (isEmpty(saleReceiptDTO.attachments)) return;
|
||||
|
||||
const keys = saleReceiptDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleReceipt',
|
||||
saleReceipt.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited sale receipt.
|
||||
* @param {ISaleReceiptEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnInvoiceEdited({
|
||||
tenantId,
|
||||
saleReceiptDTO,
|
||||
saleReceipt,
|
||||
}: ISaleReceiptEditedPayload) {
|
||||
const keys = saleReceiptDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleReceipt',
|
||||
saleReceipt.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited sale receipt.
|
||||
* @param {ISaleReceiptEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnInvoiceEdited({
|
||||
tenantId,
|
||||
saleReceiptDTO,
|
||||
oldSaleReceipt,
|
||||
trx,
|
||||
}: ISaleReceiptEditedPayload) {
|
||||
if (isEmpty(saleReceiptDTO.attachments)) return;
|
||||
|
||||
const keys = saleReceiptDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'SaleReceipt',
|
||||
oldSaleReceipt.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the receipt deleted.
|
||||
* @param {ISaleReceiptDeletingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnReceiptDeleted({
|
||||
tenantId,
|
||||
oldSaleReceipt,
|
||||
trx,
|
||||
}: ISaleReceiptDeletingPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'SaleReceipt',
|
||||
oldSaleReceipt.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
IVendorCreditCreatedPayload,
|
||||
IVendorCreditCreatingPayload,
|
||||
IVendorCreditDeletingPayload,
|
||||
IVendorCreditEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import events from '@/subscribers/events';
|
||||
import { LinkAttachment } from '../LinkAttachment';
|
||||
import { ValidateAttachments } from '../ValidateAttachments';
|
||||
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsOnVendorCredits {
|
||||
@Inject()
|
||||
private linkAttachmentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkAttachmentService: UnlinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private validateDocuments: ValidateAttachments;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onCreating,
|
||||
this.validateAttachmentsOnVendorCreditCreate.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onCreated,
|
||||
this.handleAttachmentsOnVendorCreditCreated.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onEdited,
|
||||
this.handleUnlinkUnpresentedKeysOnVendorCreditEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onEdited,
|
||||
this.handleLinkPresentedKeysOnVendorCreditEdited.bind(this)
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onDeleting,
|
||||
this.handleUnlinkAttachmentsOnVendorCreditDeleted.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the attachment keys on creating vendor credit.
|
||||
* @param {IVendorCreditCreatingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async validateAttachmentsOnVendorCreditCreate({
|
||||
vendorCreditCreateDTO,
|
||||
tenantId,
|
||||
}: IVendorCreditCreatingPayload): Promise<void> {
|
||||
if (isEmpty(vendorCreditCreateDTO.attachments)) {
|
||||
return;
|
||||
}
|
||||
const documentKeys = vendorCreditCreateDTO?.attachments?.map((a) => a.key);
|
||||
|
||||
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking the attachments of the created vendor credit.
|
||||
* @param {IVendorCreditCreatedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleAttachmentsOnVendorCreditCreated({
|
||||
tenantId,
|
||||
vendorCreditCreateDTO,
|
||||
vendorCredit,
|
||||
trx,
|
||||
}: IVendorCreditCreatedPayload): Promise<void> {
|
||||
if (isEmpty(vendorCreditCreateDTO.attachments)) return;
|
||||
|
||||
const keys = vendorCreditCreateDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'VendorCredit',
|
||||
vendorCredit.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unlinking all the unpresented keys of the edited vendor credit.
|
||||
* @param {IVendorCreditEditedPayload}
|
||||
*/
|
||||
private async handleUnlinkUnpresentedKeysOnVendorCreditEdited({
|
||||
tenantId,
|
||||
vendorCreditDTO,
|
||||
oldVendorCredit,
|
||||
}: IVendorCreditEditedPayload) {
|
||||
const keys = vendorCreditDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||
tenantId,
|
||||
keys,
|
||||
'VendorCredit',
|
||||
oldVendorCredit.id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles linking all the presented keys of the edited vendor credit.
|
||||
* @param {IVendorCreditEditedPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleLinkPresentedKeysOnVendorCreditEdited({
|
||||
tenantId,
|
||||
vendorCreditDTO,
|
||||
oldVendorCredit,
|
||||
trx,
|
||||
}: IVendorCreditEditedPayload) {
|
||||
if (isEmpty(vendorCreditDTO.attachments)) return;
|
||||
|
||||
const keys = vendorCreditDTO.attachments?.map(
|
||||
(attachment) => attachment.key
|
||||
);
|
||||
await this.linkAttachmentService.bulkLink(
|
||||
tenantId,
|
||||
keys,
|
||||
'VendorCredit',
|
||||
oldVendorCredit.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink all attachments once the vendor credit deleted.
|
||||
* @param {IVendorCreditDeletingPayload}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
private async handleUnlinkAttachmentsOnVendorCreditDeleted({
|
||||
tenantId,
|
||||
oldVendorCredit,
|
||||
trx,
|
||||
}: IVendorCreditDeletingPayload) {
|
||||
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||
tenantId,
|
||||
'VendorCredit',
|
||||
oldVendorCredit.id,
|
||||
trx
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export default class BaseCreditNotes {
|
||||
autoNextNumber;
|
||||
|
||||
const initialDTO = {
|
||||
...omit(creditNoteDTO, ['open']),
|
||||
...omit(creditNoteDTO, ['open', 'attachments']),
|
||||
creditNoteNumber,
|
||||
amount,
|
||||
currencyCode: customerCurrencyCode,
|
||||
|
||||
@@ -123,6 +123,7 @@ export class CreateExpense {
|
||||
tenantId,
|
||||
expenseId: expense.id,
|
||||
authorizedUser,
|
||||
expenseDTO,
|
||||
expense,
|
||||
trx,
|
||||
} as IExpenseCreatedPayload);
|
||||
|
||||
@@ -54,7 +54,7 @@ export class ExpenseDTOTransformer {
|
||||
|
||||
const initialDTO = {
|
||||
categories: [],
|
||||
...omit(expenseDTO, ['publish']),
|
||||
...omit(expenseDTO, ['publish', 'attachments']),
|
||||
totalAmount,
|
||||
landedCostAmount,
|
||||
paymentDate: moment(expenseDTO.paymentDate).toMySqlDateTime(),
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Transformer } from '@/lib/Transformer/Transformer';
|
||||
import { formatNumber } from 'utils';
|
||||
import { IExpense } from '@/interfaces';
|
||||
import { ExpenseCategoryTransformer } from './ExpenseCategoryTransformer';
|
||||
import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer';
|
||||
|
||||
export class ExpenseTransfromer extends Transformer {
|
||||
/**
|
||||
@@ -15,6 +16,7 @@ export class ExpenseTransfromer extends Transformer {
|
||||
'formattedAllocatedCostAmount',
|
||||
'formattedDate',
|
||||
'categories',
|
||||
'attachments',
|
||||
];
|
||||
};
|
||||
|
||||
@@ -70,4 +72,13 @@ export class ExpenseTransfromer extends Transformer {
|
||||
currencyCode: expense.currencyCode,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the sale invoice attachments.
|
||||
* @param {ISaleInvoice} invoice
|
||||
* @returns
|
||||
*/
|
||||
protected attachments = (expense: IExpense) => {
|
||||
return this.item(expense.attachments, new AttachmentTransformer());
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ export class GetExpense {
|
||||
.withGraphFetched('categories.expenseAccount')
|
||||
.withGraphFetched('paymentAccount')
|
||||
.withGraphFetched('branch')
|
||||
.withGraphFetched('attachments')
|
||||
.throwIfNotFound();
|
||||
|
||||
// Transformes expense model to POJO.
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from '@/interfaces';
|
||||
import TenancyService from '@/services/Tenancy/TenancyService';
|
||||
import events from '@/subscribers/events';
|
||||
import { Tenant, TenantMetadata } from '@/system/models';
|
||||
import { TenantMetadata } from '@/system/models';
|
||||
import UnitOfWork from '@/services/UnitOfWork';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import { CommandManualJournalValidators } from './CommandManualJournalValidators';
|
||||
@@ -59,7 +59,7 @@ export class CreateManualJournalService {
|
||||
const journalNumber = manualJournalDTO.journalNumber || autoNextNumber;
|
||||
|
||||
const initialDTO = {
|
||||
...omit(manualJournalDTO, ['publish']),
|
||||
...omit(manualJournalDTO, ['publish', 'attachments']),
|
||||
...(manualJournalDTO.publish
|
||||
? { publishedAt: moment().toMySqlDateTime() }
|
||||
: {}),
|
||||
@@ -173,6 +173,7 @@ export class CreateManualJournalService {
|
||||
tenantId,
|
||||
manualJournal,
|
||||
manualJournalId: manualJournal.id,
|
||||
manualJournalDTO,
|
||||
trx,
|
||||
} as IManualJournalEventCreatedPayload);
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ export class CreateBillPayment {
|
||||
tenantId,
|
||||
billPayment,
|
||||
billPaymentId: billPayment.id,
|
||||
billPaymentDTO,
|
||||
trx,
|
||||
} as IBillPaymentEventCreatedPayload);
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ export class EditBillPayment {
|
||||
billPaymentId,
|
||||
billPayment,
|
||||
oldBillPayment,
|
||||
billPaymentDTO,
|
||||
trx,
|
||||
} as IBillPaymentEventEditedPayload);
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ export class BillDTOTransformer {
|
||||
)(asyncEntries);
|
||||
|
||||
const initialDTO = {
|
||||
...formatDateFields(omit(billDTO, ['open', 'entries']), [
|
||||
...formatDateFields(omit(billDTO, ['open', 'entries', 'attachments']), [
|
||||
'billDate',
|
||||
'dueDate',
|
||||
]),
|
||||
|
||||
@@ -110,6 +110,7 @@ export class CreateBill {
|
||||
tenantId,
|
||||
bill,
|
||||
billId: bill.id,
|
||||
billDTO,
|
||||
trx,
|
||||
} as IBillCreatedPayload);
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ export class EditBill {
|
||||
billId,
|
||||
oldBill,
|
||||
bill,
|
||||
billDTO,
|
||||
trx,
|
||||
} as IBillEditedPayload);
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ export default class EditVendorCredit extends BaseVendorCredit {
|
||||
oldVendorCredit,
|
||||
vendorCredit,
|
||||
vendorCreditId,
|
||||
vendorCreditDTO,
|
||||
trx,
|
||||
} as IVendorCreditEditedPayload);
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ export class EditSaleEstimate {
|
||||
estimateId,
|
||||
saleEstimate,
|
||||
oldSaleEstimate,
|
||||
estimateDTO,
|
||||
trx,
|
||||
} as ISaleEstimateEditedPayload);
|
||||
|
||||
|
||||
@@ -58,10 +58,10 @@ export class SaleEstimateDTOTransformer {
|
||||
|
||||
const initialDTO = {
|
||||
amount,
|
||||
...formatDateFields(omit(estimateDTO, ['delivered', 'entries']), [
|
||||
'estimateDate',
|
||||
'expirationDate',
|
||||
]),
|
||||
...formatDateFields(
|
||||
omit(estimateDTO, ['delivered', 'entries', 'attachments']),
|
||||
['estimateDate', 'expirationDate']
|
||||
),
|
||||
currencyCode: paymentCustomer.currencyCode,
|
||||
exchangeRate: estimateDTO.exchangeRate || 1,
|
||||
...(estimateNumber ? { estimateNumber } : {}),
|
||||
|
||||
@@ -86,7 +86,12 @@ export class CommandSaleInvoiceDTOTransformer {
|
||||
|
||||
const initialDTO = {
|
||||
...formatDateFields(
|
||||
omit(saleInvoiceDTO, ['delivered', 'entries', 'fromEstimateId']),
|
||||
omit(saleInvoiceDTO, [
|
||||
'delivered',
|
||||
'entries',
|
||||
'fromEstimateId',
|
||||
'attachments',
|
||||
]),
|
||||
['invoiceDate', 'dueDate']
|
||||
),
|
||||
// Avoid rewrite the deliver date in edit mode when already published.
|
||||
|
||||
@@ -34,7 +34,8 @@ export class GetSaleInvoice {
|
||||
.withGraphFetched('entries.tax')
|
||||
.withGraphFetched('customer')
|
||||
.withGraphFetched('branch')
|
||||
.withGraphFetched('taxes.taxRate');
|
||||
.withGraphFetched('taxes.taxRate')
|
||||
.withGraphFetched('attachments');
|
||||
|
||||
// Validates the given sale invoice existance.
|
||||
this.validators.validateInvoiceExistance(saleInvoice);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Transformer } from '@/lib/Transformer/Transformer';
|
||||
import { formatNumber } from 'utils';
|
||||
import { SaleInvoiceTaxEntryTransformer } from './SaleInvoiceTaxEntryTransformer';
|
||||
import { ItemEntryTransformer } from './ItemEntryTransformer';
|
||||
import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer';
|
||||
|
||||
export class SaleInvoiceTransformer extends Transformer {
|
||||
/**
|
||||
@@ -25,6 +26,7 @@ export class SaleInvoiceTransformer extends Transformer {
|
||||
'totalLocalFormatted',
|
||||
'taxes',
|
||||
'entries',
|
||||
'attachments',
|
||||
];
|
||||
};
|
||||
|
||||
@@ -190,4 +192,13 @@ export class SaleInvoiceTransformer extends Transformer {
|
||||
currencyCode: invoice.currencyCode,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the sale invoice attachments.
|
||||
* @param {ISaleInvoice} invoice
|
||||
* @returns
|
||||
*/
|
||||
protected attachments = (invoice) => {
|
||||
return this.item(invoice.attachments, new AttachmentTransformer());
|
||||
};
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ export class CreatePaymentReceive {
|
||||
tenantId,
|
||||
paymentReceive,
|
||||
paymentReceiveId: paymentReceive.id,
|
||||
paymentReceiveDTO,
|
||||
authorizedUser,
|
||||
trx,
|
||||
} as IPaymentReceiveCreatedPayload);
|
||||
|
||||
Reference in New Issue
Block a user