diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/models/contractor/contractor.schema.ts | 5 | ||||
-rw-r--r-- | src/services/uploads.service.ts | 79 | ||||
-rw-r--r-- | src/types.ts | 1 |
3 files changed, 81 insertions, 4 deletions
diff --git a/src/models/contractor/contractor.schema.ts b/src/models/contractor/contractor.schema.ts index e3f7de6..d5ac115 100644 --- a/src/models/contractor/contractor.schema.ts +++ b/src/models/contractor/contractor.schema.ts @@ -13,6 +13,9 @@ export const contractorSchema = new Schema({ fullName: String, vatId: String, type: String, - debt: Number + debt: { + type: Number, + default: 0 + } }, { timestamps: true }); 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, + }, + }); }; diff --git a/src/types.ts b/src/types.ts index 745d7f2..fd1e7a2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,4 @@ declare module 'fs-blob-store'; declare module 'feathers-blob'; +declare module 'pdfreader'; |