/**********************************************************************
 * 
 *
 * @url: /services/apexrest/NFM114/execute
 * 
 * 
*************************************************************************/
@RestResource(urlMapping='/NFM114/*')
global with sharing class NFM114Rest {
    global class GeneralDates {
        public NFMUtil.Monitoring Monitoring;
        public GeneralDate[] GeneralDate;
    }

    global class GeneralDate {
        public String AgencyCode;
        public String DNNumber;
        public String DeliveryDate;
        public Detail[] Detail;
    }

    global class Detail {
        public String MaterialNumber;
        public String Batch;
        public String PackingQTY;
        public String DeliveryQTY;
        public String ValidTo;
    }
    
    @HttpPost
    global static void execute() {
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeneralDates sams = (GeneralDates) JSON.deserializeStrict(strData, GeneralDates.class);
        if (sams == null) {
            return;
        }

        NFMUtil.Monitoring Monitoring = sams.Monitoring;
        if (Monitoring == null) {
            return;
        }

        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM114', sams.GeneralDate);
        if (String.isBlank(rowData.Log__c) == false) {
            executefuture(rowData.Id);
        }
        // JSONを戻す
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        String jsonResponse = '{"status": "Success", "Message":""}';
        res.responseBody = blob.valueOf(jsonResponse);
        return;
    }

    @future
    global static void executefuture(String rowData_Id) {
        main(rowData_Id);
    }
    
    global static void main(String rowData_Id) {
        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 = 'NFM114';
        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog.Log__c = logstr;
        iflog.ErrorLog__c = '';
        insert iflog;

        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        List<GeneralDate> SamDNList = (List<GeneralDate>) JSON.deserialize(rowDataStr, List<GeneralDate>.class);
        if (SamDNList == null || SamDNList.size() == 0) {
            return;
        }
        
        Savepoint sp = Database.setSavepoint();

        try {
            List<Sample_order_list_DN__c> sampleDNList = new List<Sample_order_list_DN__c>();
            Map<String,List<Detail>> DNDetailMap = new Map<String,List<Detail>>();
            List<Sample_stock_log_sheet__c> samSheetList = new List<Sample_stock_log_sheet__c>();
            List<Sample_order_list_detail__c> samInventoryDetailList = new List<Sample_order_list_detail__c>();
            List<Sample_inventory_sheet__c> samInventorySheetList = new List<Sample_inventory_sheet__c>();

            Set<String> AgencyCodeList = new Set<String>();
            List<String> MaterialNumberList = new List<String>();
            Map<String, Account> getAccount = new Map<String, Account>();
            Map<String, Product2> getProduct = new Map<String, Product2>();
            List<String> OTCodeBatchValidToList = new List<String>();
            Map<String, Sample_inventory_sheet__c> OTCodeBatchValidToMap = new Map<String, Sample_inventory_sheet__c>();
            String AgencyCode = '';
            for(GeneralDate samDN : SamDNList){
                //传过来的AgencyCode前面有默认的几位0，通过trimLeft方法去0
                AgencyCodeList.add(NFMUtil.trimLeft(samDN.AgencyCode, '0'));
            }
            //查询出传过来的所有办事处
            List<Account> accountList = [select Id, Management_Code__c from Account where Management_Code__c IN: AgencyCodeList];
            for(Account ac : accountList){
                getAccount.put(ac.Management_Code__c, ac);
            }
            List<Sample_order_list_DN__c> samDNNumber = [select id, DNNumber__c from Sample_order_list_DN__c];
            Map<String, String> sNumberMap = new Map<String, String>();
            for(Sample_order_list_DN__c sDNNumber : samDNNumber){
                sNumberMap.put(sDNNumber.DNNumber__c, sDNNumber.id);
            }
            //生成发货单DN
            for(GeneralDate samDN : SamDNList){
                if(String.isBlank(samDN.DNNumber)) {
                    iflog.ErrorLog__c += 'Error! DNNumber[' + samDN.DNNumber + '] DeliveryNote[' + samDN.DeliveryDate + '] DNNumber is required. This data is skipped.\n';
                    continue;
                }
                if(sNumberMap.containsKey(samDN.DNNumber)){
                    iflog.ErrorLog__c += 'Error! DNNumber[' + samDN.DNNumber + '] DeliveryNote[' + samDN.DeliveryDate + '] DNNumber already exists. This data is skipped.\n';
                    continue;
                }
                if(String.isBlank(samDN.AgencyCode)) {
                    iflog.ErrorLog__c += 'Error! AgencyCode[' + samDN.AgencyCode + '] DeliveryNote[' + samDN.DeliveryDate + '] AgencyCode is required. This data is skipped.\n';
                    continue;
                }
                AgencyCode = NFMUtil.trimLeft(samDN.AgencyCode, '0');
                Sample_order_list_DN__c sampleDN = new Sample_order_list_DN__c();
                sampleDN.DNNumber__c   = samDN.DNNumber;
                sampleDN.DeliveryDate__c  = NFMUtil.parseStr2Date(samDN.DeliveryDate);
                //传过来的AgencyCode前面有默认的几位0，通过trimLeft方法去0
                sampleDN.AgencyCode__c = NFMUtil.trimLeft(samDN.AgencyCode, '0'); 
                sampleDN.Account__c = getAccount.get(NFMUtil.trimLeft(samDN.AgencyCode, '0')).Id;
                if(sampleDN != null){
                    sampleDNList.add(sampleDN);                        
                }
                for(Detail detail : samDN.Detail){
                    MaterialNumberList.add(detail.MaterialNumber);
                    OTCodeBatchValidToList.add(detail.MaterialNumber + detail.Batch + detail.ValidTo);
                }
                //先判断DN明细里的MaterialNumber和DeliveryQTY是否为空
                List<Detail> SampleDNDetailList = new List<Detail>();
                for(Detail de : samDN.Detail){
                    if (de.MaterialNumber == null || de.MaterialNumber == '') {
                        iflog.ErrorLog__c += 'Error! MaterialNumber[' + de.MaterialNumber + '] MaterialNumber is required. This data is skipped.\n';
                        continue;
                    }
                    if (de.DeliveryQTY == null || de.DeliveryQTY == '') {
                        iflog.ErrorLog__c += 'Error! DeliveryQTY[' + de.DeliveryQTY + '] DeliveryQTY is required. This data is skipped.\n';
                        continue;
                    }
                    SampleDNDetailList.add(de);
                }
                if(SampleDNDetailList.size() > 0){
                    DNDetailMap.put(samDN.DNNumber, SampleDNDetailList);
                }
            }
            if(sampleDNList.size() > 0){
                upsert sampleDNList;
            }
            //查询出传过来的所有产品
            List<Product2> ProductList = [select Id, Name, Asset_Model_No__c, Packing_list_manual__c, ProductCode, SFDA_Expiration_Date__c 
                                            from Product2 where ProductCode IN: MaterialNumberList];
            for(Product2 Product : ProductList){
                getProduct.put(Product.ProductCode, Product);
            }
            //查询传过来的OTCodeAgency是否存在
            List<Sample_inventory_sheet__c> oldsamInvetorySheetList = [select Id, Name, OTCode_Batch_ValidTo__c, Agency__c, ProductCode__c, Pro_Model__c, Inventory__c 
                                                                        from Sample_inventory_sheet__c where OTCode_Batch_ValidTo__c IN: OTCodeBatchValidToList and Agency__c =:AgencyCode];
            if(oldsamInvetorySheetList.size() > 0){
                for(Sample_inventory_sheet__c oldsamInvetorySheet : oldsamInvetorySheetList){
                    OTCodeBatchValidToMap.put(oldsamInvetorySheet.OTCode_Batch_ValidTo__c, oldsamInvetorySheet);
                }
            }
            for(Sample_order_list_DN__c sampleDN : sampleDNList){
                if(DNDetailMap.containsKey(sampleDN.DNNumber__c)){
                    for(Detail de : DNDetailMap.get(sampleDN.DNNumber__c)){
                        //获取物料号对应的产品
                        Product2 Product = getProduct.get(de.MaterialNumber);
                        //生成样本库存明细
                        Sample_order_list_detail__c samInventoryDetail = new Sample_order_list_detail__c(); 
                        //用DeveloperNam动态获取记录类型的id
                        ID recordTypeId = Schema.SObjectType.Sample_order_list_detail__c.getRecordTypeInfosByDeveloperName().get('Sample_inventory').getRecordTypeId();
                        samInventoryDetail.Product__c      = Product.Id;
                        samInventoryDetail.ItemQuantity__c = Decimal.valueOf(de.DeliveryQTY) * Product.Packing_list_manual__c;
                        samInventoryDetail.Agency__c       = sampleDN.Account__c;
                        samInventoryDetail.RecordTypeId    = recordTypeId;
                        samInventoryDetail.DN_Order__c     = sampleDN.Id;
                        samInventoryDetail.Pro_model__c    = Product.Asset_Model_No__c;
                        samInventoryDetail.Pro_Name__c     = Product.Name;
                        samInventoryDetail.Term_Date__c    = Product.SFDA_Expiration_Date__c;
                        if(samInventoryDetail != null){
                            samInventoryDetailList.add(samInventoryDetail); 
                        }
                        //生成样本库存表(盘点用)
                        String OTCodeBatchValidTo = de.MaterialNumber + de.Batch + de.ValidTo;
                        Sample_inventory_sheet__c samInventory = new Sample_inventory_sheet__c();
                        if(OTCodeBatchValidToMap.containsKey(OTCodeBatchValidTo)){
                            samInventory = OTCodeBatchValidToMap.get(OTCodeBatchValidTo);
                            samInventory.Inventory__c += Decimal.valueOf(de.DeliveryQTY) * Product.Packing_list_manual__c;
                        } else{
                            samInventory.Batch__c       = de.Batch;
                            samInventory.ValidTo__c     = NFMUtil.parseStr2Date(de.ValidTo);
                            samInventory.Agency__c      = sampleDN.Account__c;
                            samInventory.ProductCode__c = de.MaterialNumber;
                            samInventory.Pro_Model__c   = Product.Asset_Model_No__c;
                            samInventory.Inventory__c   = Decimal.valueOf(de.DeliveryQTY) * Product.Packing_list_manual__c;
                            samInventory.Product__c     = Product.Id;
                        }
                        System.debug('samInventory1：' + samInventory);
                        if(samInventory != null){
                            samInventorySheetList.add(samInventory);
                        }
                    }
                }
            }
            if(samInventoryDetailList.size() > 0){
                upsert samInventoryDetailList;
            }
            if(samInventorySheetList.size() > 0){
                upsert samInventorySheetList;
            }
            System.debug('samInventorySheetList1:'+ samInventorySheetList);
            //生成没拆分的总发货数量的样本库存记录表
            for(Sample_order_list_detail__c samInventoryDetail : samInventoryDetailList){
                Sample_stock_log_sheet__c samSheet = new Sample_stock_log_sheet__c();
                samSheet.Sample_order_list_detail__c = samInventoryDetail.Id;
                samSheet.Agency__c                   = samInventoryDetail.Agency__c;
                samSheet.Stock_Total__c              = samInventoryDetail.ItemQuantity__c;
                if(samSheet != null){
                    samSheetList.add(samSheet);
                }
            }
            if(samSheetList.size() > 0){
                upsert samSheetList;
            }
            logstr += '\nend';
            rowData.retry_cnt__c = 0;
        }catch(Exception ex){
            // エラーが発生した場合
            Database.rollback(sp);
            System.debug(Logginglevel.ERROR, 'NFM114_' +'_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM114_' +'_' + 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;
    }

}