flexbiz-server 12.7.6 → 12.7.7

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.
Files changed (95) hide show
  1. package/package.json +3 -3
  2. package/server/app.js +23 -19
  3. package/server/auths/rateLimiterMiddleware.js +3 -3
  4. package/server/controllers/controller.js +41 -41
  5. package/server/controllers/controllerUtils.js +61 -61
  6. package/server/controllers/controllerUtils_v1.js +72 -0
  7. package/server/controllers/controller_old.js +129 -0
  8. package/server/controllers/createHandler.js +34 -34
  9. package/server/controllers/createHandler_old.js +35 -0
  10. package/server/controllers/deleteHandler.js +11 -12
  11. package/server/controllers/deleteHandler_old.js +12 -0
  12. package/server/controllers/exportHandler.js +19 -17
  13. package/server/controllers/exportHandler_old.js +17 -0
  14. package/server/controllers/findHandler.js +61 -55
  15. package/server/controllers/findHandler_old.js +74 -0
  16. package/server/controllers/importFromGsHandler.js +10 -10
  17. package/server/controllers/importFromJsonHandler.js +6 -6
  18. package/server/controllers/importFromJsonHandler_old.js +6 -0
  19. package/server/controllers/updateBookHandler.js +1 -1
  20. package/server/controllers/updateFieldHandler.js +12 -13
  21. package/server/controllers/updateFieldHandler_old.js +13 -0
  22. package/server/controllers/updateHandler.js +38 -40
  23. package/server/controllers/updateHandler_old.js +40 -0
  24. package/server/controllers/viewHandler.js +13 -14
  25. package/server/controllers/viewHandler_old.js +14 -0
  26. package/server/flow/nodes/aiAnalysis.js +1 -1
  27. package/server/global.js +2 -3
  28. package/server/libs/WorkerStaticPool.js +14 -14
  29. package/server/libs/asyncCompat.js +10 -0
  30. package/server/libs/createSocaitheongay.js +1 -1
  31. package/server/libs/invoiceVnpt.js +1 -1
  32. package/server/libs/post-book.js +2 -2
  33. package/server/libs/post-sokho.js +5 -5
  34. package/server/libs/redis-cache.js +2 -2
  35. package/server/models/assabcihandler.js +1 -1
  36. package/server/models/counter.js +2 -2
  37. package/server/models/listinfo.js +200 -225
  38. package/server/models/listinfo_old.js +124 -0
  39. package/server/models/po1.js +4 -4
  40. package/server/models/purchase_contract.js +3 -3
  41. package/server/models/smsaccount.js +2 -2
  42. package/server/models/tdttco.js +3 -3
  43. package/server/models/tdttno.js +3 -3
  44. package/server/modules/lists/ls-afflink.js +1 -1
  45. package/server/modules/lists/ls-assbooking.js +1 -1
  46. package/server/modules/lists/ls-assinvestment.js +11 -11
  47. package/server/modules/lists/ls-asskey.js +2 -2
  48. package/server/modules/lists/ls-assneedtobuy.js +1 -1
  49. package/server/modules/lists/ls-assperiod.js +1 -1
  50. package/server/modules/lists/ls-asssell.js +1 -1
  51. package/server/modules/lists/ls-cart.js +14 -14
  52. package/server/modules/lists/ls-congdoansx.js +1 -1
  53. package/server/modules/lists/ls-consultant.js +2 -2
  54. package/server/modules/lists/ls-dkhoc.js +2 -2
  55. package/server/modules/lists/ls-dmban.js +1 -1
  56. package/server/modules/lists/ls-dmbp.js +2 -2
  57. package/server/modules/lists/ls-dmdoi.js +1 -1
  58. package/server/modules/lists/ls-dmnhtask.js +2 -2
  59. package/server/modules/lists/ls-dmvt.js +3 -3
  60. package/server/modules/lists/ls-file.js +1 -1
  61. package/server/modules/lists/ls-giaoca.js +1 -1
  62. package/server/modules/lists/ls-introducer.js +2 -2
  63. package/server/modules/lists/ls-kbm-bcqt.js +1 -1
  64. package/server/modules/lists/ls-news.js +1 -1
  65. package/server/modules/lists/ls-participant.js +1 -1
  66. package/server/modules/lists/ls-rpt.js +1 -1
  67. package/server/modules/lists/ls-smsaccount.js +1 -1
  68. package/server/modules/lists/ls-sosanxuat.js +1 -1
  69. package/server/modules/lists/ls-support.js +1 -1
  70. package/server/modules/public/callin.js +1 -1
  71. package/server/modules/reports/calc-tinhgiafifo.js +1 -1
  72. package/server/modules/reports/calc-tinhgiatb.js +1 -1
  73. package/server/modules/reports/calc-tinhgiathanh.js +1 -1
  74. package/server/modules/reports/calc-tinhluong.js +1 -1
  75. package/server/modules/reports/rp-assbonus.js +1 -1
  76. package/server/modules/reports/rp-bkchamcong.js +1 -1
  77. package/server/modules/reports/rp-cdpsdiem.js +1 -1
  78. package/server/modules/reports/rp-cdpskh.js +1 -1
  79. package/server/modules/reports/rp-cdpsnphep.js +1 -1
  80. package/server/modules/reports/rp-kcsns.js +1 -1
  81. package/server/modules/reports/rp-sctbhxh.js +1 -1
  82. package/server/modules/reports/rp-sctluong.js +1 -1
  83. package/server/modules/reports/rp-sctthuetncn.js +1 -1
  84. package/server/modules/reports/rp-sctvt.js +1 -1
  85. package/server/modules/reports/rp-sctvtnpp.js +1 -1
  86. package/server/modules/reports/rp-sctvttt.js +1 -1
  87. package/server/modules/reports/rp-thgt.js +1 -1
  88. package/server/modules/systems/sys-labelinfo.js +2 -3
  89. package/server/modules/systems/sys-listinfo.js +1 -1
  90. package/server/modules/systems/sys-menuinfo.js +1 -4
  91. package/server/modules/systems/sys-moduleinfo.js +2 -4
  92. package/server/modules/systems/sys-notification.js +1 -1
  93. package/server/workers/backupApp.js +1 -1
  94. package/server/workers/calcGrid.js +1 -1
  95. package/server/workers/runScript.js +1 -1
@@ -1,6 +1,37 @@
1
+ /**
2
+ * NÂNG CẤP:
3
+ * - Bỏ các đoạn dùng `async.parallel`, `async.series`, `async.map`, `async.mapSeries` Ở LOGIC
4
+ * NỘI BỘ của các hàm dưới đây, chuyển sang async/await + Promise.all:
5
+ * deletePost, dynamicCreating, dynamicCreated, dynamicUpdating, dynamicUpdated,
6
+ * dynamicDeleting, onView.
7
+ * - VẪN GIỮ `const async = require("async")` và tiếp tục truyền `async` vào sandbox của
8
+ * `evalute()` cho các script động do admin cấu hình trong listinfo (handle_oncreating_server,
9
+ * handle_onupdating_server, handle_view_server...) - đây là API công khai cho script của người
10
+ * dùng cấu hình hệ thống, KHÔNG thuộc phạm vi "code nội bộ" cần bỏ async, và việc bỏ đi có thể
11
+ * làm hỏng các script đã lưu sẵn trong DB.
12
+ * - GIỮ NGUYÊN toàn bộ chữ ký callback `next(error, result)` của các hàm dynamicXxx/onView vì đây
13
+ * là hợp đồng (contract) mà controller.js và các handler (updateHandler/createHandler/
14
+ * deleteHandler/updateFieldHandler) gọi vào - đổi sang Promise ở đây sẽ phá vỡ các nơi đó.
15
+ * - Tối ưu tốc độ: `onView`'s xử lý join dữ liệu tham chiếu cho nhiều field (fields_have_ref)
16
+ * chạy song song bằng Promise.all thay vì async.map (giữ đúng ngữ nghĩa "chạy song song không
17
+ * giới hạn" của async.map, nhưng nhẹ hơn).
18
+ * - FIX bug tiềm ẩn: trong `deletePost` (async.mapSeries) và `onView` (async.map), nếu một tác vụ
19
+ * con lỗi SAU đoạn try/catch nội bộ (ví dụ lỗi từ `asyncJoinModel2`), lỗi đó không được bắt lại
20
+ * -> callback `cb()`/`next()` không bao giờ được gọi -> request treo vĩnh viễn. Với async/await
21
+ * + Promise.all bọc toàn bộ logic của từng tác vụ, lỗi giờ luôn được bắt và trả về đúng.
22
+ * - Trong `model.updateModel`, thay 1 lệnh `_newModel.collection.dropIndex(old_index_unique, cb)`
23
+ * kiểu callback cũ bằng await, đồng nhất với các lệnh dropIndex khác ngay bên cạnh trong cùng
24
+ * hàm (vốn đã dùng try/await).
25
+ *
26
+ * KHÔNG THAY ĐỔI (ngoài phạm vi): `model.createModel`/`model.createController` gọi
27
+ * `model.updateModel(...)` mà KHÔNG await (fire-and-forget) vì bản thân các hàm gọi nó
28
+ * (`createModel`, phần khởi tạo trong `createController`) không phải hàm async - việc chuyển đổi
29
+ * toàn bộ chuỗi gọi này thành async sẽ ảnh hưởng tới luồng khởi tạo route/model ở nơi khác không
30
+ * có trong phạm vi file này, nên mình giữ nguyên như bản gốc. Báo lại nếu muốn xử lý luôn.
31
+ */
1
32
  const controller = require('../controllers/controller');
2
33
  const underscore =require('underscore');
3
- const async = require("async");
34
+ const async = require("../libs/asyncCompat");
4
35
  const {evalute} = require("../libs/utils");
5
36
  const utils = require("../libs/utils");
6
37
  //const {isSupperAdmin} = require("../libs/utils");
@@ -546,14 +577,14 @@ model.updateModel = async (info,_newModel)=>{
546
577
  old_index_unique[u]= (field||{}).sort || 1;
547
578
  });
548
579
  //Logger.warn("drop current index unique...",old_index_unique);
549
- _newModel.collection.dropIndex(old_index_unique,()=>{
550
- //if(e) return Logger.error("Can't drop index unique",old_index_unique,model_code,e);
551
- //create new unique
552
- if(indUq){
553
- //Logger.warn("create new index unique...",indUq);
554
- _newModel.schema.index(indUq,{unique: true });
555
- }
556
- })
580
+ try{
581
+ await _newModel.collection.dropIndex(old_index_unique);
582
+ }catch(e){/* giữ nguyên hành vi gốc: bỏ qua lỗi drop index */}
583
+ //create new unique
584
+ if(indUq){
585
+ //Logger.warn("create new index unique...",indUq);
586
+ _newModel.schema.index(indUq,{unique: true });
587
+ }
557
588
  }else{
558
589
  //create new unique
559
590
  if(indUq){
@@ -587,34 +618,34 @@ model.createModel = (info)=>{
587
618
  }
588
619
  return exModel;
589
620
  }
590
- const deletePost = (_listInfo,obj)=>{
591
- return new Promise((resolve,reject)=>{
592
- let bookbackup={};
593
- async.mapSeries((_listInfo.postinfos||[]).filter(info=>info.model && info.script && info.condition),(postInfo,callback)=>{
594
- setImmediate(async ()=>{
595
- let m = global.getModel(postInfo.model);
596
- let scriptCondition = postInfo.condition.indexOf("return ")<0?`return ${postInfo.condition}`:postInfo.condition;
597
- let condition = evalute(scriptCondition,{master:obj,data:obj,moment});
598
- condition.id_app = obj.id_app;
599
- //backup old data
600
- bookbackup[postInfo.model] = await m.find(condition).lean();
601
- //delete
602
- await m.deleteMany(condition);
603
- callback();
604
- })
605
- },async (e)=>{
606
- if(e){
607
- //restore old data
608
- for(let key in bookbackup){
609
- if(bookbackup[key].length>0){
610
- await global.getModel(key.toString()).insertMany(bookbackup[key]);
611
- }
612
- }
613
- return reject(e);
621
+
622
+ /**
623
+ * @returns {Promise<object>} bookbackup - dữ liệu đã backup trước khi xoá (theo từng model)
624
+ */
625
+ const deletePost = async (_listInfo, obj) => {
626
+ const bookbackup = {};
627
+ const postInfos = (_listInfo.postinfos || []).filter(info => info.model && info.script && info.condition);
628
+ try {
629
+ for (const postInfo of postInfos) {
630
+ const m = global.getModel(postInfo.model);
631
+ const scriptCondition = postInfo.condition.indexOf("return ") < 0 ? `return ${postInfo.condition}` : postInfo.condition;
632
+ const condition = evalute(scriptCondition, { master: obj, data: obj, moment });
633
+ condition.id_app = obj.id_app;
634
+ //backup old data
635
+ bookbackup[postInfo.model] = await m.find(condition).lean();
636
+ //delete
637
+ await m.deleteMany(condition);
638
+ }
639
+ return bookbackup;
640
+ } catch (e) {
641
+ //restore old data
642
+ for (let key in bookbackup) {
643
+ if (bookbackup[key].length > 0) {
644
+ await global.getModel(key.toString()).insertMany(bookbackup[key]);
614
645
  }
615
- resolve(bookbackup)
616
- })
617
- })
646
+ }
647
+ throw e;
648
+ }
618
649
  }
619
650
  const post = (_listInfo,obj)=>{
620
651
  if(obj.toObject) obj = obj.toObject();
@@ -700,32 +731,23 @@ const dynamicCreating = async (listInfo,user,obj,next,options={})=>{
700
731
  if(_listInfo.handle_oncreating_server.indexOf("next")<0) return next("Script xử lý dữ liệu trước khi tạo yêu cầu gọi function next");
701
732
  try{
702
733
  await new Promise((resolve,reject)=>{
703
- async.parallel([
704
- (next)=>{
705
- const func_body = `(async ()=>{
706
- try{
707
- ${_listInfo.handle_oncreating_server}
708
- }catch(e){
709
- next(e);
710
- }
711
-
712
- })();`
713
- setImmediate(async ()=>{
714
- try{
715
- await evalute(func_body,{obj,user,getLib:global.getLib,getModel:global.getModel,utils,query:utils.query,async,controller,controllerUtils,controllers:global.controllers,joinModel2,next,moment,numeral,request:options.req})
716
- }catch(e){
717
- Logger.error("[dynamicCreating][handle_oncreating_server]",{code:listInfo.code,handle_oncreating_server:_listInfo.handle_oncreating_server,e})
718
- next(e);
719
- }
720
- })
721
-
734
+ // next ở đây là callback dành riêng cho script động (khác với next của dynamicCreating)
735
+ const scriptNext = (e,rs)=> e ? reject(e) : resolve(rs);
736
+ const func_body = `(async ()=>{
737
+ try{
738
+ ${_listInfo.handle_oncreating_server}
739
+ }catch(e){
740
+ next(e);
741
+ }
742
+
743
+ })();`
744
+ setImmediate(async ()=>{
745
+ try{
746
+ await evalute(func_body,{obj,user,getLib:global.getLib,getModel:global.getModel,utils,query:utils.query,async,controller,controllerUtils,controllers:global.controllers,joinModel2,next:scriptNext,moment,numeral,request:options.req})
747
+ }catch(e){
748
+ Logger.error("[dynamicCreating][handle_oncreating_server]",{code:listInfo.code,handle_oncreating_server:_listInfo.handle_oncreating_server,e})
749
+ scriptNext(e);
722
750
  }
723
- ],(e,rs)=>{
724
- if(e){
725
- Logger.error("[dynamicCreating][handle_oncreating_server]",listInfo.code,e,_listInfo.handle_oncreating_server);
726
- return reject(e)
727
- }
728
- resolve(rs);
729
751
  })
730
752
  })
731
753
  }catch(e){
@@ -741,30 +763,21 @@ const dynamicCreated = async (_listInfo,user,obj,next,options={})=>{
741
763
  if(_listInfo.handle_oncreated_server.indexOf("next")<0) return next("Script xử lý dữ liệu sau khi tạo yêu cầu gọi function next");
742
764
  try{
743
765
  await new Promise((resolve,reject)=>{
744
- async.parallel([
745
- (next)=>{
746
- const func_body = `(async ()=>{
747
- try{
748
- ${_listInfo.handle_oncreated_server}
749
- }catch(e){
750
- next(e);
751
- }
752
- })();`
753
- setImmediate(async ()=>{
754
- try{
755
- await evalute(func_body,{obj,user,getLib:global.getLib,getModel:global.getModel,controller,controllerUtils,controllers:global.controllers,utils,query:utils.query,async,joinModel2,next,moment,numeral,request:options.req})
756
- }catch(e){
757
- Logger.error("error dynamic created",_listInfo.handle_oncreated_server,e)
758
- next(e)
759
- }
760
- })
766
+ const scriptNext = (e,rs)=> e ? reject(e) : resolve(rs);
767
+ const func_body = `(async ()=>{
768
+ try{
769
+ ${_listInfo.handle_oncreated_server}
770
+ }catch(e){
771
+ next(e);
772
+ }
773
+ })();`
774
+ setImmediate(async ()=>{
775
+ try{
776
+ await evalute(func_body,{obj,user,getLib:global.getLib,getModel:global.getModel,controller,controllerUtils,controllers:global.controllers,utils,query:utils.query,async,joinModel2,next:scriptNext,moment,numeral,request:options.req})
777
+ }catch(e){
778
+ Logger.error("error dynamic created",_listInfo.handle_oncreated_server,e)
779
+ scriptNext(e)
761
780
  }
762
- ],(e,rs)=>{
763
- if(e){
764
- Logger.error(e);
765
- return reject(e)
766
- }
767
- resolve(rs);
768
781
  })
769
782
  })
770
783
  }catch(e){
@@ -793,31 +806,22 @@ const dynamicUpdating = async (listInfo,user,data,obj,next,options={})=>{
793
806
  if(_listInfo.handle_onupdating_server.indexOf("next")<0) return next("Script xử lý dữ liệu trước khi update yêu cầu gọi function next");
794
807
  try{
795
808
  await new Promise((resolve,reject)=>{
796
- async.series([
797
- (next)=>{
798
- const func_body = `(async ()=>{
799
- try{
800
- ${_listInfo.handle_onupdating_server}
801
- }catch(e){
802
- next(e);
803
- }
804
-
805
- })();`
806
- setImmediate(async ()=>{
807
- try{
808
- await evalute(func_body,{data,obj,user,getLib:global.getLib,getModel:global.getModel,controller,controllerUtils,controllers:global.controllers,utils,query:utils.query,async,joinModel2,next,moment,numeral,request:options.req})
809
- }catch(e){
810
- Logger.error("[listinfo][dynamicUpdating] error dynamic update",_listInfo.handle_onupdating_server,e)
811
- next(e)
812
- }
813
- })
809
+ const scriptNext = (e,rs)=> e ? reject(e) : resolve(rs);
810
+ const func_body = `(async ()=>{
811
+ try{
812
+ ${_listInfo.handle_onupdating_server}
813
+ }catch(e){
814
+ next(e);
815
+ }
816
+
817
+ })();`
818
+ setImmediate(async ()=>{
819
+ try{
820
+ await evalute(func_body,{data,obj,user,getLib:global.getLib,getModel:global.getModel,controller,controllerUtils,controllers:global.controllers,utils,query:utils.query,async,joinModel2,next:scriptNext,moment,numeral,request:options.req})
821
+ }catch(e){
822
+ Logger.error("[listinfo][dynamicUpdating] error dynamic update",_listInfo.handle_onupdating_server,e)
823
+ scriptNext(e)
814
824
  }
815
- ],(e,rs)=>{
816
- if(e){
817
- Logger.error("[listinfo][dynamicUpdating]",e);
818
- return reject(e)
819
- }
820
- resolve(rs);
821
825
  })
822
826
  })
823
827
  }catch(e){
@@ -836,30 +840,21 @@ const dynamicUpdated = async (_listInfo,user,obj,next,options={})=>{
836
840
  if(_listInfo.handle_onupdated_server.indexOf("next")<0) return next("Script xử lý dữ liệu sau khi update yêu cầu gọi function next");
837
841
  try{
838
842
  await new Promise((resolve,reject)=>{
839
- async.series([
840
- (next)=>{
841
- const func_body = `(async ()=>{
842
- try{
843
- ${_listInfo.handle_onupdated_server}
844
- }catch(e){
845
- next(e)
846
- }
847
- })();`
848
- setImmediate(async ()=>{
849
- try{
850
- await evalute(func_body,{obj,user,getLib:global.getLib,getModel:global.getModel,controller,controllerUtils,controllers:global.controllers,utils,query:utils.query,async,joinModel2,next,moment,numeral,request:options.req})
851
- }catch(e){
852
- Logger.error("error dynamic updated",_listInfo.handle_onupdated_server,e)
853
- next(e)
854
- }
855
- })
843
+ const scriptNext = (e,rs)=> e ? reject(e) : resolve(rs);
844
+ const func_body = `(async ()=>{
845
+ try{
846
+ ${_listInfo.handle_onupdated_server}
847
+ }catch(e){
848
+ next(e)
849
+ }
850
+ })();`
851
+ setImmediate(async ()=>{
852
+ try{
853
+ await evalute(func_body,{obj,user,getLib:global.getLib,getModel:global.getModel,controller,controllerUtils,controllers:global.controllers,utils,query:utils.query,async,joinModel2,next:scriptNext,moment,numeral,request:options.req})
854
+ }catch(e){
855
+ Logger.error("error dynamic updated",_listInfo.handle_onupdated_server,e)
856
+ scriptNext(e)
856
857
  }
857
- ],(e,rs)=>{
858
- if(e){
859
- Logger.error(e);
860
- return reject(e)
861
- }
862
- resolve(rs);
863
858
  })
864
859
  })
865
860
  }catch(e){
@@ -888,32 +883,23 @@ const dynamicDeleting = async (listInfo,user,obj,next,options={})=>{
888
883
  if(_listInfo.handle_ondeleting_server.indexOf("next")<0) return next("Script xử lý dữ liệu trước khi update yêu cầu gọi function next");
889
884
  try{
890
885
  await new Promise((resolve,reject)=>{
891
- async.series([
892
- (next)=>{
893
- const func_body = `(async ()=>{
894
- try{
895
- ${_listInfo.handle_ondeleting_server}
896
- }catch(e){
897
- next(e);
898
- }
899
- })();`
900
- setImmediate(async ()=>{
901
- try{
902
- await evalute(func_body,{obj,user,getLib:global.getLib,getModel:global.getModel,controller,controllerUtils,controllers:global.controllers,utils,query:utils.query,async,joinModel2,next,moment,numeral,request:options.req})
903
- }catch(e){
904
- Logger.error("error dynamic delete",_listInfo.handle_ondeleting_server,e)
905
- next(e)
906
- }
907
- })
908
-
886
+ const scriptNext = (e,rs)=> e ? reject(e) : resolve(rs);
887
+ const func_body = `(async ()=>{
888
+ try{
889
+ ${_listInfo.handle_ondeleting_server}
890
+ }catch(e){
891
+ next(e);
892
+ }
893
+ })();`
894
+ setImmediate(async ()=>{
895
+ try{
896
+ await evalute(func_body,{obj,user,getLib:global.getLib,getModel:global.getModel,controller,controllerUtils,controllers:global.controllers,utils,query:utils.query,async,joinModel2,next:scriptNext,moment,numeral,request:options.req})
897
+ }catch(e){
898
+ Logger.error("error dynamic delete",_listInfo.handle_ondeleting_server,e)
899
+ scriptNext(e)
909
900
  }
910
- ],(e,rs)=>{
911
- if(e){
912
- Logger.error(e);
913
- return reject(e)
914
- }
915
- resolve(rs);
916
901
  })
902
+
917
903
  })
918
904
  }catch(e){
919
905
  Logger.error(e);
@@ -938,36 +924,31 @@ const onView = async (control,obj,user,items,next,options={})=>{
938
924
  //handle view
939
925
  if(obj.handle_view_server && obj.handle_view_server.trim()!==""){
940
926
  if(obj.handle_view_server.indexOf("next")<0) return next("Script xử lý view yêu cầu gọi function next");
941
- await new Promise((resolve,reject)=>{
942
- async.parallel([
943
- (next)=>{
944
- setImmediate(async ()=>{
945
- const func_body = `(async ()=>{
946
- try{
947
- ${obj.handle_view_server}
948
- }catch(e){
949
- next(e);
950
- }
951
-
952
- })();`
927
+ try{
928
+ await new Promise((resolve,reject)=>{
929
+ const scriptNext = (e,rs)=> e ? reject(e) : resolve(rs);
930
+ setImmediate(async ()=>{
931
+ const func_body = `(async ()=>{
953
932
  try{
954
- //Logger.warn("[listinfo][dynamicView] [handle view]",obj.code);
955
- await evalute(func_body,{items,user,getLib:global.getLib,utils,query:utils.query,next,async,joinModel2,moment,numeral,request:options.req})
933
+ ${obj.handle_view_server}
956
934
  }catch(e){
957
- Logger.error("[listinfo][dynamicView] [handle view] error dynamic view",obj.handle_view_serve,e);
958
935
  next(e);
959
936
  }
960
- })
961
- }
962
- ],(e,rs)=>{
963
- if(e){
964
- Logger.error(e);
965
- return reject(e);
966
- }
967
- resolve(rs);
937
+
938
+ })();`
939
+ try{
940
+ //Logger.warn("[listinfo][dynamicView] [handle view]",obj.code);
941
+ await evalute(func_body,{items,user,getLib:global.getLib,utils,query:utils.query,next:scriptNext,async,joinModel2,moment,numeral,request:options.req})
942
+ }catch(e){
943
+ Logger.error("[listinfo][dynamicView] [handle view] error dynamic view",obj.handle_view_serve,e);
944
+ scriptNext(e);
945
+ }
946
+ })
968
947
  })
969
- })
970
-
948
+ }catch(e){
949
+ Logger.error(e);
950
+ return next(e);
951
+ }
971
952
  }
972
953
  //
973
954
 
@@ -977,51 +958,48 @@ const onView = async (control,obj,user,items,next,options={})=>{
977
958
  //console.timeEnd(timer);
978
959
  return next(null,items);
979
960
  }
980
-
981
- async.map(fields_have_ref, (f,cb)=>{
982
- setImmediate(async ()=>{
961
+
962
+ try{
963
+ // Xử lý song song cho từng field tham chiếu (giữ đúng ngữ nghĩa "song song không giới hạn"
964
+ // của async.map bản gốc, nhưng gọn và nhẹ hơn)
965
+ await Promise.all(fields_have_ref.map(async (f)=>{
983
966
  let ref_model,where,fields,ref_name_model,ref_field,ref_condition,field_name,ref_label;
984
967
  ref_label = f.ref_label_as || f.ref_label;
985
968
  ref_field = f.ref_field;
986
969
  ref_condition = f.ref_condition;
987
970
  field_name = f.name;
988
- try{
989
- ref_name_model= f.ref_model;
990
- if(ref_name_model.indexOf("[")>=0 || ref_name_model.indexOf(",")>=0){
991
- try{
992
- if(ref_name_model.indexOf("[")>=0){
993
- ref_model = utils.JSONParser(ref_name_model)
994
- }else{
995
- ref_model = ref_name_model.split(",");
996
- }
997
- }catch(e){
998
- Logger.error("ref_model is not valid",ref_name_model,e);
999
- return cb(e);
971
+ ref_name_model= f.ref_model;
972
+ if(ref_name_model.indexOf("[")>=0 || ref_name_model.indexOf(",")>=0){
973
+ try{
974
+ if(ref_name_model.indexOf("[")>=0){
975
+ ref_model = utils.JSONParser(ref_name_model)
976
+ }else{
977
+ ref_model = ref_name_model.split(",");
1000
978
  }
1001
-
1002
- }else{
1003
- if(ref_name_model==="dmkh") ref_name_model = "customer";
1004
- if(ref_name_model==="dmtk") ref_name_model = "account";
1005
- if(ref_name_model==="dmnt") ref_name_model = "currency";
1006
- if(ref_name_model==="dmnhtask") ref_name_model = "group";
979
+ }catch(e){
980
+ Logger.error("ref_model is not valid",ref_name_model,e);
981
+ throw e;
982
+ }
983
+
984
+ }else{
985
+ if(ref_name_model==="dmkh") ref_name_model = "customer";
986
+ if(ref_name_model==="dmtk") ref_name_model = "account";
987
+ if(ref_name_model==="dmnt") ref_name_model = "currency";
988
+ if(ref_name_model==="dmnhtask") ref_name_model = "group";
1007
989
 
1008
- ref_model = global.mongoose.models[ref_name_model];
990
+ ref_model = global.mongoose.models[ref_name_model];
991
+ if(!ref_model){
992
+ let _listInofOfRef = await model.findOne({code:ref_name_model}).lean();
993
+ if(_listInofOfRef && (_listInofOfRef.api_code || _listInofOfRef.model_code)){
994
+ let model_code = _listInofOfRef.api_code || _listInofOfRef.model_code;
995
+ ref_model = global.mongoose.models[model_code];
996
+ }
1009
997
  if(!ref_model){
1010
- let _listInofOfRef = await model.findOne({code:ref_name_model}).lean();
1011
- if(_listInofOfRef && (_listInofOfRef.api_code || _listInofOfRef.model_code)){
1012
- let model_code = _listInofOfRef.api_code || _listInofOfRef.model_code;
1013
- ref_model = global.mongoose.models[model_code];
1014
- }
1015
- if(!ref_model){
1016
- let ctrl = global.controllers[ref_name_model.trim().toUpperCase()];
1017
- if(ctrl) ref_model = ctrl.getProperty("model");
1018
- }
998
+ let ctrl = global.controllers[ref_name_model.trim().toUpperCase()];
999
+ if(ctrl) ref_model = ctrl.getProperty("model");
1019
1000
  }
1020
- if(!ref_model) ref_model = global.getModel(ref_name_model);
1021
1001
  }
1022
- }catch(e){
1023
- Logger.error(e);
1024
- return cb(e);
1002
+ if(!ref_model) ref_model = global.getModel(ref_name_model);
1025
1003
  }
1026
1004
  /*//chỉ xử lý dynamic joinview nếu field có giá trị
1027
1005
  let items_will_join = items.filter(item=>{
@@ -1036,7 +1014,7 @@ const onView = async (control,obj,user,items,next,options={})=>{
1036
1014
  //Cần xử lý joinview tất cả các field để xoá dữ liệu ref không phù hợp
1037
1015
  let items_will_join = items;
1038
1016
  //
1039
- if(items_will_join.length==0) return cb();
1017
+ if(items_will_join.length==0) return;
1040
1018
  //xác định các fields cần lấy dữ liệu
1041
1019
  fields = {[ref_label]:f.ref_label};
1042
1020
  if(f.ref_model==="trangthai" && f.name=="trang_thai"){
@@ -1104,15 +1082,12 @@ const onView = async (control,obj,user,items,next,options={})=>{
1104
1082
  })
1105
1083
  }
1106
1084
  }
1107
- cb();
1108
- })
1109
-
1110
- },(e)=>{
1085
+ }))
1086
+ }catch(e){
1111
1087
  //console.timeEnd(timer);
1112
- if(e) return next(e);
1113
- next(null,items);
1114
-
1115
- })
1088
+ return next(e);
1089
+ }
1090
+ next(null,items);
1116
1091
  }
1117
1092
  model.createController = (router,_listInfo)=>{
1118
1093
  let api_code = _listInfo.api_code || _listInfo.code;
@@ -1362,4 +1337,4 @@ model.createController = (router,_listInfo)=>{
1362
1337
  }
1363
1338
  return _newList;
1364
1339
  }
1365
- module.exports = model;
1340
+ module.exports = model;