summaryrefslogtreecommitdiff
path: root/src/services/waybills.service.ts
blob: 5007faba5038e728dcfce495f3a0c3d5a732402a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { Application } from '@feathersjs/express';
import { HookContext } from '@feathersjs/feathers';
import service from 'feathers-mongoose';
import { populate } from 'feathers-hooks-common';
import Bluebird from 'bluebird';
import _ from 'lodash';
import Model from '../models/waybill/waybill.model';
import Contractor from '../models/contractor/contractor.model';
import Product from '../models/product/product.model';

const waybills = service({ Model });

const populateSchema = {
  include: [
    {
      service: 'contractors',
      nameAs: 'contractor',
      parentField: 'contractorId',
      childField: '_id'
    },
    {
      service: 'products',
      nameAs: 'product',
      parentField: 'productId',
      childField: '_id'
    },
  ]
};

const performWaybillOperation = async (id: string, cancel = false) => {
  const waybill = await Model.findById(id);
  if (!waybill) return;
  waybill.status = cancel ? 'cancelled' : 'executed';

  const signMultiplier = (waybill.operation === 'in' ? 1 : -1) * (cancel ? -1 : 1);

  const product = await Product.findById(waybill.productId);
  if (!product) return;
  product.quantity += waybill.quantity * signMultiplier;
  if (product.quantity < 0) console.log('ВНИМАНИЕ: Недостаточно товара на складе');

  const contractor = await Contractor.findById(waybill.contractorId);
  if (!contractor) return;
  contractor.debt -= waybill.quantity * product.price * signMultiplier;

  return Bluebird.all([waybill.save(), product.save(), contractor.save()]);
};

const addName = (context: HookContext): HookContext => {
  const { result } = context;

  const addNameSingle = (item: any): void => {
    const { operation, product, quantity } = item;
    const op = operation === 'in' ? 'приход' : 'расход';
    const name = `Накладная: ${product?.name} ${op} ${quantity} шт.`
    return { name, ...item };
  };

  if (Array.isArray(result)) {
    context.result = result.map(addNameSingle);
  } else {
    context.result = addNameSingle(result);
  }
  return context;
};

export default (app: Application): void => {
  app.use('/waybills', waybills);

  app.post('/waybills/:id/execute', async (req, res) => {
    const result = await performWaybillOperation(req.params.id);
    res.send(result);
  });

  app.post('/waybills/:id/cancel', async (req, res) => {
    const result = await performWaybillOperation(req.params.id, true);
    res.send(result);
  });

  app.service('waybills').hooks({
    after: {
      all: [populate({ schema: populateSchema }), addName],
    },
  })
};