global class CurrentPeriodPaymentAmountBatch implements Database.Batchable<sObject>, Database.Stateful {
	//HWAG-BCM5AK;---2019-06-12-XHL---
	String query;
	public List<String> idList = null;
	global CurrentPeriodPaymentAmountBatch() {

	}

	global CurrentPeriodPaymentAmountBatch(List<String> idList) {
		this.idList = idList;
	}

	global Database.QueryLocator start(Database.BatchableContext BC) {

		query =  'select Id,Name,Maintenance_Contract__c,Repair__c,PaymentAmount__c,PaymentDate__c ';
		query += ' from Repair_receipt__c  where Id != null ';
		if (idList != null && idList.size() > 0 ) {
			query += ' AND Id In :idList'	;
		}
		query += ' AND PaymentAmount__c != null '	;
		query += ' order by Repair__c,Maintenance_Contract__c';
		return Database.getQueryLocator(query);

	}

	global void execute(Database.BatchableContext BC, List<Repair_receipt__c> rrs) {

		Map<String, String> maintenanceContractIdMap = new Map<String, String>();
		Map<String, String> repairMap = new Map<String, String>();
		// Maintenance_Contract__c != 'a0H1000000JgvcAEAR' OR Repair__c != 'a0J1000000GjGefEAF'
		// a1v10000008llfBAAQ,a1v10000008llF8AAI
		for (Repair_receipt__c rr : rrs) {
			if (!'a0H1000000JgvcAEAR'.equals(rr.Maintenance_Contract__c)){
				maintenanceContractIdMap.put(rr.Maintenance_Contract__c, rr.Maintenance_Contract__c);
			}
			
			if (!'a0J1000000GjGefEAF'.equals(rr.Repair__c)){
				repairMap.put(rr.Repair__c, rr.Repair__c);
			}
			
		}

		if ( maintenanceContractIdMap.size() > 0) {
			updateObject(maintenanceContractIdMap,'Maintenance_Contract');
		}

		if ( repairMap.size() > 0) {
			updateObject(repairMap,'Repair');
		}

	}

	// public  void updateMaintenanceContract(Map<String, String> maintenanceContractIdMap) {

	// 	// List<Repair_receipt__c> repair_receiptList = [SELECT Id,Name,Maintenance_Contract__c,Repair__c,PaymentAmount__c,PaymentDate__c FROM Repair_receipt__c WHERE Maintenance_Contract__c In :maintenanceContractIdMap.keySet() ORDER BY Maintenance_Contract__c];
	// 	// Map<String,Decimal> lastIssueCumulativePaybackMap = new Map<String,Decimal>()
	// 	// Map<String,Decimal> contractCurrentPeriodPayMap = new Map<String,Decimal>();
	// 	// Integer monthNum = Date.month();
	// 	// Integer yearNum = Date.year();
	// 	// // 上期止累计回款结束日
	// 	// // Date thismonth_lastday = String.valueOf(Date.toDay().addMonths(-1).toStartOfMonth());
	// 	// Date lastFiscalYearDate;
	// 	// // 当期回款开始日
	// 	// Date thisFiscalYearDateStart;
	// 	// // 当期回款结束日
	// 	// Date thisFiscalYearDateEnd;
		
	// 	// if (monthNum < 4) {
			
	// 	// 	// 当期回款 大于等于上年的4月1日，小于本年的4月1日
	// 	// 	thisFiscalYearDateStart = Date.newInstance(yearNum-1, 4, 1);
	// 	// 	thisFiscalYearDateEnd = Date.newInstance(yearNum, 4, 1);
	// 	// 	// 上期止累计回款 小于上年的4月1日
	// 	// 	lastFiscalYearDate = Date.newInstance(yearNum-1, 4, 1);
	// 	// } else {
 //  //           // 当期回款 大于等于本年的4月1日，小于下年的4月1日
 //  //           thisFiscalYearDateStart = Date.newInstance(yearNum, 4, 1);
	// 	// 	thisFiscalYearDateEnd = Date.newInstance(yearNum+1, 4, 1);
 //  //           // 上期止累计回款 小于本年的4月1日
	// 	// 	lastFiscalYearDate = Date.newInstance(yearNum, 4, 1);
	// 	// }
	// 	// for(Repair_receipt__c rr:repair_receiptList ){

	// 	// 	if (rr.PaymentAmount__c != null ) {
	// 	// 		Decimal paybackAmount = 0.00;
	// 	// 		String keyId = rr.Maintenance_Contract__c;
	// 	// 		if (rr.PaymentDate__c < lastFiscalYearDate){
					
	// 	// 			if (lastIssueCumulativePaybackMap.containsKey(keyId)) {
	// 	// 				paybackAmount = lastIssueCumulativePaybackMap.get(keyId)
	// 	// 			}
	// 	// 			paybackAmount += rr.PaymentAmount__c;
	// 	// 			lastIssueCumulativePaybackMap.put(keyId,paybackAmount);
	// 	// 		} else if (thisFiscalYearDateStart <= rr.PaymentDate__c && thisFiscalYearDateEnd < rr.PaymentDate__c) {
	// 	// 			if (contractCurrentPeriodPayMap.containsKey(keyId)) {
	// 	// 				paybackAmount = contractCurrentPeriodPayMap.get(keyId)
	// 	// 			}
	// 	// 			paybackAmount += rr.PaymentAmount__c;
	// 	// 			contractCurrentPeriodPayMap.put(keyId,paybackAmount);
	// 	// 		}
	// 	// 	}

	// 	// }

	// 	List<Maintenance_Contract__c> mcList = [select Id, Name,
	// 	                                        LastIssueCumulativePayback__c,
	// 	                                        LastIssueCumulativePaybackAmount__c
	// 	                                        from Maintenance_Contract__c
	// 	                                        where Id In :maintenanceContractIdMap.values() And If_CumulativePayback__c = true];
	// 	if ( mcList.size() > 0 ) {

	// 		for (Maintenance_Contract__c mc : mcList) {

	// 			mc.LastIssueCumulativePaybackAmount__c = mc.LastIssueCumulativePayback__c;
	// 		}

	// 		update mcList;
	// 	}

	// }

	// public  void updateRepair(Map<String, String> repairMap) {

	// 	List<Repair__c> repairList = [select Id, Name,
	// 	                              LastIssueCumulativePayback__c,
	// 	                              LastIssueCumulativePaybackAmount__c
	// 	                              from Repair__c
	// 	                              where Id In :repairMap.values() And If_CumulativePayback__c = true];

	// 	List<Repair__c>   repairs = new  List<Repair__c>();
	// 	if (repairList.size() > 0) {

	// 		for (Repair__c rr : repairList) {

	// 			rr.LastIssueCumulativePaybackAmount__c = rr.LastIssueCumulativePayback__c;

	// 		}
	// 		update repairList;
	// 	}
		
	// 	if (repairs.size() > 0) {
	// 		update repairs;
	// 	}
	// }
	public Integer getTheFirstDayOftheMonth( Date tempDate) {
    	return tempDate.month();
    }

    public Integer getTheFirstDayOftheYear( Date tempDate) {
    	return tempDate.year();
    }

	public  void updateObject(Map<String, String> objectIdMap,String objectType){
        Boolean repairFlag = 'Repair'.equals(objectType) ? true:false;
        Set<String> idSet = objectIdMap.keySet();
        // 查找 修理或维修合同下全部的维修发票/回款 Start
		String soql =  'select Id,Name,Maintenance_Contract__c,Repair__c,PaymentAmount__c,PaymentDate__c ';
		soql += ' from Repair_receipt__c ';
		
		if (repairFlag) {
			soql += ' where Repair__c In :idSet ';
			soql += ' order by Repair__c';	
		} else {
			soql += ' where Maintenance_Contract__c In :idSet ';
			soql += ' order by Maintenance_Contract__c';
		}
		soql += ' limit 50000 ';
		System.debug('soql--->'+soql);
		List<Repair_receipt__c> repair_receiptList = Database.query(soql);
		// 查找 修理或维修合同下全部的维修发票/回款 End
		
		// 上期止累计回款 
		Map<String,Decimal> lastIssueCumulativePaybackMap = new Map<String,Decimal>();
		// 当期回款
		Map<String,Decimal> contractCurrentPeriodPayMap = new Map<String,Decimal>();
		
		// 获取 判断条件的三个日期 Start
		Integer monthNum = getTheFirstDayOftheMonth(Date.today());
		Integer yearNum = getTheFirstDayOftheYear(Date.today());
		// 上期止累计回款结束日
		Date lastFiscalYearDate;
		// 当期回款开始日
		Date thisFiscalYearDateStart;
		// 当期回款结束日
		Date thisFiscalYearDateEnd;
		
		if (monthNum < 4) {
			
			// 当期回款 大于等于上年的4月1日，小于本年的4月1日
			thisFiscalYearDateStart = Date.newInstance(yearNum-1, 4, 1);
			thisFiscalYearDateEnd = Date.newInstance(yearNum, 4, 1);
			// 上期止累计回款 小于上年的4月1日
			lastFiscalYearDate = Date.newInstance(yearNum-1, 4, 1);
		} else {
            // 当期回款 大于等于本年的4月1日，小于下年的4月1日
            thisFiscalYearDateStart = Date.newInstance(yearNum, 4, 1);
			thisFiscalYearDateEnd = Date.newInstance(yearNum+1, 4, 1);
            // 上期止累计回款 小于本年的4月1日
			lastFiscalYearDate = Date.newInstance(yearNum, 4, 1);
		}
		// 获取 判断条件的三个日期 End
		
		// 汇总 上期止上期止累计回款和当期回款	 Start
		for(Repair_receipt__c rr:repair_receiptList ){

			if (rr.PaymentAmount__c != null ) {
				Decimal paybackAmount = 0.00;
				String keyId = '';
				if (repairFlag) {
					keyId = rr.Repair__c;
				} else {
					keyId = rr.Maintenance_Contract__c;
				}
				
				if (rr.PaymentDate__c < lastFiscalYearDate){
					
					if (lastIssueCumulativePaybackMap.containsKey(keyId)) {
						paybackAmount = lastIssueCumulativePaybackMap.get(keyId);
					}
					paybackAmount += rr.PaymentAmount__c;
					lastIssueCumulativePaybackMap.put(keyId,paybackAmount);
				} else if (thisFiscalYearDateStart <= rr.PaymentDate__c && rr.PaymentDate__c < thisFiscalYearDateEnd) {
					if (contractCurrentPeriodPayMap.containsKey(keyId)) {
						paybackAmount = contractCurrentPeriodPayMap.get(keyId);
					}
					paybackAmount += rr.PaymentAmount__c;
					contractCurrentPeriodPayMap.put(keyId,paybackAmount);
				}
			}

		}
		// 汇总 上期止累计回款和当期回款	 End
		
		if (repairFlag) {
			List<Repair__c> repairList = [select Id, Name,
		                              LastIssueCumulativePayback__c,
		                              LastIssueCumulativePaybackAmount__c,
		                              CurrentPeriodPaymentAmount__c 
		                              from Repair__c
		                              where Id In :objectIdMap.keySet()];

			Map<String,Repair__c> updateRepairMap = new  Map<String,Repair__c>();
			if (repairList.size() > 0) {
				for (Repair__c rr : repairList) {
					String keyId = rr.Id;
					if (lastIssueCumulativePaybackMap.containsKey(keyId)) {
						if (lastIssueCumulativePaybackMap.get(keyId) != rr.LastIssueCumulativePaybackAmount__c) {
							rr.LastIssueCumulativePaybackAmount__c = lastIssueCumulativePaybackMap.get(keyId);
							updateRepairMap.put(keyId, rr);
						}
					} else {
						if (rr.LastIssueCumulativePaybackAmount__c != 0 ) {
							rr.LastIssueCumulativePaybackAmount__c = 0.00;
							updateRepairMap.put(keyId, rr);
						}
					}

					if (contractCurrentPeriodPayMap.containsKey(keyId)) {
						if (contractCurrentPeriodPayMap.get(keyId) != rr.CurrentPeriodPaymentAmount__c) {
							rr.CurrentPeriodPaymentAmount__c = contractCurrentPeriodPayMap.get(keyId);
							updateRepairMap.put(keyId, rr);
						}
					} else {
						if (rr.CurrentPeriodPaymentAmount__c != 0) {
							rr.CurrentPeriodPaymentAmount__c = 0.00;
							updateRepairMap.put(keyId, rr);
						}
					}
				}
			}
			if (updateRepairMap != null && updateRepairMap.size() > 0) {
				update updateRepairMap.values();
			}
			
		} else {
			List<Maintenance_Contract__c> mcList = [select Id, Name,
		                                        LastIssueCumulativePayback__c,
		                                        LastIssueCumulativePaybackAmount__c,
		                                        CurrentPeriodPaymentAmount__c 
		                                        from Maintenance_Contract__c
		                                        where Id In :objectIdMap.keySet()];
			Map<String,Maintenance_Contract__c> updateMaintenance_ContractMap = new  Map<String,Maintenance_Contract__c>();
			if ( mcList.size() > 0 ) {
				
				for (Maintenance_Contract__c mc : mcList) {
					String keyId = mc.Id;
					if (lastIssueCumulativePaybackMap.containsKey(keyId)) {
						if (lastIssueCumulativePaybackMap.get(keyId) != mc.LastIssueCumulativePaybackAmount__c) {
							mc.LastIssueCumulativePaybackAmount__c = lastIssueCumulativePaybackMap.get(mc.Id);
							updateMaintenance_ContractMap.put(keyId, mc);
						}
					} else {
						if (mc.LastIssueCumulativePaybackAmount__c != 0) {
							mc.LastIssueCumulativePaybackAmount__c = 0.00;
							updateMaintenance_ContractMap.put(keyId,mc );
						}
					}

					if (contractCurrentPeriodPayMap.containsKey(keyId)) {
						if (contractCurrentPeriodPayMap.get(keyId) != mc.CurrentPeriodPaymentAmount__c) {
							mc.CurrentPeriodPaymentAmount__c = contractCurrentPeriodPayMap.get(keyId);
							updateMaintenance_ContractMap.put(keyId, mc);
						}
					} else {
						if (mc.CurrentPeriodPaymentAmount__c != 0) {
							mc.CurrentPeriodPaymentAmount__c = 0.00;
							updateMaintenance_ContractMap.put(keyId, mc);
						}
					}
				}
			}

			if (updateMaintenance_ContractMap != null && updateMaintenance_ContractMap.size() > 0) {
				update updateMaintenance_ContractMap.values();
			}
		}
	}

	global void finish(Database.BatchableContext BC) {
		
	}

}