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 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');
    }

    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, 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。
        //当然，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 || aftORbef1 == 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 = '';
            if ('NDT'.equals(QuotesPage.PRODUCT_SEGMENT__c)) {
                QuotesPage.CUSTOMER_MESSAGE__c += '-仪景通光学科技(上海)有限公司北京分公司售出的维修配件为奥林巴斯原厂配件，仪景通公司对售出的维修配件不提供保修服务，也不提供退、换货服务，敬请您谨慎购买。\n';
                Messages01 = '-仪景通光学科技(上海)有限公司北京分公司售出的维修配件为奥林巴斯原厂配件，仪景通公司对售出的维修配件不提供保修服务，也不提供退、换货服务，敬请您谨慎购买。';
            }else {
                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;
            //日期2121年11月15号之后的,用新的免责申明。
            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';
            }
        }

    }


}