Browse Source

供应商导出(部分)

lrf402788946 4 years ago
parent
commit
a9139ed007

+ 22 - 0
app/controller/order/.transport.js

@@ -66,4 +66,26 @@ module.exports = {
       count: true,
       count: true,
     },
     },
   },
   },
+
+  supplierCalculate: {
+    parameters: {
+      query: {
+        owner: "owner",
+        principal: "principal",
+        client: "supplier.client",
+        car_no:"supplier.car_no",
+        "date@start": "create_time@start",
+        "date@end": "create_time@end",
+        is_js: "is_js",
+        status: "status",
+      },
+    },
+    service: "supplierCalculate",
+    options: {
+      query: ["skip", "limit"],
+      sort: ["meta.createdAt"],
+      desc: true,
+      count: true,
+    },
+  },
 };
 };

+ 1 - 0
app/controller/order/order.js

@@ -61,6 +61,7 @@ class OrderController extends Controller {
     const res = await this.service.js(this.ctx.request.body);
     const res = await this.service.js(this.ctx.request.body);
     this.ctx.ok({ data: res });
     this.ctx.ok({ data: res });
   }
   }
+
 }
 }
 
 
 module.exports = CrudController(OrderController, meta);
 module.exports = CrudController(OrderController, meta);

+ 16 - 0
app/controller/order/transport.js

@@ -51,6 +51,22 @@ class TransportController extends Controller {
     const data = await this.service.toExport(this.ctx.request.body);
     const data = await this.service.toExport(this.ctx.request.body);
     this.ctx.ok({ data });
     this.ctx.ok({ data });
   }
   }
+
+  /**
+   * 供应商结算导出
+   */
+  async supplierExport() {
+    const res = await this.service.supplierExport(this.ctx.request.body);
+    this.ctx.ok({ data: res });
+  }
+
+  /**
+   * 供应商支出结算
+   */
+  async supplierJs() {
+    const res = await this.service.js(this.ctx.request.body);
+    this.ctx.ok({ data: res });
+  }
 }
 }
 
 
 module.exports = CrudController(TransportController, meta);
 module.exports = CrudController(TransportController, meta);

+ 20 - 4
app/model/order.js

@@ -74,6 +74,20 @@ const cost_bill = new Schema({
   sh_ys: { type: Number, maxLength: 200 }, // 税后应收
   sh_ys: { type: Number, maxLength: 200 }, // 税后应收
   sh_ss: { type: Number, maxLength: 200 }, // 税后实收
   sh_ss: { type: Number, maxLength: 200 }, // 税后实收
 });
 });
+// 支出项
+const out_bill = new Schema({
+  supply_type: { type: String, maxlength: 200 }, // 运输单位类型 0:自运;1:供应商;2:第三方
+  car_no: { type: String, maxlength: 200 }, // 车牌号,0/2使用
+  client: { type: String, maxlength: 200 }, // 供应商
+  treaty: { type: String, maxlength: 200 }, // 合同
+  item: { type: String, maxlength: 200 }, // 支出项
+  taxes: { type: String, maxLength: 200 }, // 税率
+  sq_ys: { type: Number, maxLength: 200 }, // 税前应收
+  sq_ss: { type: Number, maxLength: 200 }, // 税前实收
+  sh_ys: { type: Number, maxLength: 200 }, // 税后应收
+  sh_ss: { type: Number, maxLength: 200 }, // 税后实收
+});
+
 
 
 // 订单
 // 订单
 const order = {
 const order = {
@@ -164,7 +178,7 @@ const order = {
     field: { label: '收入-服务单据' },
     field: { label: '收入-服务单据' },
   },
   },
   out_bill: {
   out_bill: {
-    type: [ cost_bill ],
+    type: [ out_bill ],
     maxLength: 200,
     maxLength: 200,
     field: { label: '支出-服务单据' },
     field: { label: '支出-服务单据' },
   },
   },
@@ -174,7 +188,7 @@ const order = {
     maxLength: 200,
     maxLength: 200,
     default: false,
     default: false,
     field: {
     field: {
-      label: '结算状态',
+      label: '收入结算状态',
       filter: 'select',
       filter: 'select',
       type: 'radio',
       type: 'radio',
       format: (i => (i ? '已结算' : '未结算')).toString(),
       format: (i => (i ? '已结算' : '未结算')).toString(),
@@ -232,8 +246,10 @@ const order = {
     type: [ recordList ],
     type: [ recordList ],
     field: { label: '订单记录' },
     field: { label: '订单记录' },
   },
   },
-  create_time: { type: String, default: moment().format('YYYY-MM-DD HH:mm:ss') },
-
+  create_time: {
+    type: String,
+    default: moment().format('YYYY-MM-DD HH:mm:ss'),
+  },
 };
 };
 
 
 const schema = new Schema(order, { toJSON: { virtuals: true } });
 const schema = new Schema(order, { toJSON: { virtuals: true } });

+ 2 - 2
app/model/transport.js

@@ -2,7 +2,7 @@
 const moment = require('moment');
 const moment = require('moment');
 const Schema = require('mongoose').Schema;
 const Schema = require('mongoose').Schema;
 const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
 const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
-// 货物列表
+// 货物列表(所有货物总价就是这票的运费)
 const goodsList = new Schema({
 const goodsList = new Schema({
   name: { type: String, maxlength: 200 }, // 货物名称
   name: { type: String, maxlength: 200 }, // 货物名称
   number: { type: Number, maxLength: 200 }, // 数量
   number: { type: Number, maxLength: 200 }, // 数量
@@ -15,7 +15,7 @@ const goodsList = new Schema({
   sh_ss: { type: Number, maxLength: 200 }, // 税后实收
   sh_ss: { type: Number, maxLength: 200 }, // 税后实收
   split_id: { type: String, maxLength: 200, required: true }, // 拆分的货物id
   split_id: { type: String, maxLength: 200, required: true }, // 拆分的货物id
 });
 });
-// 运输支出(单车,单趟)
+// 运输支出(单车/单趟的收入 或者 处运费外额外支付给供应商)
 const out_bill = new Schema({
 const out_bill = new Schema({
   item: { type: String, maxlength: 200 }, // 支出项
   item: { type: String, maxlength: 200 }, // 支出项
   money: { type: Number, maxLength: 200 }, // 金额
   money: { type: Number, maxLength: 200 }, // 金额

+ 1 - 1
app/router/order.js

@@ -6,7 +6,7 @@ module.exports = app => {
   const prefix = '/api/servicezhwl';
   const prefix = '/api/servicezhwl';
   const index = 'order';
   const index = 'order';
   const { router, controller } = app;
   const { router, controller } = app;
-  // 订单结算
+  // 订单收入结算
   router.post('order', `${prefix}/order/js`, controller[index].order.js);
   router.post('order', `${prefix}/order/js`, controller[index].order.js);
   // 客户结算单导出
   // 客户结算单导出
   router.post('order', `${prefix}/order/client/calculate/export`, controller[index].order.clientExport);
   router.post('order', `${prefix}/order/client/calculate/export`, controller[index].order.clientExport);

+ 6 - 0
app/router/transport.js

@@ -6,6 +6,12 @@ module.exports = app => {
   const prefix = '/api/servicezhwl';
   const prefix = '/api/servicezhwl';
   const index = 'order';
   const index = 'order';
   const { router, controller } = app;
   const { router, controller } = app;
+  // 供应商结算单查询
+  router.get('transport', `${prefix}/transport/supplier/calculate`, controller[index].transport.supplierCalculate);
+  // transport
+  router.post('transport', `${prefix}/transport/supplier/calculate/export`, controller[index].transport.supplierExport);
+  // 供应商支出结算
+  router.post('transport', `${prefix}/transport/supplier/js`, controller[index].transport.supplierJs);
   // 核算导出
   // 核算导出
   router.post('transport', `${prefix}/transport/calculate/export`, controller[index].transport.toExport);
   router.post('transport', `${prefix}/transport/calculate/export`, controller[index].transport.toExport);
   // 单趟核算
   // 单趟核算

+ 8 - 3
app/service/order/order.js

@@ -102,7 +102,8 @@ class OrderService extends CrudService {
   async goodsUpdate(oldGoods, newGoods, split) {
   async goodsUpdate(oldGoods, newGoods, split) {
     oldGoods = oldGoods.map(og => {
     oldGoods = oldGoods.map(og => {
       const is_split = split.find(
       const is_split = split.find(
-        f => ObjectId(f.pid).equals(og._id) && f.type === '1' && f.status === '0'
+        f =>
+          ObjectId(f.pid).equals(og._id) && f.type === '1' && f.status === '0'
       );
       );
       if (is_split) return og;
       if (is_split) return og;
       // 没有拆分,可以直接更换
       // 没有拆分,可以直接更换
@@ -716,8 +717,11 @@ class OrderService extends CrudService {
     assert(client, '缺少客户信息');
     assert(client, '缺少客户信息');
     assert(owner, '缺少创建人信息');
     assert(owner, '缺少创建人信息');
     const bill = await this.ctx.model.Bill.create({ ids, client, owner });
     const bill = await this.ctx.model.Bill.create({ ids, client, owner });
-    if (!bill) throw new BusinessError(ErrorCode.DATABASE_FAULT, '结算单创建失败');
-    const res = await this.model.updateMany({ _id: ids.map(i => ObjectId(i)) }, { is_js: true });
+    if (!bill) { throw new BusinessError(ErrorCode.DATABASE_FAULT, '结算单创建失败'); }
+    const res = await this.model.updateMany(
+      { _id: ids.map(i => ObjectId(i)) },
+      { is_js: true }
+    );
     try {
     try {
       for (const id of ids) {
       for (const id of ids) {
         this.record(id, { method: 'js' });
         this.record(id, { method: 'js' });
@@ -726,6 +730,7 @@ class OrderService extends CrudService {
       this.logger.error(`订单id:${res.id}记录创建失败:${error.toString()}`);
       this.logger.error(`订单id:${res.id}记录创建失败:${error.toString()}`);
     }
     }
   }
   }
+
 }
 }
 
 
 module.exports = OrderService;
 module.exports = OrderService;

+ 88 - 8
app/service/order/transport.js

@@ -9,6 +9,7 @@ class TransportService extends CrudService {
     super(ctx, 'transport');
     super(ctx, 'transport');
     this.model = this.ctx.model.Transport;
     this.model = this.ctx.model.Transport;
     this.os = this.ctx.service.order.order;
     this.os = this.ctx.service.order.order;
+    this.util = this.ctx.service.util.util;
   }
   }
 
 
   async create(data) {
   async create(data) {
@@ -46,7 +47,10 @@ class TransportService extends CrudService {
     // 获取要核算的运输列表
     // 获取要核算的运输列表
     let tList = await this.model.find({ _id: ids.map(i => ObjectId(i)) });
     let tList = await this.model.find({ _id: ids.map(i => ObjectId(i)) });
     if (tList.length > 0) tList = JSON.parse(JSON.stringify(tList));
     if (tList.length > 0) tList = JSON.parse(JSON.stringify(tList));
-    const res = { inBill: await this.getInBill(tList), outBill: this.getOutBill(tList) };
+    const res = {
+      inBill: await this.getInBill(tList),
+      outBill: this.getOutBill(tList),
+    };
     // 计算合计
     // 计算合计
     const count = {};
     const count = {};
     // 收入采用税后实收
     // 收入采用税后实收
@@ -72,10 +76,17 @@ class TransportService extends CrudService {
   async carCalculate({ car_no, start, end }) {
   async carCalculate({ car_no, start, end }) {
     assert(start, '缺少时间范围-开始时间');
     assert(start, '缺少时间范围-开始时间');
     assert(end, '缺少时间范围-结束时间');
     assert(end, '缺少时间范围-结束时间');
-    let query = { 'send_time@start': start, 'send_time@end': end, 'supplier.car_no': car_no };
+    let query = {
+      'send_time@start': start,
+      'send_time@end': end,
+      'supplier.car_no': car_no,
+    };
     let tList = await this.query(query);
     let tList = await this.query(query);
     if (tList.length > 0) tList = JSON.parse(JSON.stringify(tList));
     if (tList.length > 0) tList = JSON.parse(JSON.stringify(tList));
-    const res = { inBill: await this.getInBill(tList), outBill: this.getOutBill(tList) };
+    const res = {
+      inBill: await this.getInBill(tList),
+      outBill: this.getOutBill(tList),
+    };
     // 日常维护部分
     // 日常维护部分
     query = { 'date@start': start, 'date@end': end };
     query = { 'date@start': start, 'date@end': end };
     const daily = await this.ctx.service.car.daily.query({ car_no, ...query });
     const daily = await this.ctx.service.car.daily.query({ car_no, ...query });
@@ -160,7 +171,6 @@ class TransportService extends CrudService {
     return res;
     return res;
   }
   }
 
 
-
   /**
   /**
    * 核算整理数据导出
    * 核算整理数据导出
    * @param {Object} Object { data } data:数据
    * @param {Object} Object { data } data:数据
@@ -198,7 +208,6 @@ class TransportService extends CrudService {
       return i;
       return i;
     });
     });
     const res = await this.ctx.service.util.excel.toExcel({ data: arr });
     const res = await this.ctx.service.util.excel.toExcel({ data: arr });
-    console.log(res);
     return res;
     return res;
   }
   }
 
 
@@ -266,7 +275,9 @@ class TransportService extends CrudService {
   getCount(data, letter) {
   getCount(data, letter) {
     const arr = [];
     const arr = [];
     const count = _.get(data, 'count');
     const count = _.get(data, 'count');
-    if (!count) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到合计数据'); }
+    if (!count) {
+      throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到合计数据');
+    }
     // 总计行
     // 总计行
     if (count.total || count.total === 0) {
     if (count.total || count.total === 0) {
       const countTotal = {
       const countTotal = {
@@ -308,7 +319,6 @@ class TransportService extends CrudService {
     return arr;
     return arr;
   }
   }
 
 
-
   /**
   /**
    * 获取核算标题
    * 获取核算标题
    * @param {String} letter 字母
    * @param {String} letter 字母
@@ -320,9 +330,79 @@ class TransportService extends CrudService {
       ecell: `${letter}4`,
       ecell: `${letter}4`,
       font: { size: 22, bold: true },
       font: { size: 22, bold: true },
       alignment: { vertical: 'middle' },
       alignment: { vertical: 'middle' },
-
     };
     };
     return headObj;
     return headObj;
   }
   }
+
+  /**
+   * 供应商结算查询
+   * @param {Object} query 查询条件
+   */
+  async supplierCalculate(query) {
+    query = this.util.turnDateRangeQuery(this.util.turnFilter(query));
+    console.log(query);
+    const sclient = _.get(query, 'supplier.client');
+    const scar = _.get(query, 'supplier.car_no');
+    if (sclient && scar) throw new BusinessError(ErrorCode.BUSINESS, '请只选择 供应商 或 第三方车号 方式之一进行查询');
+    if (!(sclient || scar)) throw new BusinessError(ErrorCode.BUSINESS, '请至少选择 供应商 或 第三方车号 方式之一进行查询');
+    let list;
+    list = await this.model.find({ ...query, is_js: false });
+    if (list.length > 0) list = JSON.parse(JSON.stringify(list));
+    // 供应商方式来的,列表中不显示过多的信息,主要是路线,订单号
+    const split_ids = _.flattenDeep(
+      list.map(i => i.goods.map(ii => ObjectId(ii.split_id)))
+    );
+    // 运输单列表的所有货物所在的订单列表
+    const orderList = await this.ctx.model.Order.find({ 'split._id': split_ids });
+    // 进行匹配,拼接订单号
+    list = list.map(i => {
+      const orders = orderList.filter(o => {
+        const { split } = o;
+        if (!(split && _.isArray(split))) return false;
+        const r = split.find(og => i.goods.find(tg => ObjectId(tg.split_id).equals(og._id)));
+        return r;
+      });
+      i.order_nos = orders.map(i => i.order_no).join(';');
+      i.t_sh_ys = i.goods.reduce((p, n) => p + (n.sh_ys || 0), 0);
+      i.t_sq_ys = i.goods.reduce((p, n) => p + (n.sq_ys || 0), 0);
+      i.taxes = _.get(_.head(i.goods), 'taxes', '1');
+      return i;
+    });
+
+    // 支出的钱有2部分: 货物(运费)+货物对应订单的该供应商的支出数据(该供应商的额外支出费用)
+    return list;
+  }
+
+  /**
+   * 选择指定的运输单,导出收入excel
+   * @param {Object} query 查询条件
+   * @property Array ids 订单id集合
+   */
+  async supplierExport(query) {}
+
+  /**
+   * 供应商结算
+   * @param {Object} {ids} 要结算的订单
+   */
+  async js({ ids, client, owner }) {
+    assert(ids, '缺少订单信息');
+    assert(client, '缺少客户信息');
+    assert(owner, '缺少创建人信息');
+    const bill = await this.ctx.model.Bill.create({ ids, client, owner });
+    if (!bill) {
+      throw new BusinessError(ErrorCode.DATABASE_FAULT, '结算单创建失败');
+    }
+    const res = await this.model.updateMany(
+      { _id: ids.map(i => ObjectId(i)) },
+      { is_js: true }
+    );
+    try {
+      for (const id of ids) {
+        this.record(id, { method: 'js' });
+      }
+    } catch (error) {
+      this.logger.error(`订单id:${res.id}记录创建失败:${error.toString()}`);
+    }
+  }
 }
 }
 module.exports = TransportService;
 module.exports = TransportService;