|
@@ -1,6 +1,7 @@
|
|
|
'use strict';
|
|
|
|
|
|
const _ = require('lodash');
|
|
|
+const assert = require('assert');
|
|
|
const { ObjectId } = require('mongoose').Types;
|
|
|
const { CrudService } = require('naf-framework-mongoose/lib/service');
|
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
@@ -9,6 +10,7 @@ class OrderService extends CrudService {
|
|
|
constructor(ctx) {
|
|
|
super(ctx, 'order');
|
|
|
this.model = this.ctx.model.Order;
|
|
|
+ this.util = this.ctx.service.util.util;
|
|
|
}
|
|
|
/**
|
|
|
* 新添订单
|
|
@@ -46,8 +48,15 @@ class OrderService extends CrudService {
|
|
|
if (sobj) {
|
|
|
// 查找其有没有被拆分
|
|
|
const r = split.find(f => ObjectId(f.pid).equals(sobj._id));
|
|
|
- if (r) throw new BusinessError(ErrorCode.DATA_INVALID, '无法删除已被拆分过的货物');
|
|
|
- const s_index = split.findIndex(f => ObjectId(f.pid).equals(og._id));
|
|
|
+ if (r) {
|
|
|
+ throw new BusinessError(
|
|
|
+ ErrorCode.DATA_INVALID,
|
|
|
+ '无法删除已被拆分过的货物'
|
|
|
+ );
|
|
|
+ }
|
|
|
+ const s_index = split.findIndex(f =>
|
|
|
+ ObjectId(f.pid).equals(og._id)
|
|
|
+ );
|
|
|
split.splice(s_index, 1);
|
|
|
}
|
|
|
return undefined;
|
|
@@ -73,12 +82,6 @@ class OrderService extends CrudService {
|
|
|
}
|
|
|
res.goods = oldGoods;
|
|
|
res.split = split;
|
|
|
- // console.group('oldGoods');
|
|
|
- // console.log(oldGoods);
|
|
|
- // console.groupEnd();
|
|
|
- // console.group('split');
|
|
|
- // console.log(split);
|
|
|
- // console.groupEnd();
|
|
|
await this.model.update({ _id: ObjectId(id) }, info);
|
|
|
await res.save();
|
|
|
this.copyToSplit(id);
|
|
@@ -91,14 +94,16 @@ class OrderService extends CrudService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 检查并处理有修改的货物:拆分就不允许修改了
|
|
|
+ * 检查并处理有修改的货物:拆分/发车就不允许修改了
|
|
|
* @param {Array} oldGoods 查出修改前的货物列表
|
|
|
* @param {Array} newGoods 修改后的货物列表
|
|
|
* @param {Array} split 原拆分货物列表,用来检查是否可以修改
|
|
|
*/
|
|
|
async goodsUpdate(oldGoods, newGoods, split) {
|
|
|
oldGoods = oldGoods.map(og => {
|
|
|
- const is_split = split.find(f => ObjectId(f.pid).equals(og._id) && f.type === '1');
|
|
|
+ const is_split = split.find(
|
|
|
+ f => ObjectId(f.pid).equals(og._id) && f.type === '1' && f.status === '0'
|
|
|
+ );
|
|
|
if (is_split) return og;
|
|
|
// 没有拆分,可以直接更换
|
|
|
const ng = newGoods.find(f => ObjectId(f._id).equals(og._id));
|
|
@@ -152,7 +157,6 @@ class OrderService extends CrudService {
|
|
|
}
|
|
|
}
|
|
|
await order.save();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -164,8 +168,15 @@ class OrderService extends CrudService {
|
|
|
async sendGoods(goods, no, time) {
|
|
|
for (const g of goods) {
|
|
|
const { split_id, name, number, weight, volume } = g;
|
|
|
- const order = await this.model.findOne({ 'split._id': ObjectId(split_id) });
|
|
|
- if (!order) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, `未找到该${name}所在的订单信息`);
|
|
|
+ const order = await this.model.findOne({
|
|
|
+ 'split._id': ObjectId(split_id),
|
|
|
+ });
|
|
|
+ if (!order) {
|
|
|
+ throw new BusinessError(
|
|
|
+ ErrorCode.DATA_NOT_EXIST,
|
|
|
+ `未找到该${name}所在的订单信息`
|
|
|
+ );
|
|
|
+ }
|
|
|
const obj = { split_id, name, number, weight, volume, no, time };
|
|
|
// 添加该货物的发货记录
|
|
|
order.send_time.push(obj);
|
|
@@ -195,8 +206,15 @@ class OrderService extends CrudService {
|
|
|
async arriveGoods(goods, no, time) {
|
|
|
for (const g of goods) {
|
|
|
const { split_id, name, number, weight, volume } = g;
|
|
|
- const order = await this.model.findOne({ 'split._id': ObjectId(split_id) });
|
|
|
- if (!order) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, `未找到该${name}所在的订单信息`);
|
|
|
+ const order = await this.model.findOne({
|
|
|
+ 'split._id': ObjectId(split_id),
|
|
|
+ });
|
|
|
+ if (!order) {
|
|
|
+ throw new BusinessError(
|
|
|
+ ErrorCode.DATA_NOT_EXIST,
|
|
|
+ `未找到该${name}所在的订单信息`
|
|
|
+ );
|
|
|
+ }
|
|
|
const obj = { split_id, name, number, weight, volume, no };
|
|
|
if (time) obj.time = time;
|
|
|
// 添加收货记录
|
|
@@ -237,8 +255,8 @@ class OrderService extends CrudService {
|
|
|
// 检查是否有到达的
|
|
|
const is_arrive = splitList.some(e => e.status === '-1');
|
|
|
const word = [];
|
|
|
- if (is_send)word.push('部分货物已发出');
|
|
|
- if (is_arrive)word.push('部分货物已到达');
|
|
|
+ if (is_send) word.push('部分货物已发出');
|
|
|
+ if (is_arrive) word.push('部分货物已到达');
|
|
|
if (word.length > 0) return word.join(';');
|
|
|
return '状态错误';
|
|
|
}
|
|
@@ -252,7 +270,11 @@ class OrderService extends CrudService {
|
|
|
const res = await this.model.update({ _id: ObjectId(_id) }, { principal });
|
|
|
try {
|
|
|
// 跨库查询该用户姓名
|
|
|
- const user = await this.ctx.service.httpUtil.cget(`/user/${principal}`, 'userAuth', { _tenant: 'zhwl' });
|
|
|
+ const user = await this.ctx.service.httpUtil.cget(
|
|
|
+ `/user/${principal}`,
|
|
|
+ 'userAuth',
|
|
|
+ { _tenant: 'zhwl' }
|
|
|
+ );
|
|
|
const message = `变更订单负责人 ${user.name}`;
|
|
|
this.record(_id, { method: 'principal', message });
|
|
|
} catch (error) {
|
|
@@ -261,7 +283,6 @@ class OrderService extends CrudService {
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* 订单操作记录
|
|
|
* @param {String} id 订单id
|
|
@@ -269,10 +290,17 @@ class OrderService extends CrudService {
|
|
|
*/
|
|
|
async record(id, { method, message }) {
|
|
|
const order = await this.model.findById(id);
|
|
|
- if (!order) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, `未找到订单,传入id:${id}`);
|
|
|
+ if (!order) {
|
|
|
+ throw new BusinessError(
|
|
|
+ ErrorCode.DATA_NOT_EXIST,
|
|
|
+ `未找到订单,传入id:${id}`
|
|
|
+ );
|
|
|
+ }
|
|
|
const { authorization } = this.ctx.request.header;
|
|
|
let user = decodeURI(authorization);
|
|
|
- if (!user) { throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到操作人'); }
|
|
|
+ if (!user) {
|
|
|
+ throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到操作人');
|
|
|
+ }
|
|
|
user = JSON.parse(user);
|
|
|
const { id: userid, name: username } = user;
|
|
|
const record = { opera: username, operaid: userid };
|
|
@@ -282,10 +310,422 @@ class OrderService extends CrudService {
|
|
|
else if (method === 'in') record.message = `${username}修改收入`;
|
|
|
else if (method === 'out') record.message = `${username}修改支出`;
|
|
|
else if (method === 'split') record.message = `${username}拆分货物`;
|
|
|
- else if (method === 'send' || method === 'arrive' || method === 'principal') record.message = `${message}`;
|
|
|
+ else if (
|
|
|
+ method === 'send' ||
|
|
|
+ method === 'arrive' ||
|
|
|
+ method === 'principal'
|
|
|
+ ) {
|
|
|
+ record.message = `${message}`;
|
|
|
+ } else if (method === 'js') record.message = `${username}结算订单`;
|
|
|
order.record.push(record);
|
|
|
await order.save();
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 客户结算查询
|
|
|
+ * @param {Object} query 查询条件
|
|
|
+ */
|
|
|
+ async clientCalculate(query) {
|
|
|
+ query = this.util.turnDateRangeQuery(this.util.turnFilter(query));
|
|
|
+ let list = await this.model
|
|
|
+ .$where('this.split.every(i=>i.status=== "-1")')
|
|
|
+ .find({ ...query, is_js: false })
|
|
|
+ .populate([
|
|
|
+ {
|
|
|
+ path: 'client',
|
|
|
+ model: 'Client',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'item',
|
|
|
+ model: 'Item',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'route',
|
|
|
+ model: 'Route',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'treaty',
|
|
|
+ model: 'Treaty',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'goods',
|
|
|
+ populate: [
|
|
|
+ {
|
|
|
+ path: 'mode',
|
|
|
+ model: 'Mode',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ]);
|
|
|
+ if (list.length > 0) list = JSON.parse(JSON.stringify(list));
|
|
|
+ // 组织数据
|
|
|
+ list = this.toResetOrder(list);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 整合订单信息
|
|
|
+ * @param {Array} list 订单列表
|
|
|
+ */
|
|
|
+ toResetOrder(list) {
|
|
|
+ list = list.map(i => {
|
|
|
+ i = this.orderReset(i);
|
|
|
+ i = this.orderIn(i);
|
|
|
+ return i;
|
|
|
+ });
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将客户相关信息转换
|
|
|
+ * @param {Object} order 订单信息
|
|
|
+ */
|
|
|
+ orderReset(order) {
|
|
|
+ order = JSON.parse(JSON.stringify(order));
|
|
|
+ const { client, item, route, treaty } = order;
|
|
|
+ if (client && _.isObject(client)) {
|
|
|
+ order.client_id = _.get(client, '_id');
|
|
|
+ order.client = _.get(client, 'name');
|
|
|
+ }
|
|
|
+ if (item && _.isObject(item)) {
|
|
|
+ order.item_id = _.get(item, '_id');
|
|
|
+ order.item = _.get(item, 'name');
|
|
|
+ }
|
|
|
+ if (route && _.isObject(route)) {
|
|
|
+ order.route_id = _.get(route, '_id');
|
|
|
+ order.route = _.get(route, 'name');
|
|
|
+ }
|
|
|
+ if (treaty && _.isObject(treaty)) {
|
|
|
+ order.treaty_id = _.get(treaty, '_id');
|
|
|
+ order.treaty = _.get(treaty, 'number');
|
|
|
+ }
|
|
|
+ return order;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算收入总价
|
|
|
+ * @param {Object} order 订单信息
|
|
|
+ */
|
|
|
+ orderIn(order) {
|
|
|
+ const { goods, in_bill } = order;
|
|
|
+ const gi = goods.reduce((p, n) => p + (n.sh_ss || 0), 0);
|
|
|
+ const bi = in_bill.reduce((p, n) => p + (n.sh_ss || 0), 0);
|
|
|
+ const sh_ss = gi + bi;
|
|
|
+ order.sh_ss = sh_ss;
|
|
|
+ return order;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 选择指定的订单,导出收入excel
|
|
|
+ * @param {Object} query 查询条件
|
|
|
+ * @property Array ids 订单id集合
|
|
|
+ */
|
|
|
+ async clientExport(query) {
|
|
|
+ const { ids } = query;
|
|
|
+ console.log(ids);
|
|
|
+ let list = await this.model
|
|
|
+ .find({ _id: ids.map(i => ObjectId(i)) })
|
|
|
+ .populate([
|
|
|
+ {
|
|
|
+ path: 'client',
|
|
|
+ model: 'Client',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'item',
|
|
|
+ model: 'Item',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'route',
|
|
|
+ model: 'Route',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'treaty',
|
|
|
+ model: 'Treaty',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'goods',
|
|
|
+ populate: [
|
|
|
+ {
|
|
|
+ path: 'mode',
|
|
|
+ model: 'Mode',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ]);
|
|
|
+ if (list.length > 0) list = JSON.parse(JSON.stringify(list));
|
|
|
+ // 处理信息
|
|
|
+ const arr = [];
|
|
|
+ // 获取头
|
|
|
+ const { header, otherList } = this.getHeader(list);
|
|
|
+ // 已经被占用的行数
|
|
|
+ let ouse = 1;
|
|
|
+ for (const order of list) {
|
|
|
+ // 计算这个订单的开始行和结束行位置
|
|
|
+ const os = ouse + 1; // 订单开始行数
|
|
|
+ const { goods } = order;
|
|
|
+ // 整理共同部分数据
|
|
|
+ const edata = this.getPublicExcelData(order, os);
|
|
|
+ // 再处理额外项的头数据
|
|
|
+ const odata = this.getOtherInExcelData(order, os, otherList);
|
|
|
+ arr.push({ ...edata, ...odata });
|
|
|
+ // 处理完后,更新被占用行数
|
|
|
+ ouse = ouse + goods.length;
|
|
|
+ }
|
|
|
+ // 处理头
|
|
|
+ let pkeys = Object.keys(header);
|
|
|
+ pkeys = pkeys.map(i => {
|
|
|
+ const reg = /[^a-zA-Z]/i;
|
|
|
+ const res = i.replace(reg, '');
|
|
|
+ return res;
|
|
|
+ });
|
|
|
+ let lastData = this.toResetExcelData(pkeys, arr);
|
|
|
+ lastData.push({ content: header });
|
|
|
+ const alignment = { vertical: 'middle', horizontal: 'center' };
|
|
|
+ lastData = lastData.map(i => ({ ...i, alignment }));
|
|
|
+ const res = await this.ctx.service.util.excel.toExcel({ data: lastData });
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 合并处理数据
|
|
|
+ * @param {Array} keys 列字母数组
|
|
|
+ * @param {Array} data excel数据(不含头)
|
|
|
+ */
|
|
|
+ toResetExcelData(keys, data) {
|
|
|
+ const reg = /[^a-zA-Z]/i;
|
|
|
+ const arr = [];
|
|
|
+ const clear = [];
|
|
|
+ for (const key of keys) {
|
|
|
+ // 找出每列的内容
|
|
|
+ const col = data.map(i => {
|
|
|
+ const lks = Object.keys(i);
|
|
|
+ const r = lks.find(f => {
|
|
|
+ const rr = f.replace(reg, '');
|
|
|
+ return rr === key;
|
|
|
+ });
|
|
|
+ if (r) return { key: r, value: _.get(i, r) };
|
|
|
+ });
|
|
|
+ // 同一列满足以下条件可以合并:
|
|
|
+ // 1,值相同;2数字连贯;3指定范围内
|
|
|
+ // 先查范围
|
|
|
+ const head = _.head(col);
|
|
|
+ if (!head) continue;
|
|
|
+ const letter = head.key.replace(reg, '');
|
|
|
+ const r3 = this.mergeRange(letter);
|
|
|
+ if (!r3) continue;
|
|
|
+ const l = col.length;
|
|
|
+ const ul = _.uniqBy(col, 'value').length;
|
|
|
+ if (ul === l) continue;
|
|
|
+ // 可以合并,需要重新拼个Object,{scell,ecell,content}
|
|
|
+ // scell 是上面head的key, ecell是last获取key,content,随意拿出一个就行
|
|
|
+ const obj = {};
|
|
|
+ obj.scell = _.get(head, 'key');
|
|
|
+ obj.ecell = _.get(_.last(col), 'key');
|
|
|
+ obj.content = _.get(head, 'value');
|
|
|
+ clear.push(_.get(head, 'key'), _.get(_.last(col), 'key'));
|
|
|
+ arr.push(obj);
|
|
|
+ }
|
|
|
+ // 将scell和ecell都干掉
|
|
|
+ data = data.map(i => {
|
|
|
+ i = _.omitBy(i, (value, key) => {
|
|
|
+ return clear.includes(key);
|
|
|
+ });
|
|
|
+ return { content: i };
|
|
|
+ });
|
|
|
+ data = [ ...data, ...arr ];
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询该列是否可以合并
|
|
|
+ * @param {String} letter 字母
|
|
|
+ */
|
|
|
+ mergeRange(letter) {
|
|
|
+ const arr = [ 'U', 'Z', 'AA', 'AB', 'AC' ];
|
|
|
+ return !arr.includes(letter);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 整理成excel数据(先整理固定部分,即不包含额外收入部分)
|
|
|
+ * @param {Object} order 订单信息
|
|
|
+ * @param {Number} os 该订单开始行数
|
|
|
+ */
|
|
|
+ getPublicExcelData(order, os) {
|
|
|
+ // 如果不需要合并,那一个订单也就是1个object,如果需要合并,那就是多个object,
|
|
|
+ // 即使是多个object也没问题,因为控制的是每个单元格,所以出问题一定是单元格没弄明白
|
|
|
+ // 除了货物,方式外,其他的固定项都需要判断是否需要合并单元格,所以先处理货物,方式
|
|
|
+ const arr = [];
|
|
|
+ const content = {};
|
|
|
+ const { goods } = order;
|
|
|
+ // 货物,方式部分
|
|
|
+ for (let i = 0; i < goods.length; i++) {
|
|
|
+ const good = goods[i];
|
|
|
+ const {
|
|
|
+ mode,
|
|
|
+ name,
|
|
|
+ costname = '运费',
|
|
|
+ sq_ys,
|
|
|
+ sq_ss,
|
|
|
+ sh_ys,
|
|
|
+ sh_ss,
|
|
|
+ } = good;
|
|
|
+ const { name: modeName, price, is_lf, send_type, computed_type } = mode;
|
|
|
+ content[`S${i + os}`] = modeName;
|
|
|
+ content[`T${i + os}`] = price;
|
|
|
+ content[`U${i + os}`] = name;
|
|
|
+ content[`V${i + os}`] = costname;
|
|
|
+ content[`W${i + os}`] = is_lf ? '是' : '否';
|
|
|
+ content[`X${i + os}`] = send_type;
|
|
|
+ content[`Y${i + os}`] = computed_type;
|
|
|
+ content[`Z${i + os}`] = sq_ys;
|
|
|
+ content[`AA${i + os}`] = sq_ss;
|
|
|
+ content[`AB${i + os}`] = sh_ys;
|
|
|
+ content[`AC${i + os}`] = sh_ss;
|
|
|
+ // 订单
|
|
|
+ content[`A${os}`] = _.get(order, 'order_no');
|
|
|
+ content[`AD${os}`] = _.get(order, 'remark');
|
|
|
+ // 客户部分一定合并,不在这里处理
|
|
|
+ content[`B${os}`] = _.get(order.client, 'name');
|
|
|
+ content[`C${os}`] = _.get(order.client, 'address');
|
|
|
+ content[`D${os}`] = _.get(order.client, 'legal');
|
|
|
+ content[`E${os}`] = _.get(order.client, 'mobile');
|
|
|
+ content[`F${os}`] = _.get(order.client, 'taxes_no');
|
|
|
+ content[`G${os}`] = _.get(order.client, 'account_bank');
|
|
|
+ content[`H${os}`] = _.get(order.client, 'account');
|
|
|
+ // 合同部分
|
|
|
+ content[`I${os}`] = _.get(order.treaty, 'number');
|
|
|
+ content[`J${os}`] = _.get(order.treaty, 'jf');
|
|
|
+ content[`K${os}`] = _.get(order.treaty, 'yf');
|
|
|
+ content[`L${os}`] = _.get(order.treaty, 'period');
|
|
|
+ content[`M${os}`] = _.get(order.treaty, 'settle_up');
|
|
|
+ // 项目
|
|
|
+ content[`N${os}`] = _.get(order.item, 'name');
|
|
|
+ content[`O${os}`] = _.get(order.item, 'taxes');
|
|
|
+ // 线路
|
|
|
+ content[`P${os}`] = _.get(order.route, 'name');
|
|
|
+ content[`Q${os}`] = _.get(order.route, 's_p');
|
|
|
+ content[`R${os}`] = _.get(order.route, 'e_p');
|
|
|
+ }
|
|
|
+ arr.push(content);
|
|
|
+ return content;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充额外收入项
|
|
|
+ * @param {Object} order 订单信息
|
|
|
+ * @param {Number} os 该订单开始行数
|
|
|
+ * @param {Array} inList 额外收入项
|
|
|
+ */
|
|
|
+ getOtherInExcelData(order, os, inList) {
|
|
|
+ const obj = {};
|
|
|
+ const { in_bill, goods } = order;
|
|
|
+ for (let i = 0; i < goods.length; i++) {
|
|
|
+ for (const oin of inList) {
|
|
|
+ const { key, item, value } = oin;
|
|
|
+ const r = in_bill.find(f => f.item === item);
|
|
|
+ // console.log(key, item, value, r);
|
|
|
+ if (r) {
|
|
|
+ obj[`${key}${i + os}`] = _.get(r, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return obj;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取导出的订单头
|
|
|
+ * @param {Array} list 选择的订单
|
|
|
+ */
|
|
|
+ getHeader(list) {
|
|
|
+ const obj = {};
|
|
|
+ // 同一客户下:B-H一定是合并的
|
|
|
+ // 同一订单下: A,AD1一定是合并的
|
|
|
+ // 订单部分
|
|
|
+ obj.A1 = '订单编号';
|
|
|
+ // 客户部分
|
|
|
+ obj.B1 = '客户名称';
|
|
|
+ obj.C1 = '地址';
|
|
|
+ obj.D1 = '法人';
|
|
|
+ obj.E1 = '联系电话';
|
|
|
+ obj.F1 = '税号';
|
|
|
+ obj.G1 = '开户行';
|
|
|
+ obj.H1 = '银行账号';
|
|
|
+ // 合同部分
|
|
|
+ obj.I1 = '合同编号';
|
|
|
+ obj.J1 = '甲方';
|
|
|
+ obj.K1 = '乙方';
|
|
|
+ obj.L1 = '合同周期';
|
|
|
+ obj.M1 = '结算方式';
|
|
|
+ // 项目部分
|
|
|
+ obj.N1 = '项目名称';
|
|
|
+ obj.O1 = '税率';
|
|
|
+ // 线路部分
|
|
|
+ obj.P1 = '线路名称';
|
|
|
+ obj.Q1 = '起始地';
|
|
|
+ obj.R1 = '目的地';
|
|
|
+ // 方式部分
|
|
|
+ obj.S1 = '方式名称';
|
|
|
+ obj.T1 = '价格';
|
|
|
+ // 货物部分
|
|
|
+ obj.U1 = '货物名称';
|
|
|
+ obj.V1 = '费用名称'; // 固定全是运费
|
|
|
+ // 方式部分
|
|
|
+ obj.W1 = '量份收费'; // 需要换成 是/否
|
|
|
+ obj.X1 = '发货方式';
|
|
|
+ obj.Y1 = '计费方式';
|
|
|
+ // 货物部分
|
|
|
+ obj.Z1 = '税前应收';
|
|
|
+ obj.AA1 = '税前实收';
|
|
|
+ obj.AB1 = '税后应收';
|
|
|
+ obj.AC1 = '税后实收';
|
|
|
+ // 订单部分
|
|
|
+ obj.AD1 = '订单备注';
|
|
|
+ // 处理额外收入头部
|
|
|
+ const in_item = _.uniqBy(list.map(i => i.in_bill).flat(), 'item');
|
|
|
+ const arr = [];
|
|
|
+ let i = 31;
|
|
|
+ for (const inInfo of in_item) {
|
|
|
+ const { item } = inInfo;
|
|
|
+ const fl = this.ctx.service.util.excel.numberToLetter(_.floor(i / 26));
|
|
|
+ // const sl = this.ctx.service.util.excel.numberToLetter(i % 26);
|
|
|
+ const sqyl = this.ctx.service.util.excel.numberToLetter(i % 26);
|
|
|
+ obj[`${fl}${sqyl}1`] = `${item}税前应收`;
|
|
|
+ arr.push({ key: `${fl}${sqyl}`, item, value: 'sq_ys' });
|
|
|
+ i++;
|
|
|
+ const sqsl = this.ctx.service.util.excel.numberToLetter(i % 26);
|
|
|
+ obj[`${fl}${sqsl}1`] = `${item}税前实收`;
|
|
|
+ arr.push({ key: `${fl}${sqsl}`, item, value: 'sq_ss' });
|
|
|
+ i++;
|
|
|
+ const shyl = this.ctx.service.util.excel.numberToLetter(i % 26);
|
|
|
+ obj[`${fl}${shyl}1`] = `${item}税后应收`;
|
|
|
+ arr.push({ key: `${fl}${shyl}`, item, value: 'sh_ys' });
|
|
|
+ i++;
|
|
|
+ const shsl = this.ctx.service.util.excel.numberToLetter(i % 26);
|
|
|
+ obj[`${fl}${shsl}1`] = `${item}税后实收`;
|
|
|
+ arr.push({ key: `${fl}${shsl}`, item, value: 'sh_ss' });
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return { header: obj, otherList: arr };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 订单结算
|
|
|
+ * @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 = OrderService;
|