mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
feat: link and unlink document to resource model
This commit is contained in:
@@ -3,6 +3,8 @@ import { UploadDocument } from './UploadDocument';
|
||||
import { DeleteAttachment } from './DeleteAttachment';
|
||||
import { GetAttachment } from './GetAttachment';
|
||||
import { AttachmentUploadPipeline } from './S3UploadPipeline';
|
||||
import { LinkAttachment } from './LinkAttachment';
|
||||
import { UnlinkAttachment } from './UnlinkAttachment';
|
||||
|
||||
@Service()
|
||||
export class AttachmentsApplication {
|
||||
@@ -15,18 +17,25 @@ export class AttachmentsApplication {
|
||||
@Inject()
|
||||
private getDocumentService: GetAttachment;
|
||||
|
||||
@Inject()
|
||||
private uploadPipelineService: AttachmentUploadPipeline;
|
||||
|
||||
@Inject()
|
||||
private linkDocumentService: LinkAttachment;
|
||||
|
||||
@Inject()
|
||||
private unlinkDocumentService: UnlinkAttachment;
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
get uploadPipeline() {
|
||||
return this.uploadPipelineService.uploadPipeline();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Uploads
|
||||
* @param {number} tenantId
|
||||
* @param {} file
|
||||
* @returns
|
||||
@@ -53,4 +62,43 @@ export class AttachmentsApplication {
|
||||
public get(tenantId: number, documentKey: string) {
|
||||
return this.getDocumentService.getAttachment(tenantId, documentKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Links the given document to resource model.
|
||||
* @param {number} tenantId
|
||||
* @param {string} filekey
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
* @returns
|
||||
*/
|
||||
public link(
|
||||
tenantId: number,
|
||||
filekey: string,
|
||||
modelRef: string,
|
||||
modelId: number
|
||||
) {
|
||||
return this.linkDocumentService.link(tenantId, filekey, modelRef, modelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlinks the given document from resource model.
|
||||
* @param {number} tenantId
|
||||
* @param {string} filekey
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
* @returns
|
||||
*/
|
||||
public unlink(
|
||||
tenantId: number,
|
||||
filekey: string,
|
||||
modelRef: string,
|
||||
modelId: number
|
||||
) {
|
||||
return this.unlinkDocumentService.unlink(
|
||||
tenantId,
|
||||
filekey,
|
||||
modelRef,
|
||||
modelId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,35 @@
|
||||
import { DeleteObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { s3 } from '@/lib/S3/S3';
|
||||
import { Service } from 'typedi';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
|
||||
@Service()
|
||||
export class DeleteAttachment {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
* Deletes the give file attachment file key.
|
||||
* @param {number} tenantId
|
||||
* @param {string} filekey
|
||||
*/
|
||||
async delete(tenantId: number, filekey: string): Promise<void> {
|
||||
const { Document, DocumentLink } = this.tenancy.models(tenantId);
|
||||
|
||||
const params = {
|
||||
Bucket: process.env.AWS_BUCKET,
|
||||
Key: filekey,
|
||||
};
|
||||
await s3.send(new DeleteObjectCommand(params));
|
||||
|
||||
const foundDocument = await Document.query()
|
||||
.findOne('key', filekey)
|
||||
.throwIfNotFound();
|
||||
|
||||
// Delete all document links
|
||||
await DocumentLink.query().where('documentId', foundDocument.id).delete();
|
||||
|
||||
// Delete thedocument.
|
||||
await Document.query().findById(foundDocument.id).delete();
|
||||
}
|
||||
}
|
||||
|
||||
49
packages/server/src/services/Attachments/LinkAttachment.ts
Normal file
49
packages/server/src/services/Attachments/LinkAttachment.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import {
|
||||
validateLinkModelEntryExists,
|
||||
validateLinkModelExists,
|
||||
} from './_utils';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
|
||||
@Service()
|
||||
export class LinkAttachment {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} tenantId
|
||||
* @param {string} filekey
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
*/
|
||||
async link(
|
||||
tenantId: number,
|
||||
filekey: string,
|
||||
modelRef: string,
|
||||
modelId: number
|
||||
) {
|
||||
const { DocumentLink, Document, ...models } = this.tenancy.models(tenantId);
|
||||
const LinkModel = models[modelRef];
|
||||
validateLinkModelExists(LinkModel);
|
||||
|
||||
const foundLinkModel = await LinkModel.query().findById(modelId);
|
||||
validateLinkModelEntryExists(foundLinkModel);
|
||||
|
||||
const foundLinks = await DocumentLink.query()
|
||||
.where('modelRef', modelRef)
|
||||
.where('modelId', modelId);
|
||||
|
||||
if (foundLinks.length > 0) {
|
||||
throw new ServiceError('');
|
||||
}
|
||||
const foundFile = await Document.query().findOne('key', filekey);
|
||||
|
||||
await DocumentLink.query().insert({
|
||||
modelRef,
|
||||
modelId,
|
||||
documentId: foundFile.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
39
packages/server/src/services/Attachments/UnlinkAttachment.ts
Normal file
39
packages/server/src/services/Attachments/UnlinkAttachment.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import {
|
||||
validateLinkModelEntryExists,
|
||||
validateLinkModelExists,
|
||||
} from './_utils';
|
||||
|
||||
@Service()
|
||||
export class UnlinkAttachment {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} tenantId
|
||||
* @param {string} filekey
|
||||
* @param {string} modelRef
|
||||
* @param {number} modelId
|
||||
*/
|
||||
async unlink(
|
||||
tenantId: number,
|
||||
filekey: string,
|
||||
modelRef: string,
|
||||
modelId: number
|
||||
) {
|
||||
const { DocumentLink, ...models } = this.tenancy.models(tenantId);
|
||||
const LinkModel = models[modelRef];
|
||||
validateLinkModelExists(LinkModel);
|
||||
|
||||
const foundLinkModel = await LinkModel.query().findById(modelId);
|
||||
validateLinkModelEntryExists(foundLinkModel);
|
||||
|
||||
// Delete the document link.
|
||||
await DocumentLink.query()
|
||||
.where('modelRef', modelRef)
|
||||
.where('modelId', modelId)
|
||||
.delete();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,18 @@
|
||||
import { Service } from 'typedi';
|
||||
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
|
||||
@Service()
|
||||
export class UploadDocument {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
async upload(tenantId: number, file: any) {
|
||||
|
||||
const { Document } = this.tenancy.models(tenantId);
|
||||
|
||||
const insertedDocument = await Document.query().insert({
|
||||
key: file.key,
|
||||
extension: file.mimetype,
|
||||
});
|
||||
return insertedDocument;
|
||||
}
|
||||
}
|
||||
|
||||
14
packages/server/src/services/Attachments/_utils.ts
Normal file
14
packages/server/src/services/Attachments/_utils.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { ERRORS } from './constants';
|
||||
|
||||
export const validateLinkModelExists = (LinkModel) => {
|
||||
if (!LinkModel) {
|
||||
throw new ServiceError(ERRORS.DOCUMENT_LINK_REF_INVALID);
|
||||
}
|
||||
};
|
||||
|
||||
export const validateLinkModelEntryExists = (foundLinkModel) => {
|
||||
if (!foundLinkModel) {
|
||||
throw new ServiceError(ERRORS.DOCUMENT_LINK_ID_INVALID);
|
||||
}
|
||||
};
|
||||
4
packages/server/src/services/Attachments/constants.ts
Normal file
4
packages/server/src/services/Attachments/constants.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export enum ERRORS {
|
||||
DOCUMENT_LINK_REF_INVALID = 'DOCUMENT_LINK_REF_INVALID',
|
||||
DOCUMENT_LINK_ID_INVALID = 'DOCUMENT_LINK_ID_INVALID',
|
||||
}
|
||||
Reference in New Issue
Block a user