mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 14:50:32 +00:00
feat: link and unlink document to resource model
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import mime from 'mime-types';
|
import mime from 'mime-types';
|
||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import { Router, Response } from 'express';
|
import { Router, Response } from 'express';
|
||||||
import { param } from 'express-validator';
|
import { body, param } from 'express-validator';
|
||||||
import BaseController from '@/api/controllers/BaseController';
|
import BaseController from '@/api/controllers/BaseController';
|
||||||
import { Request } from 'express-validator/src/base';
|
import { Request } from 'express-validator/src/base';
|
||||||
import { AttachmentsApplication } from '@/services/Attachments/AttachmentsApplication';
|
import { AttachmentsApplication } from '@/services/Attachments/AttachmentsApplication';
|
||||||
@@ -34,6 +34,23 @@ export class AttachmentsController extends BaseController {
|
|||||||
this.validationResult,
|
this.validationResult,
|
||||||
this.getAttachment.bind(this)
|
this.getAttachment.bind(this)
|
||||||
);
|
);
|
||||||
|
router.post(
|
||||||
|
'/:id/link',
|
||||||
|
[body('modelRef').exists(), body('modelId').exists()],
|
||||||
|
this.validationResult
|
||||||
|
);
|
||||||
|
router.post(
|
||||||
|
'/:id/link',
|
||||||
|
[body('modelRef').exists(), body('modelId').exists()],
|
||||||
|
this.validationResult,
|
||||||
|
this.linkDocument.bind(this)
|
||||||
|
);
|
||||||
|
router.post(
|
||||||
|
'/:id/unlink',
|
||||||
|
[body('modelRef').exists(), body('modelId').exists()],
|
||||||
|
this.validationResult,
|
||||||
|
this.unlinkDocument.bind(this)
|
||||||
|
);
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
@@ -50,11 +67,12 @@ export class AttachmentsController extends BaseController {
|
|||||||
const file = req.file;
|
const file = req.file;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.attachmentsApplication.upload(tenantId, file);
|
const data = await this.attachmentsApplication.upload(tenantId, file);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
status: 200,
|
status: 200,
|
||||||
message: 'The document has uploaded successfully.',
|
message: 'The document has uploaded successfully.',
|
||||||
|
data,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
@@ -90,10 +108,10 @@ export class AttachmentsController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete
|
* Deletes the given document key.
|
||||||
* @param req
|
* @param {Request} req
|
||||||
* @param res
|
* @param {Response} res
|
||||||
* @param next
|
* @param {NextFunction} next
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
private async deleteAttachment(req: Request, res: Response, next: Function) {
|
private async deleteAttachment(req: Request, res: Response, next: Function) {
|
||||||
@@ -111,4 +129,60 @@ export class AttachmentsController extends BaseController {
|
|||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links the given document key.
|
||||||
|
* @param {Request} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @param {NextFunction} next
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
private async linkDocument(req: Request, res: Response, next: Function) {
|
||||||
|
const { tenantId } = req;
|
||||||
|
const { id: documentId } = req.params;
|
||||||
|
const { modelRef, modelId } = this.matchedBodyData(req);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.attachmentsApplication.link(
|
||||||
|
tenantId,
|
||||||
|
documentId,
|
||||||
|
modelRef,
|
||||||
|
modelId
|
||||||
|
);
|
||||||
|
return res.status(200).send({
|
||||||
|
status: 200,
|
||||||
|
message: 'The document has been linked successfully.',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links the given document key.
|
||||||
|
* @param {Request} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @param {NextFunction} next
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
private async unlinkDocument(req: Request, res: Response, next: Function) {
|
||||||
|
const { tenantId } = req;
|
||||||
|
const { id: documentId } = req.params;
|
||||||
|
const { modelRef, modelId } = this.matchedBodyData(req);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.attachmentsApplication.link(
|
||||||
|
tenantId,
|
||||||
|
documentId,
|
||||||
|
modelRef,
|
||||||
|
modelId
|
||||||
|
);
|
||||||
|
return res.status(200).send({
|
||||||
|
status: 200,
|
||||||
|
message: 'The document has been linked successfully.',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ import { ImportController } from './controllers/Import/ImportController';
|
|||||||
import { BankingController } from './controllers/Banking/BankingController';
|
import { BankingController } from './controllers/Banking/BankingController';
|
||||||
import { Webhooks } from './controllers/Webhooks/Webhooks';
|
import { Webhooks } from './controllers/Webhooks/Webhooks';
|
||||||
import { ExportController } from './controllers/Export/ExportController';
|
import { ExportController } from './controllers/Export/ExportController';
|
||||||
import { AttachmentsController } from './controllers/AttachmentsController';
|
import { AttachmentsController } from './controllers/Attachments/AttachmentsController';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const app = Router();
|
const app = Router();
|
||||||
@@ -80,7 +80,6 @@ export default () => {
|
|||||||
app.use('/jobs', Container.get(Jobs).router());
|
app.use('/jobs', Container.get(Jobs).router());
|
||||||
app.use('/account', Container.get(Account).router());
|
app.use('/account', Container.get(Account).router());
|
||||||
app.use('/webhooks', Container.get(Webhooks).router());
|
app.use('/webhooks', Container.get(Webhooks).router());
|
||||||
app.use('/attachments', Container.get(AttachmentsController).router());
|
|
||||||
|
|
||||||
// - Dashboard routes.
|
// - Dashboard routes.
|
||||||
// ---------------------------
|
// ---------------------------
|
||||||
@@ -145,6 +144,7 @@ export default () => {
|
|||||||
dashboard.use('/tax-rates', Container.get(TaxRatesController).router());
|
dashboard.use('/tax-rates', Container.get(TaxRatesController).router());
|
||||||
dashboard.use('/import', Container.get(ImportController).router());
|
dashboard.use('/import', Container.get(ImportController).router());
|
||||||
dashboard.use('/export', Container.get(ExportController).router());
|
dashboard.use('/export', Container.get(ExportController).router());
|
||||||
|
dashboard.use('/attachments', Container.get(AttachmentsController).router());
|
||||||
|
|
||||||
dashboard.use('/', Container.get(ProjectTasksController).router());
|
dashboard.use('/', Container.get(ProjectTasksController).router());
|
||||||
dashboard.use('/', Container.get(ProjectTimesController).router());
|
dashboard.use('/', Container.get(ProjectTimesController).router());
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
exports.up = function (knex) {
|
||||||
|
return knex.schema.createTable('document_links', (table) => {
|
||||||
|
table.increments('id').primary();
|
||||||
|
table.string('model_ref').notNullable();
|
||||||
|
table.string('model_id').notNullable();
|
||||||
|
table.integer('document_id').unsigned();
|
||||||
|
table.timestamps();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = function (knex) {
|
||||||
|
return knex.schema.dropTableIfExists('document_links');
|
||||||
|
};
|
||||||
@@ -60,9 +60,10 @@ import Time from 'models/Time';
|
|||||||
import Task from 'models/Task';
|
import Task from 'models/Task';
|
||||||
import TaxRate from 'models/TaxRate';
|
import TaxRate from 'models/TaxRate';
|
||||||
import TaxRateTransaction from 'models/TaxRateTransaction';
|
import TaxRateTransaction from 'models/TaxRateTransaction';
|
||||||
import Attachment from 'models/Attachment';
|
|
||||||
import PlaidItem from 'models/PlaidItem';
|
import PlaidItem from 'models/PlaidItem';
|
||||||
import UncategorizedCashflowTransaction from 'models/UncategorizedCashflowTransaction';
|
import UncategorizedCashflowTransaction from 'models/UncategorizedCashflowTransaction';
|
||||||
|
import Document from '@/models/Document';
|
||||||
|
import DocumentLink from '@/models/DocumentLink';
|
||||||
|
|
||||||
export default (knex) => {
|
export default (knex) => {
|
||||||
const models = {
|
const models = {
|
||||||
@@ -126,9 +127,10 @@ export default (knex) => {
|
|||||||
Task,
|
Task,
|
||||||
TaxRate,
|
TaxRate,
|
||||||
TaxRateTransaction,
|
TaxRateTransaction,
|
||||||
Attachment,
|
Document,
|
||||||
|
DocumentLink,
|
||||||
PlaidItem,
|
PlaidItem,
|
||||||
UncategorizedCashflowTransaction
|
UncategorizedCashflowTransaction,
|
||||||
};
|
};
|
||||||
return mapValues(models, (model) => model.bindKnex(knex));
|
return mapValues(models, (model) => model.bindKnex(knex));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import TenantModel from 'models/TenantModel';
|
|||||||
import ModelSetting from './ModelSetting';
|
import ModelSetting from './ModelSetting';
|
||||||
import ModelSearchable from './ModelSearchable';
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class Attachment extends mixin(TenantModel, [
|
export default class Document extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
ModelSearchable,
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
44
packages/server/src/models/DocumentLink.ts
Normal file
44
packages/server/src/models/DocumentLink.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { Model, mixin } from 'objection';
|
||||||
|
import TenantModel from 'models/TenantModel';
|
||||||
|
import ModelSetting from './ModelSetting';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
|
export default class DocumentLink extends mixin(TenantModel, [
|
||||||
|
ModelSetting,
|
||||||
|
ModelSearchable,
|
||||||
|
]) {
|
||||||
|
/**
|
||||||
|
* Table name
|
||||||
|
*/
|
||||||
|
static get tableName() {
|
||||||
|
return 'document_links';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model timestamps.
|
||||||
|
*/
|
||||||
|
get timestamps() {
|
||||||
|
return ['createdAt', 'updatedAt'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relationship mapping.
|
||||||
|
*/
|
||||||
|
static get relationMappings() {
|
||||||
|
const Document = require('models/Document');
|
||||||
|
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Sale invoice associated entries.
|
||||||
|
*/
|
||||||
|
document: {
|
||||||
|
relation: Model.HasOneRelation,
|
||||||
|
modelClass: Document.default,
|
||||||
|
join: {
|
||||||
|
from: 'document_links.documentId',
|
||||||
|
to: 'documents.id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -410,6 +410,7 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
const Account = require('models/Account');
|
const Account = require('models/Account');
|
||||||
const TaxRateTransaction = require('models/TaxRateTransaction');
|
const TaxRateTransaction = require('models/TaxRateTransaction');
|
||||||
|
const DocumentLink = require('models/DocumentLink');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@@ -523,6 +524,21 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
builder.where('reference_type', 'SaleInvoice');
|
builder.where('reference_type', 'SaleInvoice');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice may has many attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
|
relation: Model.HasManyRelation,
|
||||||
|
modelClass: DocumentLink.default,
|
||||||
|
join: {
|
||||||
|
from: 'sales_invoices.id',
|
||||||
|
to: 'document_links.modelId',
|
||||||
|
},
|
||||||
|
filter: (builder) => {
|
||||||
|
builder.where('modelRef', 'SaleInvoice');
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { UploadDocument } from './UploadDocument';
|
|||||||
import { DeleteAttachment } from './DeleteAttachment';
|
import { DeleteAttachment } from './DeleteAttachment';
|
||||||
import { GetAttachment } from './GetAttachment';
|
import { GetAttachment } from './GetAttachment';
|
||||||
import { AttachmentUploadPipeline } from './S3UploadPipeline';
|
import { AttachmentUploadPipeline } from './S3UploadPipeline';
|
||||||
|
import { LinkAttachment } from './LinkAttachment';
|
||||||
|
import { UnlinkAttachment } from './UnlinkAttachment';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class AttachmentsApplication {
|
export class AttachmentsApplication {
|
||||||
@@ -15,8 +17,15 @@ export class AttachmentsApplication {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private getDocumentService: GetAttachment;
|
private getDocumentService: GetAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
private uploadPipelineService: AttachmentUploadPipeline;
|
private uploadPipelineService: AttachmentUploadPipeline;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private linkDocumentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkDocumentService: UnlinkAttachment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
@@ -26,7 +35,7 @@ export class AttachmentsApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Uploads
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {} file
|
* @param {} file
|
||||||
* @returns
|
* @returns
|
||||||
@@ -53,4 +62,43 @@ export class AttachmentsApplication {
|
|||||||
public get(tenantId: number, documentKey: string) {
|
public get(tenantId: number, documentKey: string) {
|
||||||
return this.getDocumentService.getAttachment(tenantId, documentKey);
|
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 { DeleteObjectCommand } from '@aws-sdk/client-s3';
|
||||||
import { s3 } from '@/lib/S3/S3';
|
import { s3 } from '@/lib/S3/S3';
|
||||||
import { Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class DeleteAttachment {
|
export class DeleteAttachment {
|
||||||
|
@Inject()
|
||||||
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the give file attachment file key.
|
* Deletes the give file attachment file key.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {string} filekey
|
* @param {string} filekey
|
||||||
*/
|
*/
|
||||||
async delete(tenantId: number, filekey: string): Promise<void> {
|
async delete(tenantId: number, filekey: string): Promise<void> {
|
||||||
|
const { Document, DocumentLink } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
Bucket: process.env.AWS_BUCKET,
|
Bucket: process.env.AWS_BUCKET,
|
||||||
Key: filekey,
|
Key: filekey,
|
||||||
};
|
};
|
||||||
await s3.send(new DeleteObjectCommand(params));
|
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 { Inject, Service } from 'typedi';
|
||||||
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class UploadDocument {
|
export class UploadDocument {
|
||||||
|
@Inject()
|
||||||
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
async upload(tenantId: number, file: any) {
|
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