flexbiz-server 12.5.34 → 12.5.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server/libs/ckvt.js +268 -12
- package/server/libs/tinhgiatb.js +739 -38
package/package.json
CHANGED
package/server/libs/ckvt.js
CHANGED
|
@@ -1,12 +1,268 @@
|
|
|
1
|
-
const dmvt=global.getModel(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
const dmvt = global.getModel('dmvt');
|
|
2
|
+
const sokho = global.getModel('sokho');
|
|
3
|
+
const hanmucton = global.getModel('hanmucton');
|
|
4
|
+
const ckvtcapphat = require('./ckvtcapphat');
|
|
5
|
+
const utils = require('./utils');
|
|
6
|
+
const async = require('async');
|
|
7
|
+
const _ = require("lodash");
|
|
8
|
+
const moment = require("moment");
|
|
9
|
+
module.exports = async (condition, fn)=> {
|
|
10
|
+
if(!fn) fn = ()=>{}
|
|
11
|
+
//kiem tra dieu kien
|
|
12
|
+
if (!condition.ngay && condition.den_ngay) {
|
|
13
|
+
condition.ngay = condition.den_ngay;
|
|
14
|
+
}
|
|
15
|
+
//lay dieu kien
|
|
16
|
+
////don vi co so
|
|
17
|
+
let ma_dvcs = condition.ma_dvcs;
|
|
18
|
+
/////kho
|
|
19
|
+
let ma_kho = condition.ma_kho;
|
|
20
|
+
////vat tu
|
|
21
|
+
let ma_vt = condition.ma_vt;
|
|
22
|
+
//
|
|
23
|
+
|
|
24
|
+
if(_.isString(ma_vt) && ma_vt.indexOf('[') >= 0 && ma_vt.indexOf(']') > 0 ){
|
|
25
|
+
try {
|
|
26
|
+
ma_vt = JSON.parse(ma_vt);
|
|
27
|
+
if(ma_vt.length==0) ma_vt = undefined;
|
|
28
|
+
|
|
29
|
+
} catch (e) {console.error(e)}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (ma_vt && _.isArray(ma_vt)) {
|
|
33
|
+
let _ma_vt = Object.assign(ma_vt);
|
|
34
|
+
ma_vt = {$in:_ma_vt};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let id_app = condition.id_app;
|
|
38
|
+
//Xác định sổ cân đối tk và điều kiện thời gian
|
|
39
|
+
let app = await global.getModel("app").findOne({_id:condition.id_app},{ngay_ks:1}).lean();
|
|
40
|
+
if(!app) return fn("Công ty không tồn tại");
|
|
41
|
+
let ngay = moment(condition.ngay).endOf("date").toDate();
|
|
42
|
+
//let ngay_ks = moment(app.ngay_ks).endOf("date").toDate();
|
|
43
|
+
//lấy ngày khoá sổ gần nhất
|
|
44
|
+
let ngay_ks = ((await global.getModel('cdvttheongay').findOne({id_app,den_ngay:{$lte:moment(ngay).startOf("date").toDate()}},{den_ngay:1}).sort({den_ngay:-1}).lean())||{}).den_ngay;
|
|
45
|
+
if(ngay_ks) ngay_ks = moment(ngay_ks).endOf("date").toDate();
|
|
46
|
+
//let ngay_tinh_dn = moment(condition.tu_ngay || condition.ngay).startOf("date").toDate();
|
|
47
|
+
let ngay_tinh_dn = condition.tu_ngay && new Date(condition.tu_ngay) < ngay? moment(condition.tu_ngay).endOf("date").toDate() : ngay;
|
|
48
|
+
let ngay_dn = moment(ngay_tinh_dn).startOf("year").toDate();
|
|
49
|
+
let nam;
|
|
50
|
+
let cdvt;
|
|
51
|
+
//if(!ngay_ks || (ngay_tinh_dn<ngay_chua_ks || ngay_dn>=ngay_chua_ks)){
|
|
52
|
+
if(!ngay_ks || ngay_ks<ngay_dn){
|
|
53
|
+
cdvt = global.getModel('cdvt');
|
|
54
|
+
nam = ngay_tinh_dn.getFullYear();
|
|
55
|
+
}else{
|
|
56
|
+
cdvt = global.getModel('cdvttheongay');
|
|
57
|
+
ngay_dn = moment(ngay_ks).startOf("date").add(1,"days").toDate();
|
|
58
|
+
}
|
|
59
|
+
//
|
|
60
|
+
return new Promise((resolve,reject)=>{
|
|
61
|
+
async.parallel({
|
|
62
|
+
//capphat
|
|
63
|
+
ckcapphat:(callback)=>{
|
|
64
|
+
setImmediate(()=>{
|
|
65
|
+
ckvtcapphat(condition,(e,rs)=>{
|
|
66
|
+
callback(e,rs);
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
},
|
|
71
|
+
//dau nam
|
|
72
|
+
dn: (callback) => {
|
|
73
|
+
setImmediate(()=>{
|
|
74
|
+
const c_dk = {id_app};
|
|
75
|
+
if(nam){
|
|
76
|
+
c_dk.nam = nam;
|
|
77
|
+
}else{
|
|
78
|
+
console.log("lay cdvt theo ngay khoa so",ngay_ks);
|
|
79
|
+
c_dk.den_ngay = ngay_ks;
|
|
80
|
+
}
|
|
81
|
+
if (ma_kho) {
|
|
82
|
+
c_dk.ma_kho = ma_kho;
|
|
83
|
+
}
|
|
84
|
+
if (ma_dvcs) {
|
|
85
|
+
c_dk.ma_dvcs = ma_dvcs;
|
|
86
|
+
}
|
|
87
|
+
if (ma_vt) {
|
|
88
|
+
c_dk.ma_vt = ma_vt;
|
|
89
|
+
}
|
|
90
|
+
if (condition.ma_lo) c_dk.ma_lo = condition.ma_lo;
|
|
91
|
+
if (condition.han_sd) c_dk.han_sd = condition.han_sd;
|
|
92
|
+
if (condition.ma_tt1) c_dk.ma_tt1 = condition.ma_tt1;
|
|
93
|
+
if (condition.ma_tt2) c_dk.ma_tt2 = condition.ma_tt2;
|
|
94
|
+
if (condition.ma_tt3) c_dk.ma_tt3 = condition.ma_tt3;
|
|
95
|
+
//Tìm
|
|
96
|
+
cdvt.find(c_dk).lean().then((results)=> {
|
|
97
|
+
callback(null, results);
|
|
98
|
+
}).catch(error=>{
|
|
99
|
+
callback(error);
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
},
|
|
103
|
+
//han muc ton
|
|
104
|
+
hanmucton: (callback) => {
|
|
105
|
+
setImmediate(()=>{
|
|
106
|
+
const c_dk = {
|
|
107
|
+
id_app: id_app
|
|
108
|
+
};
|
|
109
|
+
if (ma_kho) {
|
|
110
|
+
c_dk.ma_kho = ma_kho;
|
|
111
|
+
}
|
|
112
|
+
if (ma_dvcs) {
|
|
113
|
+
c_dk.ma_dvcs = ma_dvcs;
|
|
114
|
+
}
|
|
115
|
+
if (ma_vt) {
|
|
116
|
+
c_dk.ma_vt = ma_vt;
|
|
117
|
+
}
|
|
118
|
+
if (condition.ma_lo)
|
|
119
|
+
c_dk.ma_lo = condition.ma_lo;
|
|
120
|
+
if (condition.han_sd)
|
|
121
|
+
c_dk.han_sd = condition.han_sd;
|
|
122
|
+
|
|
123
|
+
if (condition.ma_tt1)
|
|
124
|
+
c_dk.ma_tt1 = condition.ma_tt1;
|
|
125
|
+
if (condition.ma_tt2)
|
|
126
|
+
c_dk.ma_tt2 = condition.ma_tt2;
|
|
127
|
+
if (condition.ma_tt3)
|
|
128
|
+
c_dk.ma_tt3 = condition.ma_tt3;
|
|
129
|
+
hanmucton.find(c_dk).lean().then((results)=> {
|
|
130
|
+
callback(null, results);
|
|
131
|
+
}).catch(error=>{
|
|
132
|
+
callback(error);
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
},
|
|
136
|
+
//phat sinh
|
|
137
|
+
ps: (callback) => {
|
|
138
|
+
setImmediate(()=>{
|
|
139
|
+
const query = {
|
|
140
|
+
id_app: id_app,
|
|
141
|
+
ngay_ct: {
|
|
142
|
+
$gte: ngay_dn,
|
|
143
|
+
$lte: ngay
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
if (ma_kho) {
|
|
147
|
+
query.ma_kho = ma_kho;
|
|
148
|
+
}
|
|
149
|
+
if (ma_dvcs) {
|
|
150
|
+
query.ma_dvcs = ma_dvcs;
|
|
151
|
+
}
|
|
152
|
+
if (ma_vt) {
|
|
153
|
+
query.ma_vt = ma_vt;
|
|
154
|
+
}
|
|
155
|
+
if (condition.ma_lo)
|
|
156
|
+
query.ma_lo = condition.ma_lo;
|
|
157
|
+
if (condition.han_sd)
|
|
158
|
+
query.han_sd = condition.han_sd;
|
|
159
|
+
|
|
160
|
+
if (condition.ma_tt1)
|
|
161
|
+
query.ma_tt1 = condition.ma_tt1;
|
|
162
|
+
if (condition.ma_tt2)
|
|
163
|
+
query.ma_tt2 = condition.ma_tt2;
|
|
164
|
+
if (condition.ma_tt3)
|
|
165
|
+
query.ma_tt3 = condition.ma_tt3;
|
|
166
|
+
|
|
167
|
+
if(condition.id_ct){
|
|
168
|
+
query.id_ct = {$ne:condition.id_ct}
|
|
169
|
+
}
|
|
170
|
+
//Tìm
|
|
171
|
+
sokho.find(query,{ma_vt:1,ma_kho:1,ma_tt1:1,ma_tt2:1,ma_tt3:1,sl_nhap:1,sl_xuat:1,sl_nhap_qd:1,sl_xuat_qd:1,tien_nhap:1,tien_xuat:1}).inTxn().lean().then((pss)=>{
|
|
172
|
+
//lay theo so luong quy doi
|
|
173
|
+
pss = pss.map(ps=>{
|
|
174
|
+
ps.sl_nhap = utils.round(ps.sl_nhap_qd,4);
|
|
175
|
+
ps.sl_xuat =utils.round(ps.sl_xuat_qd,4);
|
|
176
|
+
return ps;
|
|
177
|
+
})
|
|
178
|
+
callback(null, pss);
|
|
179
|
+
}).catch(error=>{
|
|
180
|
+
callback(error);
|
|
181
|
+
})
|
|
182
|
+
})
|
|
183
|
+
},
|
|
184
|
+
ton_kho_mac_dinh:(callback)=>{
|
|
185
|
+
setImmediate(()=>{
|
|
186
|
+
let query = {
|
|
187
|
+
id_app: id_app,
|
|
188
|
+
ton_kho_mac_dinh:{$nin:[null,undefined,0]}
|
|
189
|
+
};
|
|
190
|
+
if (ma_vt) {
|
|
191
|
+
query.ma_vt = ma_vt;
|
|
192
|
+
}
|
|
193
|
+
dmvt.find(query,{ma_vt:1,ton_kho_mac_dinh:1}).lean().then((rs)=>{
|
|
194
|
+
callback(null, rs);
|
|
195
|
+
}).catch(error=>{
|
|
196
|
+
console.error(error);
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
}, (error, results) => {
|
|
202
|
+
if (error) {
|
|
203
|
+
fn(error);
|
|
204
|
+
return reject(new Error(error));
|
|
205
|
+
}
|
|
206
|
+
let ckcapphat = results.ckcapphat.map(c=>{
|
|
207
|
+
c.ton00_capphat = c.ton00;
|
|
208
|
+
c.du00_capphat = c.du00;
|
|
209
|
+
|
|
210
|
+
c.ton00=0;
|
|
211
|
+
c.du00=0;
|
|
212
|
+
|
|
213
|
+
return c;
|
|
214
|
+
})
|
|
215
|
+
let data = results.dn.concat(results.ps).concat(ckcapphat).concat(results.ton_kho_mac_dinh).concat(results.hanmucton);
|
|
216
|
+
|
|
217
|
+
let groupBy = condition.groupBy || condition.groupby;
|
|
218
|
+
if (!groupBy) groupBy = ['ma_vt'];
|
|
219
|
+
if(_.isString(groupBy)){
|
|
220
|
+
if (groupBy.indexOf('[') >= 0) {
|
|
221
|
+
try {
|
|
222
|
+
groupBy = JSON.parse(groupBy);
|
|
223
|
+
} catch (e) {console.error(e)}
|
|
224
|
+
}else{
|
|
225
|
+
groupBy = groupBy.split(",");
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
let sumFields = [
|
|
230
|
+
'sl_nhap',
|
|
231
|
+
'sl_xuat',
|
|
232
|
+
'ton00',
|
|
233
|
+
'du00',
|
|
234
|
+
'ton00_capphat',
|
|
235
|
+
'du00_capphat',
|
|
236
|
+
'tien_nhap',
|
|
237
|
+
'tien_xuat',
|
|
238
|
+
'ton_kho_mac_dinh',
|
|
239
|
+
'ton_toi_thieu',
|
|
240
|
+
'ton_toi_da'
|
|
241
|
+
];
|
|
242
|
+
data.groupBy(groupBy, sumFields, (e, groups) => {
|
|
243
|
+
if (e){
|
|
244
|
+
fn(e);
|
|
245
|
+
return reject(new Error(e));
|
|
246
|
+
}
|
|
247
|
+
setImmediate(()=>{
|
|
248
|
+
for (let r of groups) {
|
|
249
|
+
r.ton00 = utils.round(r.ton00 + r.sl_nhap - r.sl_xuat, 4);
|
|
250
|
+
r.du00 = Math.roundBy(r.du00, 0) + Math.roundBy(r.tien_nhap, 0) - Math.roundBy(r.tien_xuat, 0);
|
|
251
|
+
r.sl_nhap = 0;
|
|
252
|
+
r.sl_xuat = 0;
|
|
253
|
+
r.tien_nhap = 0;
|
|
254
|
+
r.tien_xuat = 0;
|
|
255
|
+
r.ton = r.ton00 - (r.ton00_capphat>0?r.ton00_capphat:0);
|
|
256
|
+
r.du = r.du00 - (r.du00_capphat>0?r.du00_capphat:0);
|
|
257
|
+
|
|
258
|
+
}
|
|
259
|
+
fn(null, groups);
|
|
260
|
+
resolve(groups);
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
});
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
};
|
package/server/libs/tinhgiatb.js
CHANGED
|
@@ -1,38 +1,739 @@
|
|
|
1
|
-
const ckvt=require(
|
|
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
|
-
|
|
1
|
+
const ckvt = require('./ckvt');
|
|
2
|
+
const sokho = global.getModel('sokho');
|
|
3
|
+
const socai = global.getModel('socai');
|
|
4
|
+
const dmvt = global.getModel('dmvt');
|
|
5
|
+
const giatb = global.getModel('giatb');
|
|
6
|
+
const dmqddvt = global.getModel('dmqddvt');
|
|
7
|
+
const tinhgiatb1vt = require('./tinhgiatb1vt');
|
|
8
|
+
const async = require('async');
|
|
9
|
+
const _ = require("lodash");
|
|
10
|
+
const Controller = require('../controllers/controller');
|
|
11
|
+
const moment = require('moment');
|
|
12
|
+
const {getCurrentSession} = require("./sessionContext")
|
|
13
|
+
module.exports = async function(condition, fn) {
|
|
14
|
+
//kiem tra dieu kien
|
|
15
|
+
if (!condition || !condition.tu_thang || !condition.den_thang || !condition.nam || !condition.id_app) {
|
|
16
|
+
fn('Lỗi: Tính năng này yêu cầu các tham số: tu_thang,den_thang,nam,id_app');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
condition.tu_thang = Number(condition.tu_thang);
|
|
20
|
+
condition.den_thang = Number(condition.den_thang);
|
|
21
|
+
//lay dieu kien
|
|
22
|
+
let ma_kho = condition.ma_kho;
|
|
23
|
+
//let tu_ngay = new Date(Date.UTC(condition.nam, condition.tu_thang-1, 1,0,0,0));
|
|
24
|
+
//let den_ngay = new Date(Date.UTC(condition.nam, condition.den_thang,0,23,59, 0));
|
|
25
|
+
let tu_ngay = moment(new Date(condition.nam, condition.tu_thang - 1, 15)).startOf("month").toDate();
|
|
26
|
+
let den_ngay = moment(new Date(condition.nam, condition.den_thang-1, 15)).endOf("month").toDate();
|
|
27
|
+
|
|
28
|
+
//console.log(tu_ngay,den_ngay)
|
|
29
|
+
let id_app = condition.id_app;
|
|
30
|
+
const app = await global.getModel("app").findOne({_id:id_app},{options:1}).lean();
|
|
31
|
+
if(!app) return fn("Công ty này không tồn tại");
|
|
32
|
+
const f_tien = (app.options||{}).f_tien || 0;
|
|
33
|
+
let query_dmvt = {
|
|
34
|
+
id_app: id_app,
|
|
35
|
+
gia_xuat: '1'
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
if (condition.ma_nvt)
|
|
39
|
+
query_dmvt.ma_nvt = condition.ma_nvt
|
|
40
|
+
if (condition.ma_ncc)
|
|
41
|
+
query_dmvt.ma_ncc = condition.ma_ncc
|
|
42
|
+
|
|
43
|
+
if (condition.ma_vt) {
|
|
44
|
+
query_dmvt.ma_vt = condition.ma_vt;
|
|
45
|
+
}
|
|
46
|
+
console.log(`🔥 [tinhgiatb] tính giá trung bình, kho:${condition.ma_kho}, sessionID=${getCurrentSession()?._debugId}`);
|
|
47
|
+
dmvt.find(query_dmvt).lean().then(function(dmvts) {
|
|
48
|
+
async.mapLimit(dmvts,100, function(vt, callback) {
|
|
49
|
+
setImmediate(()=>{
|
|
50
|
+
let query = {
|
|
51
|
+
id_app: id_app,
|
|
52
|
+
tu_ngay: tu_ngay,
|
|
53
|
+
den_ngay: den_ngay,
|
|
54
|
+
ma_vt: vt.ma_vt,
|
|
55
|
+
ma_kho: ma_kho
|
|
56
|
+
};
|
|
57
|
+
tinhgiatb1vt(query, function(error, gia) {
|
|
58
|
+
if (error){
|
|
59
|
+
console.error("[tinhgiatb] Không thể tính giá trung bình cho vật tư",query.ma_vt,error);
|
|
60
|
+
return callback(error);
|
|
61
|
+
}
|
|
62
|
+
//console.log("tinh gia trung binh",{tu_ngay,den_ngay,ma_kho,ma_vt:vt.ma_vt,gia:gia.gia});
|
|
63
|
+
gia.id_app = id_app;
|
|
64
|
+
gia.ma_kho = ma_kho;
|
|
65
|
+
gia.status = true;
|
|
66
|
+
|
|
67
|
+
callback(null, gia);
|
|
68
|
+
});
|
|
69
|
+
})
|
|
70
|
+
}, function(error, bang_gia) {
|
|
71
|
+
if (error){
|
|
72
|
+
return fn(error);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//cap nhat gia vao so sach
|
|
76
|
+
let thangs = [];
|
|
77
|
+
for (let t = condition.tu_thang; t <= condition.den_thang; t++) {
|
|
78
|
+
thangs.push(t);
|
|
79
|
+
}
|
|
80
|
+
async.map(thangs, async function(t) {
|
|
81
|
+
//xoá giá cũ
|
|
82
|
+
let query_delete = {
|
|
83
|
+
id_app: id_app,
|
|
84
|
+
ma_vt: {$in:bang_gia.map(g=>g.ma_vt)},
|
|
85
|
+
nam:condition.nam,
|
|
86
|
+
thang:t
|
|
87
|
+
};
|
|
88
|
+
if (ma_kho) {
|
|
89
|
+
query_delete.ma_kho = ma_kho;
|
|
90
|
+
}
|
|
91
|
+
await giatb.deleteMany(query_delete);
|
|
92
|
+
//Lưu giá mới
|
|
93
|
+
let gias = bang_gia.map(gia=>{
|
|
94
|
+
return {...gia,thang:t,nam:condition.nam}
|
|
95
|
+
})
|
|
96
|
+
let result = await giatb.create(gias);
|
|
97
|
+
return result;
|
|
98
|
+
}, function(error) {
|
|
99
|
+
if(error) return fn(error);
|
|
100
|
+
//Lấy các chứng từ cần cập nhật sổ sách
|
|
101
|
+
console.log(`[tinhgiatb] Lấy các chứng từ cần cập nhật sổ sách ma_kho=${condition.ma_kho}`)
|
|
102
|
+
let vouchers_x = {};
|
|
103
|
+
let vouchers_n = {};
|
|
104
|
+
let ma_vts = bang_gia.map(v=>v.ma_vt);
|
|
105
|
+
async.parallel({
|
|
106
|
+
xuat: function(callback) {
|
|
107
|
+
setImmediate(async ()=>{
|
|
108
|
+
//get phieu xuat
|
|
109
|
+
let query_sokho_x = {
|
|
110
|
+
id_app: id_app,
|
|
111
|
+
ngay_ct: {
|
|
112
|
+
$gte: tu_ngay,
|
|
113
|
+
$lte: den_ngay
|
|
114
|
+
},
|
|
115
|
+
nxt: 2,
|
|
116
|
+
ma_vt: {
|
|
117
|
+
$in: ma_vts
|
|
118
|
+
},
|
|
119
|
+
px_gia_dd: false
|
|
120
|
+
};
|
|
121
|
+
if (ma_kho) {
|
|
122
|
+
query_sokho_x.ma_kho = ma_kho;
|
|
123
|
+
}
|
|
124
|
+
const sks = await sokho.find(query_sokho_x).lean();
|
|
125
|
+
//console.log("cap nhat gia cho phieu xuat kho",query_sokho_x,sks);
|
|
126
|
+
if (sks.length === 0) {
|
|
127
|
+
return callback(null, vouchers_x);
|
|
128
|
+
}
|
|
129
|
+
//Tìm chứng từ gốc
|
|
130
|
+
const cac_ma_ct = [...new Set(sks.map(sk=>sk.ma_ct))];
|
|
131
|
+
async.map(cac_ma_ct, async function(ma_ct) {
|
|
132
|
+
const ctrl = global.controllers[ma_ct.toUpperCase()];
|
|
133
|
+
let ct = ctrl?ctrl.getProperty("model"): mongoose.models[ma_ct.toLowerCase()];
|
|
134
|
+
if (ct) {
|
|
135
|
+
const ids = [...new Set(sks.filter(sk=>sk.ma_ct===ma_ct).map(sk=>sk.id_ct))];
|
|
136
|
+
const vouchers = await ct.find({_id:{$in:ids}});
|
|
137
|
+
for(let v of vouchers){
|
|
138
|
+
vouchers_x[v._id.toString()] = v;
|
|
139
|
+
}
|
|
140
|
+
//xoá sổ sách nếu chứng từ không còn tồn tại
|
|
141
|
+
for(let id_ct of ids.filter(id=>!vouchers_x[id])){
|
|
142
|
+
console.log('⚠️ [tinhgiatb] Khong tim thay phieu xuat. chuong trinh da xoa phieu nay khoi sổ sách, id_ct=',id_ct,"ma_ct=",ma_ct);
|
|
143
|
+
await sokho.deleteMany({id_ct});
|
|
144
|
+
await socai.deleteMany({id_ct});
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
} else {
|
|
148
|
+
console.log(`⚠️ [tinhgiatb] Khong tim model cho ma_ct=`,ma_ct);
|
|
149
|
+
return null
|
|
150
|
+
}
|
|
151
|
+
}, function(error) {
|
|
152
|
+
if (error) {
|
|
153
|
+
console.error('❌ [tinhgiatb] co loi lay phieu xuat',error);
|
|
154
|
+
return callback(error);
|
|
155
|
+
}
|
|
156
|
+
callback(null, vouchers_x);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
/*//groupby lại chỉ lấy mỗi chứng từ một dòng
|
|
161
|
+
sks = await sks.asyncGroupBy(["id_ct","so_ct","ma_ct","ngay_ct"],[]);
|
|
162
|
+
//Tìm chứng từ gốc
|
|
163
|
+
async.mapLimit(sks,50, function(sk, callback) {
|
|
164
|
+
let voucher = vouchers_x[sk.id_ct];
|
|
165
|
+
const ctrl = global.controllers[sk.ma_ct.toUpperCase()];
|
|
166
|
+
let ct = ctrl?ctrl.getProperty("model"): mongoose.models[sk.ma_ct.toLowerCase()];
|
|
167
|
+
if (!voucher && ct) {
|
|
168
|
+
ct.findById(sk.id_ct, function(error, v) {
|
|
169
|
+
if (error) return callback(error);
|
|
170
|
+
if (v) {
|
|
171
|
+
voucher = v;
|
|
172
|
+
vouchers_x[sk.id_ct] = voucher;
|
|
173
|
+
} else {
|
|
174
|
+
sokho.deleteMany({id_ct:sk.id_ct.toString()},()=>{
|
|
175
|
+
console.log('[tinhgiatb] Khong tim thay phieu xuat. chuong trinh da xoa phieu nay khoi sokho',sk.id_ct,"ma_ct",sk.ma_ct,sk.so_ct,sk.ngay_ct);
|
|
176
|
+
})
|
|
177
|
+
socai.deleteMany({id_ct:sk.id_ct.toString()},()=>{
|
|
178
|
+
console.log('[tinhgiatb] Khong tim thay phieu xuat. chuong trinh da xoa phieu nay khoi socai',sk.id_ct,"ma_ct",sk.ma_ct,sk.so_ct,sk.ngay_ct);
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
callback();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
} else {
|
|
185
|
+
callback();
|
|
186
|
+
}
|
|
187
|
+
}, function(error) {
|
|
188
|
+
if (error) {
|
|
189
|
+
console.error('[tinhgiatb] co loi lay phieu xuat',error);
|
|
190
|
+
return callback(error);
|
|
191
|
+
}
|
|
192
|
+
callback(null, vouchers_x);
|
|
193
|
+
});*/
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
})
|
|
197
|
+
},
|
|
198
|
+
nhap: function(callback) {
|
|
199
|
+
setImmediate(async ()=>{
|
|
200
|
+
//get phieu nhap gia tb
|
|
201
|
+
let query_sokho_n = {
|
|
202
|
+
id_app: id_app,
|
|
203
|
+
ngay_ct: {
|
|
204
|
+
$gte: tu_ngay,
|
|
205
|
+
$lte: den_ngay
|
|
206
|
+
},
|
|
207
|
+
nxt: 1,
|
|
208
|
+
ma_vt: {
|
|
209
|
+
$in: ma_vts
|
|
210
|
+
},
|
|
211
|
+
pn_gia_tb: true,
|
|
212
|
+
ma_ct: {
|
|
213
|
+
$ne: 'PXC'
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
if(ma_kho) query_sokho_n.ma_kho = ma_kho;
|
|
217
|
+
const sks = await sokho.find(query_sokho_n).lean();
|
|
218
|
+
//console.log("cap nhat gia cho phieu nhap kho",query_sokho_n,sks);
|
|
219
|
+
if (sks.length === 0) {
|
|
220
|
+
return callback(null, vouchers_n);
|
|
221
|
+
}
|
|
222
|
+
//Lấy các chứng từ gốc
|
|
223
|
+
const ds_ma_ct = [...new Set(sks.map(sk=>sk.ma_ct))];
|
|
224
|
+
async.map(ds_ma_ct, async function(ma_ct) {
|
|
225
|
+
const ctrl = global.controllers[ma_ct.toUpperCase()];
|
|
226
|
+
let ct = ctrl?ctrl.getProperty("model"): mongoose.models[ma_ct.toLowerCase()];
|
|
227
|
+
if (ct) {
|
|
228
|
+
const ids = [...new Set(sks.filter(sk=>sk.ma_ct===ma_ct).map(sk=>sk.id_ct))];
|
|
229
|
+
const vouchers = await ct.find({_id:{$in:ids}});
|
|
230
|
+
for(let v of vouchers){
|
|
231
|
+
vouchers_n[v._id.toString()] = v;
|
|
232
|
+
}
|
|
233
|
+
//xoá sổ sách nếu chứng từ không còn tồn tại
|
|
234
|
+
for(let id_ct of ids.filter(id=>!vouchers_n[id])){
|
|
235
|
+
console.warn('⚠️ [tinhgiatb] Khong tim thay phieu nhập. chuong trinh da xoa phieu nay khoi sổ sách, id_ct=',id_ct,"ma_ct=",ma_ct);
|
|
236
|
+
await sokho.deleteMany({id_ct});
|
|
237
|
+
await socai.deleteMany({id_ct});
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
} else {
|
|
241
|
+
console.log(`⚠️ [tinhgiatb] Khong tim model cho ma_ct=`,ma_ct);
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
},(error)=>{
|
|
245
|
+
if (error) {
|
|
246
|
+
console.error('❌ [tinhgiatb] co loi lay phieu nhap',error);
|
|
247
|
+
return callback(error);
|
|
248
|
+
}
|
|
249
|
+
callback(null, vouchers_n);
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
/*//groupby lại chỉ lấy mỗi chứng từ một dòng
|
|
253
|
+
sks = await sks.asyncGroupBy(["id_ct","so_ct","ma_ct","ngay_ct"],[]);
|
|
254
|
+
//Tìm chứng từ gốc
|
|
255
|
+
async.mapLimit(sks,50, function(sk, callback) {
|
|
256
|
+
let voucher = vouchers_n[sk.id_ct];
|
|
257
|
+
const ctrl = global.controllers[sk.ma_ct.toUpperCase()];
|
|
258
|
+
let ct = ctrl?ctrl.getProperty("model"): mongoose.models[sk.ma_ct.toLowerCase()];
|
|
259
|
+
if (!voucher && ct) {
|
|
260
|
+
ct.findById(sk.id_ct, function(error, v) {
|
|
261
|
+
if (error)
|
|
262
|
+
return callback(error);
|
|
263
|
+
if (v) {
|
|
264
|
+
voucher = v;
|
|
265
|
+
vouchers_n[sk.id_ct] = voucher;
|
|
266
|
+
} else {
|
|
267
|
+
sokho.deleteMany({id_ct:sk.id_ct.toString()},(e,rs)=>{
|
|
268
|
+
console.log('[tinhgiatb] Khong tim thay phieu nhap. chuong trinh da xoa phieu nay khoi sokho',sk.id_ct,"ma_ct",sk.ma_ct,sk.so_ct,sk.ngay_ct,rs);
|
|
269
|
+
})
|
|
270
|
+
socai.deleteMany({id_ct:sk.id_ct.toString()},(e,rs)=>{
|
|
271
|
+
console.log('[tinhgiatb] Khong tim thay phieu nhap. chuong trinh da xoa phieu nay khoi socai',sk.id_ct,"ma_ct",sk.ma_ct,sk.so_ct,sk.ngay_ct,rs);
|
|
272
|
+
})
|
|
273
|
+
}
|
|
274
|
+
callback();
|
|
275
|
+
});
|
|
276
|
+
} else {
|
|
277
|
+
callback();
|
|
278
|
+
}
|
|
279
|
+
}, function(error) {
|
|
280
|
+
if (error) {
|
|
281
|
+
console.error('[tinhgiatb] co loi lay phieu nhap',error);
|
|
282
|
+
return callback(error);
|
|
283
|
+
}
|
|
284
|
+
callback(null, vouchers_n);
|
|
285
|
+
});
|
|
286
|
+
*/
|
|
287
|
+
|
|
288
|
+
})
|
|
289
|
+
},
|
|
290
|
+
nhap_dc:(callback)=>{
|
|
291
|
+
if(ma_kho){
|
|
292
|
+
let query_sokho_pnc = {
|
|
293
|
+
id_app: id_app,
|
|
294
|
+
ma_ct:"PNC",
|
|
295
|
+
ngay_ct: {
|
|
296
|
+
$gte: tu_ngay,
|
|
297
|
+
$lte: den_ngay
|
|
298
|
+
},
|
|
299
|
+
$or:[
|
|
300
|
+
{ma_kho_x:ma_kho},
|
|
301
|
+
{"details.ma_kho_x":ma_kho}
|
|
302
|
+
],
|
|
303
|
+
"details.px_gia_dd":false
|
|
304
|
+
};
|
|
305
|
+
//console.log("get pnc",query_sokho_pnc);
|
|
306
|
+
global.getModel("pnc").find(query_sokho_pnc).then(pnc=>{
|
|
307
|
+
//console.log("[tinhgiatb] Số phiếu nhập điều chuyển của kho",ma_kho,pnc.length);
|
|
308
|
+
pnc.forEach(p=>{
|
|
309
|
+
vouchers_n[p._id.toString()] = p;
|
|
310
|
+
})
|
|
311
|
+
callback();
|
|
312
|
+
}).catch(e=>{
|
|
313
|
+
console.error('[tinhgiatb] co loi lay phieu nhap dieu chuyen',e);
|
|
314
|
+
return callback(e);
|
|
315
|
+
})
|
|
316
|
+
}else{
|
|
317
|
+
callback();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}, function(error) {
|
|
321
|
+
if (error) return fn(error);
|
|
322
|
+
async.waterfall([
|
|
323
|
+
function(callback) {
|
|
324
|
+
//update gia xuat cho cac phieu xuat
|
|
325
|
+
console.log(`[tinhgiatb] Cập nhật giá xuất kho...`)
|
|
326
|
+
async.mapLimit(_.values(vouchers_x),100, (voucher_x, callback) => {
|
|
327
|
+
setImmediate(async ()=>{
|
|
328
|
+
try{
|
|
329
|
+
//thong thuong
|
|
330
|
+
const details = voucher_x.details.filter(d=>(!condition.ma_vt || condition.ma_vt ===d.ma_vt) && (
|
|
331
|
+
!d.px_gia_dd && (!ma_kho || ma_kho === (d.ma_kho || d.ma_kho_x || voucher_x.ma_kho || voucher_x.ma_kho_x))
|
|
332
|
+
));
|
|
333
|
+
await Promise.all(details.map(d => {
|
|
334
|
+
return (async ()=>{
|
|
335
|
+
let gia = _.find(bang_gia, (vt) => {
|
|
336
|
+
return d.ma_vt === vt.ma_vt;
|
|
337
|
+
})
|
|
338
|
+
//gia chuan
|
|
339
|
+
let gia_chuan = gia? gia.gia: 0;
|
|
340
|
+
//tinh he so quy doi
|
|
341
|
+
let he_so_qd=1;
|
|
342
|
+
let qd = await dmqddvt.findOne({id_app:voucher_x.id_app,ma_vt:d.ma_vt,ma_dvt:d.ma_dvt}).lean();
|
|
343
|
+
if(qd) he_so_qd = (qd.mau?(qd.tu/qd.mau): qd.ty_le_qd);
|
|
344
|
+
//cap nhat gia
|
|
345
|
+
d.gia_von = d.gia_von_nt = gia_chuan * he_so_qd;
|
|
346
|
+
d.tien_xuat = d.tien_xuat_nt = Math.roundBy(d.sl_xuat * d.gia_von, f_tien);
|
|
347
|
+
//console.log("update gia trung binh xuat hang",{ma_ct:voucher_x.ma_ct,so_ct:voucher_x.so_ct,ma_vt:d.ma_vt,gia_von:d.gia_von,gia_tb:gia_chuan,he_so_qd});
|
|
348
|
+
})();
|
|
349
|
+
}))
|
|
350
|
+
//doi doi hang
|
|
351
|
+
if(voucher_x.details_doi){
|
|
352
|
+
const details_doi = voucher_x.details_doi.filter(d=>(!condition.ma_vt || condition.ma_vt ===d.ma_vt) && (
|
|
353
|
+
!d.px_gia_dd && (!ma_kho || ma_kho === (d.ma_kho || voucher_x.ma_kho || voucher_x.ma_kho_x))
|
|
354
|
+
));
|
|
355
|
+
await Promise.all(details_doi.map(d => {
|
|
356
|
+
return (async ()=>{
|
|
357
|
+
let gia = _.find(bang_gia, (vt) => {
|
|
358
|
+
return d.ma_vt === vt.ma_vt;
|
|
359
|
+
})
|
|
360
|
+
//gia chuan
|
|
361
|
+
let gia_chuan = gia? gia.gia: 0;
|
|
362
|
+
//tinh he so quy doi
|
|
363
|
+
let he_so_qd=1;
|
|
364
|
+
let qd = await dmqddvt.findOne({id_app:voucher_x.id_app,ma_vt:d.ma_vt,ma_dvt:d.ma_dvt}).lean();
|
|
365
|
+
if(qd) he_so_qd = (qd.mau?(qd.tu/qd.mau): qd.ty_le_qd);
|
|
366
|
+
//cap nhat gia
|
|
367
|
+
d.gia_von = d.gia_von_nt = gia_chuan * he_so_qd;
|
|
368
|
+
d.tien_xuat = d.tien_xuat_nt = Math.roundBy(d.sl_xuat * d.gia_von, f_tien);
|
|
369
|
+
|
|
370
|
+
//console.log("update gia trung binh doi hang",{ma_ct:voucher_x.ma_ct,so_ct:voucher_x.so_ct,ma_vt:d.ma_vt,gia_von:d.gia_von,gia_tb:gia_chuan,he_so_qd});
|
|
371
|
+
})();
|
|
372
|
+
}))
|
|
373
|
+
}
|
|
374
|
+
//khuyen mai detail
|
|
375
|
+
await Promise.all(voucher_x.details.filter(d=>d.promotion && d.promotion.details_km).map(d=> {
|
|
376
|
+
return (async ()=>{
|
|
377
|
+
const details_km = d.promotion.details_km.filter(d=>(!condition.ma_vt || condition.ma_vt ===d.ma_vt)
|
|
378
|
+
&& !d.px_gia_dd && (!ma_kho || ma_kho === (d.ma_kho || voucher_x.ma_kho|| voucher_x.ma_kho_x))
|
|
379
|
+
);
|
|
380
|
+
await Promise.all(details_km.map(d => {
|
|
381
|
+
return (async ()=>{
|
|
382
|
+
let gia = _.find(bang_gia, (vt) => {
|
|
383
|
+
return d.ma_vt === vt.ma_vt;
|
|
384
|
+
})
|
|
385
|
+
//gia chuan
|
|
386
|
+
let gia_chuan = gia? gia.gia: 0;
|
|
387
|
+
//tinh he so quy doi
|
|
388
|
+
let he_so_qd=1;
|
|
389
|
+
let qd = await dmqddvt.findOne({id_app:voucher_x.id_app,ma_vt:d.ma_vt,ma_dvt:d.ma_dvt}).lean();
|
|
390
|
+
if(qd) he_so_qd = (qd.mau?(qd.tu/qd.mau): qd.ty_le_qd);
|
|
391
|
+
//update gia
|
|
392
|
+
d.gia_von = d.gia_von_nt = gia_chuan * he_so_qd;
|
|
393
|
+
d.tien_xuat = d.tien_xuat_nt = Math.roundBy((d.sl_xuat||d.sl_km||0) * d.gia_von, f_tien);
|
|
394
|
+
//console.log("update gia trung binh khuyen mai",{ma_ct:voucher_x.ma_ct,so_ct:voucher_x.so_ct,ma_vt:d.ma_vt,gia_von:d.gia_von,gia_tb:gia_chuan,he_so_qd});
|
|
395
|
+
})();
|
|
396
|
+
}))
|
|
397
|
+
})();
|
|
398
|
+
}))
|
|
399
|
+
//combo detail
|
|
400
|
+
await Promise.all(voucher_x.details.filter(d=>d.combo && d.combo.length>0 && !d.px_gia_dd).map(detail=> {
|
|
401
|
+
return (async ()=>{
|
|
402
|
+
const combo = detail.combo.filter(c=>(!condition.ma_vt || condition.ma_vt ===c.ma_vt)
|
|
403
|
+
&& (!ma_kho || ma_kho === (detail.ma_kho || detail.ma_kho_x || voucher_x.ma_kho|| voucher_x.ma_kho_x))
|
|
404
|
+
);
|
|
405
|
+
await Promise.all(combo.map(d => {
|
|
406
|
+
return (async ()=>{
|
|
407
|
+
let gia = _.find(bang_gia, (vt) => {
|
|
408
|
+
return d.ma_vt === vt.ma_vt;
|
|
409
|
+
})
|
|
410
|
+
//gia chuan
|
|
411
|
+
let gia_chuan = gia? gia.gia: 0;
|
|
412
|
+
//tinh he so quy doi
|
|
413
|
+
let he_so_qd=1;
|
|
414
|
+
let qd = await dmqddvt.findOne({id_app:voucher_x.id_app,ma_vt:d.ma_vt,ma_dvt:d.ma_dvt}).lean();
|
|
415
|
+
if(qd) he_so_qd = (qd.mau?(qd.tu/qd.mau): qd.ty_le_qd);
|
|
416
|
+
//update gia
|
|
417
|
+
d.gia_von = d.gia_von_nt = gia_chuan * he_so_qd;
|
|
418
|
+
d.tien_xuat = d.tien_xuat_nt = Math.roundBy((d.sl_xuat||0) * d.gia_von, f_tien);
|
|
419
|
+
|
|
420
|
+
/*if(voucher_x.ma_ct==="PXC"){
|
|
421
|
+
console.log(d);
|
|
422
|
+
}*/
|
|
423
|
+
//console.log("update gia trung binh khuyen mai",{ma_ct:voucher_x.ma_ct,so_ct:voucher_x.so_ct,ma_vt:d.ma_vt,gia_von:d.gia_von,gia_tb:gia_chuan,he_so_qd});
|
|
424
|
+
})();
|
|
425
|
+
}))
|
|
426
|
+
//detail.gia_von = detail.gia_von_nt = detail.combo.map(c=>(c.gia_von_nt||0)).reduce((a,b)=>a+b,0);
|
|
427
|
+
detail.tien_xuat = detail.tien_xuat_nt = detail.combo.map(c=>(c.tien_xuat_nt||0)).reduce((a,b)=>a+b,0);
|
|
428
|
+
detail.gia_von = detail.gia_von_nt = Math.roundBy(detail.sl_xuat?detail.tien_xuat_nt/detail.sl_xuat:0,f_tien);
|
|
429
|
+
})();
|
|
430
|
+
}))
|
|
431
|
+
//khuyen mai chung
|
|
432
|
+
if (voucher_x.promotion) {
|
|
433
|
+
const details_kmc = voucher_x.promotion.filter(d=>(!condition.ma_vt || condition.ma_vt ===d.ma_vt)
|
|
434
|
+
&& !d.px_gia_dd && (!ma_kho || ma_kho === (d.ma_kho || voucher_x.ma_kho|| voucher_x.ma_kho_x))
|
|
435
|
+
);
|
|
436
|
+
await Promise.all(details_kmc.map(d => {
|
|
437
|
+
return (async ()=>{
|
|
438
|
+
let gia = _.find(bang_gia, (vt) => {
|
|
439
|
+
return d.ma_vt === vt.ma_vt;
|
|
440
|
+
})
|
|
441
|
+
//gia chuan
|
|
442
|
+
let gia_chuan = gia? gia.gia: 0;
|
|
443
|
+
//tinh he so quy doi
|
|
444
|
+
let he_so_qd=1;
|
|
445
|
+
let qd = await dmqddvt.findOne({id_app:voucher_x.id_app,ma_vt:d.ma_vt,ma_dvt:d.ma_dvt}).lean();
|
|
446
|
+
if(qd) he_so_qd = (qd.mau?(qd.tu/qd.mau): qd.ty_le_qd);
|
|
447
|
+
//update gia
|
|
448
|
+
d.gia_von_nt = gia_chuan * he_so_qd;
|
|
449
|
+
d.gia_von = d.gia_von_nt;
|
|
450
|
+
d.tien_xuat_nt = Math.roundBy((d.sl_xuat||d.sl_km||0) * d.gia_von, f_tien);
|
|
451
|
+
d.tien_xuat = d.tien_xuat_nt;
|
|
452
|
+
|
|
453
|
+
//console.log("update gia trung binh khuyen mai chung",{ma_ct:voucher_x.ma_ct,so_ct:voucher_x.so_ct,ma_vt:d.ma_vt,gia_von:d.gia_von,gia_tb:gia_chuan,he_so_qd});
|
|
454
|
+
})();
|
|
455
|
+
}))
|
|
456
|
+
}
|
|
457
|
+
//save
|
|
458
|
+
let voucher_x_data = voucher_x.toObject();
|
|
459
|
+
//Lấy controller của chứng từ
|
|
460
|
+
const ctrl = global.controllers[voucher_x.ma_ct.toUpperCase()];
|
|
461
|
+
//Lấy model và update dữ liệu
|
|
462
|
+
let _model = ctrl?ctrl.getProperty("model"): mongoose.models[voucher_x.ma_ct.toLowerCase()];
|
|
463
|
+
await _model.updateOne({_id:voucher_x._id},voucher_x_data)
|
|
464
|
+
//post lai so sach
|
|
465
|
+
if (ctrl && ctrl.post) {
|
|
466
|
+
await (new Promise((resolve,reject)=>{
|
|
467
|
+
//console.log("posted book",{ma_ct:voucher_x.ma_ct,so_ct:voucher_x.so_ct,_id:voucher_x_data._id});
|
|
468
|
+
Controller.postData(voucher_x_data,ctrl, (e, rs) => {
|
|
469
|
+
if(e){
|
|
470
|
+
console.error("❌ [tinhgiatb] [postData] Lỗi:",e.message,voucher_x_data.so_ct,voucher_x_data.ma_ct);
|
|
471
|
+
return reject(e);
|
|
472
|
+
}
|
|
473
|
+
resolve(rs);
|
|
474
|
+
},{kiem_tra_han_muc_cong_no:false});
|
|
475
|
+
}));
|
|
476
|
+
}
|
|
477
|
+
callback(null,voucher_x);
|
|
478
|
+
}catch(e){
|
|
479
|
+
console.error("❌ [tinhgiatb] Lỗi cập nhật phiếu xuất:",voucher_x.ma_ct,voucher_x.so_ct,e.message||e.error||e);
|
|
480
|
+
callback(e);
|
|
481
|
+
}
|
|
482
|
+
})
|
|
483
|
+
}, (error) => {
|
|
484
|
+
callback(error,vouchers_x);
|
|
485
|
+
});
|
|
486
|
+
},
|
|
487
|
+
function(_vouchers_x,callback) {
|
|
488
|
+
//update gia nhap cho cac phieu nhap gia trung binh
|
|
489
|
+
console.log(`[tinhgiatb] Cập nhật giá nhập kho...`)
|
|
490
|
+
async.mapLimit(_.values(vouchers_n),100, (voucher_n, callback)=>{
|
|
491
|
+
setImmediate(async ()=>{
|
|
492
|
+
try{
|
|
493
|
+
const details_pnk = voucher_n.details.filter(d=>(!d.combo || d.combo.length==0) && (!condition.ma_vt || condition.ma_vt ===d.ma_vt)
|
|
494
|
+
&& (d.pn_gia_tb || (voucher_n.ma_ct ==="PNC" && !d.px_gia_dd) || (voucher_n.ma_ct ==="PKK" && !d.px_gia_dd))
|
|
495
|
+
&& (!ma_kho || ma_kho === d.ma_kho || ma_kho === d.ma_kho_x || ma_kho===voucher_n.ma_kho || ma_kho===voucher_n.ma_kho_n)
|
|
496
|
+
);
|
|
497
|
+
await Promise.all(details_pnk.map(d => {
|
|
498
|
+
return (async ()=>{
|
|
499
|
+
let gia = _.find(bang_gia, (vt) => {
|
|
500
|
+
return d.ma_vt === vt.ma_vt;
|
|
501
|
+
})
|
|
502
|
+
//gia chuan
|
|
503
|
+
let gia_chuan = gia? gia.gia: 0;
|
|
504
|
+
//tinh he so quy doi
|
|
505
|
+
let he_so_qd=1;
|
|
506
|
+
let qd = await dmqddvt.findOne({id_app:vouchers_n.id_app,ma_vt:d.ma_vt,ma_dvt:d.ma_dvt}).lean();
|
|
507
|
+
if(qd) he_so_qd = (qd.mau?(qd.tu/qd.mau): qd.ty_le_qd);
|
|
508
|
+
//update gia
|
|
509
|
+
d.gia_von_nt = gia_chuan * he_so_qd;
|
|
510
|
+
d.gia_von = d.gia_von_nt;
|
|
511
|
+
if(voucher_n.ma_ct ==="PNC" || voucher_n.ma_ct ==="PKK"){
|
|
512
|
+
d.tien_xuat_nt = Math.roundBy(d.sl_xuat * d.gia_von, f_tien);
|
|
513
|
+
d.tien_xuat = d.tien_xuat_nt;
|
|
514
|
+
}else{
|
|
515
|
+
d.tien_nhap_nt = Math.roundBy(d.sl_nhap * d.gia_von, f_tien);
|
|
516
|
+
d.tien_nhap = d.tien_nhap_nt;
|
|
517
|
+
}
|
|
518
|
+
//console.log("update gia trung binh cho phieu nhap gia tb",{ma_ct:vouchers_n.ma_ct,so_ct:vouchers_n.so_ct,ma_vt:d.ma_vt,gia_von:d.gia_von,gia_tb:gia_chuan,he_so_qd});
|
|
519
|
+
})();
|
|
520
|
+
}))
|
|
521
|
+
|
|
522
|
+
//combo detail
|
|
523
|
+
await Promise.all(voucher_n.details.filter(d=>d.combo && d.combo.length>0 && (d.pn_gia_tb || (voucher_n.ma_ct ==="PNC" && !d.px_gia_dd) || (voucher_n.ma_ct ==="PKK" && !d.px_gia_dd) ) ).map(detail=> {
|
|
524
|
+
return (async ()=>{
|
|
525
|
+
const combo = detail.combo.filter(c=>(!condition.ma_vt || condition.ma_vt ===c.ma_vt) && (!ma_kho || ma_kho === (detail.ma_kho || voucher_n.ma_kho|| voucher_n.ma_kho_n)));
|
|
526
|
+
await Promise.all(combo.map(d => {
|
|
527
|
+
return (async ()=>{
|
|
528
|
+
let gia = _.find(bang_gia, (vt) => {
|
|
529
|
+
return d.ma_vt === vt.ma_vt;
|
|
530
|
+
})
|
|
531
|
+
//gia chuan
|
|
532
|
+
let gia_chuan = gia? gia.gia: 0;
|
|
533
|
+
//tinh he so quy doi
|
|
534
|
+
let he_so_qd=1;
|
|
535
|
+
let qd = await dmqddvt.findOne({id_app:voucher_n.id_app,ma_vt:d.ma_vt,ma_dvt:d.ma_dvt}).lean();
|
|
536
|
+
if(qd) he_so_qd = (qd.mau?(qd.tu/qd.mau): qd.ty_le_qd);
|
|
537
|
+
//update gia
|
|
538
|
+
d.gia_von = d.gia_von_nt = gia_chuan * he_so_qd;
|
|
539
|
+
|
|
540
|
+
if(voucher_n.ma_ct ==="PNC" || voucher_n.ma_ct ==="PKK"){
|
|
541
|
+
d.tien_xuat_nt = Math.roundBy(d.sl_xuat * d.gia_von, f_tien);
|
|
542
|
+
d.tien_xuat = d.tien_xuat_nt;
|
|
543
|
+
}else{
|
|
544
|
+
d.tien_nhap_nt = Math.roundBy(d.sl_nhap * d.gia_von, f_tien);
|
|
545
|
+
d.tien_nhap = d.tien_nhap_nt;
|
|
546
|
+
}
|
|
547
|
+
//console.log("update gia trung binh cho san pham cua combo",{ma_ct:voucher_n.ma_ct,so_ct:voucher_n.so_ct,ma_vt:d.ma_vt,gia_von:d.gia_von,gia_tb:gia_chuan,he_so_qd});
|
|
548
|
+
})();
|
|
549
|
+
}))
|
|
550
|
+
//detail.gia_von = detail.gia_von_nt = detail.combo.map(c=>(c.gia_von_nt||0)).reduce((a,b)=>a+b,0);
|
|
551
|
+
if(voucher_n.ma_ct ==="PNC" || voucher_n.ma_ct ==="PKK"){
|
|
552
|
+
detail.tien_xuat = detail.tien_xuat_nt = detail.combo.map(c=>(c.tien_xuat_nt||0)).reduce((a,b)=>a+b,0);
|
|
553
|
+
detail.gia_von = detail.gia_von_nt = Math.roundBy(detail.sl_xuat?detail.tien_xuat_nt/detail.sl_xuat:0,f_tien);
|
|
554
|
+
}else{
|
|
555
|
+
detail.tien_nhap = detail.tien_nhap_nt = detail.combo.map(c=>(c.tien_nhap_nt||0)).reduce((a,b)=>a+b,0);
|
|
556
|
+
detail.gia_von = detail.gia_von_nt = Math.roundBy(detail.sl_nhap?detail.tien_nhap_nt/detail.sl_nhap:0,f_tien);
|
|
557
|
+
}
|
|
558
|
+
})();
|
|
559
|
+
}))
|
|
560
|
+
//
|
|
561
|
+
if (voucher_n.details_doi) { //xuat doi hang
|
|
562
|
+
const details_doi =voucher_n.details_doi.filter(d=>(!condition.ma_vt || condition.ma_vt ===d.ma_vt)
|
|
563
|
+
&& (d.pn_gia_tb && (!ma_kho || ma_kho === d.ma_kho))
|
|
564
|
+
);
|
|
565
|
+
await Promise.all(details_doi.map(d => {
|
|
566
|
+
return (async ()=>{
|
|
567
|
+
let gia = _.find(bang_gia, (vt) => {
|
|
568
|
+
return d.ma_vt === vt.ma_vt;
|
|
569
|
+
})
|
|
570
|
+
//gia chuan
|
|
571
|
+
let gia_chuan = gia? gia.gia: 0;
|
|
572
|
+
//tinh he so quy doi
|
|
573
|
+
let he_so_qd=1;
|
|
574
|
+
let qd = await dmqddvt.findOne({id_app:vouchers_n.id_app,ma_vt:d.ma_vt,ma_dvt:d.ma_dvt}).lean();
|
|
575
|
+
if(qd) he_so_qd = (qd.mau?(qd.tu/qd.mau): qd.ty_le_qd);
|
|
576
|
+
//update gia
|
|
577
|
+
d.gia_von_nt = gia_chuan * he_so_qd;
|
|
578
|
+
d.gia_von = d.gia_von_nt;
|
|
579
|
+
d.tien_xuat_nt = Math.roundBy(d.sl_xuat * d.gia_von, f_tien);
|
|
580
|
+
d.tien_xuat = d.tien_xuat_nt;
|
|
581
|
+
|
|
582
|
+
})();
|
|
583
|
+
}))
|
|
584
|
+
}
|
|
585
|
+
let voucher_n_data = voucher_n.toObject();
|
|
586
|
+
//let _model = mongoose.models[voucher_n_data.ma_ct.toLowerCase()];
|
|
587
|
+
const ctrl = global.controllers[voucher_n_data.ma_ct.toUpperCase()];
|
|
588
|
+
let _model = ctrl?ctrl.getProperty("model"): mongoose.models[voucher_n_data.ma_ct.toLowerCase()];
|
|
589
|
+
await _model.updateOne({_id:voucher_n_data._id},voucher_n_data);
|
|
590
|
+
//post lai so sach
|
|
591
|
+
if (ctrl && ctrl.post) {
|
|
592
|
+
await (new Promise((resolve,reject)=>{
|
|
593
|
+
//console.log("posted book",{ma_ct:vouchers_n.ma_ct,so_ct:vouchers_n.so_ct,_id:voucher_n_data._id});
|
|
594
|
+
Controller.postData(voucher_n_data,ctrl, function(e, rs) {
|
|
595
|
+
if(e){
|
|
596
|
+
console.error("❌ [tinhgiatb][postData] lỗi:",e.message,voucher_n_data.so_ct,voucher_n_data.ma_ct);
|
|
597
|
+
return reject(e);
|
|
598
|
+
}
|
|
599
|
+
resolve(rs);
|
|
600
|
+
},{kiem_tra_han_muc_cong_no:false});
|
|
601
|
+
}));
|
|
602
|
+
}
|
|
603
|
+
callback(null,voucher_n);
|
|
604
|
+
}catch(e){
|
|
605
|
+
console.error(`❌ [tinhgiatb] Lỗi cập nhất phiếu nhập`,voucher_n.ma_ct,voucher_n.so_ct,e.error||e.message||e);
|
|
606
|
+
callback(e);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
})
|
|
610
|
+
}, function(error) {
|
|
611
|
+
//console.log("Ket thuc cap nhat gia vao phieu nhap",new Date().getTime()/1000)
|
|
612
|
+
callback(error);
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
], function(e) {
|
|
616
|
+
if (e) return fn(e);
|
|
617
|
+
//danh gia chenh lech
|
|
618
|
+
//console.log("Danh gia chenh lech",new Date().getTime()/1000)
|
|
619
|
+
console.log(`[tinhgiatb] Đánh giá chênh lệch...`)
|
|
620
|
+
let query_ckvt = {
|
|
621
|
+
id_app: condition.id_app,
|
|
622
|
+
ngay: den_ngay,
|
|
623
|
+
chenh_lech: 1
|
|
624
|
+
};
|
|
625
|
+
if (condition.ma_vt) {
|
|
626
|
+
query_ckvt.ma_vt = condition.ma_vt;
|
|
627
|
+
}
|
|
628
|
+
if (condition.ma_kho) {
|
|
629
|
+
query_ckvt.ma_kho = condition.ma_kho;
|
|
630
|
+
}
|
|
631
|
+
ckvt(query_ckvt, (e, du_cuoi_ky)=> {
|
|
632
|
+
if (e) return fn(e);
|
|
633
|
+
//console.log(rs)
|
|
634
|
+
du_cuoi_ky = _.filter(du_cuoi_ky, (r)=> {
|
|
635
|
+
return r.du00 !== 0 && (r.ton00 == 0 || Math.abs(r.ton00) < 0.001);
|
|
636
|
+
});
|
|
637
|
+
vouchers_x = _.sortBy(_.values(vouchers_x), (v) => {
|
|
638
|
+
return -(new Date(v.ngay_ct)).getTime()
|
|
639
|
+
})
|
|
640
|
+
vouchers_n = _.sortBy(_.values(vouchers_n), (v) => {
|
|
641
|
+
return -(new Date(v.ngay_ct).getTime())
|
|
642
|
+
})
|
|
643
|
+
//console.log("vat tu chenh lech",rs);
|
|
644
|
+
let chung_tu_cap_nhat_chenh_lech ={};
|
|
645
|
+
async.map(du_cuoi_ky, (vt, callback)=> {
|
|
646
|
+
setImmediate(()=>{
|
|
647
|
+
let d_voucher = null;
|
|
648
|
+
//xuat
|
|
649
|
+
d_voucher = _.find(vouchers_x, (x) => {
|
|
650
|
+
return _.find(x.details, (vc) => {
|
|
651
|
+
if (vc.ma_vt == vt.ma_vt && !vc.px_gia_dd && (!ma_kho || ma_kho === vc.ma_kho || ma_kho ===x.ma_kho)) {
|
|
652
|
+
vc.tien_xuat_nt = vc.tien_xuat_nt + vt.du00;
|
|
653
|
+
vc.tien_xuat = Math.roundBy(vc.tien_xuat_nt, f_tien);
|
|
654
|
+
|
|
655
|
+
if(vc.sl_xuat) vc.gia_von_nt = vc.gia_von = Math.roundBy(vc.tien_xuat_nt/vc.sl_xuat,0);
|
|
656
|
+
|
|
657
|
+
return true;
|
|
658
|
+
} else {
|
|
659
|
+
return false;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
})
|
|
663
|
+
})
|
|
664
|
+
//nhap
|
|
665
|
+
if (!d_voucher) {
|
|
666
|
+
d_voucher = _.find(vouchers_n, (n) => {
|
|
667
|
+
return _.find(n.details, (vc) => {
|
|
668
|
+
if (vc.ma_vt == vt.ma_vt && !vc.pn_gia_tb && (!ma_kho || ma_kho === vc.ma_kho || ma_kho===n.ma_kho)) {
|
|
669
|
+
vc.tien_nhap_nt = vc.tien_nhap_nt - vt.du00;
|
|
670
|
+
vc.tien_nhap = Math.roundBy(vc.tien_nhap_nt, f_tien);
|
|
671
|
+
if(vc.sl_nhap) vc.gia_von_nt = vc.gia_von = Math.roundBy(vc.tien_nhap_nt/vc.sl_nhap,0);
|
|
672
|
+
return true;
|
|
673
|
+
} else {
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
})
|
|
678
|
+
})
|
|
679
|
+
}
|
|
680
|
+
if(d_voucher){
|
|
681
|
+
chung_tu_cap_nhat_chenh_lech[d_voucher._id.toString()] = d_voucher;
|
|
682
|
+
}
|
|
683
|
+
callback(null, d_voucher);
|
|
684
|
+
})
|
|
685
|
+
|
|
686
|
+
}, (e)=> {
|
|
687
|
+
if (e){
|
|
688
|
+
return fn(e);
|
|
689
|
+
}
|
|
690
|
+
//console.log("Cap nhat phieu chenh lech",new Date().getTime()/1000)
|
|
691
|
+
let _vouchers_chenh_lech = _.values(chung_tu_cap_nhat_chenh_lech);
|
|
692
|
+
//let _vouchers_chenh_lech = vouchers.filter(v=>v);
|
|
693
|
+
console.log(`[tinhgiatb] Cập nhật phiếu chênh lệch...`)
|
|
694
|
+
async.map(_vouchers_chenh_lech, (voucher, callback)=> {
|
|
695
|
+
setImmediate(async ()=>{
|
|
696
|
+
try{
|
|
697
|
+
let voucher_data = voucher.toObject();
|
|
698
|
+
//let _model = mongoose.models[voucher_data.ma_ct.toLowerCase()];
|
|
699
|
+
const ctrl = global.controllers[voucher_data.ma_ct.toUpperCase()];
|
|
700
|
+
let _model = ctrl?ctrl.getProperty("model"): mongoose.models[voucher_data.ma_ct.toLowerCase()];
|
|
701
|
+
await _model.updateOne({_id:voucher_data._id},voucher_data);
|
|
702
|
+
//post lai so sach
|
|
703
|
+
if (ctrl && ctrl.post) {
|
|
704
|
+
//console.log("repost voucher",voucher_data.ma_ct,voucher_data.so_ct,voucher_data._id,"...")
|
|
705
|
+
Controller.postData(voucher_data,ctrl, (e, rs)=> {
|
|
706
|
+
if(e) console.error("❌ [tinhgiatb] [postData] Lỗi:",e.message,voucher_data.so_ct,voucher_data.ma_ct);
|
|
707
|
+
callback(e, rs);
|
|
708
|
+
},{kiem_tra_han_muc_cong_no:false});
|
|
709
|
+
} else {
|
|
710
|
+
callback(null);
|
|
711
|
+
}
|
|
712
|
+
}catch(error){
|
|
713
|
+
return callback(error);
|
|
714
|
+
}
|
|
715
|
+
})
|
|
716
|
+
}, async (e)=> {
|
|
717
|
+
if (e) return fn(e);
|
|
718
|
+
bang_gia.joinModel2(id_app, dmvt, [
|
|
719
|
+
{
|
|
720
|
+
where:'ma_vt',
|
|
721
|
+
fields: 'ten_vt'
|
|
722
|
+
}
|
|
723
|
+
], ()=> {
|
|
724
|
+
fn(null, bang_gia);
|
|
725
|
+
});
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
});
|
|
729
|
+
});
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
});
|
|
733
|
+
});
|
|
734
|
+
});
|
|
735
|
+
}).catch(e=>{
|
|
736
|
+
fn(e);
|
|
737
|
+
})
|
|
738
|
+
|
|
739
|
+
};
|