feat: catch exceptions link attachment service

This commit is contained in:
Ahmed Bouhuolia
2024-05-29 22:15:31 +02:00
parent 6e50de1d28
commit 308a4f62ae
13 changed files with 53 additions and 34 deletions

View File

@@ -7,6 +7,7 @@ import {
} from './_utils'; } from './_utils';
import HasTenancyService from '../Tenancy/TenancyService'; import HasTenancyService from '../Tenancy/TenancyService';
import { ServiceError } from '@/exceptions'; import { ServiceError } from '@/exceptions';
import { ERRORS } from './constants';
@Service() @Service()
export class LinkAttachment { export class LinkAttachment {
@@ -32,18 +33,21 @@ export class LinkAttachment {
const LinkModel = models[modelRef]; const LinkModel = models[modelRef];
validateLinkModelExists(LinkModel); validateLinkModelExists(LinkModel);
const foundFile = await Document.query(trx)
.findOne('key', filekey)
.throwIfNotFound();
const foundLinkModel = await LinkModel.query(trx).findById(modelId); const foundLinkModel = await LinkModel.query(trx).findById(modelId);
validateLinkModelEntryExists(foundLinkModel); validateLinkModelEntryExists(foundLinkModel);
const foundLinks = await DocumentLink.query(trx) const foundLinks = await DocumentLink.query(trx)
.where('modelRef', modelRef) .where('modelRef', modelRef)
.where('modelId', modelId); .where('modelId', modelId)
.where('documentId', foundFile.id);
if (foundLinks.length > 0) { if (foundLinks.length > 0) {
throw new ServiceError('DOCUMENT_LINK_ALREADY_LINKED'); throw new ServiceError(ERRORS.DOCUMENT_LINK_ALREADY_LINKED);
} }
const foundFile = await Document.query(trx).findOne('key', filekey);
await DocumentLink.query(trx).insert({ await DocumentLink.query(trx).insert({
modelRef, modelRef,
modelId, modelId,
@@ -67,15 +71,12 @@ export class LinkAttachment {
modelId: number, modelId: number,
trx?: Knex.Transaction trx?: Knex.Transaction
) { ) {
await bluebird.map( return bluebird.each(filekeys, async (fieldKey: string) => {
filekeys, try {
(fieldKey: string) => await this.link(tenantId, fieldKey, modelRef, modelId, trx);
this.link(tenantId, fieldKey, modelRef, modelId, trx), } catch {
{ // Ignore catching exceptions in bulk action.
concurrency: CONCURRENCY_ASYNC,
} }
); });
} }
} }
const CONCURRENCY_ASYNC = 10;

View File

@@ -34,7 +34,7 @@ export class UnlinkAttachment {
const foundLinkModel = await LinkModel.query(trx).findById(modelId); const foundLinkModel = await LinkModel.query(trx).findById(modelId);
validateLinkModelEntryExists(foundLinkModel); validateLinkModelEntryExists(foundLinkModel);
const document = await Document.query().findOne('key', filekey); const document = await Document.query(trx).findOne('key', filekey);
// Delete the document link. // Delete the document link.
await DocumentLink.query(trx) await DocumentLink.query(trx)
@@ -59,14 +59,13 @@ export class UnlinkAttachment {
modelId: number, modelId: number,
trx?: Knex.Transaction trx?: Knex.Transaction
): Promise<void> { ): Promise<void> {
await bluebird.map( await bluebird.each(filekeys, (fieldKey: string) => {
filekeys, try {
(fieldKey: string) => this.unlink(tenantId, fieldKey, modelRef, modelId, trx);
this.unlink(tenantId, fieldKey, modelRef, modelId, trx), } catch {
{ // Ignore catching exceptions on bulk action.
concurrency: CONCURRENCY_ASYNC,
} }
); });
} }
/** /**
@@ -124,5 +123,3 @@ export class UnlinkAttachment {
await this.bulkUnlink(tenantId, modelLinkKeys, modelRef, modelId, trx); await this.bulkUnlink(tenantId, modelLinkKeys, modelRef, modelId, trx);
} }
} }
const CONCURRENCY_ASYNC = 10;

View File

@@ -1,4 +1,5 @@
export enum ERRORS { export enum ERRORS {
DOCUMENT_LINK_REF_INVALID = 'DOCUMENT_LINK_REF_INVALID', DOCUMENT_LINK_REF_INVALID = 'DOCUMENT_LINK_REF_INVALID',
DOCUMENT_LINK_ID_INVALID = 'DOCUMENT_LINK_ID_INVALID', DOCUMENT_LINK_ID_INVALID = 'DOCUMENT_LINK_ID_INVALID',
DOCUMENT_LINK_ALREADY_LINKED = 'DOCUMENT_LINK_ALREADY_LINKED'
} }

View File

@@ -96,13 +96,15 @@ export class AttachmentsOnBills {
tenantId, tenantId,
billDTO, billDTO,
bill, bill,
trx
}: IBillEditedPayload) { }: IBillEditedPayload) {
const keys = billDTO.attachments?.map((attachment) => attachment.key); const keys = billDTO.attachments?.map((attachment) => attachment.key);
await this.unlinkAttachmentService.unlinkUnpresentedKeys( await this.unlinkAttachmentService.unlinkUnpresentedKeys(
tenantId, tenantId,
keys, keys,
'Bill', 'Bill',
bill.id bill.id,
trx
); );
} }

View File

@@ -96,6 +96,7 @@ export class AttachmentsOnCreditNote {
tenantId, tenantId,
creditNoteEditDTO, creditNoteEditDTO,
oldCreditNote, oldCreditNote,
trx,
}: ICreditNoteEditedPayload) { }: ICreditNoteEditedPayload) {
const keys = creditNoteEditDTO.attachments?.map( const keys = creditNoteEditDTO.attachments?.map(
(attachment) => attachment.key (attachment) => attachment.key
@@ -104,7 +105,8 @@ export class AttachmentsOnCreditNote {
tenantId, tenantId,
keys, keys,
'CreditNote', 'CreditNote',
oldCreditNote.id oldCreditNote.id,
trx
); );
} }

View File

@@ -96,13 +96,15 @@ export class AttachmentsOnExpenses {
tenantId, tenantId,
expenseDTO, expenseDTO,
expense, expense,
trx,
}: IExpenseEventEditPayload) { }: IExpenseEventEditPayload) {
const keys = expenseDTO.attachments?.map((attachment) => attachment.key); const keys = expenseDTO.attachments?.map((attachment) => attachment.key);
await this.unlinkAttachmentService.unlinkUnpresentedKeys( await this.unlinkAttachmentService.unlinkUnpresentedKeys(
tenantId, tenantId,
keys, keys,
'Expense', 'Expense',
expense.id expense.id,
trx
); );
} }

View File

@@ -98,6 +98,7 @@ export class AttachmentsOnManualJournals {
tenantId, tenantId,
manualJournalDTO, manualJournalDTO,
manualJournal, manualJournal,
trx
}: IManualJournalEventEditedPayload) { }: IManualJournalEventEditedPayload) {
const keys = manualJournalDTO.attachments?.map( const keys = manualJournalDTO.attachments?.map(
(attachment) => attachment.key (attachment) => attachment.key
@@ -106,7 +107,8 @@ export class AttachmentsOnManualJournals {
tenantId, tenantId,
keys, keys,
'SaleInvoice', 'SaleInvoice',
manualJournal.id manualJournal.id,
trx
); );
} }

View File

@@ -12,7 +12,7 @@ import { ValidateAttachments } from '../ValidateAttachments';
import { UnlinkAttachment } from '../UnlinkAttachment'; import { UnlinkAttachment } from '../UnlinkAttachment';
@Service() @Service()
export class AttachmentsOnBillPayments{ export class AttachmentsOnBillPayments {
@Inject() @Inject()
private linkAttachmentService: LinkAttachment; private linkAttachmentService: LinkAttachment;
@@ -98,6 +98,7 @@ export class AttachmentsOnBillPayments{
tenantId, tenantId,
billPaymentDTO, billPaymentDTO,
oldBillPayment, oldBillPayment,
trx,
}: IBillPaymentEventEditedPayload) { }: IBillPaymentEventEditedPayload) {
const keys = billPaymentDTO.attachments?.map( const keys = billPaymentDTO.attachments?.map(
(attachment) => attachment.key (attachment) => attachment.key
@@ -106,7 +107,8 @@ export class AttachmentsOnBillPayments{
tenantId, tenantId,
keys, keys,
'BillPayment', 'BillPayment',
oldBillPayment.id oldBillPayment.id,
trx
); );
} }

View File

@@ -98,6 +98,7 @@ export class AttachmentsOnPaymentsReceived {
tenantId, tenantId,
paymentReceiveDTO, paymentReceiveDTO,
oldPaymentReceive, oldPaymentReceive,
trx,
}: IPaymentReceiveEditedPayload) { }: IPaymentReceiveEditedPayload) {
const keys = paymentReceiveDTO.attachments?.map( const keys = paymentReceiveDTO.attachments?.map(
(attachment) => attachment.key (attachment) => attachment.key
@@ -106,7 +107,8 @@ export class AttachmentsOnPaymentsReceived {
tenantId, tenantId,
keys, keys,
'PaymentReceive', 'PaymentReceive',
oldPaymentReceive.id oldPaymentReceive.id,
trx
); );
} }

View File

@@ -98,6 +98,7 @@ export class AttachmentsOnSaleEstimates {
tenantId, tenantId,
estimateDTO, estimateDTO,
oldSaleEstimate, oldSaleEstimate,
trx
}: ISaleEstimateEditedPayload) { }: ISaleEstimateEditedPayload) {
const keys = estimateDTO.attachments?.map((attachment) => attachment.key); const keys = estimateDTO.attachments?.map((attachment) => attachment.key);
@@ -105,7 +106,8 @@ export class AttachmentsOnSaleEstimates {
tenantId, tenantId,
keys, keys,
'SaleEstimate', 'SaleEstimate',
oldSaleEstimate.id oldSaleEstimate.id,
trx
); );
} }

View File

@@ -98,6 +98,7 @@ export class AttachmentsOnSaleInvoiceCreated {
tenantId, tenantId,
saleInvoiceDTO, saleInvoiceDTO,
saleInvoice, saleInvoice,
trx,
}: ISaleInvoiceEditedPayload) { }: ISaleInvoiceEditedPayload) {
// if (isEmpty(saleInvoiceDTO.attachments)) return; // if (isEmpty(saleInvoiceDTO.attachments)) return;
@@ -108,7 +109,8 @@ export class AttachmentsOnSaleInvoiceCreated {
tenantId, tenantId,
keys, keys,
'SaleInvoice', 'SaleInvoice',
saleInvoice.id saleInvoice.id,
trx
); );
} }

View File

@@ -98,6 +98,7 @@ export class AttachmentsOnSaleReceipt {
tenantId, tenantId,
saleReceiptDTO, saleReceiptDTO,
saleReceipt, saleReceipt,
trx,
}: ISaleReceiptEditedPayload) { }: ISaleReceiptEditedPayload) {
const keys = saleReceiptDTO.attachments?.map( const keys = saleReceiptDTO.attachments?.map(
(attachment) => attachment.key (attachment) => attachment.key
@@ -106,7 +107,8 @@ export class AttachmentsOnSaleReceipt {
tenantId, tenantId,
keys, keys,
'SaleReceipt', 'SaleReceipt',
saleReceipt.id saleReceipt.id,
trx
); );
} }

View File

@@ -98,6 +98,7 @@ export class AttachmentsOnVendorCredits {
tenantId, tenantId,
vendorCreditDTO, vendorCreditDTO,
oldVendorCredit, oldVendorCredit,
trx,
}: IVendorCreditEditedPayload) { }: IVendorCreditEditedPayload) {
const keys = vendorCreditDTO.attachments?.map( const keys = vendorCreditDTO.attachments?.map(
(attachment) => attachment.key (attachment) => attachment.key
@@ -106,7 +107,8 @@ export class AttachmentsOnVendorCredits {
tenantId, tenantId,
keys, keys,
'VendorCredit', 'VendorCredit',
oldVendorCredit.id oldVendorCredit.id,
trx
); );
} }