Subversion Repositories SmartDukaan

Rev

Rev 35001 | Rev 35355 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
34813 aman 1
<meta charset="UTF-8">
2
<link id="modal-bootstrap-css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
3
      rel="stylesheet"/>
4
<style>
5
 
6
    .chart-wrapper {
7
        overflow: hidden;
8
        transition: all 0.3s ease;
9
    }
10
 
11
    .chart-content {
12
        display: flex;
13
        flex-wrap: nowrap;
14
        gap: 20px;
15
        align-items: flex-start;
16
    }
17
 
18
    .chart-container {
19
        flex: 0 0 550px;
20
        height: 320px;
21
    }
22
 
23
    .partner-income-container {
24
        flex: 1 1 auto;
25
        min-width: 300px;
26
    }
27
 
28
 
29
 
30
 
31
    .status-ok {
32
        color: #155724;
35001 aman 33
        font-weight: 700;
34813 aman 34
    }
35
 
36
    .brand-name {
37
        font-size: 1.5rem;
38
        font-weight: 700;
39
        margin-bottom: 15px;
40
        color: #2c3e50;
41
    }
42
 
43
 
44
 
45
    .quantity-value {
46
        font-weight: 600;
47
        color: #2c3e50;
48
    }
49
 
50
    .right-panel {
51
        background: white;
52
        border-radius: 8px;
53
        padding: 20px;
54
        border: 1px solid #e9ecef;
55
    }
56
 
57
 
58
    @keyframes shimmer {
59
        0% {
60
            left: -100%;
61
        }
62
        100% {
63
            left: 100%;
64
        }
65
    }
66
 
67
 
68
 
69
    .brand-logo {
70
        width: 80px;
71
        height: 80px;
72
        object-fit: contain;
73
        border-radius: 12px;
74
        background-color: #f8f9fa;
75
        padding: 2px;
76
    }
77
 
78
 
79
 
80
    .modal-backdrop.in {
81
        filter: alpha(opacity=50);
82
        opacity: 0.35;
83
        width: auto;
84
        height: auto;
85
    }
86
 
87
    .brandText {
88
        transform: rotate(270deg) !important;
89
    }
90
 
91
    .rounded-corner {
92
        border-top-left-radius: 30px !important;
93
        border-top-right-radius: 30px !important;
94
 
95
    }
96
 
97
    .bg-danger {
98
        background-color: #D3181F !important;
99
    }
100
 
101
    .fs-8 {
102
        font-size: 25px !important;
103
    }
104
 
105
    .table-bordered th {
106
        border: 1px solid rgba(255, 255, 255, 0.2);
107
    }
108
 
109
    .table-bordered td {
110
        border: 1px solid #dee2e6;
111
        vertical-align: middle;
112
    }
113
 
114
    .fs-5 {
115
        font-size: 1.2rem !important;
116
    }
117
    .brand-btn {
35001 aman 118
        background: #444;
119
        color: white;
120
        border: none;
121
        padding: 8px 16px;
122
        border-radius: 20px;
123
        cursor: pointer;
34813 aman 124
        transition: all 0.3s ease;
35001 aman 125
        margin: 2px;
34813 aman 126
    }
127
 
35001 aman 128
    .brand-btn:hover {
129
        background: #666;
130
        color: white;
34813 aman 131
    }
132
 
133
 
35001 aman 134
    .section-header {
135
        background: #7a7a7a;
136
        color: white;
137
        padding: 15px;
138
        margin: 20px 0 10px 0;
139
        border-radius: 8px;
140
        text-align: center;
141
        font-weight: bold;
35119 aman 142
        font-size: 1.6rem;
35001 aman 143
    }
144
 
145
    .table thead th {
146
        background: #555;
147
        color: white;
148
        border: none;
149
        font-weight: bold;
150
        text-align: center;
151
        vertical-align: middle;
152
        padding: 15px 8px;
153
    }
154
 
155
    .table tbody td {
156
        text-align: center;
157
        vertical-align: middle;
158
        padding: 12px 8px;
159
        border: 1px solid #dee2e6;
160
    }
161
 
162
 
163
    .status-order {
164
        color: #17a2b8 !important;
165
        font-weight: bold;
166
    }
167
 
168
 
169
    .no-data-row {
170
        background: #f8f9fa;
171
        color: #6c757d;
172
        font-style: italic;
173
    }
174
 
34813 aman 175
    .curve {
176
        padding-left: 100px !important;
177
        border-radius: 40px 0 0 40px !important;
178
        width: 250px !important;
179
    }
180
 
181
 
182
    .stock-ribbon {
183
        position: relative;
184
        padding: 5px 15px;
185
        color: white;
186
        clip-path: polygon(0 0, 100% 0, 95% 100%, 0 100%);
187
        min-width: 220px;
188
    }
189
 
190
    .mandatory-ribbon {
191
        background-color: #D3181F !important;
192
    }
193
 
194
    .other-ribbon {
195
        background-color: #000;
196
    }
197
 
198
    .brand-item {
199
        display: flex;
200
        align-items: center;
201
        margin-bottom: 20px;
202
    }
203
 
204
    .category-header {
205
        font-size: 15px;
206
        font-weight: bold;
207
        margin: 20px 0;
208
        padding-left: 15px;
209
    }
210
 
211
    .mandatory-header {
212
        color: #d32f2f;
213
    }
214
 
215
    .other-header {
216
        color: #333;
217
    }
218
 
219
 
220
    .bg-dark-light {
221
        background-color: #3e3e3e !important;
222
        color: white;
223
    }
224
 
225
    .table-bordered td, .table-bordered th {
226
        border: 1px solid #dee2e6;
227
    }
228
 
229
    .brand-circle {
230
        width: 60px;
231
        height: 60px;
232
        object-fit: cover;
233
        border: 5px solid rgb(122, 116, 116);
234
    }
235
 
236
 
237
    .currency::before {
238
        content: "\20B9";
239
    }
240
 
241
    .fs-3, .fs-5 {
242
        font-weight: normal;
243
    }
244
 
245
    .fw-bold {
246
        font-weight: bold !important;
247
    }
248
 
249
    .btn {
250
        font-weight: normal;
251
    }
252
 
253
    .payment-circle {
254
        width: 200px;
255
        height: 200px;
256
        border: 25px solid #e0dcdc;
257
        border-radius: 50%;
258
        display: flex;
259
        align-items: center;
260
        justify-content: center;
261
        transition: transform 0.3s ease;
262
    }
263
 
264
 
265
    .payment-amount {
266
        font-size: 18px;
267
        font-weight: 700;
268
        margin-bottom: 10px;
269
        text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
35001 aman 270
        color: white;
34813 aman 271
    }
272
 
273
    .payment-label {
274
        font-size: 18px;
275
        line-height: 1.3;
276
        text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
277
    }
278
 
279
 
280
    .table-border td {
281
        border: 1px solid black !important;
282
    }
283
 
284
    .table-border thead {
285
        border: 1px solid black;
286
    }
287
 
288
    .p-0 {
289
        padding: 0 !important;
290
    }
291
</style>
292
<body style="background-color: rgb(247, 247, 247);zoom: 100%!important;">
293
<div style="overflow-y:auto;max-height: 120vh; ">
294
    <section id="ajaxSection" class="rounded"
295
             style="max-height: 120vh; overflow-y: auto;">
296
        <div class="w-full bg-danger h-25 py-3 mb-4">
297
            <h1 class="text-center text-white " style="font-size: 30px !important; font-weight: 800">Pending
298
                Tasks</h1>
299
        </div>
300
        <div class="container">
301
            ##-----------------------------------------------GRN Pending -----------------------------------------------------
302
            <div class="container-fluid p-4">
303
                #if($grnPendingOrders.entrySet().size()>0)
304
                    <div class="row justify-content-center">
305
                        <div class="col-10">
306
                            <div class="bg-dark-light rounded-3 p-3 shadow rounded-corner">
307
                                <h1 class="text-white text-center mb-0 fw-bold py-2 fs-8">GRN Pending</h1>
308
                            </div>
309
                        </div>
310
                    </div>
311
 
312
                    <div class="table-responsive rounded-3 shadow p-5">
313
                        <table id="grnTable" class="table table-bordered mb-0 table-border" style="width:100%">
314
                            <thead>
315
                            <tr class="bg-danger text-white">
316
                                <th class="ps-4 fs-5 fw-bold text-uppercase bg-danger text-white text-center"
317
                                    style="padding: 10px !important;">BRANDS
318
                                </th>
319
                                <th class="fs-5 fw-bold text-uppercase bg-danger text-white text-center"
320
                                    style="padding: 10px !important;">QUANTITY
321
                                </th>
322
                                <th class="pe-4 fs-5 fw-bold text-uppercase bg-danger text-white text-center"
323
                                    style="padding: 10px !important;">VALUE
324
                                </th>
325
                            </tr>
326
                            </thead>
327
                            <tbody>
328
                                #set($mandatoryBrands = ["Vivo", "Oppo", "Samsung", "Realme"])
329
                                #foreach($entry in $grnPendingOrders.entrySet())
330
                                    #set($brand = $entry.key)
331
                                    #set($details = $entry.value)
332
                                <tr class="">
333
                                    <td class="ps-4 text-center p-0">
334
                                        <div class="d-flex align-items-center justify-content-center">
335
                                            <div class="row align-items-center" style="width: 200px;">
336
                                                <div class="col-auto">
337
                                                    <img src="$brandLogos.getOrDefault($brand,
338
                                                        'https://static.vecteezy.com/system/resources/thumbnails/025/213/042/small_2x/mobile-phone-icon-in-black-circle-png.png')"
339
                                                         alt="$brand logo"
340
                                                         class="brand-logo rounded-circle"
341
                                                         style="width:35px;height:35px">
342
                                                </div>
343
                                                <div class="col text-start">
344
                                                    <span class="fw-bold fs-5">$brand</span>
345
                                                </div>
346
                                            </div>
347
                                        </div>
348
                                    </td>
349
                                    <td class="text-center align-middle fs-5 fw-semibold p-0">
350
                                        $details.quantity
351
                                    </td>
352
                                    <td class="pe-4 text-center align-middle fs-5 fw-semibold currency p-0 ">
353
                                        $nf.format($details.mrp)
354
                                    </td>
355
                                </tr>
356
                                #end
357
                            </tbody>
358
                        </table>
359
                    </div>
360
                #end
361
            </div>
362
 
363
            ##-----------------------------------------------Unbilled Activated -----------------------------------------------------
364
 
365
            <div class="container-fluid p-4">
366
                #if($unbilledActivated.entrySet().size()>0)
367
                    <div class="row justify-content-center">
368
                        <div class="col-10">
369
                            <div class="bg-dark-light rounded-3 p-3 shadow rounded-corner">
370
                                <h1 class="text-white text-center mb-0 py-2 fw-bold fs-8">Pending Billing</h1>
371
                            </div>
372
                        </div>
373
                    </div>
374
 
375
                    <div class="table-responsive rounded-3 shadow p-5">
376
                        <table id="unbilledTable" class="table table-bordered mb-0 table-border" style="width:100%">
377
 
378
                            <thead>
379
                            <tr class="bg-danger text-white">
380
                                <th class="ps-4 fs-5 fw-bold text-uppercase bg-danger text-white text-center p-0"
381
                                    style="padding: 10px !important;">BRANDS
382
                                </th>
383
                                <th class="fs-5 fw-bold text-uppercase bg-danger text-white text-center p-0"
384
                                    style="padding: 10px !important;">QUANTITY
385
                                </th>
386
                                <th class="pe-4 fs-5 fw-bold text-uppercase bg-danger text-white text-center p-0"
387
                                    style="padding: 10px !important;">VALUE
388
                                </th>
389
                            </tr>
390
                            </thead>
391
                            <tbody>
392
                                #set($mandatoryBrands = ["Vivo", "Realme", "Oppo", "Samsung"])
393
 
394
                                #foreach($entry in $unbilledActivated.entrySet())
395
                                    #set($brand = $entry.key)
396
                                    #set($details = $entry.value)
397
                                <tr>
398
                                    <td class="ps-4 text-center p-0">
399
                                        <div class="d-flex align-items-center justify-content-center">
400
                                            <div class="row align-items-center" style="width: 200px;">
401
                                                <div class="col-auto">
402
                                                    <img src="$brandLogos.getOrDefault($brand,
403
                                                        'https://static.vecteezy.com/system/resources/thumbnails/025/213/042/small_2x/mobile-phone-icon-in-black-circle-png.png')"
404
                                                         alt="$brand logo"
405
                                                         class="brand-logo rounded-circle"
406
                                                         style="width:35px;height:35px">
407
                                                </div>
408
                                                <div class="col text-start">
409
                                                    <span class="fw-bold fs-5">$brand</span>
410
                                                </div>
411
                                            </div>
412
                                        </div>
413
                                    </td>
414
                                    <td class="text-center align-middle fs-5 fw-semibold   p-0">
415
                                        $details.quantity
416
                                    </td>
417
                                    <td class="pe-4 text-center align-middle p-0 currency fw-semibold fs-5">
418
                                        $nf.format( $details.mtd)
419
                                    </td>
420
                                </tr>
421
                                #end
422
                            </tbody>
423
                        </table>
424
                    </div>
425
                #end
426
            </div>
427
 
428
 
429
            ##-----------------------------------------------Loan Amount -----------------------------------------------------
34971 aman 430
            #if( $totalDefaultAmount != 0 || $totalOverdueAmount != 0 || $totalDueAmount != 0 || $totalLoan != 0 )
431
                <div class="container-fluid p-4">
432
                    <div class="row mb-5 justify-content-center">
433
                        <div class="col-10">
434
                            <div class="bg-dark-light rounded-3 p-3 shadow rounded-corner">
435
                                <h1 class="text-white text-center mb-0  fw-bold py-2 fs-8">Loan </h1>
436
                            </div>
34813 aman 437
                        </div>
438
                    </div>
34971 aman 439
                    <div class="row justify-content-center">
440
                        <div class="col-12 col-md-4 text-center ">
441
                            <div class="payment-circle shadow-lg shadow-dark mx-auto "
442
                                 style="background-color: #cc0000 !important;">
443
                                <div class="payment-content">
444
                                    <div class="payment-amount currency"> $nf.format( $totalDefaultAmount) </div>
34813 aman 445
 
34971 aman 446
                                </div>
34813 aman 447
                            </div>
34971 aman 448
                            <h1 class="payment-label fw-bold mt-4" style="font-weight: 400 !important;">Default
449
                                Payment<br>(Above
450
                                30 days)</h1>
34813 aman 451
                        </div>
452
 
34971 aman 453
                        <div class="col-12 col-md-4 text-center">
454
                            <div class="payment-circle shadow-lg mx-auto" style="background-color: #FF9433 !important;">
455
                                <div class="payment-content">
456
                                    <div class="payment-amount currency">  $nf.format($totalOverdueAmount) </div>
457
                                </div>
34813 aman 458
                            </div>
34971 aman 459
                            <h1 class="payment-label fw-bold mt-4"
460
                                style="font-size: 20px !important;  font-weight: 400 !important;">Due Payment<br>(Above
461
                                15
462
                                Days)</h1>
463
 
34813 aman 464
                        </div>
34971 aman 465
                        <div class="col-12 col-md-4 text-center">
466
                            <div class="payment-circle shadow-lg mx-auto "
467
                                 style="background-color: #00B050 !important;">
468
                                <div class="payment-content">
469
                                    <div class="payment-amount currency">  $nf.format($totalDueAmount) </div>
470
                                </div>
34813 aman 471
                            </div>
34971 aman 472
                            <h1 class="payment-label fw-bold mt-4"
473
                                style="font-size: 20px !important; font-weight: 400 !important;">Other Loan<br>(Within
474
                                15
475
                                Days)</h1>
34813 aman 476
                        </div>
477
 
478
 
34971 aman 479
                        <div class="mt-4 mx-5 " style="margin-top: 6rem !important;">
480
                            <h1 class="text-center " style="font-size:30px !important;font-weight:300 !important;">Total
481
                                Loan Value :
482
                                <span class="currency fw-bold"> $nf.format( $totalLoan )</span>
483
                            </h1>
484
                        </div>
34813 aman 485
                    </div>
486
                </div>
34971 aman 487
            #end
34813 aman 488
        </div>
489
 
490
        <div class="w-full bg-danger h-25 py-3 my-4">
491
            <h1 class="text-center text-white fw-bold" style="font-size: 30px !important; font-weight: 800">My Business
492
                Analysis</h1>
493
        </div>
494
        <div class="container-fluid p-5 mt-5">
495
 
496
            <div class="row mb-1 my-4 mx-3 justify-content-center">
497
                <div class="col-10">
498
                    <div class="bg-dark-light rounded-3 p-3 shadow rounded-corner">
499
                        <h1 class="text-white text-center mb-0 fw-bold py-2 fs-8">My Earning </h1>
500
                    </div>
501
                </div>
502
            </div>
503
 
504
            <div class="container mt-4">
505
                <div class="chart-wrapper card shadow-lg rounded-5 p-2">
506
                    <span class="text-danger fs-3 fw-bold text-end">** Click on the bar to see the details</span>
507
 
508
                    <div class="chart-content ">
509
                        <div class="chart-container">
510
                            <canvas id="sixMonthChart"></canvas>
511
                        </div>
512
                        <div id="partner-income" class="partner-income-container"></div>
513
                    </div>
514
                </div>
515
            </div>
516
 
517
        </div>
518
        ##        ----------------------------------------anyalysis---------------------------=//
519
        #set($marketShareData = [
520
        {"Brand": "Vivo", "MarketShare": "20%", "Quarter": "Q1 2025", "BgColor": "#2196F3", "Rank": "1"},
521
        {"Brand": "Samsung", "MarketShare": "18%", "Quarter": "Q1 2025", "BgColor": "#1428A0", "Rank": "2"},
522
        {"Brand": "Xiaomi", "MarketShare": "13%", "Quarter": "Q1 2025", "BgColor": "#FF6900", "Rank": "3"},
523
        {"Brand": "OPPO", "MarketShare": "12%", "Quarter": "Q1 2025", "BgColor": "#006B33", "Rank": "4"},
524
        {"Brand": "realme", "MarketShare": "11%", "Quarter": "Q1 2025", "BgColor": "#FFC915", "Rank": "5"},
525
        {"Brand": "Others", "MarketShare": "26%", "Quarter": "Q1 2025", "BgColor": "#6b7280", "Rank": "-"}
526
        ])
527
 
528
        <div class="container-fluid p-5">
529
            <div class="row mb-1 my-4 mx-3 justify-content-center">
530
                <div class="col-10">
531
                    <div class="bg-dark-light rounded-3 p-3 shadow rounded-corner">
532
                        <h1 class="text-white text-center mb-0 fw-bold py-2 fs-8">Brand Analysis </h1>
533
                    </div>
534
                </div>
535
            </div>
35119 aman 536
            <img src="https://images.smartdukaan.com/uploads/campaigns/image2025-10-03/brand-analysis-note-11759485977860.png"
537
                 class="w-75 p-2 d-block mx-auto"
538
                 alt="note">
34813 aman 539
            ##        ----------------------------------------stagged chart ------------------------------------------
540
            <div class="container d-flex ">
541
                <div class="p-5" style=" height: 350px !important;width: 650px !important;">
542
                    <div class="chart-title fs-2 text-center fw-bold">Brands Share Analysis (QTY)</div>
543
                    <canvas id="combinedStackedChart"></canvas>
544
                </div>
545
                <div class="" style="width: 400px!important;">
546
                    <div class="right-panel">
547
                        <h4 class="mb-4">Quantity Analysis</h4>
548
 
549
                        <div class="brand-analysis-container">
550
                            <div class="table-responsive">
551
                                <table class="table table-striped table-hover">
552
                                    <thead class="table-light table-bordered">
553
                                    <tr>
554
                                        <th scope="col">Brand Name</th>
555
                                        <th scope="col">Available Models</th>
556
                                        <th scope="col">Required Models</th>
557
                                        <th scope="col" class="text-center">Status</th>
558
                                    </tr>
559
                                    </thead>
560
                                    <tbody class="table-bordered">
561
                                        #foreach($brandName in $targetBrands)
562
                                            #set($analysis = $brandAnalysisData.get($brandName))
563
                                        <tr>
564
                                            <td>
565
                                                <strong class="brand-name">${brandName}</strong>
566
                                            </td>
567
                                            <td>
568
                                                <span class="quantity-value">${analysis.get('availableQuantity')}</span>
569
                                            </td>
570
                                            <td>
571
                                                <span class="quantity-value">${analysis.get('requiredQuantity')}</span>
572
                                            </td>
573
                                            <td class="text-center">
574
                        <span class="badge #if($analysis.get('isOK'))bg-success#else bg-danger#end">
575
                            ${analysis.get('status')}
576
                        </span>
577
                                            </td>
578
                                        </tr>
579
                                        #end
580
                                    </tbody>
581
                                </table>
582
                            </div>
583
                        </div>
584
                    </div>
585
                </div>
586
            </div>
587
 
588
 
589
            ##        -----------------------------------------------Fast Selling & HID model ------------------------------------------------
35001 aman 590
            <div id="brand-table-section">
34813 aman 591
            <div class="container-fluid py-3">
35001 aman 592
                <div class="card mb-4 p-4">
593
                    <!-- Main Header -->
594
                    <div class="row justify-content-center">
34813 aman 595
                        <div class="col-10">
596
                            <div class="bg-dark-light rounded-3 p-3 shadow rounded-corner">
597
                                <h3 class="text-white text-center mb-0  fw-bold py-2 fs-8">Fast Selling Models &
598
                                    HID </h3>
599
                            </div>
600
                        </div>
601
                    </div>
602
 
35001 aman 603
                    <div class="card-body">
604
                        <!-- Brand Filter Buttons -->
605
                        <div class="d-flex flex-wrap justify-content-center gap-2 p-3 border-bottom mb-4">
606
                            <!-- Velocity Template Loop for Brands -->
34813 aman 607
                            #foreach($brand in $brands)
35001 aman 608
                                <button class="brand-btn" data-brand="$brand.toLowerCase()">$brand</button>
34813 aman 609
                            #end
610
                        </div>
611
 
35001 aman 612
                        <!-- HID Section -->
613
                        <div class="section-header">HID</div>
34813 aman 614
 
35001 aman 615
                        <div class="table-responsive">
616
                            <table class="table ">
617
                                <thead>
618
                                <tr>
619
                                    <th class="w-25">Model</th>
620
                                    <th class=" w-25">Suggested Qty</th>
621
                                    <th class="w-25">My Stock + Pending Indent</th>
622
                                    <th class="w-25">Remarks</th>
623
                                </tr>
624
                                </thead>
625
                                <tbody>
626
                                <!-- Velocity Template Loop for HID Data -->
627
                                    #foreach($brand in $brands)
628
                                        #if($hidAllocationModelBrandMap.containsKey($brand) && !$hidAllocationModelBrandMap.get($brand).isEmpty())
629
                                            #foreach($model in $hidAllocationModelBrandMap.get($brand))
630
                                            <tr class="brand-data" data-brand="$brand.toLowerCase()">
631
                                                <td><strong>$model.getModelNumber()</strong></td>
632
                                                <td class="w-25"><strong>$model.getHidAllocation()</strong></td>
633
                                                <td><strong>$model.getAvailableStock()</strong></td>
634
                                                <td class="w-25">
635
                                                    #if($model.getAvailableStock() == 0)
636
                                                        <span class="text-danger fw-bold">Urgently Required</span>
34813 aman 637
                                                    #elseif($model.getAvailableStock() < $model.getHidAllocation())
35001 aman 638
                                                        <span class="status-order">Need to Order</span>
34813 aman 639
                                                    #else
35001 aman 640
                                                        <span class="status-ok fw-bold">Stock OK</span>
641
                                                    #end
642
                                                </td>
643
                                            </tr>
644
                                            #end
645
                                        #else
646
                                        <tr class="brand-data no-data-row" data-brand="$brand.toLowerCase()">
647
                                            <td colspan="4">No Data Available</td>
648
                                        </tr>
649
                                        #end
650
                                    #end
651
                                </tbody>
652
                            </table>
34813 aman 653
                        </div>
654
 
35001 aman 655
                        <!-- Fast Selling Models Section -->
656
                        <div class="section-header">Fast Selling Model</div>
34813 aman 657
 
35001 aman 658
                        <div class="table-responsive">
659
                            <table class="table  ">
660
                                <tbody>
661
                                <!-- Velocity Template Loop for Fast Selling Data -->
662
                                    #if($brandwiseFastmoving && $brandwiseFastmoving.entrySet().size() > 0)
663
                                        #foreach($brandEntry in $brandwiseFastmoving.entrySet())
664
                                            #foreach($model in $brandEntry.value)
665
                                                #set($processingQty = $processingOrderCatalogQtyMap.get($model.getCatalogId()))
666
                                                #if(!$processingQty)
667
                                                    #set($processingQty = 0)
668
                                                #end
669
                                                #set($totalQty = $model.partnerCurrentQty + $processingQty)
670
                                                #set($suggestedQty = 2)
34813 aman 671
 
35001 aman 672
                                            <tr class="brand-data" data-brand="$brandEntry.key.toLowerCase()">
673
                                                <td class="w-25"><strong>$model.modelNumber</strong></td>
674
                                                <td class="suggested-qty-col w-25"><strong>$suggestedQty</strong></td>
675
                                                <td class="w-25">
676
                                                    <strong>
677
                                                        $model.partnerCurrentQty
34813 aman 678
                                                        #if($processingOrderCatalogQtyMap.get($model.getCatalogId()))
35001 aman 679
                                                            + $processingOrderCatalogQtyMap.get($model.getCatalogId())
34813 aman 680
                                                        #end
681
                                                    </strong>
35001 aman 682
                                                </td>
683
                                                <td class="remarks-col w-25">
684
                                                    #if($totalQty == 0)
685
                                                        <span class="text-danger fw-bold">Urgently Required</span>
34813 aman 686
                                                    #elseif($totalQty < 2)
35001 aman 687
                                                        <span class="status-order">Need to Order</span>
34813 aman 688
                                                    #else
35001 aman 689
                                                        <span class="status-ok fw-bold">Stock OK</span>
690
                                                    #end
691
                                                </td>
692
                                            </tr>
693
                                            #end
694
                                        #end
695
                                    #else
696
                                    <tr class="brand-data no-data-row">
697
                                        <td colspan="4">No Data Available</td>
698
                                    </tr>
699
                                    #end
700
                                </tbody>
701
                            </table>
702
                        </div>
35119 aman 703
                        <div class="section-header">Running Model</div>
704
 
705
                        <div class="table-responsive">
706
                            <table class="table  ">
707
                                <tbody>
708
                                <!-- Velocity Template Loop for Fast Selling Data -->
709
                                    #if($brandwiseRunningmoving && $brandwiseRunningmoving.entrySet().size() > 0)
710
                                        #foreach($brandEntry in $brandwiseRunningmoving.entrySet())
711
                                            #foreach($model in $brandEntry.value)
712
                                                #set($processingQty = $processingOrderCatalogQtyMap.get($model.getCatalogId()))
713
                                                #if(!$processingQty)
714
                                                    #set($processingQty = 0)
715
                                                #end
716
                                                #set($totalQty = $model.partnerCurrentQty + $processingQty)
717
                                                #set($suggestedQty = 2)
718
 
719
                                            <tr class="brand-data" data-brand="$brandEntry.key.toLowerCase()">
720
                                                <td class="w-25"><strong>$model.modelNumber</strong></td>
721
                                                <td class="suggested-qty-col w-25"><strong>$suggestedQty</strong></td>
722
                                                <td class="w-25">
723
                                                    <strong>
724
                                                        $model.partnerCurrentQty
725
                                                        #if($processingOrderCatalogQtyMap.get($model.getCatalogId()))
726
                                                            + $processingOrderCatalogQtyMap.get($model.getCatalogId())
727
                                                        #end
728
                                                    </strong>
729
                                                </td>
730
                                                <td class="remarks-col w-25">
731
                                                    #if($totalQty == 0)
732
                                                        <span class="text-danger fw-bold">Urgently Required</span>
733
                                                    #elseif($totalQty < 2)
734
                                                        <span class="status-order">Need to Order</span>
735
                                                    #else
736
                                                        <span class="status-ok fw-bold">Stock OK</span>
737
                                                    #end
738
                                                </td>
739
                                            </tr>
740
                                            #end
741
                                        #end
742
                                    #else
743
                                    <tr class="brand-data no-data-row">
744
                                        <td colspan="4">No Data Available</td>
745
                                    </tr>
746
                                    #end
747
                                </tbody>
748
                            </table>
749
                        </div>
34813 aman 750
                    </div>
751
                </div>
752
            </div>
35001 aman 753
            </div>
34813 aman 754
            ##        -----------------------------------------------My Stock ------------------------------------------------
755
            <div class="row mb-1 my-4 justify-content-center">
756
                <div class="col-10">
757
                    <div class=" bg-dark-light rounded-3 p-3 shadow rounded-corner">
758
                        <h1 class="text-center mb-0 fw-bold py-2 text-white fs-8">My Stock</h1>
759
                    </div>
760
                </div>
761
            </div>
762
 
763
            <div class="row px-5" style="margin-left: 10rem !important;">
764
                <div class="col-md-6">
765
                    <div class="category-header mandatory-header">MANDATORY BRANDS</div>
766
 
767
                    #foreach($brandStockPrice in $brandStockPrices)
768
                        #set($mandatoryBrands = ["Vivo", "Oppo", "Samsung", "Realme"])
769
                        #if($mandatoryBrands.contains($brandStockPrice.getBrand()))
770
                            <div class="brand-item">
771
                                <div class="position-relative" style="z-index: 10">
772
                                    <img src="${brandStockPrice.getBrandUrl()}"
773
                                         class="brand-circle img-fluid rounded-circle shadow border border-danger"
774
                                         data-stockbrand="$brandStockPrice.getBrand()"
775
                                         alt="$brandStockPrice.getBrand()">
776
                                </div>
777
 
778
                                <div class="stock-ribbon mandatory-ribbon ms-n3  position-absolute curve ">
779
                                    <div class="d-flex d-flex  mb-1">
780
                                        <span class="fw-bold text-start fs-5">QTY:  </span>
781
                                        <span class="fw-bold text-start fs-5">$brandStockPrice.getTotalQty()</span>
782
                                    </div>
783
                                    <div class="d-flex ">
784
                                        <span class="fw-bold text-start fs-5">Value:  </span>
785
                                        <span class="currency fw-bold text-start fs-5">  $nf.format( $brandStockPrice.getTotalValue())</span>
786
                                    </div>
787
 
788
                                    #if($brandStockPrice.getAgedValue() > 0)
789
                                        <div class="aged-stock mt-2 pt-2 border-top border-light border-opacity-25">
790
                                            <div class="d-flex justify-content-between">
791
                                                <span>Focus Stock:</span>
792
                                                <span>
793
                                        <span class="currency">  $nf.format($brandStockPrice.getAgedValue()) </span>/
794
                                                    $brandStockPrice.getAgedQty()
795
                                    </span>
796
                                            </div>
797
                                        </div>
798
                                    #end
799
                                </div>
800
                            </div>
801
                        #end
802
                    #end
803
                </div>
804
 
805
                <div class="col-md-6">
806
                    <div class="category-header other-header">OTHER BRANDS</div>
807
                    #set($mandatoryBrands = ["Vivo", "Oppo", "Samsung", "Realme"])
808
 
809
                    #foreach($brandStockPrice in $brandStockPrices)
810
                        #if(!$mandatoryBrands.contains($brandStockPrice.getBrand()))
811
                            <div class="brand-item">
812
                                <div class="position-relative " style="z-index: 10">
813
                                    <img src="${brandStockPrice.getBrandUrl()}"
814
                                         class="brand-circle img-fluid rounded-circle shadow border border-dark"
815
                                         data-stockbrand="$brandStockPrice.getBrand()"
816
                                         alt="$brandStockPrice.getBrand()">
817
                                </div>
818
 
819
                                <div class="stock-ribbon other-ribbon ms-n3 position-absolute  curve">
820
                                    <div class="d-flex d-flex  mb-1">
821
                                        <span class="fw-bold text-start fs-5">QTY:  </span>
822
                                        <span class="fw-bold text-start fs-5">$brandStockPrice.getTotalQty()</span>
823
                                    </div>
824
                                    <div class="d-flex ">
825
                                        <span class="fw-bold text-start fs-5">Value:  </span>
826
                                        <span class="currency fw-bold text-start fs-5">  $nf.format($brandStockPrice.getTotalValue())</span>
827
                                    </div>
828
 
829
                                    #if($brandStockPrice.getAgedValue() > 0)
830
                                        <div class="aged-stock mt-2 pt-2 border-top border-light border-opacity-25">
831
                                            <div class="d-flex justify-content-between">
832
                                                <span>Focus Stock:</span>
833
                                                <span>
834
                                        <span class="currency"> $nf.format($brandStockPrice.getAgedValue())</span>/
835
                                                    $brandStockPrice.getAgedQty()
836
                                    </span>
837
                                            </div>
838
                                        </div>
839
                                    #end
840
                                </div>
841
                            </div>
842
                        #end
843
                    #end
844
                </div>
845
            </div>
846
 
847
            ##        ------------------------------------my stock ageing---------------------------------
848
 
849
            <div class="card shadow-lg rounded-3">
850
                <div class="row mb-1 my-4 justify-content-center">
851
                    <div class="col-10">
852
                        <div class="bg-dark-light rounded-3 p-3 shadow rounded-corner">
853
                            <h1 class="text-white text-center mb-0 fw-bold py-2 fs-8">My Stock Ageing</h1>
854
                        </div>
855
                    </div>
856
                </div>
857
                <div class="card-body">
858
                    <div class="row mb-4">
859
                        <div class="col-md-4">
860
                            <div class="btn-group" role="group">
861
                                <button type="button" class="btn btn-danger rounded-pill px-4 me-2 fs-5" id="btnVolume">
862
                                    Volume
863
                                </button>
864
                                <button type="button" class="btn btn-danger rounded-pill px-4 fs-5" id="btnValue">Value
865
                                </button>
866
                            </div>
867
                        </div>
868
                    </div>
869
 
870
                    <div class="table-responsive rounded-5 p-5">
871
                        <table class="table table-bordered rounded-4" id="stockAgingTable">
872
                            <thead>
35001 aman 873
                            <tr class="text-center ">
34813 aman 874
                                <th></th>
35001 aman 875
                                <th class="align-middle text-white fs-5 fw-bold" style="width: 180px;">
34813 aman 876
                                    Brands
877
                                </th>
878
                                #set($intervals = ["Less Than 15 Days", "16 - 30 Days", "31 - 45 Days",
879
                                    "More Than 45 Days"])
880
                                #foreach($interval in $intervals)
35001 aman 881
                                    <th class="align-middle fs-5 fw-bold  text-wrap"
34813 aman 882
                                        style="width: 180px;height: 55px !important; word-wrap: break-word; white-space: normal;">
35001 aman 883
                                        <span class="text-white  text-wrap ">$interval</span>
34813 aman 884
                                    </th>
885
                                #end
886
                            </tr>
887
                            </thead>
888
                            <tbody>
889
                                #if(!$inventoryGroupedByBrand.isEmpty())
890
                                    #set($mandatoryBrands = ["vivo", "oppo", "samsung", "realme"])
891
                                    #set($otherBrands = [])
892
 
893
                                <tr>
894
                                    <td class="align-middle bg-secondary text-center text-white fw-bold " rowspan="5"
895
                                        style="width: 60px !important; font-size: 10px !important;">
896
                                        <div class="brandText">MANDATORY BRANDS</div>
897
                                    </td>
898
                                </tr>
899
 
900
                                    #foreach($brandKey in $mandatoryBrands)
901
                                        #set($found = false)
902
                                        #foreach($entry in $inventoryGroupedByBrand.entrySet())
903
                                            #if($entry.getKey().toLowerCase() == $brandKey)
904
                                                #set($found = true)
905
                                            <tr>
906
                                                <td class="brand-cell text-start p-0">
35001 aman 907
                                                    <div class="p-3 bg-white  #getBrandBgColor($entry.getKey())"
34813 aman 908
                                                         style="height: 40px; display: flex; align-items: center; justify-content: start;">
35001 aman 909
                                                    <span class="text-black fw-bold fs-5"><img
34813 aman 910
                                                            src="$brandLogos.getOrDefault($entry.getKey(),
911
                                                                'https://static.vecteezy.com/system/resources/thumbnails/025/213/042/small_2x/mobile-phone-icon-in-black-circle-png.png')"
912
                                                            alt="$entry.getKey() logo"
913
                                                            class="brand-logo rounded-circle me-3"
914
                                                            style="width:35px;height:35px">$entry.getKey()</span>
915
                                                    </div>
916
                                                </td>
917
                                                #foreach($i in [0..3])
918
                                                    <td class="align-middle text-center  $bgColors.get($i)"
919
                                                        style="opacity: 0.9;">
920
                                                        #set($qty = 0)
921
                                                        #set($value = 0)
922
                                                        #foreach($item in $entry.getValue())
923
                                                            #if($i < $item.getValues().size() && $item.getValues().get($i))
924
                                                                #set($qty = $math.add($qty, $item.getValues().get($i).getQuantity()))
925
                                                                #set($itemValue = $math.mul($item.getValues().get($i).getPrice(), $item.getValues().get($i).getQuantity()))
926
                                                                #set($value = $math.add($value, $itemValue))
927
                                                            #end
928
                                                        #end
35001 aman 929
                                                        <div class="volume-view fs-5 fw-bold text-black ">$qty</div>
930
                                                        <div class="value-view currency fs-5 fw-bold text-black"
34813 aman 931
                                                             style="display: none;"> $nf.format(  $value)</div>
932
                                                    </td>
933
                                                #end
934
                                            </tr>
935
                                            #end
936
                                        #end
937
 
938
                                        #if(!$found)
939
                                        <tr>
940
                                            <td class="brand-cell text-center p-0">
35001 aman 941
                                                <div class="p-3 bg-white"
34813 aman 942
                                                     style="height: 40px; display: flex; align-items: center; justify-content: center;">
35001 aman 943
                                                    <span class="text-black fw-bold">$brandKey</span>
34813 aman 944
                                                </div>
945
                                            </td>
946
                                            #foreach($i in [0..3])
947
                                                <td class="text-center align-middle $bgColors.get($i)"
948
                                                    style="opacity: 0.9;">
35001 aman 949
                                                    <div class="volume-view fs-5 fw-bold text-black">0</div>
950
                                                    <div class="value-view currency fs-5 fw-bold text-black"
34813 aman 951
                                                         style="display: none;">0.00
952
                                                    </div>
953
                                                </td>
954
                                            #end
955
                                        </tr>
956
                                        #end
957
                                    #end
958
 
959
                                <tr>
960
                                    <td class="align-middle bg-dark-light text-center text-white fw-bold "
961
                                        rowspan="$inventoryGroupedByBrand.size()"
962
                                        style="width: 60px !important; font-size: 10px !important;">
963
                                        <div class="brandText">OTHER BRANDS</div>
964
                                    </td>
965
                                </tr>
966
 
967
                                    #foreach($entry in $inventoryGroupedByBrand.entrySet())
968
                                        #set($isOtherBrand = true)
969
                                        #foreach($mandatoryBrand in $mandatoryBrands)
970
                                            #if($entry.getKey().toLowerCase() == $mandatoryBrand)
971
                                                #set($isOtherBrand = false)
972
                                                #break
973
                                            #end
974
                                        #end
975
 
976
                                        #if($isOtherBrand)
977
                                        <tr>
978
                                            <td class="brand-cell text-start p-0">
35001 aman 979
                                                <div class="p-3 text-black"
34813 aman 980
                                                     style="height: 40px; display: flex; align-items: center; justify-content: start;">
35001 aman 981
                                                <span class="text-black fw-bold fs-5  "><img
34813 aman 982
                                                        src="$brandLogos.getOrDefault($entry.getKey(),
983
                                                            'https://static.vecteezy.com/system/resources/thumbnails/025/213/042/small_2x/mobile-phone-icon-in-black-circle-png.png')"
984
                                                        alt="$entry.getKey() logo"
985
                                                        class="brand-logo rounded-circle me-3"
986
                                                        style="width:35px;height:35px">$entry.getKey()</span>
987
                                                </div>
988
                                            </td>
989
                                            #foreach($i in [0..3])
990
                                                <td class="text-center align-middle pb-4 $bgColors.get($i)"
991
                                                    style="opacity: 0.9;">
992
                                                    #set($qty = 0)
993
                                                    #set($value = 0)
994
                                                    #foreach($item in $entry.getValue())
995
                                                        #if($i < $item.getValues().size() && $item.getValues().get($i))
996
                                                            #set($qty = $math.add($qty, $item.getValues().get($i).getQuantity()))
997
                                                            #set($itemValue = $math.mul($item.getValues().get($i).getPrice(), $item.getValues().get($i).getQuantity()))
998
                                                            #set($value = $math.add($value, $itemValue))
999
                                                        #end
1000
                                                    #end
35001 aman 1001
                                                    <div class="volume-view fs-5 fw-bold text-black">$qty</div>
1002
                                                    <div class="value-view currency fs-5 fw-bold text-black"
34813 aman 1003
                                                         style="display: none;"> $nf.format($value)</div>
1004
                                                </td>
1005
                                            #end
1006
                                        </tr>
1007
                                        #end
1008
                                    #end
1009
                                #else
1010
                                <tr>
1011
                                    <td colspan="6" class="text-center">No inventory data available</td>
1012
                                </tr>
1013
                                #end
1014
                            </tbody>
1015
                        </table>
1016
                    </div>
1017
                    <div class="d-flex justify-content-center mt-5 ">
1018
                        <button type="button" class="btn-sm btn-danger fs-2 fw-bold px-4" data-dismiss="modal">X CLOSE
1019
                        </button>
1020
                    </div>
1021
                </div>
1022
            </div>
1023
    </section>
1024
</div>
1025
</body>
1026
<script>
1027
    var chart;
35001 aman 1028
    var brandColors = {
34813 aman 1029
        'vivo': '#2196F3',
1030
        'oppo': '#006b35',
1031
        'samsung': '#1428A0',
1032
        'realme': '#FFC107',
1033
        'xiaomi': '#FF5722',
1034
        'apple': '#666666',
1035
        'poco': '#FFD403',
1036
        'tecno': '#0064FE',
1037
        'lava': '#ED0F53'
1038
    };
1039
 
1040
 
1041
    function loadMonthDetails(monthIndex) {
1042
        console.log(`Loading details for month: ${monthIndex}`);
1043
        doGetAjaxRequestHandler(`${context}/monthWisePartnerIncome/${monthIndex}?partnerTask=true`, function (response) {
1044
            $('.bootbox.modal .modal-body .bootbox-body').empty();
1045
            $('#partner-income').html(response);
1046
            const $section = $('#ajaxSection');
1047
        });
1048
    }
1049
 
1050
    $(document).on("click", ".pending-income", function () {
1051
        lastMonthCreditIncome("main-content");
1052
    });
1053
 
1054
    function doGetAjaxRequestHandler(url, successCallback) {
1055
        $.ajax({
1056
            url: url,
1057
            type: 'GET',
1058
            success: successCallback,
1059
            error: function (xhr, status, error) {
1060
                console.error("AJAX request failed:", error);
1061
            }
1062
        });
1063
    }
1064
 
1065
    $(function () {
1066
        $('#reportrange').daterangepicker(getRangedDatePicker());
1067
    });
1068
    $(document).ready(function () {
1069
 
1070
        $("#btnVolume").addClass("active");
1071
 
1072
        $("#btnVolume").click(function () {
1073
            $(this).addClass("active");
1074
            $("#btnValue").removeClass("active");
1075
            $(".volume-view").show();
1076
            $(".value-view").hide();
1077
        });
1078
 
1079
        $("#btnValue").click(function () {
1080
            $(this).addClass("active");
1081
            $("#btnVolume").removeClass("active");
1082
            $(".volume-view").hide();
1083
            $(".value-view").show();
1084
        });
1085
    });
1086
    document.querySelectorAll('.brand-btn').forEach(button => {
1087
        button.addEventListener('click', function () {
35001 aman 1088
            const brand = this.getAttribute('data-brand');
1089
 
1090
            document.querySelectorAll('.brand-btn').forEach(btn => {
1091
                btn.style.backgroundColor = '';
1092
                btn.style.color = '';
34813 aman 1093
            });
35001 aman 1094
            this.style.backgroundColor = '#006b35';
1095
            this.style.color = 'white';
1096
 
1097
            document.querySelectorAll('.brand-data').forEach(item => {
1098
                item.style.display = item.getAttribute('data-brand') === brand ? 'table-row' : 'none';
1099
            });
34813 aman 1100
        });
1101
    });
35001 aman 1102
    document.querySelector('.brand-btn')?.click();
34813 aman 1103
 
1104
    function initializeBrandButtons() {
1105
        const brandButtons = document.querySelectorAll('.brand-btn');
1106
 
1107
        brandButtons.forEach(button => {
34898 aman 1108
            const brand = button.dataset.brand;
34813 aman 1109
            const color = brandColors[brand] || '#666';
1110
 
1111
            button.style.border = `2px solid ${color}`;
1112
            button.style.color = color;
1113
            button.style.backgroundColor = '#fff';
1114
        });
1115
 
1116
        brandButtons.forEach(button => {
1117
            button.addEventListener('click', function () {
1118
                const selectedBrand = this.dataset.brand;
1119
 
1120
                brandButtons.forEach(btn => {
1121
                    btn.style.backgroundColor = '#fff';
35001 aman 1122
                    btn.style.color = '#666';
34813 aman 1123
                });
1124
 
1125
                this.style.backgroundColor = brandColors[selectedBrand] || '#666';
1126
                this.style.color = '#fff';
1127
 
1128
                document.querySelectorAll('.brand-data').forEach(row => {
35001 aman 1129
                    row.style.display = row.dataset.brand === selectedBrand ? 'inline-masonry' : 'none';
34813 aman 1130
                });
1131
            });
1132
        });
1133
        brandButtons[0]?.click();
1134
    }
1135
 
1136
    initializeBrandButtons();
1137
 
1138
</script>
1139
<script>
1140
    document.querySelectorAll('.brand-btn').forEach(button => {
1141
        button.addEventListener('click', function () {
1142
            const brand = this.getAttribute('data-brand');
1143
 
1144
            document.querySelectorAll('.brand-btn').forEach(btn => {
1145
                btn.style.backgroundColor = '';
1146
                btn.style.color = '';
1147
            });
1148
            this.style.backgroundColor = '#006b35';
1149
            this.style.color = 'white';
1150
 
1151
            document.querySelectorAll('.brand-data').forEach(item => {
35001 aman 1152
                item.style.display = item.getAttribute('data-brand') === brand ? 'inline-masonry' : 'none';
34813 aman 1153
            });
1154
        });
1155
    });
1156
    document.querySelector('.brand-btn')?.click();
1157
</script>
1158
 
1159
##-------------------------------------------------------------------My Earning  chart -----------------------------------------
1160
<script>
1161
    $(document).ready(function () {
1162
        // loadMonthDetails(0);
1163
        const monthData = [
1164
            #foreach( $item in $summaryList )
1165
                {
1166
                    month: "$!item.monthValueMap[$item.monthIndex]",
1167
                    monthIndex: "$item.monthIndex",
1168
                    total: $item.get('totalIncome'),
1169
                    credited: $item.get('creditedIncome'),
1170
                    pending: $item.get('pendingIncome')
1171
                }
1172
                #if($foreach.hasNext),#end
1173
            #end
1174
        ].reverse();
1175
 
1176
        const formatIndianCurrency = (amount) => {
1177
            const rounded = Math.round(amount);
1178
            return rounded.toLocaleString('en-IN');
1179
        };
1180
 
1181
        monthData.forEach(item => {
1182
            item.totalFormatted = formatIndianCurrency(item.total);
1183
            item.creditedFormatted = formatIndianCurrency(item.credited);
1184
            item.pendingFormatted = formatIndianCurrency(item.pending);
1185
        });
1186
        chart = new Chart(document.getElementById('sixMonthChart'), {
1187
            type: 'bar',
1188
            data: {
1189
                labels: monthData.map(d => d.month),
1190
                datasets: [
1191
                    {
1192
                        label: 'Credited Income',
1193
                        data: monthData.map(d => Math.round(d.credited)),
1194
                        backgroundColor: '#aadcb4',
1195
                        borderColor: '#aadcb4',
1196
                        borderWidth: 1,
1197
                        barThickness: 30,
1198
                        hitRadius: 30,
1199
                        order: 1,
1200
                        yAxisID: 'y',
1201
                        hoverBorderWidth: 3,
1202
                        hoverBorderColor: '#aadcb4'
1203
                    },
1204
                    {
1205
                        label: 'Pending Income',
1206
                        data: monthData.map(d => Math.round(d.pending)),
1207
                        backgroundColor: 'rgba(255,0,0,0.7)',
1208
                        borderColor: 'rgba(255,0,0,1)',
1209
                        borderWidth: 1,
1210
                        barThickness: 30,
1211
                        order: 2,
1212
                        hitRadius: 0,
1213
                        yAxisID: 'y',
1214
                        hoverBorderWidth: 3,
1215
                        hoverBorderColor: '#ff0000'
1216
                    },
1217
                    {
1218
                        label: 'Total Income',
1219
                        data: monthData.map(d => Math.round(d.total)),
1220
                        borderColor: '#4bc0c0',
1221
                        backgroundColor: 'rgba(75, 192, 192, 0.1)',
1222
                        borderWidth: 4,
1223
                        type: 'line',
1224
                        order: 3,
1225
                        pointRadius: 6,
1226
                        pointHoverRadius: 0,
1227
                        pointHitRadius: 0,
1228
                        pointBackgroundColor: '#4bc0c0',
1229
                        pointBorderColor: '#ffffff',
1230
                        pointBorderWidth: 2,
1231
                        yAxisID: 'y',
1232
                        tension: 0.3
1233
                    }
1234
 
1235
                ]
1236
            },
1237
            options: {
1238
                responsive: true,
1239
                maintainAspectRatio: true,
1240
                interaction: {
1241
                    mode: 'point',
1242
                    intersect: true,
1243
                },
1244
                plugins: {
1245
                    datalabels: {
1246
                        formatter: function (value) {
1247
                            return Math.round(value).toLocaleString('en-IN');
1248
                        },
1249
                        color: '#fff',
1250
                        backgroundColor: '#333',
1251
                        borderRadius: 4,
1252
                        padding: 4,
34898 aman 1253
                        font: {weight: 'bold'},
34813 aman 1254
                        display: function (context) {
34898 aman 1255
                            const datasetLabel = context.dataset.label;
34813 aman 1256
                            const rawValue = context.dataset.data[context.dataIndex];
34898 aman 1257
                            if (!rawValue || rawValue === 0) return false;
1258
                            if (datasetLabel === 'Credited Income') {
1259
                                const total = context.chart.data.datasets
1260
                                        .find(d => d.label === 'Total Income')
1261
                                        .data[context.dataIndex];
1262
                                if (Math.round(total) === Math.round(rawValue)) return false;
1263
                            }
1264
                            return true;
1265
                        }
34813 aman 1266
                    },
1267
                    tooltip: {
1268
                        mode: 'index',
1269
                        intersect: false,
1270
                        backgroundColor: 'rgba(0, 0, 0, 0.9)',
1271
                        titleColor: '#ffffff',
1272
                        bodyColor: '#ffffff',
1273
                        borderColor: '#4bc0c0',
1274
                        borderWidth: 2,
1275
                        displayColors: true,
1276
                        padding: 12,
1277
                        boxWidth: 15,
1278
                        boxHeight: 15,
1279
                        cornerRadius: 8,
1280
                        usePointStyle: true,
1281
                        bodyFont: {
1282
                            size: 14,
34898 aman 1283
                            weight: 'bold'
34813 aman 1284
                        },
1285
                        titleFont: {
1286
                            size: 16,
1287
                            weight: 'bold'
1288
                        },
1289
                        footerFont: {
1290
                            size: 12,
34898 aman 1291
                            weight: 'bold'
34813 aman 1292
                        },
1293
                        callbacks: {
1294
                            title: function (context) {
1295
                                return `Month: ${context[0].label}`;
1296
                            },
1297
                            label: function (context) {
1298
                                const value = context.parsed.y;
1299
                                const roundedValue = Math.round(value);
1300
                                const formattedValue = roundedValue.toLocaleString('en-IN');
1301
 
1302
                                const label = context.dataset.label;
1303
                                return `${label}: ${formattedValue}`;
1304
                            },
1305
                            footer: function (tooltipItems) {
1306
                                const credited = tooltipItems.find(item => item.dataset.label === 'Credited Income')?.parsed.y || 0;
1307
                                const total = tooltipItems.find(item => item.dataset.label === 'Total Income')?.parsed.y || 0;
1308
                                if (total > 0) {
1309
                                    const percentage = ((credited / total) * 100).toFixed(1);
1310
                                    return `Credited: ${percentage}% of total income`;
1311
                                }
1312
                                return '';
1313
                            },
1314
                            labelColor: function (context) {
1315
                                return {
1316
                                    borderColor: 'transparent',
1317
                                    backgroundColor: context.dataset.borderColor,
1318
                                    borderRadius: 4,
1319
                                    borderWidth: 2
1320
                                };
1321
                            },
1322
                            labelTextColor: function (context) {
34898 aman 1323
                                return '#ffffff';
34813 aman 1324
                            }
1325
                        }
1326
                    },
1327
                    legend: {
1328
                        display: true,
1329
                        position: 'top',
1330
                        labels: {
1331
                            usePointStyle: true,
1332
                            padding: 20,
1333
                            font: {
1334
                                size: 14,
1335
                                weight: 'bold'
1336
                            },
1337
                            color: '#333',
1338
                            boxWidth: 15,
1339
                            boxHeight: 15
1340
                        }
1341
                    }
1342
                },
1343
                scales: {
1344
                    x: {
1345
 
1346
                        ticks: {
1347
 
1348
                            autoSkip: false,
1349
                            font: {
1350
                                size: 12,
1351
                                weight: 'bold'
1352
                            },
1353
                            color: '#333',
1354
                            padding: 10
1355
                        }
1356
                    },
1357
                    y: {
1358
                        type: 'linear',
1359
                        display: true,
1360
                        position: 'left',
1361
                        stacked: false,
1362
                        beginAtZero: true,
1363
                        grid: {
1364
                            color: 'rgba(0, 0, 0, 0.1)',
1365
                            lineWidth: 1
1366
                        },
1367
                        ticks: {
1368
                            callback: function (value) {
1369
                                // Round the value first, then format
1370
                                const roundedValue = Math.round(value);
1371
                                return roundedValue.toLocaleString('en-IN');
1372
                            },
1373
                            font: {
1374
                                size: 12,
1375
                                weight: 'bold'
1376
                            },
1377
                            color: '#333'
1378
                        }
1379
                    }
1380
                },
1381
                elements: {
1382
                    bar: {
1383
                        borderRadius: 4,
1384
                        categoryPercentage: 0.8,
1385
                        barPercentage: 0.9
1386
                    },
1387
                    line: {
1388
                        borderJoinStyle: 'round'
1389
                    },
1390
                    point: {
1391
                        hoverBorderWidth: 1
1392
                    }
1393
                },
1394
                onHover: function (event, elements) {
1395
                    event.native.target.style.cursor = elements.length > 0 ? 'pointer' : 'default';
1396
                },
1397
                onClick: function (event, elements) {
1398
                    if (elements && elements.length > 0) {
1399
                        const clickedIndex = elements[0].index;
1400
                        const clickedData = monthData[clickedIndex];
1401
 
1402
                        event.chart.canvas.style.cursor = 'wait';
1403
 
1404
                        console.log(`Loading details for month: ${clickedData.monthIndex} (${clickedData.month})`);
1405
 
1406
                        loadMonthDetails(clickedData.monthIndex);
1407
 
1408
                        setTimeout(() => {
1409
                            document.getElementById('partner-income').scrollIntoView({
1410
                                behavior: 'smooth',
1411
                                block: 'start'
1412
                            });
1413
                            event.chart.canvas.style.cursor = 'pointer';
1414
                        }, 300);
1415
                    }
1416
                }
1417
            }
1418
        });
1419
    })
1420
</script>
1421
##-----------------------------------------------------------------------Stagged CHart ---------------------------------
1422
<script>
1423
    $(document).ready(function () {
1424
        const MAJOR_BRANDS = ['vivo', 'samsung', 'oppo', 'realme', 'xiaomi'];
1425
 
1426
        const marketSegments = [];
1427
        const otherMarketData = {
1428
            brand: "Others",
1429
            marketShare: 0,
1430
            color: '#6b7280'
1431
        };
1432
 
1433
        const stockSegments = [];
1434
        const otherStockData = {
1435
            brand: "Others",
1436
            quantity: 0,
1437
            value: 0
1438
        };
1439
 
1440
        #foreach($entry in $marketShareData)
1441
            var marketBrandName = '$entry.Brand'.toLowerCase();
1442
            if (MAJOR_BRANDS.includes(marketBrandName)) {
1443
                marketSegments.push({
1444
                    brand: marketBrandName,
1445
                    marketShare: ${entry.MarketShare.replace('%', '')},
1446
                    color: '$entry.BgColor'
1447
                });
1448
            } else {
1449
                otherMarketData.marketShare += ${entry.MarketShare.replace('%', '')};
1450
            }
1451
        #end
1452
 
1453
        #foreach($brandStockPrice in $brandStockPrices)
1454
            var stockBrandName = "$brandStockPrice.getBrand()".toLowerCase();
1455
            if (MAJOR_BRANDS.includes(stockBrandName)) {
1456
                stockSegments.push({
1457
                    brand: stockBrandName,
1458
                    quantity: $brandStockPrice.getTotalQty(),
1459
                    value: $brandStockPrice.getTotalValue()
1460
                });
1461
            } else {
1462
                otherStockData.quantity += $brandStockPrice.getTotalQty();
1463
                otherStockData.value += $brandStockPrice.getTotalValue();
1464
            }
1465
        #end
1466
 
1467
        if (otherMarketData.marketShare > 0) {
1468
            marketSegments.push(otherMarketData);
1469
        }
1470
        if (otherStockData.quantity > 0) {
1471
            stockSegments.push(otherStockData);
1472
        }
1473
 
1474
        const combinedSegments = [];
1475
        const allBrands = [...new Set([
1476
            ...marketSegments.map(d => d.brand),
1477
            ...stockSegments.map(d => d.brand)
1478
        ])];
1479
 
1480
        allBrands.forEach(brand => {
1481
            const marketInfo = marketSegments.find(m => m.brand === brand) || {};
1482
            const stockInfo = stockSegments.find(s => s.brand === brand) || {};
1483
 
1484
            combinedSegments.push({
1485
                brand: brand.charAt(0).toUpperCase() + brand.slice(1),
1486
                marketShare: marketInfo.marketShare || 0,
1487
                stockQuantity: stockInfo.quantity || 0,
1488
                stockValue: stockInfo.value || 0,
1489
                color: marketInfo.color || brandColors[brand] || '#95a5a6'
1490
            });
1491
        });
1492
 
1493
        const totalStockQuantity = stockSegments.reduce((sum, b) => sum + b.quantity, 0);
1494
 
1495
        const ctx4 = document.getElementById('combinedStackedChart').getContext('2d');
1496
        const staggedChart = new Chart(ctx4, {
1497
            type: 'bar',
1498
            data: {
1499
                labels: combinedSegments.map(item => item.brand),
1500
                datasets: [
1501
                    {
35119 aman 1502
                        label: 'Brand Market Share Percentage',
34813 aman 1503
                        data: combinedSegments.map(item => item.marketShare),
1504
                        backgroundColor: combinedSegments.map(item => item.color + '80'),
1505
                        borderColor: combinedSegments.map(item => item.color),
1506
                        borderWidth: 2
1507
                    },
1508
                    {
35119 aman 1509
                        label: 'Brand Share Percentage in your outlet',
34813 aman 1510
                        data: combinedSegments.map(item => ((item.stockQuantity / totalStockQuantity) * 100).toFixed(1)),
1511
                        backgroundColor: combinedSegments.map(item => item.color + '40'),
1512
                        borderColor: combinedSegments.map(item => item.color),
1513
                        borderWidth: 1
1514
                    }
1515
                ]
1516
            },
1517
            options: {
1518
                responsive: true,
1519
                scales: {
1520
                    x: {
1521
                        stacked: true
1522
                    },
1523
                    y: {
1524
                        stacked: true,
1525
                        beginAtZero: true,
1526
                        title: {
1527
                            display: true,
1528
                            text: 'Percentage (%)'
1529
                        }
1530
                    }
1531
                },
1532
                plugins: {
1533
                    tooltip: {
1534
                        callbacks: {
1535
                            label: function (context) {
1536
                                const segment = combinedSegments[context.dataIndex];
1537
                                if (context.datasetIndex === 0) {
1538
                                    return `Market Share: ${segment.marketShare}%`;
1539
                                } else {
1540
                                    return [
1541
                                        `Stock Quantity: ${segment.stockQuantity}`,
1542
                                        `Percentage: ${((segment.stockQuantity / totalStockQuantity) * 100).toFixed(1)}%`
1543
                                    ];
1544
                                }
1545
                            }
1546
                        }
1547
                    }
1548
                }
1549
            }
1550
        });
1551
    });
1552
</script>