public with sharing class SampleInventoryController {
    public List<SIListInfo> SIInfo { get; set; }
    public boolean hasError { get; set; }
    public Integer SISize { get; set; }
    public String accId { get; set; }
    private List<Sample_inventory_sheet__c> samSheetList;

    public SampleInventoryController() {
        accId = ApexPages.currentPage().getParameters().get('accId'); 
    }
    public void init() {
        hasError = false;
        SIInfo = new List<SIListInfo>();
        Map<String, SIListInfo> SIListInfoMap = new Map<String, SIListInfo>();
        Decimal EffectiveInventoryInfo = 0;
        Decimal ExpiredInventoryInfo = 0;
        samSheetList = [select Id, Batch__c, ValidTo__c, ProductCode__c, OTCode_Batch_ValidTo__c, Agency__c, Inventory__c, Pro_Model__c,
                            Product__c, Product__r.Name, Product__r.Packing_list_manual__c, Product__r.Asset_Model_No__c
                            from Sample_inventory_sheet__c where Agency__c =: accId and Checked_ExpiredInventory__c = false];
        Account account = [select Id, Management_Code__c from Account where Id =: accId];
        if(samSheetList != null){
            for(Sample_inventory_sheet__c samSheet : samSheetList){
                if(!SIListInfoMap.containsKey(samSheet.ProductCode__c)){
                    if(samSheet.ValidTo__c >= Date.today() || samSheet.ValidTo__c == null){
                        EffectiveInventoryInfo = samSheet.Inventory__c;
                        ExpiredInventoryInfo = 0;
                    } else{
                        EffectiveInventoryInfo = 0;
                        ExpiredInventoryInfo = samSheet.Inventory__c;
                    }
                    SIListInfo info = new SIListInfo(samSheet, EffectiveInventoryInfo, ExpiredInventoryInfo, null, null);
                    SIInfo.add(info);
                    SIListInfoMap.put(samSheet.ProductCode__c, info);
                } else{
                    SIListInfo oldinfo = SIListInfoMap.get(samSheet.ProductCode__c);
                    if(samSheet.ValidTo__c >= Date.today() || samSheet.ValidTo__c == null){
                        EffectiveInventoryInfo = samSheet.Inventory__c;
                        ExpiredInventoryInfo = 0;
                    } else{
                        EffectiveInventoryInfo = 0;
                        ExpiredInventoryInfo = samSheet.Inventory__c;
                    }
                    oldinfo.EffectiveInventory += EffectiveInventoryInfo;
                    oldinfo.ExpiredInventory += ExpiredInventoryInfo;
                    SIListInfoMap.put(samSheet.ProductCode__c, oldinfo);
                    SIInfo.clear();
                    for(String ProModel : SIListInfoMap.keySet()){
                        SIListInfo info = SIListInfoMap.get(ProModel);
                        SIInfo.add(info);
                    }
                }
            }
            //传递样本数据数量
            SISize = SIListInfoMap.size();
        }
    }
    public PageReference InventoryConfirm() {
        List<Sample_order_list_detail__c> insertList = new List<Sample_order_list_detail__c>();
        List<Sample_inventory_sheet__c> newsamSheetList = new List<Sample_inventory_sheet__c>();
        List<Sample_stock_log_sheet__c> newsamStockList = new List<Sample_stock_log_sheet__c>();
        Map<String, Decimal> AmountChangeMap = new Map<String, Decimal>();
        Decimal AmountChange = 0;
        //生成盘点表头
        Inventory_Header_New__c InventoryHeader = new Inventory_Header_New__c();
        InventoryHeader.Account__c = accId;
        if(InventoryHeader != null){
            upsert InventoryHeader;
        }
        for (SIListInfo SIfo : SIInfo) {
            if (SIfo.IFCount) {
                //生成盘点表头明细
                Sample_order_list_detail__c samOrderDetail = new Sample_order_list_detail__c();
                ID recordTypeId = Schema.SObjectType.Sample_order_list_detail__c.getRecordTypeInfosByDeveloperName().get('Inventory').getRecordTypeId();
                samOrderDetail.ItemQuantity__c        = SIfo.EffectiveInventory + SIfo.ExpiredInventory;
                samOrderDetail.Pro_Name__c            = SIfo.ProductName;
                samOrderDetail.Standards__c           = SIfo.ProductSpecs;
                samOrderDetail.Inventory_Check__c     = SIfo.Check;
                samOrderDetail.RecordTypeId           = recordTypeId;
                samOrderDetail.Agency__c              = accId;
                samOrderDetail.Inventory_Header__c    = InventoryHeader.Id;
                samOrderDetail.Product__c             = SIfo.SISheet.Product__c;
                System.debug('samOrderDetail.Product__c1:' + samOrderDetail.Product__c);
                samOrderDetail.Pro_model__c           = SIfo.SISheet.Product__r.Asset_Model_No__c;
                insertList.add(samOrderDetail);
                //盘点的时候把过期库存全部去掉
                for(Sample_inventory_sheet__c samSheet : samSheetList){
                    if(samSheet.ProductCode__c == SIfo.OTCode && samSheet.ValidTo__c < Date.today() ){
                        samSheet.Inventory__c = 0;
                        samSheet.Checked_ExpiredInventory__c = true;
                        newsamSheetList.add(samSheet);
                    }
                }
                if(SIfo.Check < SIfo.EffectiveInventory){
                    AmountChange = SIfo.EffectiveInventory - SIfo.Check;
                    AmountChangeMap.put(SIfo.OTCode, AmountChange);
                    for(Sample_inventory_sheet__c samSheet : samSheetList){
                        if(samSheet.ProductCode__c == SIfo.OTCode && (samSheet.ValidTo__c > Date.today() || samSheet.ValidTo__c == null)){
                            AmountChange = AmountChangeMap.get(samSheet.ProductCode__c);
                            if(samSheet.Inventory__c >= AmountChange){
                                samSheet.Inventory__c -= AmountChange;
                                newsamSheetList.add(samSheet);
                                break;
                            } else{
                                samSheet.Inventory__c = 0;
                                AmountChange -= samSheet.Inventory__c;
                                AmountChangeMap.put(samSheet.ProductCode__c, AmountChange);
                                newsamSheetList.add(samSheet);
                            }
                        }
                    }
                }
            }
        }                
        Savepoint sp = Database.setSavepoint();
        try {
            if(insertList.size() > 0) {
                upsert insertList;
            }
            //生成样本库存记录表,关联办事处和盘点表头明细
            for(Sample_order_list_detail__c checkDetail : insertList){
                Sample_stock_log_sheet__c samStockSheet = new Sample_stock_log_sheet__c();
                samStockSheet.Sample_order_list_detail__c = checkDetail.Id;
                samStockSheet.Agency__c = checkDetail.Agency__c;
                AmountChange = AmountChangeMap.get(checkDetail.Product__r.ProductCode);
                samStockSheet.Stock_Total__c = checkDetail.Inventory_Check__c;
                newsamStockList.add(samStockSheet);
            }
            if(newsamSheetList.size() > 0){
                upsert newsamSheetList;
            }
            if(newsamStockList.size() > 0){
                upsert newsamStockList;
            }
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Info, '盘点完了。'));
            //测试类可以进catch
            if (System.Test.isRunningTest()) {
                throw new ControllerUtil.myException('aaa');
            }
        } catch (System.Exception e) {
            Database.rollback(sp);
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, e.getMessage()));
            hasError = true;
            return null;
        }
        return new Pagereference('/'+InventoryHeader.Id);
    }

    public class SIListInfo{
        public Boolean IFCount { get; set; }
        public Decimal Check { get; set; }
        public Decimal EffectiveInventory { get; set; }
        public Decimal ExpiredInventory { get; set; }
        public Sample_inventory_sheet__c SISheet { get; set; }
        public String ProductName { get; set; }
        public Decimal ProductSpecs { get; set; }
        public String OTCode { get; set; }
        public SIListInfo(Sample_inventory_sheet__c samSheetInfo, Decimal EffectiveInventoryInfo, Decimal ExpiredInventoryInfo, Boolean IFCountInfo, Decimal CheckInfo){
            IFCount = IFCountInfo;
            Check   = CheckInfo;
            SISheet = samSheetInfo;
            ProductName = samSheetInfo.Product__r.Name;
            ProductSpecs = samSheetInfo.Product__r.Packing_list_manual__c;
            OTCode = samSheetInfo.ProductCode__c;
            EffectiveInventory = EffectiveInventoryInfo;
            ExpiredInventory = ExpiredInventoryInfo;
        }
    }
}