//仿 EquipmentSetShippmentReceived6Controller.cls
public without sharing class ReceivingNoteStockInController {
    public ReceivingNoteSummary__c rns { get; set; }
    public List<EsdInfo> esdList { get; set; }
    public Boolean saveBtnDisabled { get; private set; }
    public boolean ReturnRefuse {get;private set;}
    public String ErrorMessage {get; set;}
    public String CDSFinished {get;set;}
    public boolean LostFlg {get;set;}
    public boolean done_flg {get;set;}
    public String SR_status { get; private set; }
    public String Step_status { get; private set; }
    public Boolean needCDS { get; private set; }
    public String open_type { get; private set; }
    public Boolean forceSave { get; set; }
    public String rnId {get;set;} //清单编号
    public String AccessoryId {get;set;}
    public String AccessorySetId {get;set;}
    public String UnCheckedId {get;set;}
    private String Id;

    public Integer getEsdListSize() {
        return esdList.size();
    }

    public ReceivingNoteStockInController() {
//        Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8');
        Id = ApexPages.currentPage().getParameters().get('id');
        if (SR_status == null) {
            SR_status = ApexPages.currentPage().getParameters().get('type');
        }
        if (Step_status == null) {
            Step_status = ApexPages.currentPage().getParameters().get('step');
        }
    }

    public void fetchPhotoStatus() {
        List<String> ids = Id.split(',');
        // 收货清单一览，把传入的id看作 一览的Id 或 编号 进行检索
        List<ReceivingNoteSummary__c> rnsList = [select Fixture_Model_No__c, Id, ReceivingNote__c, Name
                                                from ReceivingNoteSummary__c
                                                where (ReceivingNoteSummaryNo__c in :ids or Id in :ids)
                                         ];

        if (rnsList.size() > 0) {
            Set<Id> rndIdSet = new Set<Id>();
            for (ReceivingNoteSummary__c rns : rnsList) {
                rndIdSet.add(rns.Id);
            }
            List<ReceivingNoteDetail__c> rndList = getRndList(rndIdSet);
            Map<Id, ReceivingNoteDetail__c> rndMap = new Map<Id, ReceivingNoteDetail__c>();
            for(ReceivingNoteDetail__c rnd:rndList) {
                rndMap.put(rnd.Id, rnd);
            }
            List<EsdInfo> newList = new List<EsdInfo>();
            for (EsdInfo ei : esdList) {
                ReceivingNoteDetail__c rnd = rndMap.get(ei.rec.Id);
                EsdInfo einew = new EsdInfo(rnd);
                // 未入库确认 且 待上架
                if (rnd.Arrival_in_wh__c == false && rnd.Arrival_wh_Flag_F__c) {
                    einew.editable = true;
                }
                einew.accessorySetId = rnd.ReceivingNoteSummary__c;
                einew.rec.WH_location__c = ei.rec.WH_location__c;
                einew.onetoone = ei.onetoone;
                einew.rec.Arrival_in_wh__c = ei.rec.Arrival_in_wh__c;
                newList.add(einew);
            }
            esdList = newList;
        }
    }
    private List<ReceivingNoteDetail__c> getRndList(Set<Id> rnsIdSet) {
        return [select Id
                     , AcceptanceComments__c
                     , Arrival_in_wh__c                                //入库确认
                     , Arrival_wh_Flag_F__c                            //待上架标签(Sys)
                     , Arrival_wh_Request_time__c
                     , Asset_loaner_category_F__c
                     , Barcode_F__c
                     , Equipment_Type_F__c
                     , EquipmentSet_Managment_Code_F__c
                     , Fixture_Arrival_Process__c
                     , Fixture_Arrival_Product__c
                     , Fixture_Arrival_Product__r.Fixture_Model_No_T__c
                     , Fixture_Arrival_Product__r.Image__c
                     , Fixture_Arrival_Product__r.Name
                     , Fixture_Model_No_F__c
                     , Fixture_QRCode_F__c
                     , Fixture_Set_Detail__c
                     , Fixture_Set_Detail__r.Fixture_Set__c
                     , Fixture_Set_Detail__r.Is_Body__c
                     , Fixture_Set_Detail__r.Product2__c
                     , Fixture_Set_Detail__r.Product2__r.Image__c      //产品照片
                     , FSD_OneToOneAccessory_Cnt_F__c                  //一对一附属品明细件数F
                     , ImageAssetBase64__c
                     , ImageSerialBase64__c
                     , Inspection_Comment__c
                     , Inspection_result_after__c
                     , Is_Body_F__c
                     , Is_Internal_Asset__c                            //是否是固定资产
                     , Loaner_accsessary_F__c
                     , Manage_type_F__c
                     , Name                                            //明细名称
                     , OneToOne_Flag__c
                     , OT_CODE__c
                     , Packing_list_Fixture_F__c
                     , PeriodOfUse__c
                     , PeriodOfUse_Final__c
                     , Product_category_F__c
                     , Product_Name_F__c
                     , ReceivingNote__r.Internal_asset_location__c
                     , ReceivingNoteDetailNo__c                        //明细编号
                     , ReceivingNoteSummary__r.First_RND__r.RNDAssert__r.Loaner_approval_number__c
                     , ReceivingNoteSummary__r.First_RND__r.RNDAssert__r.Order_No__c
                     , ReceivingNoteSummary__r.First_RND__r.RNDAssert__r.Posting_Date__c
                     , ReceivingNoteSummary__r.First_RND__r.RNDAssert__r.Sales_order_number__c
                     , ReceivingNoteSummary__r.Fixture_Set__r.Name      //备品配套
                     , ReceivingNoteSummary__r.Name                     //一览名称
                     , ReceivingNoteSummary__r.ReceivingNoteSummaryNo__c//一览编号
                     , RNDAssert__c
                     , RNDAssert__r.AssetMark__c
                     , RNDAssert__r.ImageAsset__c                      //资产照片
                     , RNDAssert__r.ImageSerial__c                     //序列号照片
                     , RNDAssert__r.Product2.Image__c
                     , RNDAssert__r.Product2Id
                     , RNDAssert__r.Quantity
                     , Salesdepartment_F__c
                     , SalesProvince__c
                     , SerialNumber__c                         //机身编号
                     , SerialNumber_F__c
                     , unknow_serial_NO_product__c
                     , WH_location__c                     //货架号
                  from ReceivingNoteDetail__c
                 where ReceivingNoteSummary__c in :rnsIdSet and Delete_Flag__c = false and Change_Point__c != '删除'
              order by ReceivingNoteSummary__r.Name, ReceivingNoteSummary__c asc, Is_Body_F__c desc, passNo2__c, passNo3__c
            ];
    }
    // 画面初始化
    public PageReference init() {
        forceSave = false;
        done_flg = false;
        rns = new ReceivingNoteSummary__c();
        esdList = new List<EsdInfo>();
        Set<Id> rndIdSet = new Set<Id>();
        saveBtnDisabled = false;
        ReturnRefuse = true;
        ErrorMessage = '';
        if (Id != null) {
            List<String> ids = Id.split(',');
            // 当前User
            String userid = Userinfo.getUserId();
            User user = [select Id,Name from User where Id = :userid];
            // 收货清单一览，把传入的id看作 一览的Id 或 编号 进行检索
            List<ReceivingNoteSummary__c> rnsList = [select Fixture_Model_No__c, Id, ReceivingNote__c, Name
                                                    from ReceivingNoteSummary__c
                                                    where (ReceivingNoteSummaryNo__c in :ids or Id in :ids)
                                             ];

            if (rnsList.size() > 0) {
                for (ReceivingNoteSummary__c rns : rnsList) {
                    rndIdSet.add(rns.Id);
                    rnId = rns.ReceivingNote__c;
                }
            } else {
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '收货清单一览不存在'));
                saveBtnDisabled = true;
                return null;
            }

        }

        // 备品set明细
        List<ReceivingNoteDetail__c> rndList = getRndList(rndIdSet);

        // 一览Id---> 该一览下的所有明细
        Map<Id,List<ReceivingNoteDetail__c>> rnsMap = new Map<Id,List<ReceivingNoteDetail__c>>();
        for (ReceivingNoteDetail__c esd : rndList) {
            List<ReceivingNoteDetail__c> tempRndList;
            if (rnsMap.containsKey(esd.ReceivingNoteSummary__c)) {
                tempRndList = rnsMap.get(esd.ReceivingNoteSummary__c);
            } else {
                tempRndList = new List<ReceivingNoteDetail__c>();
            }
            tempRndList.add(esd);
            rnsMap.put(esd.ReceivingNoteSummary__c, tempRndList);
        }

        Set<Id> esdIds = new Set<Id>();
        Map<Id, Id> rns2fsMap = new Map<Id, Id>();
        for (Id rnsId : rnsMap.keySet()) {
            for (ReceivingNoteDetail__c esd : rnsMap.get(rnsId)) {
                EsdInfo ei = new EsdInfo(esd);
                // 未入库确认 且 待上架
                if (esd.Arrival_in_wh__c == false && esd.Arrival_wh_Flag_F__c) {
                    ei.editable = true;
                }
                ei.accessorySetId = esd.ReceivingNoteSummary__c;
                if (esd.Fixture_Set_Detail__r.Fixture_Set__c != null && !rns2fsMap.containsKey(esd.ReceivingNoteSummary__c)) {
                    rns2fsMap.put(esd.ReceivingNoteSummary__c, esd.Fixture_Set_Detail__r.Fixture_Set__c);
                }
                esdList.add(ei);
                esdIds.add(esd.ReceivingNoteSummary__c);
            }
        }

        if (esdList.size() <= 0) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '收货一览明细'));
            saveBtnDisabled = true;
            return null;
        }
        Step_status = '入库';
        SR_status = 'StockIn';

        List<Fixture_Set_Detail__c> fsdlist = [select Product2__r.Name,
                          Product2__c,
                          Quantity__c,
                          Is_OneToOne__c,
                          Fixture_Set__c,
                          (select Id from Fixture_Set_Detail__r where ReceivingNoteSummary__c in :esdIds)
                     from Fixture_Set_Detail__c
                    where Id in
                        (select Fixture_Set_Detail__c
                            from ReceivingNoteDetail__c
                            where ReceivingNoteSummary__c in :esdIds)
                      and Is_OneToOne__c = true
                 order by Fixture_Set__c, Is_OneToOne__c desc
                   ];
        Map<Id,Map<Id,Integer>> otoCntMap = new Map<Id,Map<Id,Integer>>();
        for (Fixture_Set_Detail__c fsd : fsdlist) {
            Map<Id,Integer> cntMap = new Map<Id,Integer>();
            if (otoCntMap.containsKey(fsd.Fixture_Set__c)) {
                cntMap = otoCntMap.get(fsd.Fixture_Set__c);
            }
            // 一览单位配一对一，实际一对一数量要乘以一览数量
            cntMap.put(fsd.Id, Integer.valueOf(fsd.Quantity__c)*fsd.Fixture_Set_Detail__r.size());
            otoCntMap.put(fsd.Fixture_Set__c, cntMap);
        }

        for (EsdInfo ei : esdList) {
            if (ei.onetoone) {
                Id fsId = rns2fsMap.get(ei.accessorySetId);
                Map<Id,Integer> cntMap = otoCntMap.get(fsId);
                if (cntMap != null) {
                    Integer cnt = cntMap.get(ei.rec.Fixture_Set_Detail__c);
                    if (cnt > 0) {
                        cntMap.put(ei.rec.Fixture_Set_Detail__c, cnt - 1);
                        otoCntMap.put(fsId, cntMap);
                    } else {
                        ei.onetoone = false;
                    }
                } else {
                    ei.onetoone = false;
                }
            }
        }

        return null;
    }

    // 保存按钮
    public PageReference save() {
        //ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, 'Test'));
        done_flg = false;
        boolean needSaveDetail = false;
        String userid = Userinfo.getUserId();
        List<ReceivingNoteDetail__c> eList = new List<ReceivingNoteDetail__c>(); //可编辑的明细
        List<EsdInfo> otoCheckList_main = new List<EsdInfo>(); //带附属品的主体 列表
        //List<EsdInfo> otoAccessoryList = new List<EsdInfo>();  //一对一附件 列表
        Map<Id, boolean> allOtOChecked = new Map<Id, boolean>();  //一对一附件 列表
        Map<Id, String> allOtOCheckErr = new Map<Id, String>();  //一对一附件 列表
        Set<Id> mainSet = new Set<Id>();  //主体 所在一览 集合
        Map<String, ReceivingNoteDetail__c> newAssetMap = new Map<String, ReceivingNoteDetail__c>();
        Map<String, Integer> newAssetCountMap = new Map<String, Integer>();
        Map<Id, ReceivingNoteDetail__c> assetIdMap = new Map<Id, ReceivingNoteDetail__c>();
        String sqlwhere = '';

        Set<Id> getImgIds = new Set<Id>();
        for (EsdInfo esdInfo : esdList) {
            getImgIds.add(esdInfo.rec.Id);
        }
        Map<Id, ReceivingNoteDetail__c> imgMap = new Map<Id, ReceivingNoteDetail__c>(
            [select ImageAssetBase64__c, ImageSerialBase64__c, Id from ReceivingNoteDetail__c where Id in :getImgIds]);
        for (EsdInfo esdInfo : esdList) {
            esdInfo.rec.ImageAssetBase64__c = imgMap.get(esdInfo.rec.Id).ImageAssetBase64__c;
            esdInfo.rec.ImageSerialBase64__c = imgMap.get(esdInfo.rec.Id).ImageSerialBase64__c;
        }
        imgMap = null;
        Map<Id, ReceivingNoteDetail__c> originRndMap = new Map<Id, ReceivingNoteDetail__c>([
                SELECT Id
                     , Arrival_in_wh__c
                     , Arrival_wh_Request_time__c
                  FROM ReceivingNoteDetail__c
                 WHERE ReceivingNote__c =:rnId and Delete_Flag__c = false and Change_Point__c != '删除'
                ]);
        //遍历明细
        for (EsdInfo esdInfo : esdList) {
            //无错误信息
            esdInfo.errorInfo = null;
            //if (esdInfo.accessoryFlg) {
            //    otoAccessoryList.add(esdInfo);
            //} else {
                if (esdInfo.onetoone) {
                    boolean checked = true;
                    if (allOtOChecked.containsKey(esdInfo.rec.ReceivingNoteSummary__c)) {
                        checked = allOtOChecked.get(esdInfo.rec.ReceivingNoteSummary__c);
                    }
                    checked = checked && esdInfo.rec.Arrival_in_wh__c;
                    allOtOChecked.put(esdInfo.rec.ReceivingNoteSummary__c, checked);
                    if (!checked && !allOtOCheckErr.containsKey(esdInfo.rec.ReceivingNoteSummary__c)) {
                        allOtOCheckErr.put(esdInfo.rec.ReceivingNoteSummary__c, esdInfo.rec.Product_Name_F__c);
                    }
                }
                if (!esdInfo.editable) continue;
                if(!originRndMap.containsKey(esdInfo.rec.Id)){
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '【'+ esdInfo.rec.ReceivingNoteDetailNo__c +'】已被删除，请刷新画面'));
                    return null;
                }
                else if(originRndMap.get(esdInfo.rec.Id).Arrival_wh_Request_time__c == null){
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '【'+ esdInfo.rec.ReceivingNoteDetailNo__c +'】未入库指示，请刷新画面'));
                    return null;
                }
                else if(originRndMap.get(esdInfo.rec.Id).Arrival_in_wh__c) {
                    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '【'+ esdInfo.rec.ReceivingNoteDetailNo__c +'】已入库，请刷新画面'));
                    return null;
                }
                ReceivingNoteDetail__c esd = esdInfo.rec;
                eList.add(esd);
                if (esd.Arrival_in_wh__c) {
                    if (esd.FSD_OneToOneAccessory_Cnt_F__c > 0 && esd.Is_Body_F__c && esd.Arrival_wh_Flag_F__c) {
                        otoCheckList_main.add(esdInfo);
                        mainSet.add(esd.ReceivingNoteSummary__c);
                    }
                    //else if (esd.Arrival_wh_Flag_F__c && esd.FSD_OneToOneAccessory_Cnt_F__c > 0 && esd.OneToOne_Flag__c) {
                    //    otoAccessoryList.add(esdInfo);
                    //}

                    if (esd.RNDAssert__c != null) {
                        assetIdMap.put(esd.RNDAssert__c, esd);
                    }
                    Date useDate = esd.PeriodOfUse__c;
                    if(esd.PeriodOfUse_Final__c != null){
                        useDate = esd.PeriodOfUse_Final__c;
                    }
                    if (esd.RNDAssert__c == null || esd.Manage_type_F__c == '数量管理' || esd.Asset_loaner_category_F__c == '耗材') {
                        if(esd.Fixture_Arrival_Process__c == '合并'){
                            continue;
                        }
                        String ukey;
                        String sNo = esd.SerialNumber_F__c;
                        if (esd.Asset_loaner_category_F__c == '耗材') {
                            if (useDate != null) {
                                sNo = sNo.replaceAll('\\(.*\\)', '')+'('+DateTime.newInstance(useDate.year(), useDate.month(), useDate.day()).format('yyyyMMdd')+')';
                            } else {
                                sNo = sNo.replaceAll('\\(.*\\)', '')+'()';
                            }
                        } else if (esd.Manage_type_F__c == '个体管理') {
                            sNo = esd.Id;
                        }

                        String model = esd.Fixture_Model_No_F__c;
                        if(esd.Fixture_Arrival_Process__c == '变体'){
                            model = esd.Fixture_Arrival_Product__r.Fixture_Model_No_T__c;
                        }

                        if (esd.Asset_loaner_category_F__c == '耗材' || esd.Manage_type_F__c == '个体管理') {
                            ukey = esd.Equipment_Type_F__c +';'+ esd.ReceivingNote__r.Internal_asset_location__c +';'+ esd.Salesdepartment_F__c +';'+ model +';'+useDate+';'+sNo;
                        } else {
                            ukey = esd.Equipment_Type_F__c +';'+ esd.ReceivingNote__r.Internal_asset_location__c +';'+ esd.Salesdepartment_F__c +';'+ model +';'+useDate;
                        }
                        Integer count = 0;
                        if (newAssetCountMap.containsKey(ukey)) {
                            count = newAssetCountMap.get(ukey);
                        }
                        Integer packingManual = 1;
                        if (esd.Packing_list_Fixture_F__c != null
                                && (esd.Asset_loaner_category_F__c == '耗材'
                                        || esd.Asset_loaner_category_F__c == '低值易耗品'
                                        // 附属品不是配套中的主体时，才看产品主数据的规格
                                        || (esd.Asset_loaner_category_F__c == '附属品' && !esd.Fixture_Set_Detail__r.Is_Body__c)
                                )
                        ) {
                            packingManual = Integer.valueOf(esd.Packing_list_Fixture_F__c);
                        }

                        newAssetCountMap.put(ukey, (count + packingManual));
                        if (!newAssetMap.containsKey(ukey)) {
                            newAssetMap.put(ukey, esd);
                        }
                        if (esd.Equipment_Type_F__c != null) {
                            sqlwhere += ' (Equipment_Type__c =\'' + String.escapeSingleQuotes(esd.Equipment_Type_F__c) + '\'';
                        } else {
                            sqlwhere += ' (Equipment_Type__c = null';
                        }
                        if (esd.Salesdepartment_F__c != null) {
                            sqlwhere += ' AND Salesdepartment__c =\'' + String.escapeSingleQuotes(esd.Salesdepartment_F__c) + '\'';
                        } else {
                            sqlwhere += ' AND Salesdepartment__c = null';
                        }
                        if (String.isNotBlank(model)) {
                            sqlwhere += ' AND Fixture_Model_No_F__c =\'' + String.escapeSingleQuotes(model) + '\'';
                        } else {
                            sqlwhere += ' AND Fixture_Model_No_F__c = null';
                        }
                        if (esd.ReceivingNote__r.Internal_asset_location__c != null) {
                            sqlwhere += ' AND Internal_asset_location__c =\'' + String.escapeSingleQuotes(esd.ReceivingNote__r.Internal_asset_location__c) + '\'';
                        } else {
                            sqlwhere += ' AND Internal_asset_location__c = null';
                        }
                        if (useDate != null) {
                            sqlwhere += ' AND Consumable_Guaranteen_end__c =' + String.valueOf(useDate);
                        } else {
                            sqlwhere += ' AND Consumable_Guaranteen_end__c = null';
                        }
                        if (esd.Asset_loaner_category_F__c == '耗材') {
                            if (String.isNotBlank(esd.SerialNumber_F__c)) {
                                sqlwhere += ' AND SerialNumber =\'' + String.escapeSingleQuotes(sNo) + '\') OR';
                            } else {
                                sqlwhere += ' AND SerialNumber = null) OR';
                            }
                        } else {
                            sqlwhere += ' ) OR';
                        }

                    }

                }

            //}
        }
        boolean err = false;
        Map<String, Integer> otoMap = new Map<String, Integer>();
        List<Fixture_OneToOne_Link__c> otolinkList = new List<Fixture_OneToOne_Link__c>();
        Map<Id, Id> o2oMainMap = new Map<Id, Id>();
        for (EsdInfo main : otoCheckList_main) {
            if (allOtOChecked.containsKey(main.rec.ReceivingNoteSummary__c) && !allOtOChecked.get(main.rec.ReceivingNoteSummary__c)) {
                if (!forceSave ) {
                    main.errorInfo = '未补全附属品(部分上架请勾选复选框):'+allOtOCheckErr.get(main.rec.ReceivingNoteSummary__c);
                    err = true;
                    break;
                } else {
                    continue;
                }
            }
            o2oMainMap.put(main.rec.ReceivingNoteSummary__c, main.rec.Id);
        }

        if (err) return null;

        Map<String, Integer> fsdCnt = new Map<String, Integer>();
        Map<String, String> fsdKey = new Map<String, String>();
        Map<Id, Id> fsdFirstRnd = new Map<Id, Id>();
        Map<Id, Id> rndFsdMap = new Map<Id, Id>();
        for (EsdInfo esdInfo : esdList) {
            if (esdInfo.onetoone && esdInfo.editable
                && esdInfo.rec.Arrival_in_wh__c
                && o2oMainMap.containsKey(esdInfo.rec.ReceivingNoteSummary__c)) {
                ReceivingNoteDetail__c esd = esdInfo.rec;
                Id mainId = o2oMainMap.get(esd.ReceivingNoteSummary__c);
                String key = (String)mainId + ':' + esd.Id;

                if (esd.Manage_type_F__c == '个体管理') {
                    otoMap.put(key, 1);
                } else if (esd.Manage_type_F__c == '数量管理') {
                    Integer cnt = 1;
                    //已一览为单位组合一对一
                    String fsdSummaryKey = (String)esd.Fixture_Set_Detail__c + ':' + esdInfo.rec.ReceivingNoteSummary__c;
                    //保存同型号第一个明细Id
                    if (!fsdFirstRnd.containsKey(esd.Fixture_Set_Detail__c)) {
                        fsdFirstRnd.put(esd.Fixture_Set_Detail__c, esdInfo.rec.Id);
                    }
                    rndFsdMap.put(esdInfo.rec.Id, esd.Fixture_Set_Detail__c);

                    if (fsdKey.containsKey(fsdSummaryKey)) {
                        cnt += fsdCnt.get(fsdSummaryKey);
                        key = fsdKey.get(fsdSummaryKey);
                    }
                    fsdKey.put(fsdSummaryKey, key);
                    fsdCnt.put(fsdSummaryKey, cnt);
                    otoMap.put(key, cnt);
                }
            }
        }

        // TODO 没变化不存
        if (Step_status == '入库') {

            for (ReceivingNoteDetail__c esd : eList) {

                if (esd.Arrival_in_wh__c) {
                    esd.Arrival_wh_time__c = System.now();
                    esd.StockIn_wh_check_staff__c = userid;
                } else {
                    esd.Arrival_wh_time__c = null;
                    esd.StockIn_wh_check_staff__c = null;
                }

            }
            needSaveDetail = true;
        }

        // 备品
        Account aac = [select Id, Hospital__c from Account where Management_Code__c = :System.Label.Account_Asset];
        // 备品（已收货）
        Account aacd = [select Id, Hospital__c from Account where Management_Code__c = :System.Label.Account_Asset_Client_Done];

        List<Asset> upsertList = new List<Asset>();
        Map<Id, String> assetImageMap = new Map<Id, String>();
        Map<Id, String> serialImageMap = new Map<Id, String>();
        List<Id> upsertListRndId = new List<Id>();
        if (newAssetMap.size() > 0) {
            sqlwhere = sqlwhere.removeEnd('OR');
            sqlwhere = '(' + sqlwhere + ')';
            String sqlStr = 'SELECT Id, Asset_loaner_category__c, Salesdepartment__c, Quantity, Manage_type__c, ImageAsset__c, ImageSerial__c, '
                                +'Fixture_Model_No_F__c, Product_category__c, Internal_asset_location__c, Consumable_Guaranteen_end__c, '
                                +'Equipment_Type__c, SerialNumber FROM Asset Where ' + sqlwhere
                                + ' AND Delete_Flag__c = false '
                                + ' AND Asset_Owner__c = \'Olympus\''
                                + ' AND AssetManageConfirm__c = true'
                                + ' AND Quantity >= 0'
                                + ' AND (Freeze_sign_Abandoned_Flag__c = False OR Status =\'待报废\')'
                                + ' AND Manage_type__c = \'数量管理\''
                                + ' ORDER BY Fixture_Model_No_F__c, Quantity Desc';
            List<Asset> matchingAsset = Database.query(sqlStr);

            for (Asset ast : matchingAsset) {
                String ukey;
                if (ast.Asset_loaner_category__c == '耗材') {
                    ukey = ast.Equipment_Type__c+';'+ast.Internal_asset_location__c +';' + ast.Salesdepartment__c +';'+ ast.Fixture_Model_No_F__c+';'+ast.Consumable_Guaranteen_end__c+';'+ast.SerialNumber;
                } else {
                    ukey = ast.Equipment_Type__c+';'+ast.Internal_asset_location__c +';' + ast.Salesdepartment__c +';'+ ast.Fixture_Model_No_F__c+';'+ast.Consumable_Guaranteen_end__c;
                }
                if (newAssetMap.containsKey(ukey)) {
                    //if (ast.Manage_type__c == '个体管理') {
                    //    ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, '创建个体管理保有设备失败！'));
                    //    done_flg = false;
                    //    return null;
                    //}
                    ast.Quantity = ast.Quantity + newAssetCountMap.get(ukey);
                    ast.ChangeQuantityReason__c = '新品';
                    ast.Status = '使用中';
                    upsertList.add(ast);
                    ReceivingNoteDetail__c rnd = newAssetMap.get(ukey);
                    upsertListRndId.add(rnd.Id);
                    if (rnd.ImageAssetBase64__c != null && ast.ImageAsset__c == null) {
                        assetImageMap.put(rnd.Id, rnd.ImageAssetBase64__c);
                    }
                    if (rnd.ImageSerialBase64__c != null && ast.ImageSerial__c == null) {
                        serialImageMap.put(rnd.Id, rnd.ImageSerialBase64__c);
                    }
                    newAssetMap.remove(ukey);
                }
            }

            for (String rndkey : newAssetMap.keySet()) {
                ReceivingNoteDetail__c rnd = newAssetMap.get(rndkey);
                Asset newAset = new Asset();
                if (rnd.Fixture_Arrival_Process__c == '变体'){
                    newAset.Product2Id = rnd.Fixture_Arrival_Product__c;
                }
                else {
                    newAset.Product2Id = rnd.Fixture_Set_Detail__r.Product2__c != null ? rnd.Fixture_Set_Detail__r.Product2__c : rnd.RNDAssert__r.Product2Id;
                }
                Date useDate = rnd.PeriodOfUse__c;
                if(rnd.PeriodOfUse_Final__c != null){
                    useDate = rnd.PeriodOfUse_Final__c;
                }
                newAset.Quantity = newAssetCountMap.get(rndkey);
                newAset.ChangeQuantityReason__c = '新品';
                newAset.Salesdepartment__c = rnd.Salesdepartment_F__c;
                newAset.SalesProvince__c = rnd.SalesProvince__c;
                newAset.Product_category__c = rnd.Product_category_F__c;
                newAset.Equipment_Type__c = rnd.Equipment_Type_F__c;
                newAset.Internal_asset_location__c = rnd.ReceivingNote__r.Internal_asset_location__c;
                newAset.Loaner_accsessary__c = rnd.Loaner_accsessary_F__c;
                newAset.Consumable_Guaranteen_end__c = useDate;
                newAset.unknow_serial_NO_product__c = rnd.unknow_serial_NO_product__c == 'TRUE';
                if (!newAset.unknow_serial_NO_product__c) {
                    newAset.SerialNumber = rnd.SerialNumber_F__c;
                }
                newAset.Manage_type__c = rnd.Manage_type_F__c;
                newAset.AcceptanceComments__c = rnd.Inspection_Comment__c;
                //货架号
                if (!rnd.OneToOne_Flag__c) newAset.WH_location__c = rnd.WH_location__c;
                //客户
                newAset.AccountId = aac.Id;
                newAset.Hospital__c = aac.Hospital__c;
                //状态：使用中
                newAset.Status = '使用中';
                //备品中心确认：TRUE
                newAset.AssetManageConfirm__c = true;

                newAset.Name = '*';
                newAset.RecordTypeId = '01210000000kOPR';
                if (String.isNotBlank(rnd.Barcode_F__c)) {
                    String barStr = rnd.Barcode_F__c;
                    String lastStr = barStr.right(8);
                    if (lastStr.startsWith('250')) barStr = barStr.removeEnd(lastStr);
                    newAset.Barcode__c = barStr;
                }
                if (rnd.Asset_loaner_category_F__c == '耗材') {
                    newAset.AssetMark__c = '耗材';
                    newAset.unknow_serial_NO_product__c = false;
                    newAset.Manage_type__c = '数量管理';
                    newAset.Loaner_accsessary__c = true;
                    newAset.Asset_loaner_category__c = rnd.Asset_loaner_category_F__c;
                    //newAset.Equipment_Type__c = '更新';
                    String newSNo = rnd.SerialNumber_F__c;
                    if (rnd.SerialNumber_F__c.contains('(')) {
                        newSNo = rnd.SerialNumber_F__c.replaceAll('\\(.*\\)', '');
                    }
                    if (useDate != null) {
                        newAset.SerialNumber = newSNo+'('+DateTime.newInstance(useDate.year(), useDate.month(), useDate.day()).format('yyyyMMdd')+')';
                    } else {
                        newAset.SerialNumber = newSNo+'()';
                    }
                    if(String.isNotBlank(rnd.Salesdepartment_F__c) && rnd.Salesdepartment_F__c.split('\\.').size() > 1) {
                        newAset.Product_Serial_No__c = rnd.OT_CODE__c + ':' + newAset.SerialNumber + ':' + rnd.Salesdepartment_F__c.split('\\.')[0];
                    }
                    else {
                        newAset.Product_Serial_No__c = rnd.OT_CODE__c + ':' + newAset.SerialNumber;
                    }
                }
                //移交日期最初：入库操作日
                if (newAset.Manage_type__c != '数量管理') {
                    newAset.Asset_Cutoff_Date__c = System.today();
                } else {
                    newAset.AssetMark__c = '耗材';
                }

                if (newAset.Manage_type__c == '个体管理') {
                    newAset.AssetMark__c = '主机';
                    newAset.Order_No__c = rnd.ReceivingNoteSummary__r.First_RND__r.RNDAssert__r.Order_No__c;
                    newAset.Sales_order_number__c = rnd.ReceivingNoteSummary__r.First_RND__r.RNDAssert__r.Sales_order_number__c;
                    newAset.Loaner_approval_number__c = rnd.ReceivingNoteSummary__r.First_RND__r.RNDAssert__r.Loaner_approval_number__c;
                    newAset.Posting_Date__c = rnd.ReceivingNoteSummary__r.First_RND__r.RNDAssert__r.Posting_Date__c;
                }

                upsertList.add(newAset);
                upsertListRndId.add(rnd.Id);
                if (rnd.ImageAssetBase64__c != null) {
                    assetImageMap.put(rnd.Id, rnd.ImageAssetBase64__c);
                }
                if (rnd.ImageSerialBase64__c != null) {
                    serialImageMap.put(rnd.Id, rnd.ImageSerialBase64__c);
                }
            }
        }

        if (assetIdMap.size() > 0) {
            List<Asset> astList = [select Id
                                        , AccountId
                                        , ImageAsset__c
                                        , ImageSerial__c
                                        , Hospital__c
                                        , Manage_type__c
                                        , Product2Id
                                        , Consumable_Guaranteen_end__c
                                     from Asset
                                    where id in :assetIdMap.keySet()];
            for (Asset ast : astList) {
                ReceivingNoteDetail__c rnd = assetIdMap.get(ast.Id);
                if(rnd.Fixture_Arrival_Process__c == '变体'){
                    ast.Product_Old__c = ast.Product2Id;
                    ast.Product2Id = rnd.Fixture_Arrival_Product__c;
                }
                if(rnd.PeriodOfUse_Final__c != null){
                    ast.Consumable_Guaranteen_end_old__c = ast.Consumable_Guaranteen_end__c;
                    ast.Consumable_Guaranteen_end__c = rnd.PeriodOfUse_Final__c;
                }
                if (rnd.Manage_type_F__c == '数量管理' || rnd.Asset_loaner_category_F__c == '耗材'|| rnd.Fixture_Arrival_Process__c == '合并' ) {
                    ast.AccountId = aacd.Id;
                    ast.Hospital__c = aacd.Hospital__c;
                    upsertListRndId.add(null);
                } else if (rnd.Manage_type_F__c == '个体管理') {
                    ast.Salesdepartment__c = rnd.Salesdepartment_F__c;
                    ast.Quantity = 1;
                    ast.ChangeQuantityReason__c = '新品';
                    ast.SalesProvince__c = rnd.SalesProvince__c;
                    ast.EquipmentSet_Managment_Code__c = rnd.EquipmentSet_Managment_Code_F__c;
                    ast.Product_category__c = rnd.Product_category_F__c;
                    ast.Equipment_Type__c = rnd.Equipment_Type_F__c;
                    //ast.Internal_asset_location__c = rnd.ReceivingNote__r.Internal_asset_location__c;
                    ast.Loaner_accsessary__c = rnd.Loaner_accsessary_F__c;
                    ast.unknow_serial_NO_product__c = rnd.unknow_serial_NO_product__c == 'TRUE';
                    if (!ast.unknow_serial_NO_product__c) {
                        ast.SerialNumber = rnd.SerialNumber_F__c;
                    }
                    ast.AcceptanceComments__c = rnd.Inspection_Comment__c;
                    if (!rnd.OneToOne_Flag__c) ast.WH_location__c = rnd.WH_location__c;
                    //客户
                    ast.AccountId = aac.Id;
                    ast.Hospital__c = aac.Hospital__c;
                    //状态：使用中
                    ast.Status = '使用中';
                    //备品中心确认：TRUE
                    ast.AssetManageConfirm__c = true;
                    //移交日期最初：入库操作日
                    ast.Asset_Cutoff_Date__c = System.today();
                    upsertListRndId.add(rnd.Id);
                    if (rnd.ImageAssetBase64__c != null && ast.ImageAsset__c == null) {
                        assetImageMap.put(rnd.Id, rnd.ImageAssetBase64__c);
                    }
                    if (rnd.ImageSerialBase64__c != null && ast.ImageSerial__c == null) {
                        serialImageMap.put(rnd.Id, rnd.ImageSerialBase64__c);
                    }
                }
                upsertList.add(ast);
            }
        }
        //return null;

        Savepoint sp = Database.setSavepoint();
        try {

            if (upsertList.size() > 0) FixtureUtil.withoutUpsertObjects(upsertList);
            if (needSaveDetail) FixtureUtil.withoutUpsertObjects(eList);

            //双方向asset和一览明细Map
            Map<Id,Id> rndAstIdMap = new Map<Id,Id>();
            Map<Id,Id> astRndIdMap = new Map<Id,Id>();
            for (Integer i = 0, j = upsertList.size(); i < j; i++) {
                rndAstIdMap.put(upsertListRndId[i], upsertList[i].Id);
                astRndIdMap.put(upsertList[i].Id, upsertListRndId[i]);
            }

            for (String oto : otoMap.keySet()) {
                List<String> keys = oto.split(':');

                Id main = rndAstIdMap.get(keys[0]);
                Id ass = rndAstIdMap.get(keys[1]);

                //找不到一对一附属品asset时，找同型号的asset
                if (ass == null) {
                    String asskey = rndFsdMap.get(keys[1]) == null ? null : fsdFirstRnd.get(rndFsdMap.get(keys[1]));
                    ass = asskey == null ? null : rndAstIdMap.get(asskey);
                }
                if (main != null && ass != null) {
                    Fixture_OneToOne_Link__c otolink = new Fixture_OneToOne_Link__c();
                    otolink.Main_Asset__c = main;
                    otolink.Accessory_Asset__c = ass;
                    otolink.Quantity__c = otoMap.get(oto);
                    otolinkList.add(otolink);
                }
            }

            if (otolinkList.size() > 0) {
                FixtureUtil.withoutInsert(otolinkList);
            }

            Map<String,String> assetDocNameMap = new Map<String,String>();
            Map<String,String> serialDocNameMap = new Map<String,String>();
            Map<String,String> serialDocAssetMap = new Map<String,String>();
            Map<String,String> assetDocAssetMap = new Map<String,String>();
            List<Asset> astImgList = [select Id, Product_Serial_No__c, ImageAsset__c, ImageSerial__c from Asset where id in :astRndIdMap.keySet()];
            for (Asset ast : astImgList) {
                if (ast.ImageAsset__c == null && assetImageMap.containsKey(astRndIdMap.get(ast.Id))) {
                    assetDocNameMap.put(ast.Product_Serial_No__c + '_Asset', ast.Id);
                }
                if (ast.ImageSerial__c == null && serialImageMap.containsKey(astRndIdMap.get(ast.Id))) {
                    serialDocNameMap.put(ast.Product_Serial_No__c + '_Serial', ast.Id);
                }
            }

            // 查找已上传的Asset图片
            List<Document> docList = [Select Id, Body, Name, folderid, Type From Document Where ( Name in :assetDocNameMap.keySet() or Name in :serialDocNameMap.keySet() ) And folderid =:System.Label.AssetImageFolder];
            if (docList.size() > 0) {
                for (Document doc : docList) {
                    if (serialDocNameMap.containsKey(doc.Name)) {
                        serialDocAssetMap.put(serialDocNameMap.get(doc.Name), doc.Id);
                        serialDocNameMap.put(doc.Name, null);
                    }
                    if (assetDocNameMap.containsKey(doc.Name)) {
                        assetDocAssetMap.put(assetDocNameMap.get(doc.Name), doc.Id);
                        assetDocAssetMap.put(doc.Name, null);
                    }
                }
            }

            // 创建Asset图片
            List<Document> insertDocList = new List<Document>();
            for (String adName : assetDocNameMap.keySet()) {
                String astId = assetDocNameMap.get(adName);
                if (astId != null) {
                    Document dc = new Document();
                    dc.Body = EncodingUtil.base64Decode(assetImageMap.get(astRndIdMap.get(astId)));
                    dc.Name = adName;
                    dc.folderid = System.Label.AssetImageFolder;
                    dc.Type = 'jpg';
                    insertDocList.add(dc);
                }
            }
            for (String adName : serialDocNameMap.keySet()) {
                String astId = serialDocNameMap.get(adName);
                if (astId != null) {
                    Document dc = new Document();
                    dc.Body = EncodingUtil.base64Decode(serialImageMap.get(astRndIdMap.get(astId)));
                    dc.Name = adName;
                    dc.folderid = System.Label.AssetImageFolder;
                    dc.Type = 'jpg';
                    insertDocList.add(dc);
                }
            }

            if (insertDocList.size() > 0) insert insertDocList;
            for (Document doc : insertDocList) {
                if (assetDocNameMap.containsKey(doc.Name)) {
                    assetDocAssetMap.put(assetDocNameMap.get(doc.Name), doc.Id);
                }
                if (serialDocNameMap.containsKey(doc.Name)) {
                    serialDocAssetMap.put(serialDocNameMap.get(doc.Name), doc.Id);
                }
            }

            //更新asset图片
            List<Asset> updateAssetImgs = new List<Asset>();
            if (assetDocAssetMap.size() > 0) {
                for (String astId : assetDocAssetMap.keySet()) {
                    Asset ast = new Asset(Id=astId);
                    ast.ImageAsset__c = '<img style="width:320px" src="/servlet/servlet.FileDownload?file=' + assetDocAssetMap.get(astId) + '"/>';
                    ast.ImageAssetUploadedBy__c = UserInfo.getUserId();
                    ast.ImageAssetUploadedTime__c = Datetime.now();
                    if (serialDocAssetMap.containsKey(astId)) {
                        ast.ImageSerial__c = '<img style="width:320px" src="/servlet/servlet.FileDownload?file=' + serialDocAssetMap.get(astId) + '"/>';
                        ast.ImageSerialUploadedBy__c = UserInfo.getUserId();
                        ast.ImageSerialUploadedTime__c = Datetime.now();
                    }
                    serialDocAssetMap.remove(astId);
                    updateAssetImgs.add(ast);
                }
            }
            if (serialDocAssetMap.size() > 0) {
                for (String astId : serialDocAssetMap.keySet()) {
                    Asset ast = new Asset(Id=astId);
                    ast.ImageSerial__c = '<img style="width:320px" src="/servlet/servlet.FileDownload?file=' + serialDocAssetMap.get(astId) + '"/>';
                    ast.ImageSerialUploadedBy__c = UserInfo.getUserId();
                    ast.ImageSerialUploadedTime__c = Datetime.now();
                    updateAssetImgs.add(ast);
                }
            }

            if (updateAssetImgs.size() > 0) update updateAssetImgs;

            init();
            done_flg = true;
            return null;
        } catch (Exception ex) {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, ex.getMessage()+'( '+Step_status+' )'));
            Database.rollback(sp);
            for (EsdInfo esdInfo : esdList) {
                esdInfo.rec.ImageAssetBase64__c = null;
                esdInfo.rec.ImageSerialBase64__c = null;
            }
            done_flg = false;
            return null;
        }

        return null;
    }

    public class EsdInfo {
        public ReceivingNoteDetail__c rec { get; set; } //明细
        public String errorInfo { get; set; } //明细保存时发生的错误
        public boolean accessoryFlg { get; set; }  //是否是附件
        public String accessorySetId { get; set; }  //所在的一览的Id
        public Boolean discardFlg { get; set; } //是否要丢弃
        public boolean editable { get; set; } //是否可编辑
        public boolean onetoone { get; set; } //是否一对一附属品
        public Boolean hasAssetImage {get;set;}
        public Boolean hasSerialImage {get;set;}
        public Boolean hasProductImage {get;set;}

        public EsdInfo() {
            //this.locChange = false;
            this.discardFlg = false;
            this.editable = false;
            this.onetoone = false;
            //this.otoWithoutMain = false;
        }

        public EsdInfo(ReceivingNoteDetail__c rec) {
            this.rec = rec;
            this.accessoryFlg = false;
            //this.locChange = false;
            this.discardFlg = false;
            this.editable = false;
            this.hasAssetImage = false;
            this.hasSerialImage = false;
            this.hasProductImage = false;
            // 入库指示 且 未入库
            if(rec.Arrival_wh_Request_time__c != null && !rec.Arrival_in_wh__c){
                this.editable = true;
            }
            this.onetoone = false;
            if (rec.FSD_OneToOneAccessory_Cnt_F__c > 0 && rec.OneToOne_Flag__c) {
                this.onetoone = true;
            }
            if (rec.ImageAssetBase64__c != null) {
              this.hasAssetImage = true;
              rec.ImageAssetBase64__c = null;
            }
            if (rec.ImageSerialBase64__c != null) {
              this.hasSerialImage = true;
              rec.ImageSerialBase64__c = null;
            }
            if (rec.Fixture_Arrival_Process__c == '变体') {
                this.hasProductImage = String.isNotBlank(rec.Fixture_Arrival_Product__r.Image__c);
            }
            else {
                this.hasProductImage = String.isNotBlank(rec.Fixture_Set_Detail__r.Product2__r.Image__c)
                                        || String.isNotBlank(rec.RNDAssert__r.Product2.Image__c);
            }

            //this.otoWithoutMain = false;

        }
    }
}