my-typescript-library-rahul52us 3.0.8 → 4.1.0

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.
@@ -145,21 +145,7 @@ export async function withdrawalApprovalDocument(data: any) {
145
145
 
146
146
  export const findOneByDocumentIdAndDelete = async (data: any) => {
147
147
  try {
148
- const doc = await Document.findOneAndDelete({ documentId: data.documentId });
149
-
150
- if (!doc) {
151
- return {
152
- status: "error",
153
- data: "Document does not exist",
154
- };
155
- }
156
-
157
-
158
- doc.deleted_At = new Date();
159
- await doc.save();
160
-
161
- console.log(doc)
162
-
148
+ await Document.findOneAndDelete({ documentId: data.documentId });
163
149
  return {
164
150
  status: "success",
165
151
  data: "Document has been deleted successfully (soft delete)",
@@ -2379,3 +2365,775 @@ export const deleteAllDocuments = async () => {
2379
2365
  };
2380
2366
  }
2381
2367
  };
2368
+
2369
+
2370
+ export async function getDownloadExcelDocument(
2371
+ noOfLevels: number,
2372
+ workflow: string,
2373
+ searchValue: string,
2374
+ status: string,
2375
+ company: string,
2376
+ userId: any,
2377
+ differentiateFirstLevel: any,
2378
+ level: string,
2379
+ sort: string | null = "1",
2380
+ limit: string | null = "10",
2381
+ page: string | null = "1",
2382
+ exchangeType: any | null,
2383
+ billType: string | null,
2384
+ manual: string | null,
2385
+ startDate: any,
2386
+ endDate: any,
2387
+ searchField: any,
2388
+ dateFilterKey: string,
2389
+ sortByKey: string,
2390
+ additionalFiles: string[]
2391
+ ) {
2392
+ try {
2393
+ let matchQuery: any = {};
2394
+ matchQuery.status = { $ne: "rejected" };
2395
+
2396
+ if (searchField && searchValue?.trim()) {
2397
+ matchQuery[`originalValues.${searchField}`] = {
2398
+ $regex: searchValue,
2399
+ $options: "i",
2400
+ };
2401
+ }
2402
+
2403
+ if (startDate) {
2404
+ matchQuery[dateFilterKey] = { $gte: new Date(startDate) };
2405
+ }
2406
+
2407
+ if (endDate) {
2408
+ matchQuery[dateFilterKey] = {
2409
+ ...matchQuery[dateFilterKey],
2410
+ $lte: new Date(endDate),
2411
+ };
2412
+ }
2413
+
2414
+ var matchConditions: any = {
2415
+ ...matchQuery,
2416
+ // company: new mongoose.Types.ObjectId(company),
2417
+ workflow: new mongoose.Types.ObjectId(workflow),
2418
+ deleted_At: { $exists: false },
2419
+ };
2420
+
2421
+ if (exchangeType && Array.isArray(exchangeType)) {
2422
+ exchangeType.forEach((typeObj) => {
2423
+ Object.entries(typeObj).forEach(([field, value]) => {
2424
+ if (!matchConditions[`originalValues.${field}`]) {
2425
+ matchConditions[`originalValues.${field}`] = [];
2426
+ }
2427
+ matchConditions[`originalValues.${field}`].push(value);
2428
+ });
2429
+ });
2430
+ }
2431
+
2432
+ Object.entries(matchConditions).forEach(([field, value]) => {
2433
+ if (Array.isArray(value)) {
2434
+ matchConditions[field] = { $in: value };
2435
+ }
2436
+ });
2437
+
2438
+ let pipeline: any = [];
2439
+
2440
+ let expr: any = {};
2441
+
2442
+ let levels = generateLevels(noOfLevels);
2443
+ switch (level) {
2444
+ case levels[0]:
2445
+ switch (status) {
2446
+ case "pending":
2447
+ expr = {
2448
+ $expr: {
2449
+ $and: [
2450
+ {
2451
+ $and: [
2452
+ {
2453
+ $not: [
2454
+ {
2455
+ $and: [
2456
+ {
2457
+ $in: [
2458
+ { $arrayElemAt: ["$approval.status", -1] },
2459
+ ["approved", "rejected"],
2460
+ ],
2461
+ },
2462
+ {
2463
+ $in: [
2464
+ { $arrayElemAt: ["$approval.level", -1] },
2465
+ [levels[0]],
2466
+ ],
2467
+ },
2468
+ ],
2469
+ },
2470
+ ],
2471
+ },
2472
+ {
2473
+ $not: [
2474
+ {
2475
+ $and: [
2476
+ {
2477
+ $in: [
2478
+ { $arrayElemAt: ["$approval.status", -1] },
2479
+ ["approved"],
2480
+ ],
2481
+ },
2482
+ {
2483
+ $in: [
2484
+ { $arrayElemAt: ["$approval.level", -1] },
2485
+ [levels[levels.length - 1]],
2486
+ ],
2487
+ },
2488
+ ],
2489
+ },
2490
+ ],
2491
+ },
2492
+ ],
2493
+ },
2494
+ ],
2495
+ },
2496
+ };
2497
+ break;
2498
+ case "approved":
2499
+ expr = {
2500
+ $expr: {
2501
+ $or: [
2502
+ {
2503
+ $and: [
2504
+ {
2505
+ $in: [
2506
+ { $arrayElemAt: ["$approval.status", -1] },
2507
+ [status],
2508
+ ],
2509
+ },
2510
+ {
2511
+ $in: [
2512
+ { $arrayElemAt: ["$approval.level", -1] },
2513
+ [levels[levels.length - 1], levels[0]],
2514
+ ],
2515
+ },
2516
+ {
2517
+ $not: [{ $eq: ["$approval", []] }],
2518
+ },
2519
+ ],
2520
+ },
2521
+ ],
2522
+ },
2523
+ };
2524
+ break;
2525
+ case "rejected":
2526
+ expr = {
2527
+ $expr: {
2528
+ $or: [
2529
+ {
2530
+ $and: [
2531
+ {
2532
+ $in: [
2533
+ { $arrayElemAt: ["$approval.status", -1] },
2534
+ [status],
2535
+ ],
2536
+ },
2537
+ {
2538
+ $in: [
2539
+ { $arrayElemAt: ["$approval.level", -1] },
2540
+ [levels[0]],
2541
+ ],
2542
+ },
2543
+ {
2544
+ $not: [{ $eq: ["$approval", []] }],
2545
+ },
2546
+ ],
2547
+ },
2548
+ ],
2549
+ },
2550
+ };
2551
+ break;
2552
+ }
2553
+
2554
+ pipeline = [
2555
+ {
2556
+ $match: {
2557
+ ...matchConditions,
2558
+ ...expr,
2559
+ },
2560
+ },
2561
+ ];
2562
+ break;
2563
+ default:
2564
+ let { approvedRoles, rejectedRoles, approvedBy, rejectedBy } =
2565
+ getDynamicRoles(noOfLevels, level);
2566
+ switch (status) {
2567
+ case "pending":
2568
+ expr = {
2569
+ $expr: {
2570
+ $or: [
2571
+ {
2572
+ $and: [
2573
+ {
2574
+ $and: [
2575
+ {
2576
+ $not: [
2577
+ {
2578
+ $and: [
2579
+ {
2580
+ $in: [
2581
+ {
2582
+ $arrayElemAt: ["$approval.status", -1],
2583
+ },
2584
+ ["approved"],
2585
+ ],
2586
+ },
2587
+ {
2588
+ $in: [
2589
+ {
2590
+ $arrayElemAt: ["$approval.level", -1],
2591
+ },
2592
+ approvedRoles,
2593
+ ],
2594
+ },
2595
+ ],
2596
+ },
2597
+ ],
2598
+ },
2599
+ {
2600
+ $not: [
2601
+ {
2602
+ $and: [
2603
+ {
2604
+ $in: [
2605
+ {
2606
+ $arrayElemAt: ["$approval.status", -1],
2607
+ },
2608
+ ["rejected"],
2609
+ ],
2610
+ },
2611
+ {
2612
+ $in: [
2613
+ {
2614
+ $arrayElemAt: ["$approval.level", -1],
2615
+ },
2616
+ rejectedRoles,
2617
+ ],
2618
+ },
2619
+ ],
2620
+ },
2621
+ ],
2622
+ },
2623
+ level !== levels[1] && {
2624
+ $and: [
2625
+ {
2626
+ $in: [
2627
+ {
2628
+ $arrayElemAt: ["$approval.status", -1],
2629
+ },
2630
+ ["approved"],
2631
+ ],
2632
+ },
2633
+ {
2634
+ $in: [
2635
+ {
2636
+ $arrayElemAt: ["$approval.level", -1],
2637
+ },
2638
+ approvedBy,
2639
+ ],
2640
+ },
2641
+ ],
2642
+ },
2643
+ {
2644
+ $not: [{ $eq: ["$approval", []] }],
2645
+ },
2646
+ ],
2647
+ },
2648
+ ],
2649
+ },
2650
+ level !== levels[levels.length - 1] && {
2651
+ $and: [
2652
+ {
2653
+ $in: [
2654
+ {
2655
+ $arrayElemAt: ["$approval.status", -1],
2656
+ },
2657
+ ["rejected"],
2658
+ ],
2659
+ },
2660
+ {
2661
+ $in: [
2662
+ {
2663
+ $arrayElemAt: ["$approval.level", -1],
2664
+ },
2665
+ rejectedBy,
2666
+ ],
2667
+ },
2668
+ ],
2669
+ },
2670
+ level === levels[1] && {
2671
+ $and: [
2672
+ {
2673
+ $eq: ["$tags.extraction.type", "automatic"],
2674
+ },
2675
+ { $eq: ["$approval", []] },
2676
+ ],
2677
+ },
2678
+ ],
2679
+ },
2680
+ };
2681
+
2682
+ // Only add the userId check for the first level if approval is not empty
2683
+ // let userIdCheck = {};
2684
+ // if (level === levels[1] && differentiateFirstLevel) {
2685
+ // userIdCheck = {
2686
+ // approval: {
2687
+ // $elemMatch: {
2688
+ // userId: { $in: [userId] },
2689
+ // level: levels[1],
2690
+ // },
2691
+ // },
2692
+ // };
2693
+ // }
2694
+
2695
+ let userIdCheck = {};
2696
+ if (level === levels[1] && differentiateFirstLevel) {
2697
+ userIdCheck = {
2698
+ user: userId, // Only the creator can access
2699
+ };
2700
+ }
2701
+
2702
+ pipeline = [
2703
+ {
2704
+ $match: {
2705
+ ...matchConditions,
2706
+ ...expr,
2707
+ ...userIdCheck,
2708
+ },
2709
+ },
2710
+ ];
2711
+ break;
2712
+ case "approved":
2713
+ pipeline = [
2714
+ {
2715
+ $addFields: {
2716
+ filteredApproval: {
2717
+ $filter: {
2718
+ input: "$approval",
2719
+ as: "item",
2720
+ cond: { $eq: ["$$item.level", level] },
2721
+ },
2722
+ },
2723
+ },
2724
+ },
2725
+ {
2726
+ $match: {
2727
+ ...matchConditions,
2728
+ $expr: {
2729
+ $and: [
2730
+ {
2731
+ $and: [
2732
+ {
2733
+ $eq: [
2734
+ {
2735
+ $arrayElemAt: ["$filteredApproval.status", -1],
2736
+ },
2737
+ status,
2738
+ ],
2739
+ },
2740
+ ],
2741
+ },
2742
+ {
2743
+ $cond: {
2744
+ if: differentiateFirstLevel,
2745
+ then: {
2746
+ $eq: [
2747
+ {
2748
+ $arrayElemAt: ["$filteredApproval.userId", -1],
2749
+ },
2750
+ userId,
2751
+ ],
2752
+ },
2753
+ else: true,
2754
+ },
2755
+ },
2756
+ {
2757
+ $not: [{ $eq: ["$approval", []] }],
2758
+ },
2759
+ {
2760
+ $not: [
2761
+ {
2762
+ $and: [
2763
+ {
2764
+ $in: [
2765
+ {
2766
+ $arrayElemAt: ["$approval.status", -1],
2767
+ },
2768
+ ["rejected"],
2769
+ ],
2770
+ },
2771
+ {
2772
+ $in: [
2773
+ {
2774
+ $arrayElemAt: ["$approval.level", -1],
2775
+ },
2776
+ rejectedBy,
2777
+ ],
2778
+ },
2779
+ ],
2780
+ },
2781
+ ],
2782
+ },
2783
+ // {
2784
+ // $not: [
2785
+ // {
2786
+ // $and: [
2787
+ // {
2788
+ // $in: [
2789
+ // {
2790
+ // $arrayElemAt: ["$approval.status", -1],
2791
+ // },
2792
+ // ["approved"],
2793
+ // ],
2794
+ // },
2795
+ // {
2796
+ // $in: [
2797
+ // {
2798
+ // $arrayElemAt: ["$approval.level", -1],
2799
+ // },
2800
+ // approvedBy,
2801
+ // ],
2802
+ // },
2803
+ // ],
2804
+ // },
2805
+ // ],
2806
+ // }
2807
+ ],
2808
+ },
2809
+ },
2810
+ },
2811
+ ];
2812
+ break;
2813
+ case "rejected":
2814
+ pipeline = [
2815
+ {
2816
+ $addFields: {
2817
+ filteredApproval: {
2818
+ $filter: {
2819
+ input: "$approval",
2820
+ as: "item",
2821
+ cond: { $eq: ["$$item.level", level] },
2822
+ },
2823
+ },
2824
+ },
2825
+ },
2826
+ {
2827
+ $match: {
2828
+ ...matchConditions,
2829
+ $expr: {
2830
+ $and: [
2831
+ {
2832
+ $and: [
2833
+ {
2834
+ $eq: [
2835
+ {
2836
+ $arrayElemAt: ["$filteredApproval.status", -1],
2837
+ },
2838
+ status,
2839
+ ],
2840
+ },
2841
+ ],
2842
+ },
2843
+ {
2844
+ $cond: {
2845
+ if: differentiateFirstLevel,
2846
+ then: {
2847
+ $eq: [
2848
+ {
2849
+ $arrayElemAt: ["$filteredApproval.userId", -1],
2850
+ },
2851
+ userId,
2852
+ ],
2853
+ },
2854
+ else: true,
2855
+ },
2856
+ },
2857
+ {
2858
+ $not: [{ $eq: ["$approval", []] }],
2859
+ },
2860
+ // {
2861
+ // $not: [
2862
+ // {
2863
+ // $and: [
2864
+ // {
2865
+ // $in: [
2866
+ // {
2867
+ // $arrayElemAt: ["$approval.status", -1],
2868
+ // },
2869
+ // ["rejected"],
2870
+ // ],
2871
+ // },
2872
+ // {
2873
+ // $in: [
2874
+ // {
2875
+ // $arrayElemAt: ["$approval.level", -1],
2876
+ // },
2877
+ // rejectedBy,
2878
+ // ],
2879
+ // },
2880
+ // ],
2881
+ // },
2882
+ // ],
2883
+ // },
2884
+ {
2885
+ $not: [
2886
+ {
2887
+ $and: [
2888
+ {
2889
+ $in: [
2890
+ {
2891
+ $arrayElemAt: ["$approval.status", -1],
2892
+ },
2893
+ ["approved"],
2894
+ ],
2895
+ },
2896
+ {
2897
+ $in: [
2898
+ {
2899
+ $arrayElemAt: ["$approval.level", -1],
2900
+ },
2901
+ approvedBy,
2902
+ ],
2903
+ },
2904
+ ],
2905
+ },
2906
+ ],
2907
+ },
2908
+ ],
2909
+ },
2910
+ },
2911
+ },
2912
+ ];
2913
+ }
2914
+ break;
2915
+ }
2916
+
2917
+ if (manual && (level === levels[0] || level === levels[1])) {
2918
+ pipeline = [
2919
+ {
2920
+ $match: {
2921
+ ...matchQuery,
2922
+ ...matchConditions,
2923
+ "tags.extraction.type": "manual",
2924
+ approval: { $eq: [] },
2925
+ },
2926
+ },
2927
+ ];
2928
+ } else if (manual) {
2929
+ return {
2930
+ data: [],
2931
+ totalPages: 0,
2932
+ };
2933
+ }
2934
+
2935
+ const approvalStage: any = [
2936
+ {
2937
+ $unwind: {
2938
+ path: "$approval",
2939
+ preserveNullAndEmptyArrays: true,
2940
+ },
2941
+ },
2942
+ {
2943
+ $lookup: {
2944
+ from: "fs.files",
2945
+ localField: "approval.fileId",
2946
+ foreignField: "_id",
2947
+ as: "approval.fileDetails",
2948
+ },
2949
+ },
2950
+ {
2951
+ $unwind: {
2952
+ path: "$approval.fileDetails",
2953
+ preserveNullAndEmptyArrays: true,
2954
+ },
2955
+ },
2956
+ {
2957
+ $lookup: {
2958
+ from: "accounts",
2959
+ localField: "approval.userId",
2960
+ foreignField: "_id",
2961
+ as: "approval.userDetails",
2962
+ pipeline: [
2963
+ {
2964
+ $project: {
2965
+ _id: 1,
2966
+ username: 1,
2967
+ role: 1,
2968
+ level: 1,
2969
+ },
2970
+ },
2971
+ ],
2972
+ },
2973
+ },
2974
+ {
2975
+ $unwind: {
2976
+ path: "$approval.userDetails",
2977
+ preserveNullAndEmptyArrays: true,
2978
+ },
2979
+ },
2980
+ {
2981
+ $group: {
2982
+ _id: "$_id",
2983
+ document: { $first: "$$ROOT" },
2984
+ approvals: {
2985
+ $push: {
2986
+ $mergeObjects: [
2987
+ "$approval",
2988
+ {
2989
+ file: "$approval.fileDetails",
2990
+ user: "$approval.userDetails",
2991
+ },
2992
+ ],
2993
+ },
2994
+ },
2995
+ },
2996
+ },
2997
+ {
2998
+ $addFields: {
2999
+ "document.approval": {
3000
+ $filter: {
3001
+ input: "$approvals",
3002
+ as: "approval",
3003
+ cond: { $ne: ["$$approval", {}] },
3004
+ },
3005
+ },
3006
+ },
3007
+ },
3008
+ {
3009
+ $replaceRoot: {
3010
+ newRoot: "$document",
3011
+ },
3012
+ },
3013
+ {
3014
+ $project: {
3015
+ "approval.fileDetails": 0,
3016
+ "approval.userDetails": 0,
3017
+ },
3018
+ },
3019
+ ];
3020
+
3021
+ const lookupStages = additionalFiles.map((obj: any) => ({
3022
+ $lookup: {
3023
+ from: "fs.files",
3024
+ localField: `additionalFiles.${obj}`,
3025
+ foreignField: "_id",
3026
+ as: obj,
3027
+ },
3028
+ }));
3029
+
3030
+ pipeline = [
3031
+ ...pipeline,
3032
+ {
3033
+ $lookup: {
3034
+ from: "fs.files",
3035
+ localField: "file",
3036
+ foreignField: "_id",
3037
+ as: "file",
3038
+ },
3039
+ },
3040
+ {
3041
+ $unwind: {
3042
+ path: "$additionalFiles",
3043
+ preserveNullAndEmptyArrays: true,
3044
+ },
3045
+ },
3046
+ {
3047
+ $lookup: {
3048
+ from: "fs.files",
3049
+ localField: "additionalFiles.fileId",
3050
+ foreignField: "_id",
3051
+ as: "lookupResult",
3052
+ },
3053
+ },
3054
+ {
3055
+ $addFields: {
3056
+ lookupResult: {
3057
+ $cond: {
3058
+ if: { $eq: [{ $size: "$lookupResult" }, 0] },
3059
+ then: [{}],
3060
+ else: "$lookupResult",
3061
+ },
3062
+ },
3063
+ },
3064
+ },
3065
+ {
3066
+ $group: {
3067
+ _id: "$_id",
3068
+ originalFields: { $first: "$$ROOT" },
3069
+ additionalFilesDetails: {
3070
+ $push: {
3071
+ $mergeObjects: ["$additionalFiles", { $first: "$lookupResult" }],
3072
+ },
3073
+ },
3074
+ },
3075
+ },
3076
+ {
3077
+ $replaceRoot: {
3078
+ newRoot: {
3079
+ $mergeObjects: [
3080
+ "$originalFields",
3081
+ { additionalFilesDetails: "$additionalFilesDetails" },
3082
+ ],
3083
+ },
3084
+ },
3085
+ },
3086
+ {
3087
+ $lookup: {
3088
+ from: "fs.files",
3089
+ localField: "filexls",
3090
+ foreignField: "_id",
3091
+ as: "filexls",
3092
+ },
3093
+ },
3094
+ ...lookupStages,
3095
+ ...approvalStage,
3096
+ ];
3097
+
3098
+ if (sortByKey) {
3099
+ const sortStage: any = {};
3100
+ if (sortByKey === "created_At" || sortByKey === "updated_At") {
3101
+ sortStage[`${sortByKey}`] = Number(sort);
3102
+ } else {
3103
+ sortStage[`originalValues.${sortByKey}`] = Number(sort);
3104
+ }
3105
+ pipeline.push({
3106
+ $sort: sortStage,
3107
+ });
3108
+ }
3109
+
3110
+ let countPipeline = [
3111
+ ...pipeline,
3112
+ { $group: { _id: null, count: { $sum: 1 } } },
3113
+ ];
3114
+ if (limit && page) {
3115
+ const skip = (parseInt(page) - 1) * parseInt(limit);
3116
+ pipeline.push({ $skip: skip } as any, { $limit: parseInt(limit) } as any);
3117
+ }
3118
+
3119
+ const [pendingData, totalCount]: any = await Promise.all([
3120
+ Document.aggregate(pipeline),
3121
+ Document.aggregate(countPipeline),
3122
+ ]);
3123
+
3124
+ // fs.writeFileSync('aggregationResult.json', JSON.stringify(pipeline, null, 2));
3125
+
3126
+ let totalPages;
3127
+ if (limit) {
3128
+ totalPages = Math.ceil(totalCount?.[0]?.count / parseInt(limit));
3129
+ }
3130
+
3131
+ return {
3132
+ data: pendingData,
3133
+ totalPages,
3134
+ };
3135
+ } catch (error) {
3136
+ console.log(error?.message);
3137
+ throw new Error(error.message);
3138
+ }
3139
+ }