public with sharing class OpportunityProductController {
    public List<OpportunityProduceInfo> OPInfoList { get; set; }
    public Opportunity opp { get; set; }
    public Id pricebook2Id {get; set;}
    public String currencyIsoCode {get; set;}
    public Boolean saveBtnDisabled { get; set; }
    public Integer lineNo { get; set; }

    public String baseUrl { get; set; }
    public Boolean errorFlag { get; set; }
    public String errorMessage {get; set;}
    public Boolean refresh { get; set; }

    public String oppId { get; private set; }
    public Integer maxLine { get; private set; }

    public boolean is_IE_direct { get; set; }
    public boolean is_Parts_direct { get; set; }

    public boolean is_hidden_user { get; set; }
    public boolean is_dealer_user { get; set; }

    public boolean is_hidden_all { get; set; }

    public Boolean specialDealer { get; set; }
    public Boolean specialDealer_NotisProductModel_Amountcheck;


    public boolean is_IE { get; set; }
    public boolean is_RVI { get; set; }
    public boolean is_NDT { get; set; }
    public Decimal dealer_coefficient { get; set; }
    public Decimal dealer_discount { get; set; }

    public String fileName { get; set; }
    public String strExpirationDate { get; set; }
    public List<OpportunityProduceInfo> csv_activities {get; set;}
    public Blob contentFile { get; set; }
    public String nameFile { get; set; }
    public Boolean hasQuote {get; set;}
    public Integer getOPInfoListSize() {
        return OPInfoList == null ? 0 : OPInfoList.size();
    }
    // WLIG-BTA8C2 XHL 20200925 -Start
    public String initStringConcatenation;
    public String saveStringConcatenation;
    public Boolean verifyProductValidFlag;
    // WLIG-BTA8C2 XHL 20200925 -End
    private static Map<String, String> paymentTermsMap = new Map<String, String> {
        'Z001' => '预收款/预付款',
        'Z002' => '立即付款',
        'Z003' => '月结30天内付款',
        'Z004' => '月结60天内付款',
        'Z005' => '月结90天内付款',
        'Z006' => '月结120天内付款',
        'Z007' => '月结25天内付款',
        'Z008' => '月结55天内付款',
        'Z009' => '月结85天内付款',
        'Z010' => '月结115天内付款',
        'Z011' => '月结175天内付款',
        'Z012' => '月结205天内付款',
        'Z013' => '半月结，15日之前发货，当月15日到期',
        'Z014' => '月结30天内付款',
        'Z015' => '验收后15天电汇',
        'Z020' => '100%发货后30天内支付',
        'Z021' => '100%发货后60天内电汇支付',
        'Z030' => '收到发票后30天内电汇',
        'Z045' => '月结45天内付款',
        'Z060' => '收到发票后60天内电汇',
        'Z075' => '收到发票后75天内电汇',
        'Z090' => '收到发票后90天内电汇',
        'Z0LC' => '100% L/C (90/10)',
        'Z120' => '收到发票后120天内电汇',
        'Z1LC' => '100% L/C (80/20)',
        'Z1TT' => '90%TT ADV，10%TT AFTER',
        'Z2LC' => '100% L/C (70/30)',
        'Z2TT' => '80%TT ADV，20%TT AFTER',
        'Z30E' => '下月末',
        'Z3LC' => '100% L/C 90 days',
        'Z3TT' => '70%TT ADV，30%TT AFTER',
        'Z4LC' => '90%L/CTransfer 10%TT AFTER',
        'Z4TT' => '100% TT AFTER',
        'Z5LC' => '100%L/C at sight Transfer',
        'Z5TT' => '30% TT ADV，50% TT AT SIGHT，20% TT AFTER',
        'Z60E' => '下2个月末',
        'Z6LC' => '100%L/C (85/15)',
        'Z6TT' => '30% TT ADV，60% TT AT SIGHT，10% TT AFTER',
        'Z7LC' => '100% L/C (60/40)',
        'Z7TT' => '100％TT AFTER(80/20)',
        'Z8TT' => '100% TT AFTER（70/30）',
        'Z9TT' => '100%TT发货后20天内支付',
        'ZCOD' => 'C.O.D.',
        'ZD60' => '立即应付的 到期净值',
        'ZFR1' => '半月结，15日之前发货，当月15日到期',
        'ZL6T' => '90% LC 60 days，10% TT AFTER',
        'ZL95' => '95% L/C AFTER,5% L/C AFTER 6M FROM ACCEPTANCE DATE',
        'ZLC1' => '100% L/C (90/10) Transfer',
        'ZLC2' => '100% L/C AT SIGHT (95/5)',
        'ZLT1' => '90%LC，10%TT',
        'ZLT2' => '80%LC，20%TT',
        'ZLT3' => '70%LC，30%TT',
        'ZLT4' => '95%LC，5%TT',
        'ZLT5' => '50%L/C，50%TT after',
        'ZT20' => '20% T/T ADV,80% T/T AFTER',
        'ZT30' => '30% T/T ADV, 70%T/T AFTER',
        'ZT35' => '35% TT ADV，65% TT AFTER',
        'ZT40' => '40% TT ADV，60% TT AFTER',
        'ZT50' => '50% TT ADV，50% TT AFTER',
        'ZT55' => '95%TT ADV，5%TT AFTER',
        'ZT90' => '验收合格后T/T支付90%，设备正常运行三个月T/T支付10%',
        'ZTT1' => 'TT AFTER DELIVERY 45 DAY',
        'ZTT2' => 'TT AFTER DELIVERY 120 DAY',
        'ZTT3' => '100%TT发货后15个工作日内支付',
        'ZTT4' => '验收合格后T/T支付80%，设备正常运行三个月T/T支付20%',
        'ZZ60' => '60 DAYS AFTER ISSUING INVOICE',
        'ZZ95' => '95% L/C AFTER,5% T/T AFTER 6M FROM ACCEPTANCE DATE',
        'ZZLC' => '100% L/C AT SIGHT',
        'ZZTT' => '100% TT IN ADVANCE',
        'ZFHQ' => '发货前付清全款',
        'ZZ19' => '10% T/T下单前预付 90% T/T发货前预付',
        'ZZ28' => '20% T/T下单前预付 80% T/T发货前预付',
        'ZF60' => '发货后60天内支付（内贸）',
        'ZF30' => '发货后30天内支付（内贸）',
        'Z022' => '100% T/T WITHIN 90 DAYS AFTER SHIPMENT'
    };

    public OpportunityProductController() {
        Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
        baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
        String path = URL.getCurrentRequestUrl().getPath();
        if (path.indexOf('/apex') > 0) {
            baseUrl += path.substring(0, path.indexOf('/apex'));
        }
        oppId = System.currentPageReference().getParameters().get('oppid');
        is_IE_direct = false;
        is_Parts_direct = false;
        specialDealer = false;
        List<Opportunity> oppList = [select Id, Pricebook2Id, ProductSegment__c, ApprovalStatus_D__c, CurrencyIsoCode, Is_Decided__c, Machine_Parts__c, SalesChannel__c, IE_Discount_Normal__c, IE_Discount_Special__c, IE_Custom_Price__c, IE_ShipmentTerm__c, IE_Shipment_Term2__c, IE_Payment_terms__c, IE_Warranty__c, Dealer__r.Dealer_Rank__c,
                                     IE_Subtotal__c, IE_Discount_final__c, Amount, Quote_TotalPrice__c, Payment_terms__c, IE_ShippingHandling__c, IE_local_cost__c, Subuse__c, IE_dealer_profit__c, IE_dealer_profit_percent__c, Dealer__c,
                                     DealerId__c, Quote_CustomPrice__c, SyncedQuote_Id__c,Trade_Type_D__c 
                                     from Opportunity where Id = :oppId];
        if (oppList.size() > 0) {
            //specialDealer = oppList[0].DealerId__c
            //specialDealer = StaticParameter.specialDealerMap.containsKey(oppList[0].DealerId__c);
            specialDealer = IfspecialDealer(oppList[0].DealerId__c);
            specialDealer_NotisProductModel_Amountcheck = false;
            opp = oppList[0];
            pricebook2Id = opp.pricebook2Id;
            currencyIsoCode = opp.currencyIsoCode;
            if (opp.Machine_Parts__c == 'Parts' && opp.SalesChannel__c == 'direct') {
                is_Parts_direct = true;
            }
            if (String.isBlank(opp.Dealer__c) && opp.SalesChannel__c == 'direct') {
                is_IE_direct = true;
            }
            if (opp.IE_Warranty__c == null || opp.IE_Warranty__c == 0) {
                opp.IE_Warranty__c = 1;
            }
            if (opp.SyncedQuote_Id__c == null || opp.SyncedQuote_Id__c == '') {
                hasQuote = false;
            } else {
                hasQuote = true;
            }
        }
    }

    public OpportunityProductController(ApexPages.StandardController controller) {
        Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
        baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
        String path = URL.getCurrentRequestUrl().getPath();
        if (path.indexOf('/apex') > 0) {
            baseUrl += path.substring(0, path.indexOf('/apex'));
        }
        oppId = controller.getRecord().Id;
        is_IE_direct = false;
        is_Parts_direct = false;
        specialDealer = false;
        specialDealer_NotisProductModel_Amountcheck = false;
        List<Opportunity> oppList = [select Id, RecordTypeId, Pricebook2Id, ProductSegment__c, ApprovalStatus_D__c, CurrencyIsoCode, Is_Decided__c, Machine_Parts__c, SalesChannel__c, IE_Discount_Normal__c, IE_Discount_Special__c, IE_Custom_Price__c, IE_ShipmentTerm__c, IE_Shipment_Term2__c, IE_Payment_terms__c, IE_Warranty__c, Dealer__r.Dealer_Rank__c,
                                     IE_Subtotal__c, IE_Discount_final__c, Amount, Quote_TotalPrice__c, Payment_terms__c, IE_ShippingHandling__c, IE_local_cost__c, Subuse__c, IE_dealer_profit__c, IE_dealer_profit_percent__c, Dealer_Code__c, Province__c, Dealer_Rank__c, Dealer__c, Account.MarketVerticals__c,
                                     DealerId__c, Quote_CustomPrice__c, SyncedQuote_Id__c, OrderIsChange__c,Trade_Type_D__c 
                                     from Opportunity where Id = :oppId];
        if (oppList.size() > 0) {
            //specialDealer = StaticParameter.specialDealerMap.containsKey(oppList[0].DealerId__c);
            specialDealer = IfspecialDealer(oppList[0].DealerId__c);
            opp = oppList[0];
            pricebook2Id = opp.pricebook2Id;
            currencyIsoCode = opp.currencyIsoCode;
            if (opp.Machine_Parts__c == 'Parts' && opp.SalesChannel__c == 'direct') {
                is_Parts_direct = true;
            }
            if (String.isBlank(opp.Dealer__c) && opp.SalesChannel__c == 'direct') {
                is_IE_direct = true;
            }
            if (opp.IE_Warranty__c == null || opp.IE_Warranty__c == 0) {
                opp.IE_Warranty__c = 1;
            }
            if (opp.SyncedQuote_Id__c == null || opp.SyncedQuote_Id__c == '') {
                hasQuote = false;
            } else {
                hasQuote = true;
            }
        }
    }

    public PageReference init() {

        initStringConcatenation = '';
        saveStringConcatenation = '';
        verifyProductValidFlag = false;
        is_hidden_user = false;
        // String profileid = UserInfo.getProfileId();

        //新的获取简档ID  calendarUtil.getMemberProfileID  这里用到的人员ID 和获取到的简档ID都是15位的
        String new_profileId = calendarUtil.getMemberProfileID(UserInfo.getUserId().subString(0,15));
        
        if (new_profileId.substring(0, 15) == System.Label.RT_BS_No_Price) {//} || profileId.substring(0, 15) == System.Label.SystemAdmin) {
            is_hidden_user = true;
        }
        is_dealer_user = false;
        if (UserInfo.getUserType() == 'PowerPartner' || UserInfo.getUserId().substring(0, 15) == '00528000006hJeB') {
            is_dealer_user = true;
        }

        saveBtnDisabled = false;
        refresh = false;
        if (opp != null && opp.ApprovalStatus_D__c == 'Submit') {
            saveBtnDisabled = true;
        }
        if (opp != null && opp.Is_Decided__c == true) {
            saveBtnDisabled = true;
        }
        String opentype = System.currentPageReference().getParameters().get('opentype');
        if (opentype == 'order') {
            saveBtnDisabled = true;
        }

        is_hidden_all = false;

        is_IE = false;
        if (opp.ProductSegment__c == 'IE' || opp.ProductSegment__c == 'RVI' || opp.ProductSegment__c == 'NDT' || opp.ProductSegment__c == 'ANI') {
            is_IE = true;
        }
        is_RVI = false;
        if (opp.ProductSegment__c == 'RVI') {
            is_RVI = true;
        }
        if (opp.ProductSegment__c == 'NDT' || opp.ProductSegment__c == 'ANI') {
            is_NDT = true;
        } else {
            is_NDT = false;
        }
        specialDealer = false;
        //specialDealer = StaticParameter.specialDealerMap.containsKey(opp.DealerId__c);
        specialDealer = IfspecialDealer(opp.DealerId__c);
        specialDealer_NotisProductModel_Amountcheck = false;
        if (specialDealer) {
            is_hidden_all = true;
        }
        if (opp.SyncedQuote_Id__c == null || opp.SyncedQuote_Id__c == '') {
            hasQuote = false;
        } else {
            hasQuote = true;
        }
        /*if (is_IE == true) {
            String dealer_rank = opp.Dealer__r.Dealer_Rank__c;
            if (dealer_rank == 'A') {
                dealer_coefficient = is_RVI ? Decimal.valueOf(System.Label.Dealer_Rank_A_RVI) / 100 : Decimal.valueOf(System.Label.Dealer_Rank_A) / 100;
                dealer_coefficient.setScale(2);
                opp.IE_Discount_Normal__c = 100 - (is_RVI ? Decimal.valueOf(System.Label.Dealer_Rank_A_RVI) : Decimal.valueOf(System.Label.Dealer_Rank_A));
            } else if (dealer_rank == 'B') {
                dealer_coefficient = is_RVI ? Decimal.valueOf(System.Label.Dealer_Rank_B_RVI) / 100 : Decimal.valueOf(System.Label.Dealer_Rank_B) / 100;
                dealer_coefficient.setScale(2);
                opp.IE_Discount_Normal__c = 100 - (is_RVI ? Decimal.valueOf(System.Label.Dealer_Rank_B_RVI) : Decimal.valueOf(System.Label.Dealer_Rank_B));
            } else if (dealer_rank == 'C') {
                dealer_coefficient = is_RVI ? Decimal.valueOf(System.Label.Dealer_Rank_C_RVI) / 100 : Decimal.valueOf(System.Label.Dealer_Rank_C) / 100;
                dealer_coefficient.setScale(2);
                opp.IE_Discount_Normal__c = 100 - (is_RVI ? Decimal.valueOf(System.Label.Dealer_Rank_C_RVI) : Decimal.valueOf(System.Label.Dealer_Rank_C));
            } else if (dealer_rank == 'D') {
                dealer_coefficient = is_RVI ? Decimal.valueOf(System.Label.Dealer_Rank_D_RVI) / 100 : 1;
                dealer_coefficient.setScale(2);
                opp.IE_Discount_Normal__c = 100 - (is_RVI ? Decimal.valueOf(System.Label.Dealer_Rank_D_RVI) : 100);
            } else {
                dealer_coefficient = 1;
                dealer_coefficient.setScale(2);
                opp.IE_Discount_Normal__c = 0;
            }
        }*/

        Map<String, Decimal> ddMap = new Map<String, Decimal>();
        String key1 = '';
        String key2 = '';
        List<Dealer_Discount__c> ddList = [select id, Product_Segment__c, DimensionField1__c, DimensionField2__c, DimensionValue1__c, DimensionValue2__c, Dealer_Rank__c, Dealer_Rank_F__c from Dealer_Discount__c where Product_Segment__c = :opp.ProductSegment__c];
        for (Dealer_Discount__c dd : ddList) {
            ddMap.put(dd.DimensionValue1__c + '|' + dd.DimensionValue2__c, dd.Dealer_Rank_F__c);
            key1 = dd.DimensionField1__c == null ? '' : dd.DimensionField1__c;
            key2 = dd.DimensionField2__c == null ? '' : dd.DimensionField2__c;

        }

        String keyF = ''; // ((key1 == '' || opp.get(key1) == null) ? 'null' : opp.get(key1)) + '|' + ((key2 == '' || opp.get(key2) == null) ? 'null' : opp.get(key2));
        if (opp.ProductSegment__c == 'RVI') {
            keyF = ((key1 == '' || opp.get(key1) == null) ? 'null' : opp.get(key1)) + '|' + ((key2 == '' || opp.get(key2) == null) ? 'null' : opp.get(key2));
        } else {
            keyF = ((key1 == '' || opp.get(key1) == null) ? 'null' : opp.get(key1)) + '|' + ((key2 == '' || opp.get(key2) == null) ? 'null' : opp.get(key2));
        }
        system.debug(opp.get('Dealer__c'));
        System.debug(keyF);
        System.debug(ddMap.get(keyF));
        if (opp.ProductSegment__c == 'NDT' || opp.ProductSegment__c == 'ANI') {
            opp.IE_Discount_Normal__c = 100 - (ddMap.get(keyF) == null ? 100.0 : (ddMap.get(keyF) > 100.0 ? 100.0 : ddMap.get(keyF))) ;

        } else {
            opp.IE_Discount_Normal__c = 100 - (ddMap.get(keyF) == null ? 100.0 : ddMap.get(keyF));
        }

        if (opp.ProductSegment__c == 'BS') {
            dealer_coefficient = opp.IE_Discount_Normal__c;
        } else if (opp.ProductSegment__c == 'IE' || opp.ProductSegment__c == 'RVI') {
            dealer_coefficient = (ddMap.get(keyF) == null ? 100.0 : ddMap.get(keyF)) / 100;
        } else {
            dealer_coefficient = (ddMap.get(keyF) == null ? 100.0 : (ddMap.get(keyF) > 100.0 ? 100.0 : ddMap.get(keyF))) / 100;
        }
        system.debug('=====ddMap:' + ddMap);
        system.debug('=====keyF:' + keyF);
        system.debug('=====IE_Discount_Normal__c:' + opp.IE_Discount_Normal__c);
        dealer_discount = (opp.IE_Discount_Normal__c == null ? 0 : opp.IE_Discount_Normal__c) + (opp.IE_Discount_Special__c == null ? 0 : opp.IE_Discount_Special__c);

        maxLine = Integer.valueOf(System.Label.MaxLine);
        Integer rownum = 0;
        OPInfoList = new List<OpportunityProduceInfo>();
        if (oppId != null && oppId.length() > 0) {
            List<OpportunityLineItem> oliList = [select Id, Discount, Quantity, Product2Id, PricebookEntryId, PricebookEntry.Product2Id, Product_Search__c,
                                                 Product_Search__r.Name, Product_Search__r.Product__c, QuantityD__c, UnitPriceD__c,
                                                 IsNew__c, IsDelete__c, DescriptionD__c, PricebookEntry.SalesPrice__c, Product_Search__r.ProductModels1__c, PricebookEntry.Hidden_flag__c,
                                                 Product_Search__r.ProductCode__c, Product_Search__r.Product_ECCode__c
                                                 from OpportunityLineItem
                                                 where OpportunityId = :oppId
                                                         order by Id];
            initStringConcatenation = opp.IE_Discount_Special__c + '|';
            for (OpportunityLineItem oli : oliList) {
                rownum += 1;
                if (specialDealer) {
                    OpportunityProduceInfo opi = new OpportunityProduceInfo(rownum, oli, specialDealer);

                    //if ( specialDealer || (is_dealer_user == true && opi.hiddenflg == true)) {
                    if ( specialDealer || (is_dealer_user == true && opi.hiddenflg == true)) {
                        system.debug('opi.isProductModel--->1' + opi.isProductModel);
                        //opi.oli.UnitPriceD__c = 0;
                        if (opi.isProductModel) {

                        } else {
                            opi.oli.UnitPriceD__c = 0;
                        }
                        is_hidden_all = true;
                    }
                    OPInfoList.add(opi);
                } else {
                    OpportunityProduceInfo opi = new OpportunityProduceInfo(rownum, oli);

                    //if ( specialDealer || (is_dealer_user == true && opi.hiddenflg == true)) {
                    if (is_dealer_user == true && opi.hiddenflg == true) {

                        //opi.oli.UnitPriceD__c = 0;
                        if (opi.isProductModel) {

                        } else {
                            opi.oli.UnitPriceD__c = 0;
                        }
                        is_hidden_all = true;
                    }
                    OPInfoList.add(opi);
                }

                if (opp.OrderIsChange__c) {
                    String productCode = oli.Product_Search__r.ProductCode__c;
                    if (String.isNotBlank(productCode)) {

                        initStringConcatenation += productCode + '|' + oli.Quantity;
                    }

                }
                //OpportunityProduceInfo opi = new OpportunityProduceInfo(rownum, oli);
                //if ( specialDealer || (is_dealer_user == true && opi.hiddenflg == true)) {
                //    //opi.oli.UnitPriceD__c = 0;
                //    if(specialDealer && opi.isProductModel){

                //    }else{
                //        opi.oli.UnitPriceD__c = 0;
                //    }
                //    is_hidden_all = true;
                //}
                //OPInfoList.add(opi);
            }
            system.debug('initStringConcatenation--->' + initStringConcatenation);
            for (OpportunityProduceInfo opinfo : OPInfoList) {
                if (opInfo.discount != null && opInfo.discount != 0) {
                    Decimal ie_discount_n = opp.IE_Discount_Normal__c == null ? 0.00 : opp.IE_Discount_Normal__c;
                    Decimal tmp_discount = ie_discount_n == 100 ? 0 : (opInfo.discount - ie_discount_n) / (100 - ie_discount_n) * 100;
                    opinfo.discount = tmp_discount.setScale(2, System.RoundingMode.HALF_UP);
                    if (is_IE == true) {
                        opinfo.discount = opp.IE_Discount_Special__c;
                    } else {
                        Decimal discount_o = opinfo.oli.discount == null ? 0 : opinfo.oli.discount;
                        opinfo.discount = discount_o;//(discount_o - ie_discount_n) / (1 - ie_discount_n / 100);
                        opinfo.discount = opinfo.discount.setScale(2, System.RoundingMode.HALF_UP);
                    }
                } else {
                    opinfo.discount = 0.0;
                }
            }
        }
        //rownum += 1;
        //OpportunityProduceInfo opi= new OpportunityProduceInfo(rownum);
        //OPInfoList.add(opi);

        if (rownum < maxLine) {
            for (Integer i = rownum; i < maxLine; i++) {
                if (specialDealer) {
                    //if (rownum != OPInfoList.size()) {
                    //    String oliId = OPInfoList[i].oli.id;
                    //    String pName = OPInfoList[i].productName;
                    //    String pId = OPInfoList[i].productId;
                    //    Boolean isProductModel = OPInfoList[i].isProductModel;
                    //    if (pName != null && pName.length() > 0 && pId != null && pId.length() > 0) {
                    //        if (oliId != null && oliId.length() > 0 && isProductModel) {
                    //            OpportunityProduceInfo opi = new OpportunityProduceInfo(i + 1,specialDealer);
                    //            OPInfoList.add(opi);
                    //        } else {
                    //            OpportunityProduceInfo opi = new OpportunityProduceInfo(i + 1);
                    //            OPInfoList.add(opi);
                    //        }
                    //    }
                    //} else {
                    //    OpportunityProduceInfo opi = new OpportunityProduceInfo(i + 1);
                    //    OPInfoList.add(opi);
                    //}
                    OpportunityProduceInfo opi = new OpportunityProduceInfo(i + 1, specialDealer);
                    //OpportunityProduceInfo opi = new OpportunityProduceInfo(i + 1);
                    OPInfoList.add(opi);

                } else {
                    OpportunityProduceInfo opi = new OpportunityProduceInfo(i + 1);
                    OPInfoList.add(opi);
                }
                //OpportunityProduceInfo opi = new OpportunityProduceInfo(i + 1);
                //OPInfoList.add(opi);
            }
        }

        return null;
    }

    public PageReference addLine() {
        system.debug('=====before add size:' + OPInfoList.size());
        Integer nowLine = getOPInfoListSize();
        OpportunityProduceInfo newopi = new OpportunityProduceInfo(nowLine + 1);

        List<OpportunityProduceInfo> temp = new List<OpportunityProduceInfo>();
        for (OpportunityProduceInfo opi : OPInfoList) {
            temp.add(opi);
        }
        temp.add(newopi);
        OPInfoList = temp.clone();
        system.debug('=====after add size:' + OPInfoList.size());

        return null;
    }

    public PageReference deleteLine() {
        system.debug('=====before del size:' + OPInfoList.size());
        Integer rownum = 0;
        List<OpportunityProduceInfo> temp = new List<OpportunityProduceInfo>();
        for (OpportunityProduceInfo opi : OPInfoList) {
            if (opi.lineNo != lineNo) {
                rownum += 1;
                OpportunityProduceInfo tmp = new OpportunityProduceInfo(rownum, opi.oli);
                if ( specialDealer || (is_dealer_user == true && tmp.hiddenflg == true)) {
                    tmp.oli.UnitPriceD__c = 0;
                    //if(specialDealer && opi.isProductModel){

                    //}else{
                    //    opi.oli.UnitPriceD__c = 0;
                    //}
                    is_hidden_all = true;
                }
                temp.add(tmp);
            }
        }
        OPInfoList = temp.clone();
        system.debug('=====after del size:' + OPInfoList.size());

        return null;
    }

    public PageReference saveLine() {
        specialDealer_NotisProductModel_Amountcheck = false;
        for (OpportunityProduceInfo opi : OPInfoList) {
            system.debug( ' opi.oli.UnitPriceD__c--->' + opi.oli.UnitPriceD__c);
        }
        system.debug('OPInfoList--->' + OPInfoList);
        system.debug('=====is_hidden_all11111:' + is_hidden_all);
        List<PricebookEntry> pbeList = [select Id, Product2Id, Pricebook2Id from PricebookEntry where Pricebook2Id = :opp.Pricebook2Id and CurrencyIsoCode = :opp.CurrencyIsoCode];
        Map<String, String> pbeMap = new Map<String, String>();
        for (PricebookEntry pbe : pbeList) {
            pbeMap.put(pbe.Product2Id, pbe.Id);
        }
        system.debug('pbeMap--->' + pbeMap);
        errorFlag = false;

        if (is_IE && (opp.IE_Custom_Price__c == null || opp.IE_Custom_Price__c == 0)) {
            opp.IE_Custom_Price__c.addError('请输入客户价格。');
            errorFlag = true;
        }
        //外贸询价优化2021-05-28 start
        if (is_IE && opp.IE_ShipmentTerm__c == null && opp.Trade_Type_D__c =='Tax Exemption') {
            opp.IE_ShipmentTerm__c.addError('请选择国际贸易条件。');
            errorFlag = true;
        }
        if (is_IE && opp.IE_Shipment_Term2__c == null && opp.Trade_Type_D__c =='Tax Exemption') {
            opp.IE_Shipment_Term2__c.addError('请选择国际贸易条件2。');
            errorFlag = true;
        }
        if (is_NDT == false && is_IE == true && opp.Payment_terms__c == null) {
            opp.Payment_terms__c.addError('请选择付款条件。');
            errorFlag = true;
        }
        if (is_NDT && opp.IE_Payment_terms__c == null) {
            opp.IE_Payment_terms__c.addError('请选择付款条件。');
            errorFlag = true;
        }
        //外贸询价优化2021-05-28 end


        Map<String, String> keepIdMap = new Map<String, String>();
        for (OpportunityProduceInfo opi : OPInfoList) {
            String pName = opi.productName;
            String pId = opi.productId;
            if (pName != null && pName.length() > 0 && pId != null && pId.length() > 0) {
                if (pbeMap.containsKey(pId) == false) {
                    opi.oli.Product_Search__c.addError('选择产品与询价产品分类不匹配。');
                    errorFlag = true;

                }
                if (opi.oli.QuantityD__c == null || opi.oli.QuantityD__c == 0) {
                    opi.oli.QuantityD__c.addError('请输入数量。');
                    errorFlag = true;
                }
                if (specialDealer == false && is_hidden_all == false && is_hidden_user == false && opi.hiddenflg == false && (opi.oli.UnitPriceD__c == null || opi.oli.UnitPriceD__c == 0)) {
                    //if (opi.oli.UnitPriceD__c == null || opi.oli.UnitPriceD__c == 0) {
                    opi.oli.UnitPriceD__c.addError('请输入单价。');
                    errorFlag = true;

                }

                String oliId = opi.oli.id;
                keepIdMap.put(oliId, oliId);
            }
        }
        /*String dealerId = opp.Dealer__c;
        dealerId = dealerId.subString(0,dealerId.length()-3);*/
        if (errorFlag == true /*&& dealerId != '0012800000DUL3i' && dealerId != '0012800000etOTu'*/ ) {
            return null;
        }

        List<OpportunityLineItem> upsertList = new List<OpportunityLineItem>();
        List<OpportunityLineItem> deleteList = new List<OpportunityLineItem>();

        Map<String, Decimal> productIdQuantityMap = new  Map<String, Decimal>();



        List<OpportunityLineItem> nowOli = [select id from OpportunityLineItem where OpportunityId = :oppId and IsNew__c = true];
        for (OpportunityLineItem oli : nowOli) {
            if (keepIdMap.containsKey(oli.id) == false) {
                deleteList.add(oli);
            }
        }

        List<String> pList = new List<String>();
        saveStringConcatenation = opp.IE_Discount_Special__c + '|';
        for (OpportunityProduceInfo opi : OPInfoList) {
            String oliId = opi.oli.id;
            String pName = opi.productName;
            String pId = opi.productId;
            if (pName != null && pName.length() > 0 && pId != null && pId.length() > 0) {
                pList.add(pId);
            }

            if (opp.OrderIsChange__c) {
                // stringConcatenation = opp.IE_Discount_Special__c + '|';
                // String saveStringConcatenation = '';
                String productCode = opi.oli.Product_Search__r.ProductCode__c;
                if (String.isNotBlank(productCode)) {

                    // stringConcatenation += RadiationUtil.getStringConcatenation(productCode,oli.Quantity);
                    saveStringConcatenation += productCode + '|' + opi.oli.QuantityD__c;
                }

            }
        }
        List<Product_Search__c> psList = new List<Product_Search__c>();
        psList = [select id, Product__c from Product_Search__c where Product__c = :pList];
        Map<String, String> psMap = new Map<String, String>();
        for (Product_Search__c ps : psList) {
            psMap.put(ps.Product__c, ps.Id);
        }

        Decimal discount_n = opp.IE_Discount_Normal__c == null ? 0.0 : opp.IE_Discount_Normal__c;
        //Decimal subtotal = 0.00;
        //Decimal totalprice = 0.00;
        Decimal discount_sp = opp.IE_Discount_Special__c == null ? 0.0 : opp.IE_Discount_Special__c;

        List<String> pidList = new List<String>();
        Decimal specialdiscount = 0.00;

        if (specialDealer) {
            specialdiscount = Specialdiscount(OPInfoList, opp);

            if (specialDealer_NotisProductModel_Amountcheck) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, '总价字段必填'));
                return null;
            }
            if (specialdiscount == -1) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, '折扣 必须在 0 到 100 之间'));
                return null;
            }
        }
        if (opp.OrderIsChange__c) {
            if (initStringConcatenation != saveStringConcatenation) {
                verifyProductValidFlag = true;
            }
        }

        for (OpportunityProduceInfo opi : OPInfoList) {
            String oliId = opi.oli.id;
            String pName = opi.productName;
            String pId = opi.productId;

            if (opi.oli.IsDelete__c == true) {
                deleteList.add(opi.oli);
            } else if (pName != null && pName.length() > 0 && pId != null && pId.length() > 0) {
                if (oliId != null && oliId.length() > 0) {
                    opi.oli.Product_Search__c = psMap.get(pId);
                    //if (opp.ProductSegment__c == 'BS' || opp.ProductSegment__c == 'IE') {
                    opi.oli.Quantity = opi.oli.QuantityD__c;
                    if (is_hidden_all == true || is_dealer_user == true && opi.hiddenflg == true) {
                        //opi.oli.UnitPriceD__c = opi.salesPrice;
                        system.debug('opi.isProductModel--->3' + opi.isProductModel);
                        if (specialDealer && opi.isProductModel) {

                        } else {
                            opi.oli.UnitPriceD__c = opi.salesPrice;
                        }
                    }
                    if (opi.isProductModel == true) {
                        system.debug('11111111111111111');
                        opi.oli.UnitPrice = opi.oli.UnitPriceD__c;
                    } else {
                        system.debug('222222222222222222');
                        system.debug(opi.test);
                        opi.oli.UnitPrice = opi.salesPrice;
                        opi.oli.UnitPriceD__c = opi.salesPrice;
                    }
                    opi.oli.Description = opi.oli.DescriptionD__c;
                    opi.oli.IsNew__c = false;
                    if (is_IE) {
                        //opi.discount = opi.discount == null ? 0.0 : opi.discount;
                        //opi.oli.Discount = discount_n + (100 - discount_n) / 100 * opi.discount;
                        Decimal discount = discount_n + (100 - discount_n) / 100 * discount_sp;
                        opi.oli.Discount = discount.setScale(2, System.RoundingMode.HALF_UP);
                    } else {
                        if (specialDealer) {
                            opi.oli.Discount = specialdiscount;
                        } else {
                            opi.oli.Discount = opi.discount;
                        }
                        //opi.oli.Discount = opi.discount;
                        //opi.oli.Discount = discount_n + (100 - discount_n) * opi.discount / 100;
                    }
                    opi.oli.oppLiVerifyProductValid__c = verifyProductValidFlag;

                    upsertList.add(opi.oli);
                    pidList.add(pId);
                    //subtotal += opi.oli.Quantity * opi.oli.UnitPrice;
                    //totalprice += opi.oli.Quantity * opi.oli.UnitPrice * (100 - opi.oli.Discount) / 100;
                } else {

                    //if (opp.ProductSegment__c == 'BS' || opp.ProductSegment__c == 'IE') {
                    opi.oli.PricebookEntryId = pbeMap.get(pId);
                    opi.oli.Quantity = opi.oli.QuantityD__c;
                    if (is_hidden_all == true || is_dealer_user == true && opi.hiddenflg == true) {
                        system.debug('opi.isProductMode---->4' + opi.isProductModel);
                        //if(specialDealer && opi.isProductModel){
                        if (specialDealer ) {


                        } else {
                            //opi.oli.UnitPriceD__c = opi.salesPrice;
                        }
                    }
                    if (opi.isProductModel == true) {
                        system.debug('11111111111111111');
                        opi.oli.UnitPrice = opi.oli.UnitPriceD__c;
                    } else {
                        system.debug('222222222222222222');
                        system.debug(opi.test);
                        opi.oli.UnitPrice = opi.salesPrice;
                        opi.oli.UnitPriceD__c = opi.salesPrice;
                    }
                    opi.oli.Description = opi.oli.DescriptionD__c;
                    opi.oli.IsNew__c = false;
                    if (is_IE) {
                        //opi.discount = opi.discount == null ? 0.0 : opi.discount;
                        //opi.oli.Discount = discount_n + (100 - discount_n) / 100 * opi.discount;
                        Decimal discount = discount_n + (100 - discount_n) / 100 * discount_sp;
                        opi.oli.Discount = discount.setScale(2, System.RoundingMode.HALF_UP);
                    } else {
                        if (specialDealer) {
                            opi.oli.Discount = specialdiscount;
                        } else {
                            opi.oli.Discount = opi.discount;
                        }
                        //opi.oli.Discount = opi.discount;

                        //opi.oli.Discount = discount_n + (100 - discount_n) * opi.discount / 100;
                    }
                    //opi.oli.OLISingleProduct__c = true;
                    //}
                    OpportunityLineItem newoli = opi.oli.clone();
                    newoli.OpportunityId = oppId;
                    newoli.Product_Search__c = psMap.get(pId);
                    //XHL-20190513-AddStart
                    newoli.OLISingleProduct__c = true;
                    //XHL-20190513-AddEnd
                    system.debug('12345');
                    system.debug('newoli.UnitPriceD__c----->' + newoli.UnitPriceD__c);

                    upsertList.add(newoli);
                    pidList.add(pId);
                    //subtotal += opi.oli.Quantity * opi.oli.UnitPrice;
                    //totalprice += opi.oli.Quantity * opi.oli.UnitPrice * (100 - opi.oli.Discount) / 100;
                }

                // 产品首营状态Z5(停产) ---XHL 2021/02/07 Start
                Decimal quantity = opi.oli.QuantityD__c;
                if (productIdQuantityMap.containsKey(pId)) {
                    quantity += productIdQuantityMap.get(pId);
                }
                productIdQuantityMap.put(pId, quantity);
                // 产品首营状态Z5(停产) ---XHL 2021/02/07 End
            }
        }
//system.debug('=====subtotal:' + subtotal);
//system.debug('=====totalprice:' + totalprice);
        opp.IE_Discount_Normal__c = opp.IE_Discount_Normal__c == null ? 0.0 : opp.IE_Discount_Normal__c;
        //discount_sp = (subtotal == 0 || opp.IE_Discount_Normal__c == 100) ? 0 : ((1 - totalprice / subtotal) * 100 - opp.IE_Discount_Normal__c) / (100 - opp.IE_Discount_Normal__c) * 100;
        //discount_sp = discount_sp.setScale(2, System.RoundingMode.HALF_UP);
//system.debug('=====discount_sp:' + discount_sp);

        Opportunity saveOpp = new Opportunity();
        saveOpp.Id = opp.Id;
        saveOpp.IE_Discount_Normal__c = discount_n;
        saveOpp.IE_Discount_Special__c = discount_sp;
        saveOpp.IE_Custom_Price__c = opp.IE_Custom_Price__c;
        saveOpp.IE_ShipmentTerm__c = opp.IE_ShipmentTerm__c;
        saveOpp.IE_Shipment_Term2__c = opp.IE_Shipment_Term2__c;
        saveOpp.IE_Payment_terms__c = opp.IE_Payment_terms__c;
        saveOpp.IE_Warranty__c = opp.IE_Warranty__c;
        saveOpp.IE_ShippingHandling__c = opp.IE_ShippingHandling__c;
        saveOpp.IE_local_cost__c = opp.IE_local_cost__c;
        system.debug('ndt' + is_NDT);
        if (is_NDT) {
            saveOpp.Quote_PaymentTerms_Text__c = paymentTermsMap.get(opp.IE_Payment_terms__c);
        } else {
            saveOpp.IE_Payment_terms__c = opp.Payment_terms__c;
            saveOpp.Quote_PaymentTerms_Text__c = paymentTermsMap.get(opp.Payment_terms__c);
            saveOpp.Payment_terms__c = opp.Payment_terms__c;
        }
        // if (opp.OrderIsChange__c) {
        //     system.debug('saveStringConcatenation--->' +saveStringConcatenation);
        //     system.debug('initStringConcatenation--->' +initStringConcatenation);
        //     if (initStringConcatenation != saveStringConcatenation) {
        saveOpp.VerifyProductValid__c = verifyProductValidFlag;
        //     }
        // }

        saveOpp.Amount = opp.Amount;

        system.debug('saveOpp.Amount---->' + saveOpp.Amount);
        system.debug('opp.Amount---->' + opp.Amount);
        system.debug('upsertList---->' + upsertList);

        System.debug(pidList);
        if (pidList.size() > 0 && opp.RecordTypeId == System.Label.SSBD_Replacement) {
            List<Product2> p1List = new List<Product2>();
            p1List = [select id from Product2 where isMain__c = true and id in :pidList];
            System.debug('@@@@@@@@@@@' + p1List);
            if (p1List.size() > 0) {
                //opp.addError('包含非零配件产品，请检查产品内容');
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, '包含非零配件产品，请检查产品内容'));
                return null;
            }
        }

        if (upsertList.size() > 0) {

            // 产品首营状态Z5(停产) ---XHL 2021/02/07 Start
            if (productIdQuantityMap.size() > 0) {
                
                String productSegment = opp.ProductSegment__c == 'BS' ? 'LS' : opp.ProductSegment__c;
                String FGSPStr = 'Machine'.equals(opp.Machine_Parts__c) ? 'FG' : 'SP';
                Map<String, Decimal> productQuantityMap = new  Map<String, Decimal>();

                List<Product2> getProductList = [SELECT Id, Name, ProductCode, NMPAStatus__c, ProductStatusFormula__c FROM Product2 WHERE Id IN:productIdQuantityMap.keySet() AND NMPAStatus__c = '停产' AND ProductStatusFormula__c = '1'];

                for (Product2 pro : getProductList) {
                    String productCode = pro.ProductCode.trim();
                    Decimal productQuantity = productIdQuantityMap.get(pro.Id);
                    String key = productCode + '_' + productSegment + '_' + FGSPStr;
                    if (productQuantityMap.containsKey(key)) {
                        productQuantity += productQuantityMap.get(key); 
                    }
                    system.debug('Key---->'+key);
                    system.debug('value---->'+productQuantity);

                    productQuantityMap.put(key, productQuantity);
                }

                String result = OrderWebService.ProductInventoryCheck(productQuantityMap);
                if (result != '1') {
                    saveOpp.ProductInventoryCheck__c = result;
                }
            }
            // 产品首营状态Z5(停产) ---XHL 2021/02/07 End


            upsert upsertList;
        }
        if (deleteList.size() > 0) {
            delete deleteList;
        }

        update saveOpp;
        system.debug('saveOpp.Amount2---->' + saveOpp.Amount);
        for (OpportunityProduceInfo opi : OPInfoList) {
            if (specialDealer || (is_dealer_user == true && opi.hiddenflg == true)) {
                //opi.oli.UnitPriceD__c = 0;
                //if(specialDealer && opi.isProductModel){
                system.debug('opi.isProductModel--->6' + opi.isProductModel);
                if (specialDealer) {

                } else {
                    opi.oli.UnitPriceD__c = 0;
                }
                is_hidden_all = true;
            }
        }

        refresh = true;

        return null;
    }

    public PageReference reloadPage() {
        system.debug('=====reloadPage,is_hidden_all:' + is_hidden_all);

        return null;
    }

    public PageReference csvRead() {
        String strFile = '';
        List<String> listFile = new List<String>();
        errorFlag = false;
        errormessage = null;
        try {
            if (contentFile != null) {
                strFile = contentFile.toString();
                listFile = strFile.split('\n');
                system.debug('=====strFile:' + strFile);
            } else {
                errorFlag = true;
                errormessage = '读取内容为空。';
                return null;
            }
        } catch (Exception ex) {
            errorFlag = true;
            errormessage = System.Label.Error_Message02;
            return null;
        }

        for (Integer i = 0; i < listFile.size(); i++) {
            system.debug('=====listFile_' + i + ':' + listFile[i]);
        }

        List<String[]> arrayFile = new List<String[]>();
        String firstline = listFile[0];
        if (firstline.indexOf('套装') < 0) {
            errorFlag = true;
            errormessage = '读取内容格式不正确。';
            return null;
        } else {
            String strReplace = '';
            List<String> temp = strFile.split('"');
            for (Integer i = 0; i < temp.size(); i++) {
                if (math.mod(i, 2) == 1) {
                    temp[i] = temp[i].replace(',', '#%&');
                }
                strReplace += temp[i];
            }
            system.debug('=====strReplace:' + strReplace);
            List<String> listReplace = strReplace.split('\n');
            for (String replace : listReplace) {
                system.debug('=====replace:' + replace);
                if (replace != '\r' && replace.length() > 0) {
                    replace = replace.replace('\r', '');
                    String[] a = replace.split(',', -1);
                    for (Integer i = 0; i < a.size(); i++) {
                        if (a[i].indexOf('#%&') > 0) {
                            a[i] = a[i].replace('#%&', ',');
                        }
                    }
                    if (a.size() != 5) {
                        errorFlag = true;
                        errormessage = '读取内容格式不正确。Line:' + arrayFile.size();
                        return null;
                    }
                    arrayFile.add(a);
                }
            }
        }

        for (Integer i = 0; i < arrayFile.size(); i++) {
            system.debug('=====arrayFile' + i + ':' + arrayFile[i]);
        }

        List<String> prdCodeList = new List<String>();
        for (Integer i = 1; i < arrayFile.size(); i++) {
            if (arrayFile[i] != null && arrayFile[i].size() > 1 && arrayFile[i][0] != '') {
                if (opp.ProductSegment__c == 'BS') {
                    errorFlag = true;
                    errormessage = '此页面不可上传产品，若需上传请前往报价页面上传';
                    return null;
                }

                String tmp = '00000000000' + arrayFile[i][1];
                prdCodeList.add(tmp);
                prdCodeList.add(arrayFile[i][1]);
            }
        }
        system.debug('=====prdCodeList:' + prdCodeList);

        Map<String, Product_Search__c> psMap = new Map<String, Product_Search__c>(); // keyがProductCodeです。
        List<String> forSelect = new List<String>();
        List<Product_Search__c> psList = [
                                             select Id, Name, ProductCode__c, Product_ECCode__c, ProductDescription__c, ProductStatus__c, Product__c, ProductModels1__c
                                             from Product_Search__c
                                             where ProductCode__c in :prdCodeList];
        String errProduct = '';
        for (Product_Search__c ps : psList) {
            if (ps.ProductStatus__c == '0') {
                errorFlag = true;
                errProduct = ps.ProductCode__c + ',';
            }
            String pc = ps.ProductCode__c;
            if (pc.startsWith('00000000000')) {
                pc = pc.substring(11);
                psMap.put(pc, ps);
            }
            psMap.put(ps.ProductCode__c, ps);
            forSelect.add(ps.Product__c);
        }

        if (errorFlag == true) {
            errProduct = errProduct.substring(0, errProduct.length() - 1);
            errormessage = '产品状态为无效，不能使用。产品：' + errProduct;
            return null;
        }
        Map<String, PricebookEntry> pbeMap = new Map<String, PricebookEntry>(); // keyがProductCodeです。
        List<PricebookEntry> pbeList = [
                                           select Id, Product2Id, ProductCode, Product2.Product_ECCode__c, Product2.Dummy__c, CostPrice__c, SalesPrice__c, SalesPriceA__c, SalesPriceB__c, SalesPriceC__c, Hidden_flag__c
                                           from PricebookEntry
                                           where Pricebook2Id = :pricebook2Id
                                                   and CurrencyIsoCode = :currencyIsoCode
                                                           and Product2.ManualHidden__c = false
                                                                   and Product2Id in :forSelect];

        for (PricebookEntry pbe : pbeList) {
            String pc = pbe.ProductCode;
            if ((pbe.CostPrice__c == 0 && pbe.Product2.Dummy__c == false) || pbe.SalesPrice__c == 0) {
                errorFlag = true;
                errProduct += pbe.productCode + ',';
            } else {
                if (pc.startsWith('00000000000')) {
                    pc = pc.substring(11);
                    pbeMap.put(pc, pbe);
                }
                pbeMap.put(pbe.ProductCode, pbe);
            }
        }
        if (errorFlag == true) {
            errProduct = errProduct.substring(0, errProduct.length() - 1);
            errormessage = '产品价格信息不正确，不能使用。产品：' + errProduct;
            return null;
        }
        system.debug('=====psMap:' + psMap);
        system.debug('=====pbeMap:' + pbeMap);
        for (Integer i = 1; i < arrayFile.size(); i++) {
            if (psMap.containsKey(arrayFile[i][1]) == false || pbeMap.containsKey(arrayFile[i][1]) == false) {
                errorFlag = true;
                errProduct += arrayFile[i][1] + ',';
            }
        }
        if (errorFlag == true) {
            errProduct = errProduct.substring(0, errProduct.length() - 1);
            errormessage = '产品价格信息不正确，不能使用。产品：' + errProduct;
            return null;
        }

        List<OpportunityProduceInfo> OPInfoList2 = new List<OpportunityProduceInfo>();
        for (OpportunityProduceInfo opInfo : OPInfoList) {
            String pName = opInfo.productName;
            String pId = opInfo.productId;
            if (pName != null && pName.length() > 0 && pId != null && pId.length() > 0) {
                OPInfoList2.add(opInfo);
            }
        }
        Integer no = OPInfoList2.size() + 1;
        if (arrayFile.size() > 1) {
            OpportunityProduceInfo c = new OpportunityProduceInfo(no);
            is_hidden_all = false;
            for (Integer line = 1; line < arrayFile.size(); line++) {
                Product_Search__c ps = psMap.get(arrayFile[line][1]);
                PricebookEntry pbe = pbeMap.get(arrayFile[line][1]);
                system.debug('=====key:' + arrayFile[line][1]);
                system.debug('=====ps:' + ps);
                system.debug('=====pbe:' + pbe);
                c = new OpportunityProduceInfo(no, new OpportunityLineItem(IsNew__c = true, QuantityD__c = Decimal.valueOf(arrayFile[line][3]), UnitPriceD__c =  pbe.SalesPrice__c), ps.Name, true, ps.Product__c, ps.ProductCode__c, ps.Product_ECCode__c, pbe.SalesPrice__c, ps.ProductModels1__c, pbe.Hidden_flag__c, Decimal.valueOf(arrayFile[line][4]));
                if (specialDealer || (is_dealer_user == true && c.hiddenflg == true)) {
                    c.oli.UnitPriceD__c = 0;
                    is_hidden_all = true;
                }
                OPInfoList2.add(c);
                no++;
            }

            for (integer j = no; j < maxLine; j++) {
                c = new OpportunityProduceInfo(j);
                OPInfoList2.add(c);
            }

        } else {
            for (no = 0; no < maxLine; no++) {
                OpportunityProduceInfo active_activity = new OpportunityProduceInfo(no);
                OPInfoList2.add(active_activity);
            }
        }
        OPInfoList = OPInfoList2;

        return null;
    }

    public PageReference csvExport() {
        if (fileName == null || fileName == '') {
            errorFlag = true;
            errormessage = '请输入配置导出文件名。';
            return null;
        }
        csv_activities = new List<OpportunityProduceInfo>();
        for (OpportunityProduceInfo opi : OPInfoList) {
            String pName = opi.productName;
            String pId = opi.productId;
            if (pName != null && pName.length() > 0 && pId != null && pId.length() > 0) {
                csv_activities.add(opi);
            }
        }
        PageReference pr = page.OpportunityCSVExport;
        return pr;
    }

    class OpportunityProduceInfo {
        public Integer lineNo { get; set; }
        public OpportunityLineItem oli { get; set; }
        public String productName { get; set; }
        public Boolean isNew { get; set; }
        public String productId { get; set; }
        public String productCode { get; set; }
        public String productEC { get; set; }

        public Decimal salesPrice { get; set; }
        public boolean isProductModel { get; set; }
        public boolean hiddenflg { get; set; }

        public Decimal discount { get; set; }
        public Decimal test {get; set;}

        public OpportunityProduceInfo(Integer line) {
            lineNo = line;
            oli = new OpportunityLineItem(IsNew__c = true);
            productName = '';
            isNew = true;
            productId = '';
            productCode = '';
            productEC = '';

            salesPrice = 0;
            isProductModel = false;

            hiddenflg = false;

            //discount = 0.00;
        }

        public OpportunityProduceInfo(Integer line, Boolean specialDealer) {
            lineNo = line;
            oli = new OpportunityLineItem(IsNew__c = true);
            productName = '';
            isNew = true;
            productId = '';
            productCode = '';
            productEC = '';

            isProductModel = true;
            hiddenflg = false;

            //discount = 0.00;
        }

        public OpportunityProduceInfo(Integer line, OpportunityLineItem lineItem) {
            lineNo = line;
            oli = lineItem;
            productName = lineItem.Product_Search__r.Name;
            isNew = lineItem.IsNew__c;
            productId = lineItem.Product_Search__r.Product__c;
            String pCode = lineItem.Product_Search__r.ProductCode__c;
            productCode = pCode == null ? '' : (pCode.startsWith('0000000000') ? pCode.substring(10) : pCode);
            productEC = lineItem.Product_Search__r.Product_ECCode__c;

            salesPrice = lineItem.PricebookEntry.SalesPrice__c;
            isProductModel = lineItem.Product_Search__r.ProductModels1__c;
            hiddenflg = lineItem.PricebookEntry.Hidden_flag__c;

            discount = lineItem.Discount;
        }

        public OpportunityProduceInfo(Integer line, OpportunityLineItem lineItem, Boolean specialDealer) {
            lineNo = line;
            oli = lineItem;
            productName = lineItem.Product_Search__r.Name;
            isNew = lineItem.IsNew__c;
            productId = lineItem.Product_Search__r.Product__c;
            String pCode = lineItem.Product_Search__r.ProductCode__c;
            productCode = pCode == null ? '' : (pCode.startsWith('0000000000') ? pCode.substring(10) : pCode);
            productEC = lineItem.Product_Search__r.Product_ECCode__c;
            isProductModel = lineItem.Product_Search__r.ProductModels1__c;
            hiddenflg = lineItem.PricebookEntry.Hidden_flag__c;
            salesPrice = lineItem.PricebookEntry.SalesPrice__c;

            discount = lineItem.Discount;
        }

        public OpportunityProduceInfo(Integer in_line, OpportunityLineItem in_lineItem, String in_productName, Boolean in_isNew, String in_productId, String in_productCode, String in_productEC, Decimal in_salesPrice, Boolean in_isProductModel, Boolean in_hiddenflg, Decimal in_discount) {
            lineNo = in_line;
            oli = in_lineItem;
            productName = in_productName;
            isNew = in_isNew;
            productId = in_productId;
            String pCode = in_productCode;
            productCode = pCode == null ? '' : (pCode.startsWith('0000000000') ? pCode.substring(10) : pCode);
            productEC = in_productEC;

            salesPrice = in_salesPrice;
            isProductModel = in_isProductModel;
            hiddenflg = in_hiddenflg;

            //discount = in_discount;
        }
    }
    //特殊代理商的特殊折扣处理(中誉、佰诺)
    public Decimal Specialdiscount(List<OpportunityProduceInfo> OPInfoList, Opportunity opp) {
        Decimal discount = 0.00;
        Decimal all_price1 = 0.00;
        Decimal cut_rate_price = 0.00;
        Boolean temp = false;
        for (OpportunityProduceInfo opi : OPInfoList) {
            String oliId = opi.oli.id;
            String pName = opi.productName;
            String pId = opi.productId;
            if (opi.oli.IsDelete__c == true) {

            } else if (pName != null && pName.length() > 0  && pId.length() > 0) {
                if (opi.isProductModel == false) {
                    all_price1 += opi.salesPrice * opi.oli.QuantityD__c;
                } else {
                    all_price1 += opi.oli.UnitPriceD__c * opi.oli.QuantityD__c;
                }
                if (!opi.isProductModel) {
                    temp = true;
                }
            }

        }
        system.debug('all_price1--->' + all_price1);
        system.debug('opp.Amount--->' + opp.Amount);

        if (temp && (opp.Amount == null || opp.Amount == 0)) {
            specialDealer_NotisProductModel_Amountcheck = true;
        }
        if (all_price1 > 0) {

            Decimal amo = opp.Amount == null || opp.Amount == 0 ? all_price1 : opp.Amount;
            cut_rate_price = all_price1 - amo;
            if (cut_rate_price >= 0) {
                discount = (all_price1 - amo) * 100 / all_price1;
            } else {
                discount = -1;
            }

        }
        return discount;

    }


    public static Boolean IfspecialDealer(String oppDealerId) {
        if (String.isBlank(oppDealerId)) {
            return false;
        }
        return StaticParameter.specialDealerMap.containsKey(oppDealerId.substring(0, 15)) && UserInfo.getUserType() == 'PowerPartner';
    }


    @TestVisible private void testI() {
        integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
    }








}