buli
2022-04-15 900c50a247705d6fe8833e84d31b5d51616b7c26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
public without sharing class NEWCreateSWOQuoteController {
    public Integer quoteEntryMaxLine {get; private set;}
 
    public List<Product2> product2List { get; set; }
    public List<QuotesItemInfo> productInfoList { get; set; }
    public Quotes__c QuotesPage { get; set; }
 
    public QuotesItemInfo QuotesItemInfo;
    public Integer ProductInfoListSize {get; set;}
    public String swoId { get; private set; }
    public String Id {get; set;}
 
    public List<EmailInfo> mailList {get; set;}
 
    public String baseUrl { get; set; }
    public String rtUrl { get; set; }
 
    public Map<String, Product2> specialProductMap;
 
 
    public String Messages01 { get; set; }
    public String Messages02 { get; set; }
    public String Messages03 { get; set; }
    public String Messages04 { get; set; }
    public String Messages05 { get; set; }
    public String Messages06 { get; set; }
    public String Messages07 { get; set; }
 
    public Boolean aftORbef { get; set; }
    public Boolean aftORbef1 { get; set; }
 
    public String staticResource { get; private set; }// 20220311 PI改造 by Bright
    public String contactstaticResource { get; private set; }// 20220311 PI改造 by Bright
 
    public NEWCreateSWOQuoteController() {
        swoId = System.currentPageReference().getParameters().get('swoId');
        Id = System.currentPageReference().getParameters().get('Id');
        quoteEntryMaxLine = Integer.valueOf(System.Label.QuoteEntryMaxLine);
 
        baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
        String path = URL.getCurrentRequestUrl().getPath();
        if (path.indexOf('/apex') > 0) {
            baseUrl += path.substring(0, path.indexOf('/apex'));
        } else if (path.indexOf('production/') > 0) {
            baseUrl += '/production';
        }
        rtUrl = System.currentPageReference().getParameters().get('retURL');
 
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Quotes__c'));// 20220221 PI改造 by Bright
        contactstaticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));// 20220221 PI改造 by Bright
    }
 
    public NEWCreateSWOQuoteController(ApexPages.StandardController controller) {
        this();
    }
 
    public void init () {
        ProductInfoListSize = 1;
        productInfoList = new  List<QuotesItemInfo>();
        QuotesPage = new Quotes__c();
        QuotesPage.CURRENCY__c = 'Chinese Yuan';
        mailList = new List<EmailInfo>();
        // 获取特殊产品 Start
        specialProductMap = new Map<String, Product2>();
        List<Product2> specialProductList = [Select Id, Name, ProductCode, Description, PART_NUMBER__c from Product2 where SpecialProduct__c = true];
        if (specialProductList.size() > 0) {
 
            for (Product2  product : specialProductList) {
                specialProductMap.put(product.ProductCode, product);
            }
        }
        // 获取特殊产品 End
 
        // SWO的Id不为空,为从SWO创建的报价
        if (String.isNotBlank(swoId)) {
            QuotesPage.QuotesType__c = '维修报价单';
 
            // select Id,Name,SpecialProduct__c from Product2 where ProductCode In ('Service Quote Labour','DESCRIPTION','Service Quote Subtotal','OnsiteSupportFee','Transportation','Payment Info')
 
            List<SWO__c> swoList = [SELECT Id, Name, COMPANY__c, CONTACT__c, ITEM__c, ITEM__r.ProductCode , QUANTITY__c, CONTACT__r.Address1D__c, ESTIMATED_LABOUR_HOURS__c, LABOUR_RATE__c, COMPANY__r.Name, CONTACT__r.Name, COMPANY__r.Address1__c, COMPANY__r.Address1D__c, DESCRIPTION_F__c, SERIAL__c, CONTACT__r.MobilePhoneD__c, CONTACT__r.PhoneD__c, CONTACT__r.Phone, CONTACT__r.MobilePhone  FROM SWO__c WHERE Id = :swoId limit 1];
            if (swoList.size() > 0) {
                String productId = swoList[0].ITEM__c;
                Product2 product = [Select Id, Name, ProductCode, Description, PART_NUMBER__c from Product2 where id = :productId limit 1];
                // 将 DESCRIPTION 特殊产品放在 第一行 Start
                if (specialProductMap.containsKey('DESCRIPTION')) {
                    Product2 productDes = specialProductMap.get('DESCRIPTION');
 
                    Quotes_item__c quotesItemDes = new Quotes_item__c();
                    if (String.isNotBlank(swoList[0].DESCRIPTION_F__c) && String.isNotBlank(swoList[0].SERIAL__c)) {
 
                        quotesItemDes.DESCRIPTION__c = swoList[0].DESCRIPTION_F__c + ' ' + swoList[0].SERIAL__c;
                    } else if (String.isNotBlank(swoList[0].SERIAL__c)) {
                        quotesItemDes.DESCRIPTION__c = swoList[0].SERIAL__c;
                    } else if (String.isNotBlank(swoList[0].DESCRIPTION_F__c)) {
                        quotesItemDes.DESCRIPTION__c = swoList[0].DESCRIPTION_F__c;
                    }
 
                    quotesItemDes.QUANTITY__c = 1;
                    quotesItemDes.RATE__c = 0;
                    productInfoList.add(new QuotesItemInfo(ProductInfoListSize, productDes, 1, QuotesPage, quotesItemDes));
                    ProductInfoListSize++;
                }
                // 将 DESCRIPTION 特殊产品放在 第一行 End
 
                // Integer quantity = Integer.valueof(swoList[0].QUANTITY__c);
                // Quotes_item__c quotesItem = new Quotes_item__c();
                // // quotesItem.DESCRIPTION__c = product.Description;
                // if (String.isNotBlank(swoList[0].DESCRIPTION_F__c) && String.isNotBlank(swoList[0].SERIAL__c)) {
 
                //     quotesItem.DESCRIPTION__c = swoList[0].DESCRIPTION_F__c + ' ' + swoList[0].SERIAL__c;
                // } else if (String.isNotBlank(swoList[0].SERIAL__c)) {
                //     quotesItem.DESCRIPTION__c = swoList[0].SERIAL__c;
                // } else if (String.isNotBlank(swoList[0].DESCRIPTION_F__c)) {
                //     quotesItem.DESCRIPTION__c = swoList[0].DESCRIPTION_F__c;
                // }
                // quotesItem.QUANTITY__c = Decimal.valueof(quantity);
 
                // productInfoList.add(new QuotesItemInfo(ProductInfoListSize, product, quantity, QuotesPage, quotesItem));
                // ProductInfoListSize++;
            }
 
            // 获取SWO下修理上产品的Id
            Map<String, Integer> rpProductQuantityMap = new Map<String, Integer>();
            List<RepairPart__c> repairPartList = [Select Id, Name, Product__c, QUANTITY__c From RepairPart__c where SWO_ID__c = :swoId];
            List<String> repairPartProductIdList = new List<String>();
            if (repairPartList.size() > 0) {
 
                for (RepairPart__c repairpart : repairPartList) {
                    repairPartProductIdList.add(repairpart.Product__c);
                    Integer quantity = Integer.valueOf(repairpart.QUANTITY__c);
                    rpProductQuantityMap.put(repairpart.Product__c, quantity);
                }
 
            }
            // 获取修理产品的相关信息
            if (repairPartProductIdList.size() > 0) {
                product2List = [Select Id, Name, ProductCode, Description, PART_NUMBER__c from Product2 where Id IN :repairPartProductIdList];
 
                if (product2List.size() > 0) {
                    for (Product2 product : product2List) {
                        Quotes_item__c quotesItem = new Quotes_item__c();
                        Integer rpProductQuantity = rpProductQuantityMap.get(product.Id);
                        quotesItem.DESCRIPTION__c = product.Description;
                        quotesItem.QUANTITY__c = rpProductQuantityMap.get(product.Id);
                        productInfoList.add(new QuotesItemInfo(ProductInfoListSize, product, rpProductQuantity, QuotesPage, quotesItem));
                        ProductInfoListSize++;
                    }
                }
 
            }
 
            // 获取 SWO 上客户与联系人的信息
            Boolean labour = false;
            if (swoList[0].ESTIMATED_LABOUR_HOURS__c != null && swoList[0].ESTIMATED_LABOUR_HOURS__c != 0) {
                labour = true;
            }
 
            if (swoList[0].LABOUR_RATE__c != null && swoList[0].LABOUR_RATE__c != 0) {
                labour = true;
            }
 
            if (specialProductMap.containsKey('Service Quote Labour')) {
                Product2 productLabour = specialProductMap.get('Service Quote Labour');
                Quotes_item__c quotesItem = new Quotes_item__c();
                Integer quantity =  Integer.valueOf(swoList[0].ESTIMATED_LABOUR_HOURS__c);
                if (quantity == null) {
                    quantity = 1;
                }
                quotesItem.QUANTITY__c = quantity;
                quotesItem.RATE__c = swoList[0].LABOUR_RATE__c;
                quotesItem.CURRENCY__c = QuotesPage.CURRENCY__c;
                productInfoList.add(new QuotesItemInfo(ProductInfoListSize, productLabour, quantity, QuotesPage, quotesItem));
                ProductInfoListSize++;
 
 
            }
 
            if (specialProductMap.containsKey('Service Quote Subtotal')) {
                Product2 productSubtotal = specialProductMap.get('Service Quote Subtotal');
                Quotes_item__c quotesItem = new Quotes_item__c();
                Integer quantity1 =  1;
                quotesItem.QUANTITY__c = 1;
                quotesItem.RATE__c = 0;
                quotesItem.CURRENCY__c = QuotesPage.CURRENCY__c;
                quotesItem.DESCRIPTION__c = 'Service Quote Subtotal:' + swoList[0].Name;
                productInfoList.add(new QuotesItemInfo(ProductInfoListSize, productSubtotal, quantity1, QuotesPage, quotesItem));
                ProductInfoListSize++;
            }
 
            // 数据拼接 BILL TO/BILL TO Start
            // 客户名称
            // QuotesPage.BILL_TO__c = swoList[0].COMPANY__r.Name + '\n';
            // QuotesPage.SHIP_TO__c = swoList[0].COMPANY__r.Name + '\n';
            if (String.isNotBlank(swoList[0].COMPANY__r.Name)) {
                QuotesPage.BILL_TO__c = swoList[0].COMPANY__r.Name + '\n';
                QuotesPage.SHIP_TO__c = swoList[0].COMPANY__r.Name + '\n';
            }
            // 客户地址
            if (String.isNotBlank(swoList[0].COMPANY__r.Address1D__c)) {
                QuotesPage.BILL_TO__c +=  swoList[0].COMPANY__r.Address1D__c + '\n';
                QuotesPage.SHIP_TO__c +=  swoList[0].COMPANY__r.Address1D__c + '\n';
            } else if (String.isNotBlank(swoList[0].COMPANY__r.Address1__c)) {
                QuotesPage.BILL_TO__c +=  swoList[0].COMPANY__r.Address1__c + '\n';
                QuotesPage.SHIP_TO__c +=  swoList[0].COMPANY__r.Address1__c + '\n';
            }
            // 联系人名称
 
            if (String.isNotBlank(swoList[0].CONTACT__r.Name)) {
                QuotesPage.BILL_TO__c += swoList[0].CONTACT__r.Name + '\n';
                QuotesPage.SHIP_TO__c += swoList[0].CONTACT__r.Name + '\n';
            }
            // 联系人手机
            if (String.isNotBlank(swoList[0].CONTACT__r.MobilePhoneD__c)) {
                QuotesPage.BILL_TO__c +=  swoList[0].CONTACT__r.MobilePhoneD__c + '\n';
                QuotesPage.SHIP_TO__c +=  swoList[0].CONTACT__r.MobilePhoneD__c + '\n';
            } else if (String.isNotBlank(swoList[0].CONTACT__r.MobilePhone)) {
                QuotesPage.BILL_TO__c +=  swoList[0].CONTACT__r.MobilePhone + '\n';
                QuotesPage.SHIP_TO__c +=  swoList[0].CONTACT__r.MobilePhone + '\n';
            }
            // 联系人电话
            if (String.isNotBlank(swoList[0].CONTACT__r.PhoneD__c)) {
                QuotesPage.BILL_TO__c +=  swoList[0].CONTACT__r.PhoneD__c + '\n';
                QuotesPage.SHIP_TO__c +=  swoList[0].CONTACT__r.PhoneD__c + '\n';
            } else if (String.isNotBlank(swoList[0].CONTACT__r.Phone)) {
                QuotesPage.BILL_TO__c +=  swoList[0].CONTACT__r.Phone + '\n';
                QuotesPage.SHIP_TO__c +=  swoList[0].CONTACT__r.Phone + '\n';
            }
            // 数据拼接  BILL TO/BILL TO End
 
            QuotesPage.CONTACT_NAME__c =  swoList[0].CONTACT__c;
            QuotesPage.CONTACT_PHONE__c = swoList[0].CONTACT__r.PhoneD__c;
            QuotesPage.COMPANY__c = swoList[0].COMPANY__c;
            QuotesPage.DATE__c = Date.today();
            QuotesPage.STATUS__c = 'Qualifying';
            QuotesPage.PROBABILITY__c = 25;
        }
 
        if (String.isNotBlank(Id)) {
 
            List<Quotes__c> quotesList = new List<Quotes__c>();
            quotesList = [SELECT  Id, 
            AWS_Data_Id__c,CONTACT_NAME__r.Name,CONTACT_NAME__r.AWS_Data_Id__c, // 20220311 PI改造 by Bright
            Name, BILLING_SCHEDULE__c, BILL_TO__c, SHIP_TO__c, BILL_TO_SELECT__c, CATEGORY_1_INDUSTRY_SO__c, CATEGORY_2_USE_SO__c, COLLECTION_STATUS__c, CONTACT_EMAIL__c, CONTACT_FAX__c, CONTACT_NAME__c, CONTACT_PHONE__c, CONTRACT_NAME__c, CURRENCY__c, DATE__c, DISCOUNT_ITEM__c, DISCOUNT_ITEM_F__c, DISCOUNT_WORKFLOW_TYPE__c, EST_EXTENDED_COST__c, EST_GROSS_PROFIT__c, EST_GROSS_PROFIT_PERCENT__c, ESTIMATE__c, EXP_CLOSE__c, EXPIRES__c, FDA_REPORT_COMPLETE__c, GOVERNMENT_ORDER__c, GSA_ORDER__c, INCOTERM__c, INITIATE_APPROVAL_ROUTING__c, INVOICE_MESSAGING__c, IS_SELLER_IMPORTER_OF_RECORD__c, LEAD_SOURCE__c, LEAD_TIME__c, LOCATION__c, NO_CHARGE_TYPE__c, notSaveEmail__c, NSN__c, ONLINE_BILLING__c, ONLINE_BILLING_ADDRESS__c, OPPORTUNITY__c, ORDER_TYPE__c, PKMS_PO_FOR_RECEIPT__c, PO__c, PROBABILITY__c, PRODUCT_SEGMENT__c, QUOTE_TITLE__c, RATE__c, RepairPart__c, REVISION_NEEDED__c, RMA_NOTES__c, COMPANY__c, SALES_TEAM_AUTO_ASSIGNMENT_OVERRIDE__c, SALES_TEAM_AUTO_ASSIGN_ON_SAVE__c, SELECT_MESSAGE__c, SHIPPING_CARRIER__c, SHIPPING_COST__c, SHIPPING_TAX_CODE__c, SHIPPING_TAX_RATE__c, SHIP_TO_ENTITY_USE_CODE__c, SHIP_TO_SELECT__c, SHIP_VIA__c, STATUS__c, SUBSIDIARY__c, SUBTOTAL__c, SWO__c, SWOName__c, SWO_NUMBER__c, SWO_PART_NUMBERS__c, SWO_SERIAL__c, SWOStatus__c, TAX_ID__c, TAX_OVERRIDE__c, TERMS__c, TERMS_OVERRIDE__c, THROW_MESSAGE__c, TOTAL_TRANSACTION_ITEM_WEIGHT_KGS__c, VERTICAL_MARKET_SEGMENT_SO__c, QuotesType__c, CUSTOMER_MESSAGE__c, TOTAL__c, BILL_TO_ENTITY_USE_CODE__c, COMPANYId__c, COMPANYName__c, DISCOUNT_STATUS__c, DISCOUNT_STATUS_ROUTING__c, TAX_CODE__c, TAX_RATE__c, TAX__c, DISCOUNT__c, SWOStatusMark__c  FROM Quotes__c WHERE Id = :Id];
            if (quotesList.size() > 0) {
                QuotesPage = quotesList[0];
            }
            List<Quotes_item__c> quotesItemList = new List<Quotes_item__c>();
            quotesItemList = [SELECT Id, Name, QuotesItemName__c, PART_NUMBERNew__c, ON_HAND__c,
                              QUANTITY__c , QuotesItemProduct__c,ProductDESCRIPTION__c, PRICE_LEVEL__c, RATE__c, AMOUNT__c ,
                              PRE_APPROVED_DISCOUNT__c, DISCOUNTED_RATE__c, EST_COST__c ,
                              EST_GROSS_MARGIN__c, TAX_CODE__c, TAX_RATE__c, TAX_AMT__c , GROSS_AMT__c,
                              LOCATION__c, OPTIONS__c, EXPECTED_SHIP_DATE__c , ITEM_NOTE__c, SERIALIZED__c, ITEM_WEIGHT__c,
                              SWOName__c, RE_INVOICE_CREDIT_AMOUNT__c , DISCOUNTED_RATE_USD__c, ITEM_TYPE__c,
                              NIS__c, CQP_AD_HOC_PRODUCT__c ,  ESTIMATED_TOTAL_WEIGHT__c,
                              SHIP_TO_ENTITY_USE_CODE__c , EQ_NUMBER__c, HUNT_PRICE_VARIANCE__c,
                              BASE_PRICE_FOR_HUNT__c , TRANSACTION_RESTRICTED_ITEM__c,
                              TRANSACTION_RESTRICTED_ITEM_OVERRIDE__c , SERVICE_WORK_ORDER__c,
                              productName__c, ProductOTcode__c, DESCRIPTION__c, QuotesItemProduct__r.SpecialProduct__c, QUOTE__c,LineNumber__c FROM Quotes_item__c WHERE QUOTE__c = :Id];
            if (quotesItemList.size() > 0 ) {
                Boolean specialQuotesItemFlag = false;
                Map<String, Quotes_item__c> specialProductMap = new Map<String, Quotes_item__c>();
                for (Quotes_item__c quotesItem : quotesItemList) {
                    String quotesItemName = quotesItem.ProductOTcode__c;
 
                    if (quotesItem.QuotesItemProduct__r.SpecialProduct__c && !'DESCRIPTION'.equals(quotesItemName)) {
                        specialQuotesItemFlag = true;
                        specialProductMap.put(quotesItem.Id, quotesItem);
                        continue;
                    }
                    productInfoList.add(new QuotesItemInfo(ProductInfoListSize, quotesItem, QuotesPage));
                    ProductInfoListSize++;
                }
                // 其余 特殊产品放置在最下面
                List<Quotes_item__c> subtotalList = new List<Quotes_item__c>();
                if (specialQuotesItemFlag) {
                    for (String quotesItemId : specialProductMap.keySet()) {
 
                        Quotes_item__c quotesItem = specialProductMap.get(quotesItemId);
                        String quotesItemName = quotesItem.ProductOTcode__c;
                        if ('Service Quote Subtotal'.equals(quotesItemName)) {
                            subtotalList.add(quotesItem);
                            continue;
                        }
                        productInfoList.add(new QuotesItemInfo(ProductInfoListSize, quotesItem, QuotesPage));
                        ProductInfoListSize++;
                    }
                }
                // Service Quote Subtotal 特殊产品 放置在最后
                if (subtotalList.size() > 0) {
                    for (Quotes_item__c quotesItem : subtotalList) {
                        productInfoList.add(new QuotesItemInfo(ProductInfoListSize, quotesItem, QuotesPage));
                        ProductInfoListSize++;
                    }
                }
                // 其余 特殊产品放置在最下面
 
            }
            // Mail 页面初始化 Start
            List<String> mailIdList = new List<String>();
 
            List<Attachment> attList = new List<Attachment>();
            Map<String, List<Attachment>> attMap = new Map<String, List<Attachment>>();
 
            Map<String, Mail_Merge__c> mailMap = new Map<String, Mail_Merge__c>([select id, FROM__c, ccName__c, SUBJECT__c, MESSAGE__c, DATE__c, toName__c, EMAIL_SENT__c from Mail_Merge__c where Quotes__c = :Id order by id]);
 
 
            if (mailMap != null) {
                mailIdList.addAll(mailMap.keySet());
 
                attList =  [select id, Name, ParentId from Attachment where ParentId in :mailIdList order by ParentId, id];
                if (attList.size() > 0) {
                    for (Attachment att : attList) {
                        if (attMap.containsKey(att.ParentId)) {
                            attMap.get(att.ParentId).add(att);
                        } else {
                            List<Attachment> a = new List<Attachment>();
                            a.add(att);
                            attMap.put(att.ParentId, a);
                        }
                    }
                }
 
                for (String id : mailMap.keySet()) {
                    if (attMap.containsKey(id)) {
                        mailList.add(new EmailInfo(mailMap.get(id), attMap.get(id)));
                    } else {
                        mailList.add(new EmailInfo(mailMap.get(id), null));
                    }
                }
            }
            // Mail 页面初始化 End
 
        }
        //首先是从swo创建quotes,有了swoid,就是用新的静态资源显示的免责申明。
        //之后,编辑已经创建完了的quotes,15号之前创建的,显示的是旧的。旧的就是aftORbef==false。
        if (String.isNotBlank(swoId)) {
            aftORbef1 = true;
        }else{
            aftORbef1 = false;
        }
        System.debug('aftORbef1='+aftORbef1);
        //如果2121年11月15号以及之后创建的quotes,用新的免责申明。
        //用于展示页面NEWCreateSWOQuoteReadOnly的查看和编辑页面NEWCreateSWOQuote(url为id)的编辑。
        List<Quotes__c> quotescreateList = new List<Quotes__c>();
        quotescreateList = [select 
                            Id 
                            FROM Quotes__c 
                            WHERE Id = :Id and CreatedDate >= 2021-11-15T00:00:00.000+0000]; 
        if(quotescreateList.size() > 0){
            aftORbef = true;
        }else{
            aftORbef = false;
        }
        System.debug('aftORbef='+aftORbef);
        // Message模板 Start
        getmessageTemplate(QuotesPage);
        // Message模板 End
 
        // 当报价行项目小于50个时,用空行进行填补 Start
        if (productInfoList.size() < 50) {
            for (Integer i = ProductInfoListSize; i <= 50; i++) {
                Quotes_item__c quotesItem = new Quotes_item__c();
                productInfoList.add(new QuotesItemInfo(i, quotesItem));
            }
        }
        // 当报价行项目小于50个时,用空行进行填补 End
    }
 
    public void getmessageTemplate(Quotes__c quotes) {
        if ('维修报价单'.equals(QuotesPage.QuotesType__c)) {
            QuotesPage.CUSTOMER_MESSAGE__c = '';
            //日期2121年11月15号之后的,用新的免责申明。
           if (aftORbef == true) {
                QuotesPage.CUSTOMER_MESSAGE__c += '-维修质保只涵盖于本次维修的配件,维修质保期为仪器发货后三个月加八天。\n';
                Messages01 = '-维修质保只涵盖于本次维修的配件,维修质保期为仪器发货后三个月加八天。';
            }else{
                QuotesPage.CUSTOMER_MESSAGE__c += '-维修质保期为仪器发货后三个月加八天。\n';
                Messages01 = '-维修质保期为仪器发货后三个月加八天。';
            } 
            QuotesPage.CUSTOMER_MESSAGE__c += '-如您确认此报价并同意维修,敬请您在90天之内完成付款。否则您的仪器被将视为放弃维修,我们会以运费到付的方式把 \n';
            QuotesPage.CUSTOMER_MESSAGE__c += '仪器给您寄回,并向您收取1000元的检测费用。\n';
            Messages02 = '-如您确认此报价并同意维修,敬请您在90天之内完成付款。否则您的仪器被将视为放弃维修,我们会以运费到付的方式把仪器给您寄回,并向您收取1000元的检测费用。';
            QuotesPage.CUSTOMER_MESSAGE__c += '-用户在此确认同意此次维修报价: \n';
            Messages03 = '-用户在此确认同意此次维修报价:';
            QuotesPage.CUSTOMER_MESSAGE__c += '客户签字或盖章:\n';
            Messages04 = '客户签字或盖章:';
            QuotesPage.CUSTOMER_MESSAGE__c += '日期:';
            Messages05 = '日期:';
        } else if ('零件报价单'.equals(QuotesPage.QuotesType__c)) {
            QuotesPage.CUSTOMER_MESSAGE__c = '';
            QuotesPage.CUSTOMER_MESSAGE__c += '-奥林巴斯服务部售出的维修配件确保为质量符合奥林巴斯参数指标的新品,奥林巴斯对售出的维修配件不提供保修服务,同时也不提供退、换货服务。敬请您谨慎购买。\n';
            Messages01 = '-奥林巴斯服务部售出的维修配件确保为质量符合奥林巴斯参数指标的新品,奥林巴斯对售出的维修配件不提供保修服务,同时也不提供退、换货服务。敬请您谨慎购买。';
            QuotesPage.CUSTOMER_MESSAGE__c += '-用户在此确认此次报价,决定购买:\n';
            Messages02 = '-用户在此确认此次报价,决定购买:';
            QuotesPage.CUSTOMER_MESSAGE__c += '客户签字或盖章:\n';
            Messages03 = '客户签字或盖章:';
            QuotesPage.CUSTOMER_MESSAGE__c += '日期:';
            Messages04 = '日期:';
        }
    }
 
    public PageReference Save() {
        System.debug('QuotesPage----->' + QuotesPage);
 
        if (String.isNotBlank(swoId)) {
            QuotesPage.SWO__c = swoId;
            aftORbef = true;
        }
        if (!'Cancel'.equals(QuotesPage.STATUS__c)) {
            // 必填字段验证
            if (!QuotesDataCheck()) {
                return null;
            }
        }
 
        getmessageTemplate(QuotesPage);
        Savepoint sp = Database.setSavepoint();
        try {
            QuotesPage.CURRENCY__c = 'Chinese Yuan';
            if ( String.isNotBlank(QuotesPage.STATUS__c) && 'Cancel'.equals(QuotesPage.STATUS__c)) {
                QuotesPage.InvalidData__c = true;
            } else {
                QuotesPage.InvalidData__c = false;
            }
            upsert QuotesPage;
            Id = QuotesPage.Id;
            // 新增或变更报价行项目
            List<Quotes_item__c> upsertQuotesItemList = new List<Quotes_item__c>();
            List<String> productIdList = new List<String>();
            Decimal quotesSUBTOTAL = 0;
            Decimal tAX_AMTSUBTOTAL = 0;
            Decimal tAX_AMTSUBTOTAL1 = 0;
            Decimal tAX_RATE = 0 ;
            Map<String, Quotes_item__c> specialMap = new Map<String, Quotes_item__c>();
            Quotes_item__c subtotalQuotesItem = new Quotes_item__c();
 
            List<Quotes_item__c> delectQuotesItemList = new List<Quotes_item__c>();
            
            delectQuotesItemList = [SELECT Id, Name,LineNumber__c FROM Quotes_item__c WHERE QUOTE__c = :Id];
 
            Integer lineNumber = 1;
            System.debug('productInfoList--->' + productInfoList);
            for (QuotesItemInfo QuotesItemInfo : productInfoList) {
                // 产品名称 为空 并且 报价行项目Id 不为空,删除
                if (String.isBlank(QuotesItemInfo.productName) && String.isNotBlank(QuotesItemInfo.quotesItemId)) {
                    continue;
                }
 
                if (String.isBlank(QuotesItemInfo.productName)) {
                    continue;
                }
 
                if (String.isNotBlank(QuotesItemInfo.productName) &&
                        (String.isBlank(QuotesItemInfo.quotesItemId) && String.isBlank(QuotesItemInfo.productId))) {
                    continue;
                }
 
                Quotes_item__c quotesItem = new Quotes_item__c();
                
                quotesItem = QuotesItemInfo.quotesItemINFO;
                quotesItem.Id = null;//QuotesItemInfo.quotesItemId;
                quotesItem.LineNumber__c = QuotesItemInfo.lineNumber;
                // 产品名称 不为空 并且 产品Id 不为空 新增;
                if (String.isNotBlank(QuotesItemInfo.productId)) {
                    quotesItem.QuotesItemProduct__c = QuotesItemInfo.productId;
                    quotesItem.QUOTE__c = Id;
 
                }
                
 
                if ('Service Quote Subtotal'.equals(QuotesItemInfo.productName)) {
                    subtotalQuotesItem = quotesItem;
 
                    continue;
                }
 
                upsertQuotesItemList.add(quotesItem);
                if (specialProductMap.containsKey(QuotesItemInfo.productName) && !'Service Quote Labour'.equals(QuotesItemInfo.productName)) {
                    quotesItem.AMOUNT__c = 0;
                    continue;
                }
 
 
 
                quotesItem.CURRENCY__c = QuotesPage.CURRENCY__c;
                quotesItem.AMOUNT__c =  QuotesItemInfo.quotesItemINFO.RATE__c  *  QuotesItemInfo.quotesItemINFO.QUANTITY__c;
                quotesSUBTOTAL += quotesItem.AMOUNT__c;
                if (QuotesPage.RATE__c == -500) {
                    tAX_AMTSUBTOTAL += quotesItem.TAX_AMT__c + (-500 * QuotesItemInfo.quotesItemINFO.TAX_RATE__c) / 100;
                } else {
                    tAX_AMTSUBTOTAL += quotesItem.TAX_AMT__c;
                }
                tAX_AMTSUBTOTAL1 += quotesItem.TAX_AMT__c;
            }
 
            if (delectQuotesItemList.size() >0) {
                delete delectQuotesItemList;
            }
 
            // 新增或变更报价行项目
            if (upsertQuotesItemList.size() > 0 ) {
                Quotes__c updateQuotes = new Quotes__c();
                updateQuotes.Id = Id;
                updateQuotes.SUBTOTAL__c = quotesSUBTOTAL;
 
                if (QuotesPage.RATE__c != -500) {
                    updateQuotes.TAX__c = tAX_AMTSUBTOTAL * (100 + QuotesPage.RATE__c) / 100;
                    updateQuotes.DISCOUNT__c = (quotesSUBTOTAL * QuotesPage.RATE__c) / 100;
                } else {
                    updateQuotes.DISCOUNT__c = -500;
                    updateQuotes.TAX__c = tAX_AMTSUBTOTAL; //+ (-500 * tAX_RATE)/100;
                }
 
                updateQuotes.TOTAL__c = updateQuotes.SUBTOTAL__c + updateQuotes.DISCOUNT__c + updateQuotes.TAX__c ;
                if (String.isNotBlank(subtotalQuotesItem.QUOTE__c)) {
                    subtotalQuotesItem.AMOUNT__c = quotesSUBTOTAL;
                    subtotalQuotesItem.TAX_AMT__c = tAX_AMTSUBTOTAL1;
                    subtotalQuotesItem.GROSS_AMT__c = updateQuotes.SUBTOTAL__c + updateQuotes.TAX__c;
                    upsertQuotesItemList.add(subtotalQuotesItem);
                }
 
                upsert upsertQuotesItemList;
 
                update updateQuotes;
 
 
            }
 
            
        }catch (Exception e) {
            ApexPages.addMessages(e);
            Database.rollback(sp);
            
            return null;
        }
        return UnabletoEdit();
    }
 
    public PageReference Editbtn() {
        String url = '/apex/NEWCreateSWOQuote?Id=' + Id;
        PageReference  ref = new Pagereference(url);
        ref.setRedirect(true);
        return ref;
    }
 
    // 刷新SWO报价
    public PageReference UnabletoEdit() {
        String url = '/apex/NEWCreateSWOQuoteReadOnly?Id=' + Id;
        PageReference  ref = new Pagereference(url);
        ref.setRedirect(true);
        return ref;
    }
    //必填字段检查
    public Boolean QuotesDataCheck() {
        Boolean result = true;
        String errormessage = '';
        if (QuotesPage.DATE__c == null) {
            errormessage = errorMessage('DATE');
            // QuotesPage.DATE__c.addError('DATE Can\'t be empty');
            QuotesPage.DATE__c.addError(errormessage);
 
            result = false;
        }
        // LEAD_TIME__c
        if (String.isBlank(QuotesPage.LEAD_TIME__c)) {
            errormessage = errorMessage('LEAD TIME');
            QuotesPage.LEAD_TIME__c.addError(errormessage);
            result = false;
        }
        if (String.isBlank(QuotesPage.STATUS__c)) {
            errormessage =  errorMessage('STATUS');
            QuotesPage.STATUS__c.addError(errormessage);
            result = false;
        }
 
        if (String.isBlank(QuotesPage.LOCATION__c)) {
            errormessage =  errorMessage('LOCATION');
            QuotesPage.LOCATION__c.addError(errormessage);
            result = false;
        }
 
        if (String.isBlank(QuotesPage.TERMS__c)) {
            errormessage =  errorMessage('TERMS');
            QuotesPage.TERMS__c.addError(errormessage);
            result = false;
        }
 
        if (QuotesPage.EXPIRES__c == null) {
            errormessage =  errorMessage('EXPIRES');
            QuotesPage.EXPIRES__c.addError(errormessage);
            result = false;
        }
 
        if (QuotesPage.EXP_CLOSE__c == null) {
            errormessage =  errorMessage('EXP. CLOSE');
            QuotesPage.EXP_CLOSE__c.addError(errormessage);
            result = false;
        }
 
        if (String.isBlank(QuotesPage.ORDER_TYPE__c)) {
            errormessage =  errorMessage('ORDER TYPE');
            QuotesPage.ORDER_TYPE__c.addError(errormessage);
            result = false;
        }
 
        for (QuotesItemInfo QuotesItemInfo : productInfoList) {
            String productName = QuotesItemInfo.productName;
            if (String.isBlank(productName)) {
                continue;
            }
            if (String.isNotBlank(productName) &&
                    (String.isBlank(QuotesItemInfo.quotesItemId) && String.isBlank(QuotesItemInfo.productId))) {
 
                continue;
            }
            Boolean specialProduct = false;
            // if (String.isNotBlank(productName) &&
            //         ('Service Quote Labour'.equals(productName) ||
            //          'DESCRIPTION'.equals(productName) ||
            //          'Service Quote Subtotal'.equals(productName) ||
            //          'Onsite Support Fee'.equals(productName) ||
            //          'Transportation'.equals(productName) ||
            //          'Payment Info'.equals(productName))) {
 
            //     specialProduct = true;
            // }
            if (specialProductMap != null && specialProductMap.size() > 0 && specialProductMap.containsKey(productName)) {
                specialProduct = true;
            }
 
            String descriptionStr = QuotesItemInfo.quotesItemINFO.DESCRIPTION__c;
            if ('Payment Info'.equals(productName) &&
                    String.isNotBlank(descriptionStr)) {
                descriptionStr = descriptionStr.replaceAll(';', ';');
                if (descriptionStr.indexOf(';') != -1) {
                    QuotesItemInfo.quotesItemINFO.DESCRIPTION__c = '';
                    for (String descriptionLine : descriptionStr.split(';')) {
                        QuotesItemInfo.quotesItemINFO.DESCRIPTION__c += descriptionLine + ';\n';
                    }
                } else {
                    errormessage = 'Quotes Item No [ ' + QuotesItemInfo.lineNumber + ' ] DESCRIPTION Error';
                    QuotesItemInfo.quotesItemINFO.DESCRIPTION__c.addError(errormessage);
                    result = false;
                }
            }
 
            if (String.isNotBlank(productName) &&
                    ((String.isNotBlank(QuotesItemInfo.quotesItemId) || String.isNotBlank(QuotesItemInfo.productId)))) {
                if (!specialProduct) {
                    if (String.isBlank(QuotesItemInfo.quotesItemINFO.TAX_CODE__c)) {
                        errormessage =  errorMessage('Quotes Item No [ ' + QuotesItemInfo.lineNumber + ' ] TAX CODE');
                        QuotesItemInfo.quotesItemINFO.TAX_CODE__c.addError(errormessage);
                        result = false;
                    }
                    if (String.isBlank(QuotesItemInfo.quotesItemINFO.LOCATION__c)) {
                        errormessage =  errorMessage('Quotes Item No [ ' + QuotesItemInfo.lineNumber + ' ] LOCATION');
                        QuotesItemInfo.quotesItemINFO.LOCATION__c.addError(errormessage);
                        result = false;
                    }
                }
 
                if (QuotesItemInfo.quotesItemINFO.QUANTITY__c == null ||
                        QuotesItemInfo.quotesItemINFO.QUANTITY__c == 0) {
                    errormessage =  errorMessage('Quotes Item No [ ' + QuotesItemInfo.lineNumber + ' ] QUANTITY');
                    errormessage += ' OR Can not be Zero';
                    QuotesItemInfo.quotesItemINFO.QUANTITY__c.addError(errormessage);
                    result = false;
                }
 
            }
 
        }
 
        return result;
    }
 
    public String errorMessage(String type) {
        String result = type + ' can not be empty';
        return result;
    }
 
    public class QuotesItemInfo {
        public String productId {get; set;}//产品Id
        public Quotes_item__c quotesItemINFO {get; set;} //报价行项目
        public String quotesItemName {get; private set;}
        public String quotesItemId {get; set;} //报价行项目Id
        public Decimal lineNumber {get; set;}//行号
        public Decimal quantity {get; set;}//数量
        public Decimal price {get; set;} //单价
        public Decimal totalPrice {get; set;} //总价
        public String productCode {get; set;} //OT Code
        public String description {get; set;} //描述
        public String partNumber {get; set;} //PART_NUMBER
        public Decimal productInventory {get; set;}//库存
        public String productName {get; set;}//产品名称
        public String on_hand {get; set;}
 
        public QuotesItemInfo (Integer productNo, Quotes_item__c quotesItem) {
            lineNumber = productNo;
            quotesItemINFO = quotesItem;
            quotesItemId = quotesItem.Id;
        }
        public QuotesItemInfo ( Integer productNo, Product2 product, Integer productQuantity, Quotes__c quotes, Quotes_item__c quotesItem) {
            lineNumber = productNo;//quotesItem.LineNumber__c;
            quotesItemINFO = quotesItem;
            quantity = productQuantity;
            productCode = product.ProductCode;
            description = product.Description;
            //partNumber  = product.PART_NUMBER__c;
            //productInventory = product.ProductInventory__c;
            productName = product.Name;
            productId = product.Id;
            price = 0;
            totalPrice = 0;
            quotesItemId = quotesItem.Id;
 
        }
        public QuotesItemInfo ( Integer productNo, Quotes_item__c quotesItem, Quotes__c quotes) {
            quotesItemINFO = quotesItem;
            quotesItemName = quotesItem.Name;
            lineNumber = productNo;//quotesItem.LineNumber__c;//productNo;
            quantity = quotesItem.QUANTITY__c;
            productName = quotesItem.productName__c;
            productId = quotesItem.QuotesItemProduct__c;
            quotesItemId = quotesItem.Id;
        }
 
    }
 
    public class EmailInfo {
 
        public Mail_Merge__c mm {get; set; }
        public List<Attachment> attList {get; set; }
        public String haveAtt {get; set;}
        public EmailInfo() {
 
        }
        public EmailInfo(Mail_Merge__c mm_in, List<Attachment> attList_in) {
            mm = mm_in;
            if (attList_in == null || attList_in.size() == 0) {
                haveAtt = 'No';
                attList = new List<Attachment>();
            } else {
                attList = attList_in;
                haveAtt = 'Yes';
            }
        }
 
    }
 
 
}