flexbiz-server 12.4.10 → 12.4.11

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "flexbiz-server",
3
3
  "main": "./server/app.js",
4
4
  "description": "Flexible Server",
5
- "version": "12.4.10",
5
+ "version": "12.4.11",
6
6
  "author": {
7
7
  "name": "Van Truong Pham",
8
8
  "email": "invncur@gmail.com"
@@ -1,6 +1,5 @@
1
1
  const moment = require("moment");
2
2
  const {createSocaiTC} = require("../libs/utils")
3
- const {onAfterCommit,getCurrentSession,getCurrentStore} = require("../libs/sessionContext")
4
3
  const socaiSchema = new Schema({
5
4
  id_app: {type: String, required: true, maxlength: 1024},
6
5
  ma_dvcs: {type: String, required: true, maxlength: 1024},
@@ -202,10 +201,29 @@ const handleCreateSocaiTc = async ()=>{
202
201
  handleCreateSocaiTc();
203
202
  }
204
203
  }
204
+
205
+ const {onAfterCommit,getCurrentSession,getCurrentStore} = require("../libs/sessionContext")
206
+
207
+ socaiSchema.pre("save", function (next) {
208
+ const session = getCurrentSession();
209
+ const store = getCurrentStore();
210
+
211
+ if (session && store) {
212
+ // Lưu store vào map global
213
+ global.registerSessionStore(session, store);
214
+
215
+ // Gắn Session ID vào document TẠM THỜI (để post hook lấy)
216
+ // Dùng một trường không có trong Schema (non-schema property)
217
+ this.$__sessionKey = session._id || session._debugId;
218
+ }
219
+ next();
220
+ });
221
+
205
222
  socaiSchema.post("save",async function(doc){
223
+
206
224
  // Lấy session từ document
207
- const session = doc.$session() || getCurrentSession();
208
- const store = getCurrentStore();
225
+ const sessionKey = this.$__sessionKey; // Lấy khóa từ pre hook
226
+ const capturedStore = global.SESSION_STORE_MAP.get(sessionKey);
209
227
  // Định nghĩa hàm xử lý
210
228
  const handleSaveAfterCommit = async () => {
211
229
  //cập nhật ngày mua gần nhất của khác hàng
@@ -233,17 +251,15 @@ socaiSchema.post("save",async function(doc){
233
251
  }
234
252
  }
235
253
  };
236
-
237
- if (session) {
254
+ if (sessionKey && capturedStore) {
238
255
  // Nếu có session, thêm vào danh sách
239
- onAfterCommit(handleSaveAfterCommit, "Xử lý sự kiện sau khi lưu socai",session,store);
256
+ onAfterCommit(handleSaveAfterCommit, "Xử lý sự kiện sau khi lưu socai",capturedStore.session,capturedStore);
240
257
  } else {
241
- // Không có session (chạy ngoài transaction), chạy ngay
242
258
  try {
243
- await handleSaveAfterCommit();
244
- } catch (e) {
245
- console.error("❌ post save immediate error:", e);
246
- }
259
+ await handleSaveAfterCommit();
260
+ } catch (e) {
261
+ console.error("❌ post save immediate error:", e);
262
+ }
247
263
  }
248
264
  });
249
265
 
@@ -2,193 +2,193 @@ const moment = require("moment");
2
2
  const {createSokhoTC} = require("../libs/utils")
3
3
  const {onAfterCommit,getCurrentSession,getCurrentStore} = require("../libs/sessionContext")
4
4
  const sokhoSchema = new Schema({
5
- id_app: {type: String, required: true, maxlength: 1024},
6
- ma_dvcs: {type: String, required: true, maxlength: 1024},
7
- id_ct: {type: String, required: true, maxlength: 1024},
8
- ma_ct: {type: String, required: true, uppercase: true, maxlength: 32,trim:true},
9
- ma_gd: {type: String, default: '0', maxlength: 32,trim:true},
10
- ngay_ct: {type: Date, required: true},
11
- ngay_ct_full:Date,
12
- so_ct: {type: String, required: true, uppercase: true, maxlength: 32,trim:true},
13
- nxt: {type: Number, required: true},
14
- ma_nt: {type: String, default: 'VND', required: true, uppercase: true, maxlength: 32,trim:true},
15
- ty_gia: {type: Number, default: 1},
16
-
17
- ma_vt: {type: String, required: true, uppercase: true, maxlength: 1024,trim:true},
18
- ma_dvt: {type: String, maxlength: 32,trim:true},
19
- ma_kho: {type: String, required: true, uppercase: true, maxlength: 32,trim:true},
20
- ma_kho_n: {type: String},
21
- ma_kho_x: {type: String},
22
-
23
-
24
- sl_nhap: {type: Number, default: 0},
25
- sl_xuat: {type: Number, default: 0},
26
-
27
- he_so_qd: {type: Number, default: 1},
28
- sl_nhap_qd: {type: Number, default: 0},
29
- sl_xuat_qd: {type: Number, default: 0},
30
- pn_gia_tb: {type: Boolean, default: false},
31
- px_gia_dd: {type: Boolean, default: false},
32
-
33
- gia_von_nt: {type: Number, default: 0},
34
- gia_von: {type: Number, default: 0},
35
-
36
- tien_hang_nt: {type: Number, default: 0},
37
- tien_hang: {type: Number, default: 0},
38
-
39
-
40
- ty_le_ck: {type: Number, default: 0},
41
- tien_ck_nt: {type: Number, default: 0},
42
- tien_ck: {type: Number, default: 0},
43
- tien_phi_nt: {type: Number, default: 0},
44
- tien_phi: {type: Number, default: 0},
45
-
46
- tien_cp_nt: {type: Number, default: 0},
47
- tien_cp: {type: Number, default: 0},
48
-
49
- tien_hang_nk: {type: Number, default: 0},
50
- tien_hang_nk_nt: {type: Number, default: 0},
51
- thue_suat_nk: {type: Number, default: 0},
52
- tien_thue_nk: {type: Number, default: 0},
53
- tien_thue_nk_nt: {type: Number, default: 0},
54
-
55
- tien_nhap_nt: {type: Number, default: 0},
56
- tien_nhap: {type: Number, default: 0},
57
-
58
- tien_xuat: {type: Number, default: 0},
59
- tien_xuat_nt: {type: Number, default: 0},
60
-
61
- gia_ban: {type: Number, default: 0},
62
- gia_ban_nt: {type: Number, default: 0},
63
- tien: {type: Number, default: 0},
64
- tien_nt: {type: Number, default: 0},
65
-
66
- gia_ban_ct: {type: Number, default: 0},
67
- gia_ban_ct_nt: {type: Number, default: 0},
68
- tien_hang_ct_nt: {type: Number, default: 0},
69
- tien_hang_ct: {type: Number, default: 0},
70
- tien_ct: {type: Number, default: 0},
71
- tien_ct_nt: {type: Number, default: 0},
72
- thue_suat:{type: Number, default: 0},
73
- tien_thue_nt: {type: Number, default: 0},
74
- tien_thue: {type: Number, default: 0},
75
-
76
-
77
- tk_vt: {type: String, uppercase: true, maxlength: 32,trim:true},
78
- tk_gv: {type: String, uppercase: true, maxlength: 32,trim:true},
79
- tk_du: {type: String, uppercase: true, maxlength: 32,trim:true},
80
-
81
- tk_tl: {type: String, uppercase: true, maxlength: 32,trim:true},
82
- tk_dt: {type: String, uppercase: true, maxlength: 32,trim:true},
83
- tk_ck: {type: String, uppercase: true, maxlength: 32,trim:true},
84
-
85
- ma_kh: {type: String, uppercase: true, default: '', maxlength: 32,trim:true},
86
- dien_giai: {type: String, default: '', maxlength: 1024},
87
-
88
- ma_bp: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
89
- ma_phi: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
90
- ma_hd: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
91
- ma_dt: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
92
- ma_nv: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
93
-
94
-
95
- ma_lo: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
96
- han_sd: {type: Date},
97
- ma_vt2: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
98
- ma_tt1: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
99
- ma_tt2: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
100
- ma_tt3: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
101
-
102
-
103
-
104
-
105
- gio:Number,
106
- ngay:Number,
107
- thang:Number,
108
- quy:Number,
109
- nam:Number,
110
-
111
- ma_kenh:String,
112
- ma_td1:Schema.Types.Mixed,
113
- ma_td2:Schema.Types.Mixed,
114
- ma_td3:Schema.Types.Mixed,
115
- ma_td4:Schema.Types.Mixed,
116
- ma_td5:Schema.Types.Mixed,
117
- ma_td6:Schema.Types.Mixed,
118
- ma_td7:Schema.Types.Mixed,
119
- ma_td8:Schema.Types.Mixed,
120
- ma_td9:Schema.Types.Mixed,
121
-
122
- pt_thanh_toan:String,
123
- pt_thanh_toan2:String,
124
-
125
-
126
- tien_paymentByPoints:Number,
127
- tien_evoucher:Number,
128
-
129
- cashier:String,
130
-
131
- ma_sp: {type: String, default: '', uppercase: true, maxlength: 1024,trim:true},
132
- sl_sp:Number,
133
- ma_dvt_sp: {type: String, maxlength: 32,trim:true},
134
- ma_tt1_sp: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
135
- ma_tt2_sp: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
136
- ma_tt3_sp: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
137
- ma_cum_chi_tiet: {type: String, uppercase: true, default: '', maxlength: 32,trim:true},
138
- ten_cum_chi_tiet: {type: String, default: '', maxlength: 1024},
139
- ma_cong_doan: {type: String, uppercase: true, default: '', maxlength: 32,trim:true},
140
- id_lenhsx: {type: String, maxlength: 1024},
141
- id_dinhmucsx: {type: String, maxlength: 1024},
142
- id_lenhcapphat: {type: String, maxlength: 1024},
143
- id_cs: {type: String, maxlength: 1024},
144
- id_cs_ck: {type: String, maxlength: 1024},
145
-
146
- ma_ca: {type: String, uppercase: true, maxlength: 32,trim:true},
147
- trang_thai: {type: String, maxlength: 32},
148
- id_reason: {type: String, maxlength: 1024},
149
- exfields:Schema.Types.Mixed,
150
- exfields_detail:Schema.Types.Mixed,
151
-
152
- //thong tin hoa hong theo tung san pham
153
- user_nv:String,
154
- ty_le_hoa_hong:Number,
155
- tien_hoa_hong:Number,
156
- chuyen_ngay:Boolean,
157
- tk_no_hoa_hong:String,
158
- tk_co_hoa_hong:String,
159
-
160
- user_gt:String,
161
- ty_le_hoa_hong_gt:Number,
162
- tien_hoa_hong_gt:Number,
163
- chuyen_ngay_gt:Boolean,
164
- tk_no_hoa_hong_gt:String,
165
- tk_co_hoa_hong_gt:String,
166
-
167
- user_ctv:String,
168
- ty_le_hoa_hong_ctv:Number,
169
- tien_hoa_hong_ctv:Number,
170
- chuyen_ngay_ctv:Boolean,
171
- tk_cn_ctv:String,
172
- tk_cp_ctv:String,
173
-
174
- user_ql:String,
175
- ty_le_hoa_hong_ql:Number,
176
- tien_hoa_hong_ql:Number,
177
- chuyen_ngay_ql:Boolean,
178
- tk_no_hoa_hong_ql:String,
179
- tk_co_hoa_hong_ql:String,
180
-
181
-
182
-
183
- line:Number,
184
- status: {type: Boolean, default: true},
185
- date_created: {type: Date, default: Date.now},
186
- date_updated: {type: Date, default: Date.now},
187
- user_created: {type: String, default: ''},
188
- user_updated: {type: String, default: ''},
189
-
190
- id_client:String,//app dùng để nhập liệu
191
- listinfo_code:String,//form dùng để nhập liệu
5
+ id_app: {type: String, required: true, maxlength: 1024},
6
+ ma_dvcs: {type: String, required: true, maxlength: 1024},
7
+ id_ct: {type: String, required: true, maxlength: 1024},
8
+ ma_ct: {type: String, required: true, uppercase: true, maxlength: 32,trim:true},
9
+ ma_gd: {type: String, default: '0', maxlength: 32,trim:true},
10
+ ngay_ct: {type: Date, required: true},
11
+ ngay_ct_full:Date,
12
+ so_ct: {type: String, required: true, uppercase: true, maxlength: 32,trim:true},
13
+ nxt: {type: Number, required: true},
14
+ ma_nt: {type: String, default: 'VND', required: true, uppercase: true, maxlength: 32,trim:true},
15
+ ty_gia: {type: Number, default: 1},
16
+
17
+ ma_vt: {type: String, required: true, uppercase: true, maxlength: 1024,trim:true},
18
+ ma_dvt: {type: String, maxlength: 32,trim:true},
19
+ ma_kho: {type: String, required: true, uppercase: true, maxlength: 32,trim:true},
20
+ ma_kho_n: {type: String},
21
+ ma_kho_x: {type: String},
22
+
23
+
24
+ sl_nhap: {type: Number, default: 0},
25
+ sl_xuat: {type: Number, default: 0},
26
+
27
+ he_so_qd: {type: Number, default: 1},
28
+ sl_nhap_qd: {type: Number, default: 0},
29
+ sl_xuat_qd: {type: Number, default: 0},
30
+ pn_gia_tb: {type: Boolean, default: false},
31
+ px_gia_dd: {type: Boolean, default: false},
32
+
33
+ gia_von_nt: {type: Number, default: 0},
34
+ gia_von: {type: Number, default: 0},
35
+
36
+ tien_hang_nt: {type: Number, default: 0},
37
+ tien_hang: {type: Number, default: 0},
38
+
39
+
40
+ ty_le_ck: {type: Number, default: 0},
41
+ tien_ck_nt: {type: Number, default: 0},
42
+ tien_ck: {type: Number, default: 0},
43
+ tien_phi_nt: {type: Number, default: 0},
44
+ tien_phi: {type: Number, default: 0},
45
+
46
+ tien_cp_nt: {type: Number, default: 0},
47
+ tien_cp: {type: Number, default: 0},
48
+
49
+ tien_hang_nk: {type: Number, default: 0},
50
+ tien_hang_nk_nt: {type: Number, default: 0},
51
+ thue_suat_nk: {type: Number, default: 0},
52
+ tien_thue_nk: {type: Number, default: 0},
53
+ tien_thue_nk_nt: {type: Number, default: 0},
54
+
55
+ tien_nhap_nt: {type: Number, default: 0},
56
+ tien_nhap: {type: Number, default: 0},
57
+
58
+ tien_xuat: {type: Number, default: 0},
59
+ tien_xuat_nt: {type: Number, default: 0},
60
+
61
+ gia_ban: {type: Number, default: 0},
62
+ gia_ban_nt: {type: Number, default: 0},
63
+ tien: {type: Number, default: 0},
64
+ tien_nt: {type: Number, default: 0},
65
+
66
+ gia_ban_ct: {type: Number, default: 0},
67
+ gia_ban_ct_nt: {type: Number, default: 0},
68
+ tien_hang_ct_nt: {type: Number, default: 0},
69
+ tien_hang_ct: {type: Number, default: 0},
70
+ tien_ct: {type: Number, default: 0},
71
+ tien_ct_nt: {type: Number, default: 0},
72
+ thue_suat:{type: Number, default: 0},
73
+ tien_thue_nt: {type: Number, default: 0},
74
+ tien_thue: {type: Number, default: 0},
75
+
76
+
77
+ tk_vt: {type: String, uppercase: true, maxlength: 32,trim:true},
78
+ tk_gv: {type: String, uppercase: true, maxlength: 32,trim:true},
79
+ tk_du: {type: String, uppercase: true, maxlength: 32,trim:true},
80
+
81
+ tk_tl: {type: String, uppercase: true, maxlength: 32,trim:true},
82
+ tk_dt: {type: String, uppercase: true, maxlength: 32,trim:true},
83
+ tk_ck: {type: String, uppercase: true, maxlength: 32,trim:true},
84
+
85
+ ma_kh: {type: String, uppercase: true, default: '', maxlength: 32,trim:true},
86
+ dien_giai: {type: String, default: '', maxlength: 1024},
87
+
88
+ ma_bp: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
89
+ ma_phi: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
90
+ ma_hd: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
91
+ ma_dt: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
92
+ ma_nv: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
93
+
94
+
95
+ ma_lo: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
96
+ han_sd: {type: Date},
97
+ ma_vt2: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
98
+ ma_tt1: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
99
+ ma_tt2: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
100
+ ma_tt3: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
101
+
102
+
103
+
104
+
105
+ gio:Number,
106
+ ngay:Number,
107
+ thang:Number,
108
+ quy:Number,
109
+ nam:Number,
110
+
111
+ ma_kenh:String,
112
+ ma_td1:Schema.Types.Mixed,
113
+ ma_td2:Schema.Types.Mixed,
114
+ ma_td3:Schema.Types.Mixed,
115
+ ma_td4:Schema.Types.Mixed,
116
+ ma_td5:Schema.Types.Mixed,
117
+ ma_td6:Schema.Types.Mixed,
118
+ ma_td7:Schema.Types.Mixed,
119
+ ma_td8:Schema.Types.Mixed,
120
+ ma_td9:Schema.Types.Mixed,
121
+
122
+ pt_thanh_toan:String,
123
+ pt_thanh_toan2:String,
124
+
125
+
126
+ tien_paymentByPoints:Number,
127
+ tien_evoucher:Number,
128
+
129
+ cashier:String,
130
+
131
+ ma_sp: {type: String, default: '', uppercase: true, maxlength: 1024,trim:true},
132
+ sl_sp:Number,
133
+ ma_dvt_sp: {type: String, maxlength: 32,trim:true},
134
+ ma_tt1_sp: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
135
+ ma_tt2_sp: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
136
+ ma_tt3_sp: {type: String, default: '', uppercase: true, maxlength: 32,trim:true},
137
+ ma_cum_chi_tiet: {type: String, uppercase: true, default: '', maxlength: 32,trim:true},
138
+ ten_cum_chi_tiet: {type: String, default: '', maxlength: 1024},
139
+ ma_cong_doan: {type: String, uppercase: true, default: '', maxlength: 32,trim:true},
140
+ id_lenhsx: {type: String, maxlength: 1024},
141
+ id_dinhmucsx: {type: String, maxlength: 1024},
142
+ id_lenhcapphat: {type: String, maxlength: 1024},
143
+ id_cs: {type: String, maxlength: 1024},
144
+ id_cs_ck: {type: String, maxlength: 1024},
145
+
146
+ ma_ca: {type: String, uppercase: true, maxlength: 32,trim:true},
147
+ trang_thai: {type: String, maxlength: 32},
148
+ id_reason: {type: String, maxlength: 1024},
149
+ exfields:Schema.Types.Mixed,
150
+ exfields_detail:Schema.Types.Mixed,
151
+
152
+ //thong tin hoa hong theo tung san pham
153
+ user_nv:String,
154
+ ty_le_hoa_hong:Number,
155
+ tien_hoa_hong:Number,
156
+ chuyen_ngay:Boolean,
157
+ tk_no_hoa_hong:String,
158
+ tk_co_hoa_hong:String,
159
+
160
+ user_gt:String,
161
+ ty_le_hoa_hong_gt:Number,
162
+ tien_hoa_hong_gt:Number,
163
+ chuyen_ngay_gt:Boolean,
164
+ tk_no_hoa_hong_gt:String,
165
+ tk_co_hoa_hong_gt:String,
166
+
167
+ user_ctv:String,
168
+ ty_le_hoa_hong_ctv:Number,
169
+ tien_hoa_hong_ctv:Number,
170
+ chuyen_ngay_ctv:Boolean,
171
+ tk_cn_ctv:String,
172
+ tk_cp_ctv:String,
173
+
174
+ user_ql:String,
175
+ ty_le_hoa_hong_ql:Number,
176
+ tien_hoa_hong_ql:Number,
177
+ chuyen_ngay_ql:Boolean,
178
+ tk_no_hoa_hong_ql:String,
179
+ tk_co_hoa_hong_ql:String,
180
+
181
+
182
+
183
+ line:Number,
184
+ status: {type: Boolean, default: true},
185
+ date_created: {type: Date, default: Date.now},
186
+ date_updated: {type: Date, default: Date.now},
187
+ user_created: {type: String, default: ''},
188
+ user_updated: {type: String, default: ''},
189
+
190
+ id_client:String,//app dùng để nhập liệu
191
+ listinfo_code:String,//form dùng để nhập liệu
192
192
  },{ toJSON: { virtuals: true } });
193
193
 
194
194
 
@@ -213,158 +213,171 @@ sokhoSchema.pre("save",function(next){
213
213
  self.nam = ngay_ct.get("year");
214
214
  self.ngay_ct = ngay_ct.startOf("date").toDate();
215
215
  if(self.han_sd){
216
- let han_sd = moment(self.han_sd);
217
- self.han_sd = han_sd.endOf("date").toDate();
216
+ let han_sd = moment(self.han_sd);
217
+ self.han_sd = han_sd.endOf("date").toDate();
218
218
  }
219
219
  next();
220
220
  });
221
221
 
222
222
  if((global.configs||{}).createIndexes){
223
- sokhoSchema.index({id_app: 1});
224
- sokhoSchema.index({id_app:1,ngay_ct: -1});
225
- sokhoSchema.index({id_app:1,ma_dvcs: 1,ngay_ct: -1});
223
+ sokhoSchema.index({id_app: 1});
224
+ sokhoSchema.index({id_app:1,ngay_ct: -1});
225
+ sokhoSchema.index({id_app:1,ma_dvcs: 1,ngay_ct: -1});
226
226
 
227
- sokhoSchema.index({id_app:1,so_ct: 1,ngay_ct: -1});
228
- sokhoSchema.index({id_app:1,ma_ct: 1,ngay_ct: -1});
227
+ sokhoSchema.index({id_app:1,so_ct: 1,ngay_ct: -1});
228
+ sokhoSchema.index({id_app:1,ma_ct: 1,ngay_ct: -1});
229
229
 
230
230
 
231
- sokhoSchema.index({id_app:1,ma_vt: 1,ngay_ct: -1});
232
- sokhoSchema.index({id_app:1,ma_vt: 1,ma_lo: 1,ngay_ct: -1});
233
- sokhoSchema.index({id_app:1,ma_vt: 1,ma_lo: 1,han_sd: -1,ngay_ct: -1});
234
- sokhoSchema.index({id_app:1,ma_vt: 1,ma_tt1: 1,ngay_ct: -1});
235
- sokhoSchema.index({id_app:1,ma_vt: 1,ma_tt2: 1,ngay_ct: -1});
236
- sokhoSchema.index({id_app:1,ma_vt: 1,ma_tt3: 1,ngay_ct: -1});
231
+ sokhoSchema.index({id_app:1,ma_vt: 1,ngay_ct: -1});
232
+ sokhoSchema.index({id_app:1,ma_vt: 1,ma_lo: 1,ngay_ct: -1});
233
+ sokhoSchema.index({id_app:1,ma_vt: 1,ma_lo: 1,han_sd: -1,ngay_ct: -1});
234
+ sokhoSchema.index({id_app:1,ma_vt: 1,ma_tt1: 1,ngay_ct: -1});
235
+ sokhoSchema.index({id_app:1,ma_vt: 1,ma_tt2: 1,ngay_ct: -1});
236
+ sokhoSchema.index({id_app:1,ma_vt: 1,ma_tt3: 1,ngay_ct: -1});
237
237
 
238
- sokhoSchema.index({id_app:1,ma_kho: 1,ngay_ct: -1});
239
- sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ngay_ct: -1});
240
- sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_lo: 1,ngay_ct: -1});
241
- sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_lo: 1,han_sd: -1,ngay_ct: -1});
242
- sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_tt1: 1,ngay_ct: -1});
243
- sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_tt2: 1,ngay_ct: -1});
244
- sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_tt3: 1,ngay_ct: -1});
238
+ sokhoSchema.index({id_app:1,ma_kho: 1,ngay_ct: -1});
239
+ sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ngay_ct: -1});
240
+ sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_lo: 1,ngay_ct: -1});
241
+ sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_lo: 1,han_sd: -1,ngay_ct: -1});
242
+ sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_tt1: 1,ngay_ct: -1});
243
+ sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_tt2: 1,ngay_ct: -1});
244
+ sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,ma_tt3: 1,ngay_ct: -1});
245
245
 
246
- sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,nxt:1,pn_gia_tb:1,ngay_ct: -1});
247
- sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,nxt:1,px_gia_dd:1,ngay_ct: -1});
246
+ sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,nxt:1,pn_gia_tb:1,ngay_ct: -1});
247
+ sokhoSchema.index({id_app:1,ma_kho: 1,ma_vt: 1,nxt:1,px_gia_dd:1,ngay_ct: -1});
248
248
 
249
- sokhoSchema.index({id_app:1,ma_kho_n: 1,ngay_ct: -1});
250
- sokhoSchema.index({id_app:1,ma_kho_x: 1,ngay_ct: -1});
249
+ sokhoSchema.index({id_app:1,ma_kho_n: 1,ngay_ct: -1});
250
+ sokhoSchema.index({id_app:1,ma_kho_x: 1,ngay_ct: -1});
251
251
 
252
- sokhoSchema.index({id_app:1,ma_kh: 1,ngay_ct: -1});
253
- sokhoSchema.index({id_app:1,ma_bp: 1,ngay_ct: -1});
254
- sokhoSchema.index({id_app:1,ma_phi: 1,ngay_ct: -1});
255
- sokhoSchema.index({id_app:1,ma_nv: 1,ngay_ct: -1});
256
- sokhoSchema.index({id_app:1,ma_dt: 1,ngay_ct: -1});
257
- sokhoSchema.index({id_app:1,ma_kenh: 1,ngay_ct: -1});
252
+ sokhoSchema.index({id_app:1,ma_kh: 1,ngay_ct: -1});
253
+ sokhoSchema.index({id_app:1,ma_bp: 1,ngay_ct: -1});
254
+ sokhoSchema.index({id_app:1,ma_phi: 1,ngay_ct: -1});
255
+ sokhoSchema.index({id_app:1,ma_nv: 1,ngay_ct: -1});
256
+ sokhoSchema.index({id_app:1,ma_dt: 1,ngay_ct: -1});
257
+ sokhoSchema.index({id_app:1,ma_kenh: 1,ngay_ct: -1});
258
258
 
259
259
 
260
- sokhoSchema.index({id_app:1,ma_sp: 1,ngay_ct: -1});
261
- sokhoSchema.index({id_app:1,ma_sp: 1,ma_tt1_sp:1,ngay_ct: -1});
262
- sokhoSchema.index({id_app:1,ma_sp: 1,ma_tt2_sp:1,ngay_ct: -1});
263
- sokhoSchema.index({id_app:1,ma_sp: 1,ma_tt3_sp:1,ngay_ct: -1});
264
- sokhoSchema.index({id_app:1,ma_sp: 1,ma_cum_chi_tiet:1,ngay_ct: -1});
265
- sokhoSchema.index({id_app:1,ma_sp: 1,ma_cong_doan:1,ngay_ct: -1});
260
+ sokhoSchema.index({id_app:1,ma_sp: 1,ngay_ct: -1});
261
+ sokhoSchema.index({id_app:1,ma_sp: 1,ma_tt1_sp:1,ngay_ct: -1});
262
+ sokhoSchema.index({id_app:1,ma_sp: 1,ma_tt2_sp:1,ngay_ct: -1});
263
+ sokhoSchema.index({id_app:1,ma_sp: 1,ma_tt3_sp:1,ngay_ct: -1});
264
+ sokhoSchema.index({id_app:1,ma_sp: 1,ma_cum_chi_tiet:1,ngay_ct: -1});
265
+ sokhoSchema.index({id_app:1,ma_sp: 1,ma_cong_doan:1,ngay_ct: -1});
266
266
 
267
- sokhoSchema.index({id_app:1,ma_sp: 1,id_lenhsx: 1,ngay_ct: -1});
268
- sokhoSchema.index({id_app:1,ma_sp: 1,id_dinhmucsx: 1,ngay_ct: -1});
269
- sokhoSchema.index({id_app:1,ma_sp: 1,id_lenhcapphat: 1,ngay_ct: -1});
267
+ sokhoSchema.index({id_app:1,ma_sp: 1,id_lenhsx: 1,ngay_ct: -1});
268
+ sokhoSchema.index({id_app:1,ma_sp: 1,id_dinhmucsx: 1,ngay_ct: -1});
269
+ sokhoSchema.index({id_app:1,ma_sp: 1,id_lenhcapphat: 1,ngay_ct: -1});
270
270
 
271
271
 
272
- sokhoSchema.index({id_ct: 1});
273
- sokhoSchema.index({id_app:1,id_ct: 1});
274
- sokhoSchema.index({id_app:1,id_cs: 1});
275
- sokhoSchema.index({id_app:1,id_cs_ck: 1});
272
+ sokhoSchema.index({id_ct: 1});
273
+ sokhoSchema.index({id_app:1,id_ct: 1});
274
+ sokhoSchema.index({id_app:1,id_cs: 1});
275
+ sokhoSchema.index({id_app:1,id_cs_ck: 1});
276
276
 
277
-
277
+
278
278
 
279
- sokhoSchema.index({id_app:1,cashier: 1,ngay_ct: -1});
279
+ sokhoSchema.index({id_app:1,cashier: 1,ngay_ct: -1});
280
280
 
281
- sokhoSchema.index({id_app:1,nam: -1,quy: 1,thang: 1,ngay: 1,gio: 1});
281
+ sokhoSchema.index({id_app:1,nam: -1,quy: 1,thang: 1,ngay: 1,gio: 1});
282
282
 
283
283
 
284
- sokhoSchema.index({id_app:1,ma_td1: 1,ngay_ct: -1});
285
- sokhoSchema.index({id_app:1,ma_td2: 1,ngay_ct: -1});
286
- sokhoSchema.index({id_app:1,ma_td3: 1,ngay_ct: -1});
284
+ sokhoSchema.index({id_app:1,ma_td1: 1,ngay_ct: -1});
285
+ sokhoSchema.index({id_app:1,ma_td2: 1,ngay_ct: -1});
286
+ sokhoSchema.index({id_app:1,ma_td3: 1,ngay_ct: -1});
287
287
 
288
- sokhoSchema.index({id_app:1,user_nv: 1,ngay_ct: -1});
289
- sokhoSchema.index({id_app:1,user_ctv: 1,ngay_ct: -1});
290
- sokhoSchema.index({id_app:1,user_ql: 1,ngay_ct: -1});
291
- sokhoSchema.index({id_app:1,user_gt: 1,ngay_ct: -1});
288
+ sokhoSchema.index({id_app:1,user_nv: 1,ngay_ct: -1});
289
+ sokhoSchema.index({id_app:1,user_ctv: 1,ngay_ct: -1});
290
+ sokhoSchema.index({id_app:1,user_ql: 1,ngay_ct: -1});
291
+ sokhoSchema.index({id_app:1,user_gt: 1,ngay_ct: -1});
292
292
 
293
293
 
294
- sokhoSchema.index({id_app:1,date_created:-1});
294
+ sokhoSchema.index({id_app:1,date_created:-1});
295
295
  }
296
296
 
297
297
  let sokhoQueue = [];
298
298
  let sokhoIsHandling = false;
299
299
  const handleCreateSokhoTc = async ()=>{
300
- if(sokhoIsHandling) return;
301
- sokhoQueue = [...new Set(sokhoQueue)];
302
- let doc = sokhoQueue.shift();
303
- if(doc){
304
- try{
305
- sokhoIsHandling = true;
306
- doc = JSON.parse(doc);
307
- await createSokhoTC(doc.id_app,doc.ngay_ct,doc.ngay_ct);
308
- }catch(e){
309
- console.error("handleCreateSokhoTc",doc,e);
310
- }
311
- sokhoIsHandling = false;
312
- handleCreateSokhoTc();
313
- }
300
+ if(sokhoIsHandling) return;
301
+ sokhoQueue = [...new Set(sokhoQueue)];
302
+ let doc = sokhoQueue.shift();
303
+ if(doc){
304
+ try{
305
+ sokhoIsHandling = true;
306
+ doc = JSON.parse(doc);
307
+ await createSokhoTC(doc.id_app,doc.ngay_ct,doc.ngay_ct);
308
+ }catch(e){
309
+ console.error("handleCreateSokhoTc",doc,e);
310
+ }
311
+ sokhoIsHandling = false;
312
+ handleCreateSokhoTc();
313
+ }
314
314
  }
315
+
316
+ sokhoSchema.pre("save", function (next) {
317
+ const session = getCurrentSession();
318
+ const store = getCurrentStore();
319
+
320
+ if (session && store) {
321
+ // Lưu store vào map global
322
+ global.registerSessionStore(session, store);
323
+
324
+ // Gắn Session ID vào document TẠM THỜI (để post hook lấy)
325
+ // Dùng một trường không có trong Schema (non-schema property)
326
+ this.$__sessionKey = session._id || session._debugId;
327
+ }
328
+ next();
329
+ });
315
330
  sokhoSchema.post("save",async function(doc){
316
- // Lấy session từ document
317
- const session = doc.$session() || getCurrentSession();
318
- const store = getCurrentStore();
331
+ // Lấy session từ document
332
+ const sessionKey = this.$__sessionKey; // Lấy khóa từ pre hook
333
+ const capturedStore = global.SESSION_STORE_MAP.get(sessionKey);
319
334
 
320
335
  // Định nghĩa hàm xử lý
321
336
  const handleSaveAfterCommit = async () => {
322
337
  let key = JSON.stringify({id_app:doc.id_app,ngay_ct:doc.ngay_ct});
323
- if(!sokhoQueue.find(d=>d==key)){
324
- sokhoQueue.push(key);
325
- if(!sokhoIsHandling){
326
- handleCreateSokhoTc();
327
- }
328
- }
338
+ if(!sokhoQueue.find(d=>d==key)){
339
+ sokhoQueue.push(key);
340
+ if(!sokhoIsHandling){
341
+ handleCreateSokhoTc();
342
+ }
343
+ }
329
344
  };
330
345
 
331
- if (session) {
346
+ if (sessionKey && capturedStore) {
332
347
  // Nếu có session, thêm vào danh sách
333
- onAfterCommit(handleSaveAfterCommit, "Xử lý sự kiện sau khi lưu sokho",session,store);
348
+ onAfterCommit(handleSaveAfterCommit, "Xử lý sự kiện sau khi lưu sokho",capturedStore.session,capturedStore);
334
349
  } else {
335
- // Không có session (chạy ngoài transaction), chạy ngay
336
350
  try {
337
- await handleSaveAfterCommit();
338
- } catch (e) {
339
- console.error("❌ post save immediate error:", e);
340
- }
351
+ await handleSaveAfterCommit();
352
+ } catch (e) {
353
+ console.error("❌ post save immediate error:", e);
354
+ }
341
355
  }
342
356
 
343
-
344
357
  },"Xử lý sự kiện sau khi lưu sokho");
345
358
 
346
359
  sokhoSchema.pre('deleteMany', async function (next) {
347
360
 
348
- // 1. Lấy session từ Query object
361
+ // 1. Lấy session từ Query object
349
362
  const session = this.options.session || getCurrentSession();
350
- const store = getCurrentStore();
363
+ const store = getCurrentStore();
351
364
 
352
365
  // 2. Định nghĩa hàm xử lý
353
366
  const handleDeletionAfterCommit = async () => {
354
367
  let query = this.getQuery();
355
- let deletedDocs =(await global.getModel("sokho").find(query,{id_app:1,ngay_ct:1}).lean()).map(r=>{
356
- return JSON.stringify({id_app:r.id_app,ngay_ct:r.ngay_ct});
357
- })
358
-
359
- deletedDocs = [...new Set(deletedDocs)];
360
- deletedDocs.forEach(doc=>{
361
- if(!sokhoQueue.find(d=>d==doc)){
362
- sokhoQueue.push(doc);
363
- }
364
- })
365
- if(!sokhoIsHandling){
366
- handleCreateSokhoTc();
367
- }
368
+ let deletedDocs =(await global.getModel("sokho").find(query,{id_app:1,ngay_ct:1}).lean()).map(r=>{
369
+ return JSON.stringify({id_app:r.id_app,ngay_ct:r.ngay_ct});
370
+ })
371
+
372
+ deletedDocs = [...new Set(deletedDocs)];
373
+ deletedDocs.forEach(doc=>{
374
+ if(!sokhoQueue.find(d=>d==doc)){
375
+ sokhoQueue.push(doc);
376
+ }
377
+ })
378
+ if(!sokhoIsHandling){
379
+ handleCreateSokhoTc();
380
+ }
368
381
  };
369
382
 
370
383
  if (session) {
@@ -381,29 +394,29 @@ sokhoSchema.pre('deleteMany', async function (next) {
381
394
  }
382
395
  }
383
396
 
384
-
385
-
397
+
398
+
386
399
  });
387
400
  sokhoSchema.pre('deleteOne', async function (next) {
388
- // 1. Lấy session từ Query object
401
+ // 1. Lấy session từ Query object
389
402
  const session = this.options.session || getCurrentSession();
390
- const store = getCurrentStore();
403
+ const store = getCurrentStore();
391
404
 
392
405
  // 2. Định nghĩa hàm xử lý
393
406
  const handleDeletionAfterCommit = async () => {
394
407
  let query = this.getQuery();
395
- let deletedDocs =(await global.getModel("sokho").find(query,{id_app:1,ngay_ct:1}).lean()).map(r=>{
396
- return JSON.stringify({id_app:r.id_app,ngay_ct:r.ngay_ct});
397
- })
398
- deletedDocs = [...new Set(deletedDocs)];
399
- deletedDocs.forEach(doc=>{
400
- if(!sokhoQueue.find(d=>d==doc)){
401
- sokhoQueue.push(doc);
402
- }
403
- })
404
- if(!sokhoIsHandling){
405
- handleCreateSokhoTc();
406
- }
408
+ let deletedDocs =(await global.getModel("sokho").find(query,{id_app:1,ngay_ct:1}).lean()).map(r=>{
409
+ return JSON.stringify({id_app:r.id_app,ngay_ct:r.ngay_ct});
410
+ })
411
+ deletedDocs = [...new Set(deletedDocs)];
412
+ deletedDocs.forEach(doc=>{
413
+ if(!sokhoQueue.find(d=>d==doc)){
414
+ sokhoQueue.push(doc);
415
+ }
416
+ })
417
+ if(!sokhoIsHandling){
418
+ handleCreateSokhoTc();
419
+ }
407
420
  };
408
421
 
409
422
  if (session) {
@@ -419,17 +432,17 @@ sokhoSchema.pre('deleteOne', async function (next) {
419
432
  next(e);
420
433
  }
421
434
  }
422
-
435
+
423
436
  });
424
437
 
425
438
  const model = mongoose.models.sokho || mongoose.model('sokho', sokhoSchema);
426
439
  if((global.configs||{}).createIndexes){
427
- model.on('index', async function(err) {
428
- if (err) {
429
- console.error('sokho index error',err);
430
- } else {
431
- console.info('sokho indexing complete');
432
- }
433
- });
440
+ model.on('index', async function(err) {
441
+ if (err) {
442
+ console.error('sokho index error',err);
443
+ } else {
444
+ console.info('sokho indexing complete');
445
+ }
446
+ });
434
447
  }
435
448
  module.exports =model