mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 20:30:33 +00:00
88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
import { first, values } from 'lodash';
|
|
import { Inject, Service } from 'typedi';
|
|
import { ServiceError } from '@/exceptions';
|
|
import XLSX from 'xlsx';
|
|
import * as R from 'ramda';
|
|
import HasTenancyService from '../Tenancy/TenancyService';
|
|
import { ERRORS, trimObject } from './_utils';
|
|
import ResourceService from '../Resource/ResourceService';
|
|
import fs from 'fs/promises';
|
|
import { IModelMetaField } from '@/interfaces';
|
|
import { ImportFileCommon } from './ImportFileCommon';
|
|
@Service()
|
|
export class ImportFileUploadService {
|
|
@Inject()
|
|
private tenancy: HasTenancyService;
|
|
|
|
@Inject()
|
|
private resourceService: ResourceService;
|
|
|
|
@Inject()
|
|
private importFileCommon: ImportFileCommon;
|
|
|
|
/**
|
|
* Reads the imported file and stores the import file meta under unqiue id.
|
|
* @param {number} tenantId - Tenant id.
|
|
* @param {string} resource - Resource name.
|
|
* @param {string} filePath - File path.
|
|
* @param {string} fileName - File name.
|
|
* @returns
|
|
*/
|
|
public async import(
|
|
tenantId: number,
|
|
resource: string,
|
|
filePath: string,
|
|
filename: string
|
|
) {
|
|
const { Import } = this.tenancy.models(tenantId);
|
|
|
|
const resourceMeta = this.resourceService.getResourceMeta(
|
|
tenantId,
|
|
resource
|
|
);
|
|
// Throw service error if the resource does not support importing.
|
|
if (!resourceMeta.importable) {
|
|
throw new ServiceError(ERRORS.RESOURCE_NOT_IMPORTABLE);
|
|
}
|
|
// Reads the imported file into buffer.
|
|
const buffer = await this.importFileCommon.readImportFile(filename);
|
|
|
|
// Parse the buffer file to array data.
|
|
const jsonData = this.importFileCommon.parseXlsxSheet(buffer);
|
|
|
|
const columns = this.getColumns(jsonData);
|
|
const coumnsStringified = JSON.stringify(columns);
|
|
|
|
// @todo validate the resource.
|
|
const _resource = this.resourceService.resourceToModelName(resource);
|
|
|
|
const exportFile = await Import.query().insert({
|
|
filename,
|
|
importId: filename,
|
|
resource: _resource,
|
|
columns: coumnsStringified,
|
|
});
|
|
const resourceColumns = this.resourceService.getResourceImportableFields(
|
|
tenantId,
|
|
resource
|
|
);
|
|
const resourceColumnsTransformeed = Object.entries(resourceColumns).map(
|
|
([key, { name }]: [string, IModelMetaField]) => ({ key, name })
|
|
);
|
|
return {
|
|
export: exportFile,
|
|
columns,
|
|
resourceColumns: resourceColumnsTransformeed,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Retrieves the sheet columns from the given sheet data.
|
|
* @param {unknown[]} json
|
|
* @returns {string[]}
|
|
*/
|
|
private getColumns(json: unknown[]): string[] {
|
|
return R.compose(Object.keys, trimObject, first)(json);
|
|
}
|
|
}
|