// Daily
// RowDataを残すため、@future execute にします
global class NFM110WebService {
    public static boolean isRunning = false;
    //public transient static List<Id> orderoutIdList;
    public transient static List<Id> orderReturnIdList;
    // Integer batchsize = 200;  考量する必要がないと思います。
    global class ProductsDelivery {
        webservice NFMUtil.Monitoring Monitoring;
        webservice NFM110WebService.GeneralData[] GeneralData;
    }
    global class GeneralData {
        webservice String SoNo;
        webservice String InquiryNo;
        webservice String ReturnMark;
        webservice String DeliveryDate;
        webservice String EndUserNo;
        webservice String DepartmentNo;
        webservice String DeliveryNote;
        webservice NFM110WebService.DnInformation[] DnInformation;
    }
    global class DnInformation {
        webservice String OTCode;
        webservice String Qty;
        webservice String SerialNoorLotNo;
        webservice String SorLMark;
        webservice String GuaranteePeriod;
        webservice String TracingCode;
        webservice String ValidTo;
        webservice String Barcode;
    }
    // 非同期を見せかけ、常にreturn void
    webservice static void NFM110(NFM110WebService.ProductsDelivery ProductsDelivery) {
        if (ProductsDelivery == null) {
            return;
        }
        NFMUtil.Monitoring Monitoring = ProductsDelivery.Monitoring;
        if (Monitoring == null) {
            return;
        }
        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM110', ProductsDelivery.GeneralData);
        if (String.isBlank(rowData.Log__c) == false) executefuture(rowData.Id);
    }

    @future
    global static void executefuture(String rowData_Id) {
        execute(rowData_Id);
    }
    global static void execute(String rowData_Id) {
        // 在进行NFM110处理时跳过消耗品明细2 arrived return 处理 HWAG-B3D9UV 2018/8/14 start
        StaticParameter.ConsumableAssetHanderTrigger= true;
        StaticParameter.EscapeConsumableOrderDetail2Trigger = true;
        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c from BatchIF_Log__c where RowDataFlg__c = true and Id = :rowData_Id];
        String logstr = rowData.MessageGroupNumber__c + ' start\n';
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = 'NFM110';
        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog.Log__c = logstr;
        iflog.ErrorLog__c = '';
        insert iflog;
        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        List<GeneralData> generalDataList = (List<GeneralData>) JSON.deserialize(rowDataStr, List<GeneralData>.class);
        if (generalDataList == null || generalDataList.size() == 0) {
            return;
        }

        Account ocm = [select Id from Account where AgentCode_Ext__c = '9999900'];
        // HHOA-AGN2EH start
        Account olympus = [select Id from Account where AgentCode_Ext__c = '9999999'];
        Account olympus_return = [select Id, ParentId from Account where AgentCode_Ext__c = '9999901'];
        // HHOA-AGN2EH end
        isRunning = true;
        //orderoutIdList = new List<Id>();
        orderReturnIdList = new List<Id>();
        Savepoint sp = Database.setSavepoint();
        try {
            // 更新対応配列とMapなどをセット
            Set<String> managementCodeList = new Set<String>();
            Set<String> soNoList = new Set<String>();
            Set<String> inquiryNoList = new Set<String>();
            Set<String> productCodeList = new Set<String>();
            List<String> barCodeList = new List<String>();
            List<String> tracingCodeList = new List<String>();
            Set<String> productSerialNoList = new Set<String>();
            for (NFM110WebService.GeneralData infoH : generalDataList) {
                if (String.isBlank(infoH.DeliveryNote)) {
                    continue;
                }
                if (infoH.DnInformation == null || infoH.DnInformation.size() == 0) {
                    continue;
                }
                // 病院と診療科の管理コード、TODO 販売店
                infoH.EndUserNo = NFMUtil.trimLeft(infoH.EndUserNo, '0');
                infoH.DepartmentNo = NFMUtil.trimLeft(infoH.DepartmentNo, '0');
                if (infoH.EndUserNo == null || infoH.EndUserNo  == '') {
                    // 病院と診療科の管理コードがない場合、処理と飛ばす
                    continue;
                }
                if (infoH.DepartmentNo == null || infoH.DepartmentNo == '') {
                    infoH.DepartmentNo = infoH.EndUserNo;
                }
                managementCodeList.add(infoH.EndUserNo);
                managementCodeList.add(infoH.DepartmentNo);
                if (String.isBlank(infoH.SoNo) == false) {
                    soNoList.add(infoH.SoNo);
                }
                if (String.isBlank(infoH.InquiryNo) == false) {
                    String[] Inquiry;
                    if(infoH.InquiryNo.contains(',')){
                        Inquiry = infoH.InquiryNo.split(',');
                        inquiryNoList.add(Inquiry[0]);
                    }else{
                        //根据数据传的样式决定
                    }
                }
                if (!(infoH.ReturnMark == null || infoH.ReturnMark  == ''
                        || infoH.ReturnMark == '1' || infoH.ReturnMark == '3'
                )) {
                    // ReturnMark = 上記以外の場合 Errorメッセージ出力
                    continue;
                }
                for (NFM110WebService.DnInformation dnInfo : infoH.DnInformation) {
                    dnInfo.SerialNoorLotNo = checkSerialNoorLotNo(dnInfo.SerialNoorLotNo);
                    if (dnInfo.OTCode == null || dnInfo.OTCode == ''
                        || dnInfo.SerialNoorLotNo == null || dnInfo.SerialNoorLotNo == ''
                    ) {
                        // 商品コードがない場合、処理と飛ばす
                        productCodeList.add(dnInfo.OTCode);
                        continue;
                    }
                    productCodeList.add(dnInfo.OTCode);
                    // HHOA-AGN2EH start
                    //productSerialNoList.add(dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo);
                    productSerialNoList.add(dnInfo.SerialNoorLotNo);
                    productSerialNoList.add(dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')');
                    //if(dnInfo.TracingCode == null || dnInfo.TracingCode == ''){
                    //    continue;
                    //}else{
                    //    tracingCodeList.add(dnInfo.TracingCode);
                        
                    //}
                    // HHOA-AGN2EH end
                    if(dnInfo.Barcode == null || dnInfo.Barcode == ''){
                        continue;
                    }else{
                        barCodeList.add(dnInfo.Barcode);
                    }
                    if(dnInfo.TracingCode == null || dnInfo.TracingCode == ''){
                        continue;
                    }else{
                        tracingCodeList.add(dnInfo.TracingCode);
                        productSerialNoList.add(dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')');
                    }
                }
            }

            // 事前に（マスタ）データを取得
            List<Account> accList = [select Id,Name, Management_Code__c, Department_Class__c, Hospital__c, ParentId,
                                            RecordType.DeveloperName,Department_Name__c
                                       from Account
                                      where Management_Code__c in :managementCodeList];
            Map<String, Account> accsMap = new Map<String, Account>();
            for (Account acc : accList) {
                accsMap.put(acc.Management_Code__c, acc);
            }
            //经销商合同
            List<Account> agencyContractList = [select Id, Management_Code__c, Department_Class__c, Hospital__c,
                                         ParentId,Parent.Name, RecordType.DeveloperName,Sales_Section__c
                                       from Account
                                      where Management_Code__c in :managementCodeList
                                      and RecordType.DeveloperName = 'AgencyContract'];
            Map<String, Account> agencyContractMap = new Map<String, Account>();
            //经销商合同申请销售课
            Map<String, String> conSalesSectionMap = new Map<String, String>();
            List<String> agencyNameList = new List<String>();
            List<String> agencyIds = new List<String>();
            for (Account acc : agencyContractList) {
                agencyContractMap.put(acc.Management_Code__c, acc);
                agencyNameList.add(acc.Parent.Name);
                //conSalesSectionMap.put(acc.Management_Code__c, acc.ParentId + acc.Sales_Section__c);
                //agencyIds.add(acc.ParentId);
            }
            List<Statu_Achievements__c> boList = [select Id, Name
                                       from Statu_Achievements__c
                                      where Name in :soNoList and OverviewStatus__c <> '无效合同'];
            Map<String, String> boMap = new Map<String, String>();
            for (Statu_Achievements__c bo : boList) {
                boMap.put(bo.Name, bo.Id);
            }
            List<Product2> prdList = [select Id, Name, ProductCode, ProductCode_Ext__c, MDM_Model_No__c
                                        from Product2
                                       where ProductCode_Ext__c in :productCodeList];
            Map<String, Product2> prdsMap = new Map<String, Product2>();
            for (Product2 prd : prdList) {
                prdsMap.put(prd.ProductCode_Ext__c, prd);
            }
            List<Product2__c> prdSearchList = [select Id, Name, Product2__r.ProductCode_Ext__c,Pro2_Dealer_ENG__c,
                                             Intra_Trade_List_RMB__c, Asset_Model_No__c, Pro2_Dealer_Object__c
                                        from Product2__c
                                       where Product2__r.ProductCode_Ext__c in :productCodeList];
            Map<String, Product2__c> prdSearchMap = new Map<String, Product2__c>();
            for (Product2__c prd2 : prdSearchList) {
                prdSearchMap.put(prd2.Product2__r.ProductCode_Ext__c, prd2);
            }
            List<Asset> astList = [select Id, Name, Product2.ProductCode,Product2.Dealer_special_Object__c ,Product2.Dealer_Object__c,
                                          SerialNumber, Product_Serial_No__c, Repair_Count__c,TracingCode__c,
                                          Product2Id, AccountId, Account.Management_Code__c, Department_Class__c, Hospital__c,
                                          Posting_Date__c, InstallDate, SLMark__c, MDM_Model_No__c, OT_CODE__c,
                                          Guarantee_period_for_products__c, Installation_Site__c, Delete_Flag__c, Return_Flag__c
                                    from Asset
                                    where SerialNumber in :productSerialNoList
                                    and IsCompetitorProduct = false
                                    and Information_From__c <> '失单'];
            // HHOA-AGN2EH end
            Map<String, Asset> astsMap = new Map<String, Asset>();
            Map<String, Asset> consumableastsMap = new Map<String, Asset>();
            Map<String, Integer> astcheckMap = new Map<String, Integer>();
            for (Asset ast : astList) {
                // HHOA-AGN2EH start
                //astsMap.put(ast.Product_Serial_No__c, ast);
                //if((Product2.Dealer_Object__c || Product2.Dealer_special_Object__c) && String.isNotBlank(ass.TracingCode__c)){
                //    consumableastsMap.put(ast.MDM_Model_No__c + ast.SerialNumber + '(' + ass.TracingCode__c + ')', ast);
                //}else{
                astsMap.put(ast.MDM_Model_No__c + ast.SerialNumber, ast);
                //}
                if (astcheckMap.containsKey(ast.MDM_Model_No__c + ast.SerialNumber) == false) {
                    astcheckMap.put(ast.MDM_Model_No__c + ast.SerialNumber, 1);
                } else {
                    astcheckMap.put(ast.MDM_Model_No__c + ast.SerialNumber, astcheckMap.get(ast.MDM_Model_No__c + ast.SerialNumber) + 1);
                }
                // HHOA-AGN2EH end
            }
            List<Consumable_order__c> orderList = [Select Id, RecordType.Developername, Name, OwnerId From Consumable_order__c Where Name IN :inquiryNoList];
            Map<String, Consumable_order__c> orderMap = new Map<String, Consumable_order__c>();
            for (Consumable_order__c ord : orderList) {
                orderMap.put(ord.Name, ord);
            }
            //SFDCの询价产品の単価から取得
            List<Consumable_orderdetails__c> orderdet1List = [Select Id, Consumable_product__c,Intra_Trade_List_RMB__c From Consumable_orderdetails__c Where Consumable_order__r.Name IN :inquiryNoList];
            Map<String, Decimal> orderdet1priceMap = new Map<String, Decimal>();
            for (Consumable_orderdetails__c orddet : orderdet1List) {
                orderdet1priceMap.put(orddet.Consumable_product__c, orddet.Intra_Trade_List_RMB__c);
            }
            List<Opportunity> oppList = [Select Id, Purchase_Type__c, Opportunity_No__c,Sales_Root__c,SAP_Province__c From Opportunity Where Opportunity_No__c IN :inquiryNoList];
            Map<String, Opportunity> oppMap = new Map<String, Opportunity>();
            for (Opportunity opp : oppList) {
                oppMap.put(opp.Opportunity_No__c, opp);
            }
            //直接到货产品barcode Map做成
            List<Consumable_order_details2__c> orderDetails = [Select Id,
                                                                    Consumable_order_minor__r.Name,
                                                                    Bar_Code__c,
                                                                    TracingCode__c,
                                                                    Deliver_date__c,
                                                                    Asset_Model_No__c
                                                                    from Consumable_order_details2__c
                                                                    where Consumable_order_minor__r.Name IN :inquiryNoList
                                                                    and Dealer_Arrive__c = true
                                                                    and Direct_Arrive_Product__c = true];
            Map<String, Consumable_order_details2__c> orderDetailDeliveryMap = new Map<String, Consumable_order_details2__c>();
            for (Consumable_order_details2__c ordD : orderDetails) {
                if (String.isBlank(ordD.TracingCode__c) == false) {
                    orderDetailDeliveryMap.put(ordD.Consumable_order_minor__r.Name + ':' + ordD.TracingCode__c, ordD);
                }
            }
            orderDetails = [Select Id,
                                Consumable_order_minor__r.Name,
                                Bar_Code__c,
                                TracingCode__c,
                                Deliver_date__c,
                                Asset_Model_No__c
                            from Consumable_order_details2__c
                            where TracingCode__c IN :tracingCodeList
                            and Dealer_Arrive__c = true
                            and Direct_Arrive_Product__c = true];
            Map<String, Consumable_order_details2__c> orderDetailTCDeliveryMap = new Map<String, Consumable_order_details2__c>();
            for (Consumable_order_details2__c ordD : orderDetails) {
                if (String.isBlank(ordD.TracingCode__c) == false) {
                    orderDetailTCDeliveryMap.put(ordD.TracingCode__c, ordD);
                }
            }
            //NFM110发货产品barcode Map做成
            List<Consumable_order_details2__c> detailsSendAgain = [Select Id,
                                                                    Consumable_order_minor__r.Name,
                                                                    Bar_Code__c,
                                                                    Deliver_date__c,
                                                                    Asset_Model_No__c
                                                                    from Consumable_order_details2__c
                                                                    where Consumable_order_minor__r.Name IN :inquiryNoList
                                                                    and Direct_Arrive_Product__c = false];
            Map<String, Consumable_order_details2__c> detailsSendAgainMap = new Map<String, Consumable_order_details2__c>();
            for (Consumable_order_details2__c ordD : detailsSendAgain) {
                if (String.isBlank(ordD.Bar_Code__c) == false) {
                    detailsSendAgainMap.put(ordD.Consumable_order_minor__r.Name + ':' + ordD.Bar_Code__c, ordD);
                }
            }

            //NFM110发货产品barcode Map做成
            detailsSendAgain = [Select Id,
                                    Consumable_order_minor__r.Name,
                                    Bar_Code__c,
                                    Deliver_date__c,
                                    Asset_Model_No__c
                                    from Consumable_order_details2__c
                                    where (Dealer_Info_text__c IN :agencyNameList
                                    and Bar_Code__c in : barCodeList
                                    and Direct_Arrive_Product__c = false)
                                    or (Bar_Code__c in : barCodeList
                                        and Consumable_order_minor__c = null
                                        and Dealer_Saled__c = true)];
            Map<String, Consumable_order_details2__c> detailsSendAgainNoMap = new Map<String, Consumable_order_details2__c>();
            for (Consumable_order_details2__c ordD : detailsSendAgain) {
                if (String.isBlank(ordD.Bar_Code__c) == false) {
                    detailsSendAgainNoMap.put(ordD.Bar_Code__c, ordD);
                }
            }
            // 更新対応配列をセット
            astList = new List<Asset>();
            Map<String, Asset> astUpdateMap = new Map<String, Asset>();
            List<Asset> astDelList = new List<Asset>();
            Map<String, Asset> astDelMap = new Map<String, Asset>();
            // 发货订单最新发货日等更新 
            Map<String, Consumable_order__c> oUpdateMap = new Map<String, Consumable_order__c>();
            // 直销耗材，出库单新建
            Map<String, Consumable_order__c> orderOutMap = new Map<String, Consumable_order__c>();
            // 直销耗材，返品单新建
            //Map<String, Consumable_order__c> orderReturnMap = new Map<String, Consumable_order__c>();

            Map<String, Consumable_order_details2__c> odUpsertMap = new Map<String, Consumable_order_details2__c>();
            Map<String, Consumable_order_details2__c> odDetailUpsertMap = new Map<String, Consumable_order_details2__c>();
            // 直销耗材消耗品明细2
            Map<String, Consumable_order_details2__c> odDSUpsertMap = new Map<String, Consumable_order_details2__c>();
            // 直销耗材出库单明细2 （医院:科室）
            Map<String, List<Consumable_order_details2__c>> odDSUpsertIdxMap = new Map<String, List<Consumable_order_details2__c>>();
            for (NFM110WebService.GeneralData infoH : generalDataList) {
                // 订单明细2编号 auto NO
                Map<String, Integer> odUpsertIdxMap = new Map<String, Integer>();
                String InquiryNoStr = '';
                String InquiryNoStr2 = '';
                if (String.isBlank(infoH.InquiryNo) == false) {
                    if(infoH.InquiryNo.contains(',')){
                        InquiryNoStr = infoH.InquiryNo.split(',')[0];
                        if(infoH.InquiryNo.split(',').size() > 1){
                            InquiryNoStr2 = infoH.InquiryNo.split(',')[1];
                        }
                    }
                    if (String.isBlank(InquiryNoStr)) {
                        iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] InquiryNo is required. This DN is skipped.\n';
                        continue;
                    }
                }
                if (String.isBlank(infoH.DeliveryNote)) {
                    iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote is required. This DN is skipped.\n';
                    continue;
                }
                if (infoH.DnInformation == null || infoH.DnInformation.size() == 0) {
                    iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] DnInformation is required. This DN is skipped.\n';
                    continue;
                }
                if (infoH.EndUserNo == null || infoH.EndUserNo  == '') {
                    iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] EndUserNo is required. This DN is skipped.\n';
                    continue;
                }
                if (accsMap.get(infoH.EndUserNo) == null) {
                    iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] EndUserNo[' + infoH.EndUserNo + ']NotExist. This DN is skipped.\n';
                    continue;
                } else if (accsMap.get(infoH.EndUserNo).RecordType.DeveloperName != 'HP'
                        && accsMap.get(infoH.EndUserNo).RecordType.DeveloperName != 'Agency'
                        && accsMap.get(infoH.EndUserNo).RecordType.DeveloperName != 'AgencyContract') {
                    iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] EndUserNo[' + infoH.EndUserNo + ']Is Not HP or Agency(Contract). This DN is skipped.\n';
                    continue;
                }
                if (accsMap.get(infoH.DepartmentNo) == null) {
                    iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] DepartmentNo[' + infoH.DepartmentNo + ']NotExist. This DN is skipped.\n';
                    continue;
                }
                if (!(infoH.ReturnMark == null || infoH.ReturnMark  == ''
                        || infoH.ReturnMark == '1' || infoH.ReturnMark == '3'
                )) {
                    iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] ReturnMark[' + infoH.ReturnMark + '] Not Defined. This DN is skipped.\n';
                    continue;
                }
                // 直销耗材明细2
                List<Consumable_order_details2__c> cod2List= new List<Consumable_order_details2__c>();
                for (NFM110WebService.DnInformation dnInfo : infoH.DnInformation) {
                    dnInfo.SerialNoorLotNo = checkSerialNoorLotNo(dnInfo.SerialNoorLotNo);
                    if (String.isBlank(dnInfo.SorLMark)){
                        continue;
                    }
                    /*if (orderMap.containsKey(InquiryNoStr) == false &&
                            //&& agencyContractMap.size() < 0
                            oppMap.containsKey(InquiryNoStr) == true
                            && oppMap.get(InquiryNoStr).Purchase_Type__c == 'ET24時間販売'
                            && dnInfo.SorLMark == 'S'){
                        // HHOA-AGN2EH start
                        //iflog.Log__c += 'SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] Warning! [' + infoH.InquiryNo + ':Purchase_Type__c] is not ET24\n';
                        // HHOA-AGN2EH end
                        continue;
                    }*/
                    if (dnInfo.OTCode == null || dnInfo.OTCode == '') {
                        iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] SerialNoorLotNo[' + dnInfo.SerialNoorLotNo + '] OTCode is required. This asset is skipped.\n';
                        continue;
                    }
                    if (dnInfo.SerialNoorLotNo == null || dnInfo.SerialNoorLotNo == '') {
                        iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] OTCode[' + dnInfo.OTCode + '] SerialNoorLotNo is required. This asset is skipped.\n';
                        continue;
                    }
                    Product2 prd = prdsMap.get(dnInfo.OTCode);
                    if (orderMap.containsKey(InquiryNoStr) == false &&
                        prd == null) {
                        iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] [' + dnInfo.SerialNoorLotNo + ']Product[' + dnInfo.OTCode + ']NotExist. This asset is skipped.\n';
                        continue;
                    }
                    Product2__c prdSearch = prdSearchMap.get(dnInfo.OTCode);
                    if (prdSearch == null) {
                        iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] [' + InquiryNoStr + ']ProductSerch[' + dnInfo.OTCode + ']NotExist. This asset is skipped.\n';
                        continue;
                    }
                    // HHOA-AGN2EH start
                    if (astcheckMap.containsKey(prd.MDM_Model_No__c + dnInfo.SerialNoorLotNo) == true && astcheckMap.get(prd.MDM_Model_No__c + dnInfo.SerialNoorLotNo) > 1) {
                        iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] Asset[' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + ']Exist more than one. This asset is skipped.\n';
                        continue;
                    }
                    //Asset ast = astsMap.get(dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo);
                    Asset ast = astsMap.get(prd.MDM_Model_No__c + dnInfo.SerialNoorLotNo);
                    //System.debug('astsMap +++++   ' + astsMap.values());
                    if(dnInfo.SorLMark == 'S'){
                        ast = astsMap.get(prd.MDM_Model_No__c + dnInfo.SerialNoorLotNo);
                    }else{
                        ast = astsMap.get(prd.MDM_Model_No__c + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')');
                    }
                    Boolean hasAst = true;
                    // HHOA-AGN2EH end
                    if (ast == null) {
                        // 存在しないのに、delete 受信の場合
                        if (infoH.ReturnMark == '1' && dnInfo.SorLMark != 'L') {
                            iflog.ErrorLog__c += 'Warning! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] Delete Asset[' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + ']NotExist. This asset is skipped.\n';
                            continue;
                        }else if(infoH.ReturnMark == '1' && dnInfo.SorLMark == 'L'
                            && oppMap.get(InquiryNoStr).Sales_Root__c == 'OCM直接販売'
                            && accsMap.get(infoH.EndUserNo) != null && String.isNotBlank( dnInfo.Barcode)){
                            Product2__c prdMap = prdSearchMap.get(dnInfo.OTCode);
                            if (!prdMap.Pro2_Dealer_Object__c && !prdMap.Pro2_Dealer_ENG__c) {
                                continue;
                            }
                            if (orderOutMap.containsKey(InquiryNoStr) == false) {
                                Consumable_order__c autoOrder = new Consumable_order__c();
                                autoOrder.Name = '*';
                                autoOrder.OwnerId = System.Label.User_OlympusSystem;
                                autoOrder.RecordTypeid = System.Label.Dealer_Returned_Label;
                                autoOrder.Opportunity__c = oppMap.get(InquiryNoStr).Id;
                                autoOrder.Dealer_Info__c = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                                autoOrder.Order_ForHospital__c = accsMap.get(infoH.EndUserNo).Id;
                                autoOrder.Order_type__c = '返品';
                                autoOrder.ReturnGs_Uploader_ID__c = System.Label.User_OlympusSystem;
                                autoOrder.ReturnGs_Upload_Date__c = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                autoOrder.Order_status__c         = '批准';
                                orderOutMap.put(InquiryNoStr, autoOrder);
                            }

                            Consumable_order_details2__c rac = detailsSendAgainNoMap.get(dnInfo.Barcode);
                            if (rac == null) {
                                rac = new Consumable_order_details2__c();
                                if(String.isNotBlank(dnInfo.Qty)){
                                    rac.Intra_Trade_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                                }else if(orderdet1priceMap.containsKey(prdSearch.Id)){
                                    rac.Intra_Trade_List_RMB__c = orderdet1priceMap.get(prdSearch.Id);
                                }else{
                                    rac.Intra_Trade_List_RMB__c   = prdSearch.Intra_Trade_List_RMB__c;
                                }
                                rac.Delivery_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                                rac.Asset_Model_No__c         = prdSearch.Asset_Model_No__c;
                                rac.Deliver_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                rac.Arrive_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                rac.Used_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                rac.Sterilization_limit__c    = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                                rac.Consumable_product__c     = prdSearch.Id;
                                rac.Bar_Code__c               = dnInfo.Barcode;
                                rac.Used_account__c           = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                                rac.Dealer_Info_IF__c         = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                                rac.DeliveryNote__c           = infoH.DeliveryNote;
                                rac.SerialLotNo__c            = dnInfo.SerialNoorLotNo;
                                rac.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                                rac.TracingCode__c            = dnInfo.TracingCode;
                            }
                            cod2List.add(rac);
                            odDSUpsertMap.put(InquiryNoStr + ':' + dnInfo.Barcode, rac);
                            odUpsertIdxMap.put(InquiryNoStr + ':' + dnInfo.Barcode, odDSUpsertMap.size());
                            System.debug('autoNo+++++' + odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode));
                            odDSUpsertIdxMap.put(accsMap.get(infoH.EndUserNo).Id + ':' + oppMap.get(InquiryNoStr).Id + '', cod2List);
                            rac.Name                      = InquiryNoStr + ':' + ('000'+ odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode)).right(4);
                            rac.RecordTypeId              = System.Label.RT_ConOrderDetail2_Return;              // TODO 本番IDにする label
                            rac.Box_Piece__c              = '盒';
                            rac.Return_date__c            = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                            rac.Return_reason__c          = '医院退货';
                            //全部System
                            rac.OwnerId                   = System.Label.User_OlympusSystem;
                            continue;
                        }
                        ast = new Asset();
                        hasAst = false;
                    } else {
                        if (infoH.ReturnMark == '1') {
                            //System.debug('耗材退货+++++ ');
                            // 物理削除用
                            if (astDelMap.get(ast.Product_Serial_No__c) == null) {
                                // HHOA-AGN2EH start
                                Asset delAst = new Asset(Id = ast.Id);
                                delAst.Product2Id = prdsMap.get(dnInfo.OTCode).Id;
                                // HHOA-AGN2EH end
                                astDelList.add(delAst);
                                astDelMap.put(ast.Product_Serial_No__c, ast);


                                if(dnInfo.SorLMark == 'L'
                                    && oppMap.get(InquiryNoStr).Sales_Root__c == 'OCM直接販売'
                                    && accsMap.get(infoH.EndUserNo) != null && String.isNotBlank( dnInfo.Barcode)){
                                    Product2__c prdMap = prdSearchMap.get(dnInfo.OTCode);

                                    if (!prdMap.Pro2_Dealer_Object__c && !prdMap.Pro2_Dealer_ENG__c) {
                                        continue;
                                    }
                                    if (orderOutMap.containsKey(InquiryNoStr) == false) {
                                        Consumable_order__c autoOrder = new Consumable_order__c();
                                        autoOrder.Name = '*';
                                        autoOrder.OwnerId = System.Label.User_OlympusSystem;
                                        autoOrder.RecordTypeid = System.Label.Dealer_Returned_Label;
                                        autoOrder.Opportunity__c = oppMap.get(InquiryNoStr).Id;
                                        autoOrder.Dealer_Info__c = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                                        autoOrder.Order_ForHospital__c = accsMap.get(infoH.EndUserNo).Id;
                                        autoOrder.Order_type__c = '返品';
                                        autoOrder.ReturnGs_Uploader_ID__c = System.Label.User_OlympusSystem;
                                        autoOrder.ReturnGs_Upload_Date__c = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                        autoOrder.Order_status__c         = '批准';
                                        orderOutMap.put(InquiryNoStr, autoOrder);
                                    }

                                    Consumable_order_details2__c rac = detailsSendAgainNoMap.get(dnInfo.Barcode);
                                    if (rac == null) {
                                        rac = new Consumable_order_details2__c();
                                        //cod2List.add(rac);
                                        //odDSUpsertMap.put(InquiryNoStr + ':' + dnInfo.Barcode, rac);
                                        //odUpsertIdxMap.put(InquiryNoStr + ':' + dnInfo.Barcode, odDSUpsertMap.size());
                                        //odDSUpsertIdxMap.put(accsMap.get(infoH.EndUserNo).Id + ':' + oppMap.get(InquiryNoStr).Id + '', cod2List);
                                        //rac.Name                      = InquiryNoStr + ':' + ('000'+ odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode)).right(4);
                                        if(String.isNotBlank(dnInfo.Qty)){
                                            rac.Intra_Trade_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                                        }else if(orderdet1priceMap.containsKey(prdSearch.Id)){
                                            rac.Intra_Trade_List_RMB__c = orderdet1priceMap.get(prdSearch.Id);
                                        }else{
                                            rac.Intra_Trade_List_RMB__c   = prdSearch.Intra_Trade_List_RMB__c;
                                        }
                                        rac.Delivery_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                                        rac.Asset_Model_No__c         = prdSearch.Asset_Model_No__c;
                                        rac.Deliver_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                        rac.Arrive_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                        rac.Used_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                        rac.Sterilization_limit__c    = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                                        rac.Consumable_product__c     = prdSearch.Id;
                                        rac.Bar_Code__c               = dnInfo.Barcode;
                                        rac.Used_account__c           = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                                        rac.Dealer_Info_IF__c         = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                                        rac.DeliveryNote__c           = infoH.DeliveryNote;
                                        rac.SerialLotNo__c            = dnInfo.SerialNoorLotNo;
                                        rac.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                                        rac.TracingCode__c            = dnInfo.TracingCode;
                                    }
                                    cod2List.add(rac);
                                    odDSUpsertMap.put(InquiryNoStr + ':' + dnInfo.Barcode, rac);
                                    odUpsertIdxMap.put(InquiryNoStr + ':' + dnInfo.Barcode, odDSUpsertMap.size());
                                    //System.debug('autoNo+++++' + odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode));
                                    odDSUpsertIdxMap.put(accsMap.get(infoH.EndUserNo).Id + ':' + oppMap.get(InquiryNoStr).Id + '', cod2List);
                                    rac.Name                      = InquiryNoStr + ':' + ('000'+ odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode)).right(4);

                                    rac.RecordTypeId              = System.Label.RT_ConOrderDetail2_Return;              // TODO 本番IDにする label
                                    rac.Box_Piece__c              = '盒';
                                    rac.Return_date__c            = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                    rac.Return_reason__c          = '医院退货';
                                    //全部System
                                    rac.OwnerId                   = System.Label.User_OlympusSystem;
                                }
                            }
                            logstr += dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '(delete) ';
                            // InstallDateがある場合、Warning! を出す
                            if (ast.InstallDate != null) {
                                // HHOA-AGN2EH start
                                //iflog.ErrorLog__c += 'SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] Warning! Delete Asset[' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '] is installed at ' + NFMUtil.formatDate2Str(ast.InstallDate) + '\n';
                                // HHOA-AGN2EH end
                            }
                            // 修理がある場合、Warning! を出す
                            if (ast.Repair_Count__c > 0) {
                                // HHOA-AGN2EH start
                                //iflog.ErrorLog__c += 'SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] Warning! Delete Asset[' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '] with repair.\n';
                                // HHOA-AGN2EH end
                            }
                            continue;
                        }
                    }
                    // HHOA-AGN2EH start
                    boolean clearflg = false;
                    if (hasAst == true) {
                        if (infoH.ReturnMark != '1' && ast.Delete_Flag__c == true) {
                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + ast.OT_CODE__c + ':' + ast.SerialNumber  + '] Delete Flag was cancelled.\n';
                        }
                        if (infoH.ReturnMark != '1' && ast.Return_Flag__c == true) {
                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + ast.OT_CODE__c + ':' + ast.SerialNumber  + '] Return Flag was cancelled.\n';
                        }
                        if (accsMap.get(infoH.DepartmentNo).Id != ast.AccountId) {
                            if (accsMap.get(infoH.EndUserNo).RecordType.DeveloperName != 'Agency' && accsMap.get(infoH.EndUserNo).RecordType.DeveloperName != 'AgencyContract') {
                                iflog.ErrorLog__c += 'Warning! Asset' + '[' + ast.OT_CODE__c + ':' + ast.SerialNumber  + '] DepartmentCode:' + ast.Account.Management_Code__c + ' is updated to '+ infoH.DepartmentNo + '.\n';
                            }
                        }
                        if (accsMap.get(infoH.DepartmentNo).Id != ast.AccountId && ast.InstallDate != null && NFMUtil.parseStr2Date(infoH.DeliveryDate) > ast.InstallDate) {
                            clearflg = true;
                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + ast.OT_CODE__c + ':' + ast.SerialNumber  + '] Install Date:' + ast.InstallDate + 'is cleared.\n';
                        }
                        if (ast.SerialNumber == dnInfo.SerialNoorLotNo && ast.MDM_Model_No__c == prd.MDM_Model_No__c && ast.OT_CODE__c != dnInfo.OTCode) {
                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + ast.OT_CODE__c + ':' + ast.SerialNumber  + '] is updated to [' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '].\n';
                        }
                    }
                    // HHOA-AGN2EH end
                    // 消耗品、以下 Consumable_order_details2__c
                    if (orderMap.containsKey(InquiryNoStr)) {
                        //System.debug('step 1');
                        Consumable_order__c order = orderMap.get(InquiryNoStr);
                        if (oUpdateMap.containsKey(InquiryNoStr) == false
                                && order.RecordType.Developername == 'Order') {
                            order.RecordTypeId = System.Label.RT_ConOrder_Delivery;
                            oUpdateMap.put(InquiryNoStr, order);
                        }
                        // 消耗品直接到货，NFM110再入库对应
                        Consumable_order_details2__c orderdetInfo = orderDetailTCDeliveryMap.get(dnInfo.TracingCode);
                        if(orderdetInfo != null && String.isNotBlank( dnInfo.Barcode)){
                            odUpsertMap.put(InquiryNoStr + ':' + dnInfo.Barcode, orderdetInfo);
                            odUpsertIdxMap.put(InquiryNoStr + ':' + dnInfo.Barcode, odUpsertMap.size());
                            //System.debug('消耗品直接到货，NFM110再入库对应' + orderdetInfo);
                            iflog.ErrorLog__c += 'Warning! Consumable Asset ['+ orderdetInfo.Asset_Model_No__c +'] DN [' + infoH.DeliveryNote +'] DeliveryDate[' + orderdetInfo.Deliver_date__c +'] is updated to [' + NFMUtil.parseStr2Date(infoH.DeliveryDate) +'].\n';
                            orderdetInfo.Deliver_date__c = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                            orderdetInfo.Name = InquiryNoStr + ':' + ('000'+ odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode)).right(4);
                            orderdetInfo.Direct_Arrive_Product__c = false;
                            if(String.isNotBlank(dnInfo.Qty)){
                                orderdetInfo.Intra_Trade_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                            }
                            orderdetInfo.Consumable_order_minor__c = order.Id;
                            orderdetInfo.Used_account__c           = accsMap.get(infoH.EndUserNo).Id;
                            orderdetInfo.Sterilization_limit__c    = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                            //orderdetInfo.Bar_Code__c               = dnInfo.Barcode;
                            orderdetInfo.DeliveryNote__c           = infoH.DeliveryNote;
                            orderdetInfo.SerialLotNo__c            = dnInfo.SerialNoorLotNo;
                            orderdetInfo.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                            odDetailUpsertMap.put(InquiryNoStr + ':' + dnInfo.Barcode, orderdetInfo);
                            orderDetailDeliveryMap.put(InquiryNoStr + ':' + dnInfo.TracingCode, orderdetInfo);

                            // upsert用、項目転送
                            if(dnInfo.SorLMark == 'S'){
                                ast.AssetMark__c = '主机';
                                //ast = astsMap.get(ANY key)
                                ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo;
                            }else{
                                ast.AssetMark__c = '耗材';
                                ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                            }
                            if (astsMap.get(ast.Product_Serial_No__c ) == null) {
                                ast = new Asset();
                                astList.add(ast);
                                //astUpdateMap.put(ast.Product_Serial_No__c, ast);
                                logstr += dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')' + ' ';
                            } else {
                                iflog.ErrorLog__c += 'Warning! Asset' + '[' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo  + '] Exist. This asset is skipped.\n';
                                continue;
                                //ast = astUpdateMap.get(ast.Product_Serial_No__c);
                            }
                            ast.Name                             = prd.Name;
                            if(String.isNotEmpty(InquiryNoStr2)){
                                ast.Order_No__c                  = InquiryNoStr2;
                            }else{
                                ast.Order_No__c                  = InquiryNoStr;
                            }
                            ast.Backorder__c                     = String.isBlank(infoH.SoNo) ? null : boMap.get(infoH.SoNo);
                            ast.Posting_Date__c                  = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                            ast.DeliveryNote__c                  = infoH.DeliveryNote;
                            //if (accsMap.get(infoH.EndUserNo).RecordType.DeveloperName == 'Agency') {
                                // default AccountId を設定しない
                            //if(!hasAst){
                            ast.Asset_Owner__c                   = '经销商资产';
                            ast.Asset_owner_delaer_name__c       = accsMap.get(infoH.EndUserNo).ParentId;
                            ast.AccountId                        = ocm.Id;
                            ast.Department_Class__c              = accsMap.get(infoH.EndUserNo).Id;
                            ast.Hospital__c                      = accsMap.get(infoH.EndUserNo).ParentId;
                            ast.Product2Id                       = prdsMap.get(dnInfo.OTCode).Id;
                            //}
                            
                            //ast.Quantity                         = String.isBlank(dnInfo.Qty) ? null : Decimal.valueOf(dnInfo.Qty);
                            if(dnInfo.SorLMark == 'S'){
                                ast.AssetMark__c = '主机';
                                ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                                ast.SerialNumber                     = dnInfo.SerialNoorLotNo;
                            }else{
                                ast.AssetMark__c = '耗材';
                                ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                                ast.SerialNumber                     = dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                            }
                            ast.SLMark__c                        = 'Serial Number';         // 固定 dnInfo.SorLMark;
                            //HWAG-B9AAD9 当保有设备 的 保有设备标记 =耗材时，保修期限 =发货日
                            //ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                            ast.TracingCode__c                   = dnInfo.TracingCode;
                            ast.Guaranteen_end__c                = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                            ast.Barcode__c                       = dnInfo.Barcode;
                            ast.IF_Information_From__c           = true;
                            // HHOA-AGN2EH start
                            ast.Return_Flag__c = false;
                            ast.Delete_Flag__c = false;
                            if (clearflg == true) {
                                ast.InstallDate = null;
                            }
                            continue;
                        }
                        if(detailsSendAgainMap.containsKey(InquiryNoStr + ':' + dnInfo.Barcode) == true){
                            iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] [' + InquiryNoStr + '] Barcode[' + dnInfo.Barcode + ']Duplicate. This asset is skipped.\n';
                            continue;
                        }
                        if(orderDetailDeliveryMap.containsKey(InquiryNoStr + ':' + dnInfo.TracingCode) == false
                            && String.isNotBlank( dnInfo.Barcode)){
                            Product2__c prdMap = prdSearchMap.get(dnInfo.OTCode);

                            if (!prdMap.Pro2_Dealer_Object__c && !prdMap.Pro2_Dealer_ENG__c) {
                                continue;
                            }
                            Consumable_order_details2__c rac = odUpsertMap.get(InquiryNoStr + ':' + dnInfo.Barcode);
                            if (rac == null) {
                                rac = new Consumable_order_details2__c();
                                odUpsertMap.put(InquiryNoStr + ':' + dnInfo.Barcode, rac);
                                odUpsertIdxMap.put(InquiryNoStr + ':' + dnInfo.Barcode, odUpsertMap.size());
                            }
                            rac.Name                      = InquiryNoStr + ':' + ('000'+ odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode)).right(4);
                            rac.RecordTypeId              = System.Label.RT_ConOrderDetail2_Delivery;                // TODO 本番IDにする label
                            if(String.isNotBlank(dnInfo.Qty)){
                                rac.Intra_Trade_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                            }else if(orderdet1priceMap.containsKey(prdSearch.Id)){
                                rac.Intra_Trade_List_RMB__c = orderdet1priceMap.get(prdSearch.Id);
                            }else{
                                rac.Intra_Trade_List_RMB__c = prdSearch.Intra_Trade_List_RMB__c;
                            }
                            rac.Asset_Model_No__c         = prdSearch.Asset_Model_No__c;
                            rac.Consumable_order_minor__c = order.Id;
                            rac.Deliver_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                            rac.Sterilization_limit__c    = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                            rac.Consumable_product__c     = prdSearch.Id;
                            rac.Bar_Code__c               = dnInfo.Barcode;
                            rac.Used_account__c           = accsMap.get(infoH.EndUserNo).Id;
                            //rac.Dealer_Info_IF__c         = accsMap.get(infoH.EndUserNo).Id;
                            rac.DeliveryNote__c           = infoH.DeliveryNote;
                            rac.SerialLotNo__c            = dnInfo.SerialNoorLotNo;
                            rac.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                            rac.TracingCode__c            = dnInfo.TracingCode;
                            // ====lw edit start ====
                            if (order.OwnerId != null) {
                                rac.OwnerId               = order.OwnerId;
                            }
                        }
                        // 设备、以下 ET24小时 Asset
                        // upsert用、項目転送
                        if(dnInfo.SorLMark == 'S'){
                            ast.AssetMark__c = '主机';
                            //ast = astsMap.get(ANY key)
                            ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo;
                        }else{
                            ast.AssetMark__c = '耗材';
                            ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        }
                        if (astsMap.get(ast.Product_Serial_No__c ) == null) {
                            ast = new Asset();
                            astList.add(ast);
                            //astUpdateMap.put(ast.Product_Serial_No__c, ast);
                            logstr += dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')' + ' ';
                        } else {
                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo  + '] Exist. This asset is skipped.\n';
                            continue;
                            //ast = astUpdateMap.get(ast.Product_Serial_No__c);
                        }
                        ast.Name                             = prd.Name;
                        if(String.isNotEmpty(InquiryNoStr2)){
                            ast.Order_No__c                  = InquiryNoStr2;
                        }else{
                            ast.Order_No__c                  = InquiryNoStr;
                        }
                        ast.Backorder__c                     = String.isBlank(infoH.SoNo) ? null : boMap.get(infoH.SoNo);
                        ast.Posting_Date__c                  = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                        ast.DeliveryNote__c                  = infoH.DeliveryNote;
                        //if (accsMap.get(infoH.EndUserNo).RecordType.DeveloperName == 'Agency') {
                            // default AccountId を設定しない
                        //if(!hasAst){
                        ast.Asset_Owner__c                   = '经销商资产';
                        ast.Asset_owner_delaer_name__c       = accsMap.get(infoH.EndUserNo).ParentId;
                        ast.AccountId                        = ocm.Id;
                        ast.Department_Class__c              = accsMap.get(infoH.EndUserNo).Id;
                        ast.Hospital__c                      = accsMap.get(infoH.EndUserNo).ParentId;
                        ast.Product2Id                       = prdsMap.get(dnInfo.OTCode).Id;
                        //}
                        //ast.Quantity                         = String.isBlank(dnInfo.Qty) ? null : Decimal.valueOf(dnInfo.Qty);
                        if(dnInfo.SorLMark == 'S'){
                            ast.AssetMark__c = '主机';
                            ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                            ast.SerialNumber                     = dnInfo.SerialNoorLotNo;
                        }else{
                            ast.AssetMark__c = '耗材';
                            ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                            ast.SerialNumber                     = dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        }
                        ast.SLMark__c                        = 'Serial Number';         // 固定 dnInfo.SorLMark;
                        //HWAG-B9AAD9 当保有设备 的 保有设备标记 =耗材时，保修期限 =发货日
                        //ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                        ast.TracingCode__c                   = dnInfo.TracingCode;
                        ast.Guaranteen_end__c                = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                        ast.Barcode__c                       = dnInfo.Barcode;
                        ast.IF_Information_From__c           = true;
                        // HHOA-AGN2EH start
                        ast.Return_Flag__c = false;
                        ast.Delete_Flag__c = false;
                        if (clearflg == true) {
                            ast.InstallDate = null;
                        }
                    }else if(oppMap.get(InquiryNoStr) != null
                             && oppMap.get(InquiryNoStr).Purchase_Type__c == 'ET24時間販売'
                             && oppMap.get(InquiryNoStr).Sales_Root__c == '販売店'
                             && agencyContractMap.get(infoH.EndUserNo) != null
                             && agencyContractMap.get(infoH.EndUserNo).RecordType.Developername == 'AgencyContract'
                             && String.isNotBlank( dnInfo.Barcode)){
                        System.debug('ET24時間販売');
                        //System.debug('step 2');
                        Product2__c prdMap = prdSearchMap.get(dnInfo.OTCode);

                        if (!prdMap.Pro2_Dealer_Object__c  && !prdMap.Pro2_Dealer_ENG__c) {
                            continue;
                        }

                        if(detailsSendAgainNoMap.containsKey(dnInfo.Barcode) == true){
                            iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] [' + InquiryNoStr + '] Barcode[' + dnInfo.Barcode + ']Duplicate. This asset is skipped.\n';
                            continue;
                        }
                        Consumable_order_details2__c rac = odUpsertMap.get(InquiryNoStr + ':' + dnInfo.Barcode);
                        if (rac == null) {
                            rac = new Consumable_order_details2__c();
                            odUpsertMap.put(InquiryNoStr + ':' + dnInfo.Barcode, rac);
                            odUpsertIdxMap.put(InquiryNoStr + ':' + dnInfo.Barcode, odUpsertMap.size());
                        }
                        rac.Name                      = InquiryNoStr + ':' + ('000'+ odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode)).right(4);
                        rac.RecordTypeId              = System.Label.RT_ConOrderDetail2_Delivery;                // TODO 本番IDにする label
                        if(String.isNotBlank(dnInfo.Qty)){
                            rac.Intra_Trade_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                        }else if(orderdet1priceMap.containsKey(prdSearch.Id)){
                            rac.Intra_Trade_List_RMB__c = orderdet1priceMap.get(prdSearch.Id);
                        }else{
                            rac.Intra_Trade_List_RMB__c   = prdSearch.Intra_Trade_List_RMB__c;
                        }
                        rac.Asset_Model_No__c         = prdSearch.Asset_Model_No__c;
                        //rac.Consumable_order_minor__c = order.Id;
                        rac.Deliver_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                        rac.Sterilization_limit__c    = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                        rac.Consumable_product__c     = prdSearch.Id;
                        rac.Bar_Code__c               = dnInfo.Barcode;
                        rac.Used_account__c           = accsMap.get(infoH.EndUserNo).Id;
                        rac.Dealer_Info_IF__c         = agencyContractMap.get(infoH.EndUserNo).ParentId;
                        rac.DeliveryNote__c           = infoH.DeliveryNote;
                        rac.SerialLotNo__c            = dnInfo.SerialNoorLotNo;
                        rac.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                        rac.TracingCode__c            = dnInfo.TracingCode;
                        //全部System
                        rac.OwnerId                   = System.Label.User_OlympusSystem;

                        // 设备、以下 ET24小时 Asset 非追溯系统订单
                        // upsert用、項目転送
                        if(dnInfo.SorLMark == 'S'){
                            ast.AssetMark__c = '主机';
                            //ast = astsMap.get(ANY key)
                            ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo;
                        }else{
                            ast.AssetMark__c = '耗材';
                            ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        }
                        if (astsMap.get(ast.Product_Serial_No__c ) == null) {
                            ast = new Asset();
                            astList.add(ast);
                            //astUpdateMap.put(ast.Product_Serial_No__c, ast);
                            logstr += dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')' + ' ';
                        } else {
                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo  + '] Exist. This asset is skipped.\n';
                            continue;
                            //ast = astUpdateMap.get(ast.Product_Serial_No__c);
                        }
                        ast.Name                             = prd.Name;
                        if(String.isNotEmpty(InquiryNoStr2)){
                            ast.Order_No__c                  = InquiryNoStr2;
                        }else{
                            ast.Order_No__c                  = InquiryNoStr;
                        }
                        ast.Backorder__c                     = String.isBlank(infoH.SoNo) ? null : boMap.get(infoH.SoNo);
                        ast.Posting_Date__c                  = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                        ast.DeliveryNote__c                  = infoH.DeliveryNote;
                        //if (accsMap.get(infoH.EndUserNo).RecordType.DeveloperName == 'Agency') {
                            // default AccountId を設定しない
                        //if(!hasAst){
                        ast.Asset_Owner__c                   = '经销商资产';
                        ast.Asset_owner_delaer_name__c       = accsMap.get(infoH.EndUserNo).ParentId;
                        ast.AccountId                        = ocm.Id;
                        ast.Department_Class__c              = accsMap.get(infoH.EndUserNo).Id;
                        ast.Hospital__c                      = accsMap.get(infoH.EndUserNo).ParentId;
                        ast.Product2Id                       = prdsMap.get(dnInfo.OTCode).Id;
                        //}
                        
                        //ast.Quantity                         = String.isBlank(dnInfo.Qty) ? null : Decimal.valueOf(dnInfo.Qty);
                        if(dnInfo.SorLMark == 'S'){
                            ast.AssetMark__c = '主机';
                            ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                            ast.SerialNumber                     = dnInfo.SerialNoorLotNo;
                        }else{
                            ast.AssetMark__c = '耗材';
                            ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                            ast.SerialNumber                     = dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        }
                        ast.SLMark__c                        = 'Serial Number';         // 固定 dnInfo.SorLMark;
                        //HWAG-B9AAD9 当保有设备 的 保有设备标记 =耗材时，保修期限 =发货日
                        //ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                        ast.TracingCode__c                   = dnInfo.TracingCode;
                        ast.Guaranteen_end__c                = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                        ast.Barcode__c                       = dnInfo.Barcode;
                        ast.IF_Information_From__c           = true;
                        // HHOA-AGN2EH start
                        ast.Return_Flag__c = false;
                        ast.Delete_Flag__c = false;
                        if (clearflg == true) {
                            ast.InstallDate = null;
                        }
                    }
                    // HHOA-BBACNL 直销耗材信息
                    else if(oppMap.get(InquiryNoStr) != null && infoH.ReturnMark != '1'
                             && oppMap.get(InquiryNoStr).Sales_Root__c == 'OCM直接販売'
                             && accsMap.get(infoH.EndUserNo) != null
                             //&& agencyContractMap.get(infoH.EndUserNo).RecordType.Developername == 'AgencyContract'
                             && String.isNotBlank( dnInfo.Barcode)){
                        System.debug('OCM直接販売');

                        // 耗材直销
                        // upsert用、項目転送
                        if(dnInfo.SorLMark == 'S'){
                            ast.AssetMark__c = '主机';
                            //ast = astsMap.get(ANY key)
                            ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo;
                        }else{
                            ast.AssetMark__c = '耗材';
                            ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        }
                        if (astsMap.get(ast.Product_Serial_No__c ) == null) {
                            ast = new Asset();
                            astList.add(ast);
                            //astUpdateMap.put(ast.Product_Serial_No__c, ast);
                            logstr += dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')' + ' ';
                        } else {
                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo  + '] Exist. This asset is skipped.\n';
                            continue;
                            //ast = astUpdateMap.get(ast.Product_Serial_No__c);
                        }
                        ast.Name                             = prd.Name;
                        if(String.isNotEmpty(InquiryNoStr2)){
                            ast.Order_No__c                  = InquiryNoStr2;
                        }else{
                            ast.Order_No__c                  = InquiryNoStr;
                        }
                        ast.Backorder__c                     = String.isBlank(infoH.SoNo) ? null : boMap.get(infoH.SoNo);
                        ast.Posting_Date__c                  = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                        ast.DeliveryNote__c                  = infoH.DeliveryNote;
                        ast.Asset_Owner__c                   = '病院資産';
                        ast.AccountId                        = accsMap.get(infoH.DepartmentNo).Id;
                        ast.Department_Class__c              = accsMap.get(infoH.DepartmentNo).Department_Class__c;
                        ast.Hospital__c                      = accsMap.get(infoH.EndUserNo).Id;
                        ast.Product2Id                       = prdsMap.get(dnInfo.OTCode).Id;
                        //ast.Quantity                         = String.isBlank(dnInfo.Qty) ? null : Decimal.valueOf(dnInfo.Qty);
                        if(dnInfo.SorLMark == 'S'){
                            ast.AssetMark__c = '主机';
                            ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                            ast.SerialNumber                     = dnInfo.SerialNoorLotNo;
                        }else{
                            ast.AssetMark__c = '耗材';
                            ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                            ast.SerialNumber                     = dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        }
                        ast.SLMark__c                        = 'Serial Number';         // 固定 dnInfo.SorLMark;
                        //HWAG-B9AAD9 当保有设备 的 保有设备标记 =耗材时，保修期限 =发货日
                        //ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                        ast.TracingCode__c                   = dnInfo.TracingCode;
                        ast.Guaranteen_end__c                = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                        ast.Barcode__c                       = dnInfo.Barcode;
                        ast.IF_Information_From__c           = true;
                        // HHOA-AGN2EH start
                        ast.Return_Flag__c = false;
                        ast.Delete_Flag__c = false;
                        if (clearflg == true) {
                            ast.InstallDate = null;
                        }

                        if (orderOutMap.containsKey(InquiryNoStr) == false) {
                            Consumable_order__c autoOrder = new Consumable_order__c();
                            autoOrder.Name = '*';
                            autoOrder.OwnerId = System.Label.User_OlympusSystem;
                            autoOrder.RecordTypeid = System.Label.RT_ConOrder_Sale;
                            autoOrder.Dealer_Info__c = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                            autoOrder.Order_ForHospital__c = accsMap.get(infoH.EndUserNo).Id;
                            autoOrder.Order_type__c = '销售';
                            autoOrder.SummonsStatus_c__c = '已完成';
                            autoOrder.SummonsForDirction__c = '直接销售给医院';
                            autoOrder.Outbound_Date__c = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                            autoOrder.Order_ForCustomerText__c = accsMap.get(infoH.DepartmentNo).Department_Name__c;
                            autoOrder.Opportunity__c = oppMap.get(InquiryNoStr).Id;
                            orderOutMap.put(InquiryNoStr, autoOrder);
                        }
                        Product2__c prdMap = prdSearchMap.get(dnInfo.OTCode);

                        if (!prdMap.Pro2_Dealer_Object__c && !prdMap.Pro2_Dealer_ENG__c) {
                            continue;
                        }

                        //if(detailsSendAgainNoMap.containsKey(dnInfo.Barcode) == true){
                        //    iflog.ErrorLog__c += 'Error! SoNo[' + infoH.SoNo + '] DeliveryNote[' + infoH.DeliveryNote + '] [' + InquiryNoStr + '] Barcode[' + dnInfo.Barcode + ']Duplicate. This asset is skipped.\n';
                        //    continue;
                        //}
                        Consumable_order_details2__c rac = odDSUpsertMap.get(InquiryNoStr + ':' + dnInfo.Barcode);
                        if (rac == null) {
                            rac = new Consumable_order_details2__c();
                            cod2List.add(rac);
                            odDSUpsertMap.put(InquiryNoStr + ':' + dnInfo.Barcode, rac);
                            odUpsertIdxMap.put(InquiryNoStr + ':' + dnInfo.Barcode, odDSUpsertMap.size());
                            odDSUpsertIdxMap.put(accsMap.get(infoH.EndUserNo).Id + ':' + oppMap.get(InquiryNoStr).Id + '', cod2List);
                        }
                        rac.Name                      = InquiryNoStr + ':' + ('000'+ odUpsertIdxMap.get(InquiryNoStr + ':' + dnInfo.Barcode)).right(4);
                        rac.RecordTypeId              = System.Label.RT_ConOrderDetail2_Delivery;                // TODO 本番IDにする label
                        if(String.isNotBlank(dnInfo.Qty)){
                            rac.Intra_Trade_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                        }else if(orderdet1priceMap.containsKey(prdSearch.Id)){
                            rac.Intra_Trade_List_RMB__c = orderdet1priceMap.get(prdSearch.Id);
                        }else{
                            rac.Intra_Trade_List_RMB__c   = prdSearch.Intra_Trade_List_RMB__c;
                        }
                        rac.Delivery_List_RMB__c = Decimal.valueOf(dnInfo.Qty);
                        rac.Asset_Model_No__c         = prdSearch.Asset_Model_No__c;
                        //rac.Consumable_order_minor__c = order.Id;
                        rac.Deliver_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                        rac.Arrive_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                        rac.Used_date__c           = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                        rac.Sterilization_limit__c    = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                        rac.Consumable_product__c     = prdSearch.Id;
                        rac.Bar_Code__c               = dnInfo.Barcode;
                        rac.Used_account__c           = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                        rac.Dealer_Info_IF__c         = addressNameApiMap.get(oppMap.get(InquiryNoStr).SAP_Province__c);
                        //rac.Used_account__c           = accsMap.get(infoH.EndUserNo).Id;
                        //rac.Dealer_Info_IF__c         = agencyContractMap.get(infoH.EndUserNo).ParentId;
                        rac.DeliveryNote__c           = infoH.DeliveryNote;
                        rac.SerialLotNo__c            = dnInfo.SerialNoorLotNo;
                        rac.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                        rac.TracingCode__c            = dnInfo.TracingCode;
                        //全部System
                        rac.OwnerId                   = System.Label.User_OlympusSystem;

                    }else{
                        System.debug('正常询价');
                        //upsert用、項目転送
                        if(dnInfo.SorLMark == 'S'){
                            ast.AssetMark__c = '主机';
                            ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo;
                        }else{
                            ast.AssetMark__c = '耗材';
                            ast.Product_Serial_No__c = prdsMap.get(dnInfo.OTCode).MDM_Model_No__c + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        }
                        if (astsMap.get(ast.Product_Serial_No__c ) == null) {
                            ast = new Asset();
                            astList.add(ast);
                            logstr += dnInfo.SorLMark == 'S'? dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo : dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        } else {
                            String errMes = dnInfo.SorLMark == 'S'? dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo : dnInfo.OTCode + ':' + dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                            iflog.ErrorLog__c += 'Warning! Asset' + '[' + errMes + '] Exist. This asset is skipped.\n';
                            continue;
                        }
                        if(dnInfo.SorLMark == 'S'){
                            ast.AssetMark__c = '主机';
                            ast.SerialNumber                     = dnInfo.SerialNoorLotNo;
                        }else{
                            ast.AssetMark__c = '耗材';
                            ast.SerialNumber                     = dnInfo.SerialNoorLotNo + '(' + dnInfo.TracingCode + ')';
                        }
                        ast.Name                             = prd.Name;
                        if(String.isNotEmpty(InquiryNoStr2)){
                            ast.Order_No__c                  = InquiryNoStr2;
                        }else{
                            ast.Order_No__c                  = InquiryNoStr;
                        }
                        ast.Backorder__c                     = String.isBlank(infoH.SoNo) ? null : boMap.get(infoH.SoNo);
                        ast.Posting_Date__c                  = NFMUtil.parseStr2Date(infoH.DeliveryDate);
                        ast.DeliveryNote__c                  = infoH.DeliveryNote;
                        if (accsMap.get(infoH.EndUserNo).RecordType.DeveloperName == 'Agency') {
                            // default AccountId を設定しない
                            ast.Asset_Owner__c                   = '经销商资产';
                            ast.Asset_owner_delaer_name__c       = accsMap.get(infoH.EndUserNo).Id;
                            ast.AccountId                        = ocm.Id;
                            ast.Department_Class__c              = null;
                            ast.Hospital__c                      = accsMap.get(infoH.EndUserNo).Id;
                        }
                        else if (accsMap.get(infoH.EndUserNo).RecordType.DeveloperName == 'AgencyContract') {
                            // default AccountId を設定しない
                            ast.Asset_Owner__c                   = '经销商资产';
                            ast.Asset_owner_delaer_name__c       = accsMap.get(infoH.EndUserNo).ParentId;
                            ast.AccountId                        = ocm.Id;
                            ast.Department_Class__c              = accsMap.get(infoH.EndUserNo).Id;
                            ast.Hospital__c                      = accsMap.get(infoH.EndUserNo).ParentId;
                        } else {
                            // 前提：備品こない
                            ast.Asset_Owner__c                   = '病院資産';
                            ast.AccountId                        = accsMap.get(infoH.DepartmentNo).Id;
                            ast.Department_Class__c              = accsMap.get(infoH.DepartmentNo).Department_Class__c;
                            ast.Hospital__c                      = accsMap.get(infoH.EndUserNo).Id;
                        }
                        ast.Product2Id                       = prdsMap.get(dnInfo.OTCode).Id;
                        //ast.Quantity                         = String.isBlank(dnInfo.Qty) ? null : Decimal.valueOf(dnInfo.Qty);
                        ast.SLMark__c                        = 'Serial Number';         // 固定 dnInfo.SorLMark;
                        ast.Guarantee_period_for_products__c = NFMUtil.parseStr2Date(dnInfo.GuaranteePeriod);
                        ast.TracingCode__c                   = dnInfo.TracingCode;
                        ast.Guaranteen_end__c                = NFMUtil.parseStr2Date(dnInfo.ValidTo);
                        ast.Barcode__c                       = dnInfo.Barcode;
                        ast.IF_Information_From__c           = true;
                        // HHOA-AGN2EH start
                        ast.Return_Flag__c = false;
                        ast.Delete_Flag__c = false;
                        if (clearflg == true) {
                            ast.InstallDate = null;
                        }
                        // HHOA-AGN2EH end
                    }
                }
            }
            // HHOA-AGN2EH 先退后发
            if (astDelList.size() > 0) {
                //delete astDelList;
                // TODO 今後 返品設備の科室に移動する可能性がある
                // TODO 消耗品の出荷 return があるか？
                for (Asset ast : astDelList) {
                    ast.Return_Flag__c = true;
                    ast.Delete_Flag__c = true;
                    // HHOA-AGN2EH start
                    ast.Hospital__c = olympus.Id;                      //'Olympus社内'
                    ast.Department_Class__c = olympus_return.ParentId; //'Olympus社内 其他'
                    ast.AccountID = olympus_return.Id;                 //'Olympus社内 其他 退货'
                    ast.Order_No__c = '';
                    ast.Posting_Date__c = null;
                    ast.DeliveryNote__c = '';
                    ast.InstallDate = null;
                    ast.Guarantee_period_for_products__c = null;
                    ast.Install_Account_Name__c = '';
                    ast.Install_Account_Code__c = '';
                    ast.Install_Hospital_code__c = '';
                    ast.Install_Hospital_Name__c = '';
                    // HHOA-AGN2EH end
                }
                update astDelList;
            }
            if (astList.size() > 0) {
                upsert astList;
            }
            //明细2直接到货，再入库更新
            if (odDetailUpsertMap.size() > 0){
                upsert odDetailUpsertMap.values();
            }
            // 消耗品订单更新，最新发货日、记录类型
            if (oUpdateMap.size() > 0) {
                update oUpdateMap.values();
            }
            // 消耗品明细2更新
            if (odUpsertMap.size() > 0) {
                upsert odUpsertMap.values();
            }
            //直销耗材 明细2
            if (odDSUpsertMap.size() > 0) {
                upsert odDSUpsertMap.values();
            }
            //直销耗材 返品单、出库单新建
            if (orderOutMap.size() > 0) {
                insert orderOutMap.values();
                for (Consumable_order__c co : orderOutMap.values()) {
                    orderReturnIdList.add(co.Id);
                }
            }

            // 自动生成出库单信息
            if(odDSUpsertIdxMap.size() > 0){
                addReturnOrderAuto(odDSUpsertIdxMap);
            }

            logstr += '\nend';
            rowData.retry_cnt__c=0;
        } catch (Exception ex) {
            // エラーが発生した場合
            Database.rollback(sp);
            System.debug(Logginglevel.ERROR, 'NFM110_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM110_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            logstr += '\n' + ex.getMessage();
            iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c;
            if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
            if (rowData.retry_cnt__c < batch_retry_max_cnt){
                rowData.retry_cnt__c++;
                //LogAutoSendSchedule.assignOneMinute();
            }
            if (rowData.retry_cnt__c >= batch_retry_max_cnt){
                rowData.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowData.ErrorLog__c+'错误次数已经超过自动收信设定的最大次数，请手动收信';
            }
        }
        update rowData;
        iflog.Log__c = logstr;
        if (iflog.Log__c.length() > 131072) {
            iflog.Log__c = iflog.Log__c.subString(0, 131065) + ' ...';
        }
        if (iflog.ErrorLog__c.length() > 32768) {
            iflog.ErrorLog__c = iflog.ErrorLog__c.subString(0, 32760) + ' ...';
        }
        update iflog;
    }

    // 耗材直销自动生成出库单
    //global static void addSaleOrderAuto (Map<String,List<Consumable_order_details2__c>> addMap) {
    //    Map<String, List<Consumable_order_details2__c>> accountGroupMap = new Map<String, List<Consumable_order_details2__c>>();
    //    Map<String, Map<Id, Integer>> productMap = new Map<String, Map<Id, Integer>> ();
    //    // 生成各经销商出库订单List
    //    List<Consumable_order__c> orderList = [select Id, Name, Order_ForHospital__c,Order_ForCustomerText__c,
    //                    Dealer_Info__c,Opportunity__c
    //                from Consumable_order__c
    //                where id in : orderoutIdList];
    //    Map<String, List<Consumable_orderdetails__c>> insDetail1Map = new Map<String, List<Consumable_orderdetails__c>>();
    //    for(String keystr : addMap.keySet()){
    //        System.debug('订单明细2+++ ' + addMap.get(keystr).size() + addMap.get(keystr));
    //        //List<Consumable_order_details2__c> accGroupList = new List<Consumable_order_details2__c> ();
    //        for(Consumable_order_details2__c cod : addMap.get(keystr)){
    //            List<Consumable_order_details2__c> accGroupList = new List<Consumable_order_details2__c> ();
    //            Map<Id, Integer> pNumMap = new Map<Id, Integer> ();
    //            Integer num = 1;
    //            if (accountGroupMap.containsKey(keystr)) {
    //                accGroupList = accountGroupMap.get(keystr);
    //                pNumMap = productMap.get(keystr);
    //                if (pNumMap.containsKey(cod.Consumable_Product__c)) {
    //                    num = pNumMap.get(cod.Consumable_Product__c) + 1;
    //                }
    //            } 
    //            pNumMap.put(cod.Consumable_Product__c, num);
    //            accGroupList.add(cod);
    //            productMap.put(keystr, pNumMap);
    //            accountGroupMap.put(keystr, accGroupList);
    //        }
    //        List<Consumable_order_details2__c> prodPriceList = addMap.get(keystr);
    //        Map<Id, Integer> pNumMap = new Map<Id, Integer> ();
    //        pNumMap = productMap.get(keystr);
    //        System.debug('pNumMap+++  ' + pNumMap);
    //        List<Consumable_orderdetails__c> insDetail1 = New List<Consumable_orderdetails__c>();
    //        for (Id id : pNumMap.keySet()) {
    //            Consumable_orderdetails__c ins = new Consumable_orderdetails__c();
                
    //            //InsAfterDel.Consumable_order__c = p.id;
    //            ins.Shipment_Count__c = pNumMap.get(id);
    //            ins.Consumable_Product__c = id;
    //            for (Consumable_order_details2__c pri : prodPriceList) {
    //                if (pri.Consumable_Product__c == id) {
    //                    ins.Intra_Trade_List_RMB__c =pri.Intra_Trade_List_RMB__c;
    //                    break;
    //                }
    //            }
    //            ins.Box_Piece__c = '盒';
    //            ins.Out_unit__c = '盒';
    //            //ins.Delivery_List_RMB__c = ass.orderdetails1.Delivery_List_RMB__c;
    //            //ins.Unitprice_To_agency__c = ass.orderdetails1.Unitprice_To_agency__c;
    //            //ins.Dealer_Custom_Price__c = ass.orderdetails1.Dealer_Custom_Price__c;
    //            ins.RecordTypeId = System.Label.RT_ConOrderDetail1_Shipment;
    //            ins.Used_date__c = Date.today();
    //            //ins.OwnerId = arriveAccount.OwnerId;

    //            insDetail1.add(ins);
    //        }
    //        insDetail1Map.put(keystr, insDetail1);
    //    }
    //    //insert orderList;

    //    // 设置明细1 和 明细2 的 订单ID
    //    List<Consumable_orderdetails__c> insDetail1List = new List<Consumable_orderdetails__c> ();
    //    List<Consumable_order_details2__c> updDetail2List = new List<Consumable_order_details2__c> ();
    //    for (Consumable_order__c setId : orderList) {
    //        // 明细1
    //        // 
    //        System.debug('出库单Name   ' + setId.Name);
    //        //System.debug('ins 00   ' + setId.Order_ForHospital__c + ':' + setId.Order_ForCustomerText__c + ':' + setId.Dealer_Info__c + ':' + setId.Opportunity__c);
    //        List<Consumable_orderdetails__c> d1list = insDetail1Map.get(setId.Order_ForHospital__c + ':' + setId.Order_ForCustomerText__c + ':' + setId.Dealer_Info__c + ':' + setId.Opportunity__c);
    //        Integer i = 1;
    //        for (Consumable_orderdetails__c dtl1 : d1list) {
    //            String str = string.valueOf(i);
    //            if(str.length() == 1){
    //                str = '0' + str;
    //            }
    //            dtl1.Consumable_order__c = setId.Id;
    //            dtl1.Name = setId.Name + '-'+ str;
    //            insDetail1List.add(dtl1);
    //        }

    //        // 明细2
    //        List<Consumable_order_details2__c> d2list = accountGroupMap.get(setId.Order_ForHospital__c + ':' + setId.Order_ForCustomerText__c + ':' + setId.Dealer_Info__c + ':' + setId.Opportunity__c);
    //        Integer j = 1;
    //        for (Consumable_order_details2__c dtl2 : d2list) {
    //            dtl2.Name = setId.Name + ':' + ('000'+ j).right(4);
    //            dtl2.Consumable_Sale_order__c = setId.Id;
    //            dtl2.Consumable_ZS_order__c = setId.Id;
    //            updDetail2List.add(dtl2);
    //        }
    //    }
    //    insert insDetail1List;
    //    update updDetail2List;
    //}

    // 耗材直销自动生成出库、退货单
    global static void addReturnOrderAuto (Map<String,List<Consumable_order_details2__c>> addMap) {
        Map<String, List<Consumable_order_details2__c>> accountGroupMap = new Map<String, List<Consumable_order_details2__c>>();
        Map<String, Map<Id, Integer>> productMap = new Map<String, Map<Id, Integer>> ();
        // 根据订单生成返品订单List
        List<Consumable_order__c> orderList = [select Id, Name, Order_ForHospital__c,Order_ForCustomerText__c,
                        Order_type__c,Dealer_Info__c,Opportunity__c
                    from Consumable_order__c
                    where id in : orderReturnIdList];
        Map<String, List<Consumable_orderdetails__c>> insDetail1Map = new Map<String, List<Consumable_orderdetails__c>>();
        //出库单明细
        for(String keystr : addMap.keySet()){
            //System.debug('订单明细11111 ' + keystr);
            //System.debug('订单明细2+++ ' + addMap.get(keystr).size() + addMap.get(keystr));
            //List<Consumable_order_details2__c> accGroupList = new List<Consumable_order_details2__c> ();
            for(Consumable_order_details2__c cod : addMap.get(keystr)){
                List<Consumable_order_details2__c> accGroupList = new List<Consumable_order_details2__c> ();
                if (accountGroupMap.containsKey(keystr)) {
                    accGroupList = accountGroupMap.get(keystr);
                }
                accGroupList.add(cod);
                accountGroupMap.put(keystr, accGroupList);
            }
        }
        // 设置明细2 的 订单ID
        List<Consumable_order_details2__c> updDetail2List = new List<Consumable_order_details2__c> ();
        for (Consumable_order__c setId : orderList) {
            //System.debug('订单明细22222 ' + setId.Order_ForHospital__c + ':' + setId.Opportunity__c);
            //System.debug('返品单Name   ' + setId.Name);
            // 明细2
            List<Consumable_order_details2__c> d2list = accountGroupMap.get(setId.Order_ForHospital__c + ':' + setId.Opportunity__c);
            Integer i = 1;
            for (Consumable_order_details2__c dtl2 : d2list) {
                dtl2.Name = setId.Name + ':' + ('000'+ i).right(4);
                if(setId.Order_type__c == '销售'){
                    dtl2.Consumable_Sale_order__c = setId.Id;
                    dtl2.Consumable_ZS_order__c = setId.Id;
                }else{
                    dtl2.Consumable_Return_order__c = setId.Id;
                }
                updDetail2List.add(dtl2);
                i++;
            }
        }
        update updDetail2List;
    }

    private static Map<String, String> addressNameApiMap = new Map<String, String> {
        '湖南省' => '0011000000V9SLSAA3',
        '四川省' => '0011000000V9SLSAA3',
        '广东省' => '0011000000V9SLSAA3',
        '贵州省' => '0011000000V9SLSAA3',
        '云南省' => '0011000000V9SLSAA3',
        '广西自治区' => '0011000000V9SLSAA3',
        '深圳市' => '0011000000V9SLSAA3',
        '湖北省' => '0011000000V9SLSAA3',
        '重庆市' => '0011000000V9SLSAA3',
        '北京市' => '0011000001HfVL2AAN',
        '吉林省' => '0011000001HfVL2AAN',
        '大连市' => '0011000001HfVL2AAN',
        '黑龙江省' => '0011000001HfVL2AAN',
        '内蒙古' => '0011000001HfVL2AAN',
        '山东省' => '0011000001HfVL2AAN',
        '甘肃省' => '0011000001HfVL2AAN',
        '青岛市' => '0011000001HfVL2AAN',
        '辽宁省' => '0011000001HfVL2AAN',
        '河北省' => '0011000001HfVL2AAN',
        '山西省' => '0011000001HfVL2AAN',
        '天津市' => '0011000001HfVL2AAN',
        '新疆自治区' => '0011000001HfVL2AAN',
        '陕西省' => '0011000001HfVL2AAN',
        '青海省' => '0011000001HfVL2AAN',
        '宁夏自治区' => '0011000001HfVL2AAN',
        '河南省' => '0011000001HfVL2AAN',
        '浙江省' => '0011000000V9SLTAA3', // 上线前修改
        '安徽省' => '0011000000V9SLTAA3',
        '江西省' => '0011000000V9SLTAA3',
        '福建省' => '0011000000V9SLTAA3',
        '江苏省' => '0011000000V9SLTAA3',
        '上海市' => '0011000000V9SLTAA3'
    };

    // CHAN-AXQBDY: 传过来的机身号最后5位都是字母并且倒数6,7,8位是052, SFDC删除机身号的最后8位
    private static String checkSerialNoorLotNo(String sn) {
        if (sn == null || sn == '' || sn.length() < 8) {
            return sn;
        }
        String regEx = '[a-zA-Z]';
        Pattern pattern = Pattern.compile(regEx);
        boolean strCheck = true;
        boolean numCheck = true;
        for (Integer i = 0; i < 8; i++) {
            String s = sn.substring(sn.length()-i-1, sn.length()-i);
            if (i < 5) {
                Matcher matcher = pattern.matcher(s);
                if(!matcher.matches()) {
                    strCheck = false;
                    break;
                }
            } else {
                if (i == 5) {
                    if (s != '0') {
                        numCheck = false;
                        break;
                    }
                } else if (i == 6) {
                    if (s != '5') {
                        numCheck = false;
                        break;
                    }
                } else if (i == 7) {
                    if (s != '2') {
                        numCheck = false;
                        break;
                    }
                }
            }
        }
        if (strCheck && numCheck) {
            return sn.substring(0, sn.length()-8);
        }
        return sn;
    }
}