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'; | 
