mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-24 16:49:48 +00:00
- Add missing DELETE /credit-notes/applied-invoices/:id endpoint - Fix CreditNotesApplyInvoice controller to use correct service methods - Add missing GetCreditNoteAssociatedInvoicesToApply endpoint - Add proper DTO for ApplyCreditNoteToInvoices - Update frontend creditNote hook to use correct API paths Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
import { ModuleRef } from '@nestjs/core';
|
|
import * as bluebird from 'bluebird';
|
|
import { Knex } from 'knex';
|
|
import {
|
|
validateLinkModelEntryExists,
|
|
validateLinkModelExists,
|
|
} from './_utils';
|
|
import { ERRORS } from './constants';
|
|
import { TenantModelProxy } from '../System/models/TenantBaseModel';
|
|
import { DocumentLink } from '../ChromiumlyTenancy/models/DocumentLink';
|
|
import { Inject, Injectable } from '@nestjs/common';
|
|
import { ServiceError } from '../Items/ServiceError';
|
|
import { getAttachableModelsMap } from './decorators/InjectAttachable.decorator';
|
|
import { DocumentModel } from './models/Document.model';
|
|
import { SaleInvoice } from '../SaleInvoices/models/SaleInvoice';
|
|
|
|
@Injectable()
|
|
export class LinkAttachment {
|
|
constructor(
|
|
private moduleRef: ModuleRef,
|
|
|
|
@Inject(DocumentLink.name)
|
|
private readonly documentLinkModel: TenantModelProxy<typeof DocumentLink>,
|
|
|
|
@Inject(DocumentModel.name)
|
|
private readonly documentModel: TenantModelProxy<typeof DocumentModel>,
|
|
) {}
|
|
|
|
/**
|
|
* Links the given file key to the given model type and id.
|
|
* @param {string} filekey - File key.
|
|
* @param {string} modelRef - Model reference.
|
|
* @param {number} modelId - Model id.
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async link(
|
|
filekey: string,
|
|
modelRef: string,
|
|
modelId: number,
|
|
trx?: Knex.Transaction,
|
|
) {
|
|
const attachmentsAttachableModels = getAttachableModelsMap();
|
|
const attachableModel = attachmentsAttachableModels.get(modelRef);
|
|
|
|
validateLinkModelExists(attachableModel);
|
|
|
|
const LinkModel = this.moduleRef.get(modelRef, { strict: false });
|
|
const foundFile = await this.documentModel()
|
|
.query(trx)
|
|
.findOne('key', filekey)
|
|
.throwIfNotFound();
|
|
|
|
const foundLinkModel = await LinkModel().query(trx).findById(modelId);
|
|
validateLinkModelEntryExists(foundLinkModel);
|
|
|
|
const foundLinks = await this.documentLinkModel()
|
|
.query(trx)
|
|
.where('modelRef', modelRef)
|
|
.where('modelId', modelId)
|
|
.where('documentId', foundFile.id);
|
|
|
|
if (foundLinks.length > 0) {
|
|
throw new ServiceError(ERRORS.DOCUMENT_LINK_ALREADY_LINKED);
|
|
}
|
|
await this.documentLinkModel().query(trx).insert({
|
|
modelRef,
|
|
modelId,
|
|
documentId: foundFile.id,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Links the given file keys to the given model type and id.
|
|
* @param {string[]} filekeys - File keys.
|
|
* @param {string} modelRef - Model reference.
|
|
* @param {number} modelId - Model id.
|
|
* @param {Knex.Transaction} trx - Knex transaction.
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async bulkLink(
|
|
filekeys: string[],
|
|
modelRef: string,
|
|
modelId: number,
|
|
trx?: Knex.Transaction,
|
|
) {
|
|
return bluebird.each(filekeys, async (fieldKey: string) => {
|
|
try {
|
|
await this.link(fieldKey, modelRef, modelId, trx);
|
|
} catch {
|
|
// Ignore catching exceptions in bulk action.
|
|
}
|
|
});
|
|
}
|
|
}
|