summaryrefslogtreecommitdiff
path: root/src/services/uploads.service.ts
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2021-03-20 17:01:41 +0300
committereug-vs <eug-vs@keemail.me>2021-03-20 17:01:41 +0300
commitf0fe802df9fd7e98c0333a80922f6008cab7abab (patch)
tree9d4ec9e822621c4693e015edf17811c340e8a1be /src/services/uploads.service.ts
parent2434c687bbc8f5b42b380a75e48cf1879a508674 (diff)
downloadcommercel-api-f0fe802df9fd7e98c0333a80922f6008cab7abab.tar.gz
feat: parse pdf bills into transfers
Diffstat (limited to 'src/services/uploads.service.ts')
-rw-r--r--src/services/uploads.service.ts79
1 files changed, 76 insertions, 3 deletions
diff --git a/src/services/uploads.service.ts b/src/services/uploads.service.ts
index 520079f..1d39a66 100644
--- a/src/services/uploads.service.ts
+++ b/src/services/uploads.service.ts
@@ -1,13 +1,86 @@
import { Application } from '@feathersjs/express';
+import { HookContext } from '@feathersjs/feathers';
import blobService from 'feathers-blob';
import fs from 'fs-blob-store';
+import moment from 'moment';
import Bluebird from 'bluebird';
+import { PdfReader } from 'pdfreader'
import _ from 'lodash';
-const blobStorage = fs('./uploads');
-
+const dir = './documents';
+const blobStorage = fs(dir);
const uploads = blobService({ Model: blobStorage });
+
+const parseTransfersBill = async (context: HookContext): Promise<HookContext> => {
+ const { id } = context.result;
+ const fileName = `${dir}/${id}`;
+
+ const reader = new PdfReader();
+ const items: any[] = [];
+
+ reader.parseFileItems(fileName, (err: Error, item: any) => {
+ if (item) items.push(item);
+ else { // Finished parsing. TODO: wrap into async
+ const hash = _.groupBy(items, 'y')
+ const rows = _.map(hash, (elements: any[]) => _.map(elements, 'text'));
+
+ const transfers = rows.reduce((acc: any, cols: string[]) => {
+ if (cols[0]?.startsWith('УНП')) {
+ acc[acc.length - 1].vatId = cols[2];
+ acc[acc.length - 1].name = cols[3];
+ } else if (cols.length === 7) {
+ const [dateString, doc, op, code, account, debet, credit] = cols;
+ try {
+ const date = moment(dateString, 'DD.MM.YYYY').toISOString();
+ acc.push({ date, doc, op, code, account, debet, credit });
+ } catch (e) {
+ console.log(`Skipping row because not a date: ${dateString}`);
+ }
+ }
+
+ return acc;
+ }, []);
+
+ return Bluebird.mapSeries(transfers, async (transfer: any) => {
+ const { date, vatId, name } = transfer;
+ const debet = parseFloat(transfer.debet.replace(/ /g, ''));
+ const credit = parseFloat(transfer.credit.replace(/ /g, ''));
+
+ const operation = debet ? 'out' : 'in';
+ const amount = debet || credit;
+
+ const contractorId = await context.app
+ .service('contractors')
+ .find({ query: { vatId } })
+ .then((results: any[]) => {
+ if (results.length) return results[0];
+ return context.app
+ .service('contractors')
+ .create({ vatId, name });
+ })
+ .then((contractor: any) => contractor._id);
+
+ return context.app.service('transfers').create({
+ date,
+ operation,
+ amount,
+ contractorId,
+ });
+ }).then(() => context.service.remove(id));
+ }
+ });
+
+ return context;
+};
+
+
export default (app: Application): void => {
- app.use('/uploads', uploads)
+ app.use('/uploads', uploads);
+
+ app.service('uploads').hooks({
+ after: {
+ create: parseTransfersBill,
+ },
+ });
};