diff options
Diffstat (limited to 'src/services')
| -rw-r--r-- | src/services/uploads.service.ts | 114 | 
1 files changed, 62 insertions, 52 deletions
| diff --git a/src/services/uploads.service.ts b/src/services/uploads.service.ts index 1d39a66..3479d0f 100644 --- a/src/services/uploads.service.ts +++ b/src/services/uploads.service.ts @@ -11,64 +11,74 @@ const dir = './documents';  const blobStorage = fs(dir);  const uploads = blobService({ Model: blobStorage }); +// Async wrapper for pdfreader +const parsePdfItems = async (fileName: string): Promise<any[]> => { +  return new Promise((resolve, reject) => { +    const reader = new PdfReader(); +    const items: any[] = []; + +    reader.parseFileItems(fileName, (err: Error, item: any) => { +      if (err) reject(err); +      else if (item) items.push(item); +      else resolve(items); +    }); +  }); +};  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)); +  const items = await parsePdfItems(fileName); +  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; +  }, []); + + +  // At this point we can remove the file +  context.service.remove(id); + +  context.result = await 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, +    });    });    return context; | 
