package com.bankaudit.rest.process.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.jboss.logging.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bankaudit.constants.BankAuditConstant;
import com.bankaudit.dto.process.AuditGradingBasicDtlsDto;
import com.bankaudit.dto.process.AuditGradingDto;
import com.bankaudit.model.MaintGradingParamScoreMatrix;
import com.bankaudit.model.MaintGradingQsnBasicDtls;
import com.bankaudit.model.MaintGradingQsnDtls;
import com.bankaudit.model.User;
import com.bankaudit.process.model.AuditGradingParamCompositeRatingDtls;
import com.bankaudit.process.model.AuditGradingParamDtls;
import com.bankaudit.process.model.AuditGradingQsnBasicDtls;
import com.bankaudit.process.model.AuditGradingQsnDtls;
import com.bankaudit.process.model.AuditGradingQsnRemarks;
import com.bankaudit.process.model.AuditGradingQsoDtlsHO;
import com.bankaudit.process.model.AuditGradingQsoDtlsRO;
import com.bankaudit.process.model.AuditLetterUserInputs;
import com.bankaudit.process.model.AuditLetterUserInputsWrk;
import com.bankaudit.process.model.AuditRating;
import com.bankaudit.process.model.AuditSchedule;
import com.bankaudit.process.model.AuditScheduleStagesStatusHst;
import com.bankaudit.process.model.AuditScheduleStatus;
import com.bankaudit.rest.process.dao.AuditGradingDao;
import com.bankaudit.service.BusinessDateService;
import com.bankaudit.service.UserService;
import com.bankaudit.util.BankAuditUtil;

@Service("auditGradingService")
@Transactional("transactionManager")
public class AuditGradingServiceImpl implements AuditGradingService  {

	static final Logger logger = Logger.getLogger(AuditGradingService.class);
	
	@Autowired
	AuditGradingDao auditGradingDao;
	
	@Autowired
	InterfaceParameterService interfaceParameterService;
	
	@Autowired
	BusinessDateService businessDateService;
	 	
	@Autowired
	UserService userService;
	
	@Autowired
	AuditScheduleStagesStatusHstService  auditScheduleStagesStatusHstService; 
	
    public String initiateAuditGrading(Integer legalEntityCode, String auditTypeCode, String auditId, String unitId, String userId, String role, String userUnitType){
    	logger.info("Inside initiateAuditGrading .. "+legalEntityCode +" :: "+auditTypeCode+" :: "+auditId+" :: "+userId+" :: "+role+" :: "+userUnitType );
    	try{
    		
    		auditGradingDao.cleanUpBeforeInitiateGrading(legalEntityCode, auditTypeCode, auditId);
    		Map<String, String> parameterMap = interfaceParameterService.getProfileDetailsByAuditId(legalEntityCode, auditId, null);
    		List<MaintGradingQsnBasicDtls> maintGradingQsnBasicDtlsList = auditGradingDao.getMaintGradingQsnBasicDtls(legalEntityCode, auditTypeCode);
    		AuditGradingBasicDtlsDto auditGradingBasicDtlsDto = auditGradingDao.getAuditDetails(legalEntityCode, auditTypeCode, auditId);
    		auditGradingBasicDtlsDto.setSponsorBankName(parameterMap.get("3BOM-121"));
    		List<MaintGradingQsnDtls> maintGradingQsnDtlsList = auditGradingDao.getMaintGradingQsnDetails(legalEntityCode, auditTypeCode);
	    	List<Object[]> qsnDynamicValueDtlsList =auditGradingDao.getAuditGradingDynamicMappingDetails(legalEntityCode, auditTypeCode, auditId);
	    	Map<String, String>  qsnDynamicValueDtlsMap = qsnDynamicValueDtlsList.stream().collect(Collectors.groupingBy(
								(key->key[0]+""+key[1]+""+key[2]+""+key[3]), 
								Collectors.mapping(value->value[4]+"",
										Collectors.joining(System.getProperty("line.separator"))))); 
	    		    	
	    	for (MaintGradingQsnBasicDtls maintGradingQsnBasicDtls : maintGradingQsnBasicDtlsList) {
	    		AuditGradingQsnBasicDtls auditGradingQsnBasicDtls = new AuditGradingQsnBasicDtls();
	    		BeanUtils.copyProperties(maintGradingQsnBasicDtls, auditGradingQsnBasicDtls); 
	    		auditGradingQsnBasicDtls.setAuditId(auditId);
	    		auditGradingQsnBasicDtls.setCheckboxValue(BankAuditConstant.NO);
	    		auditGradingQsnBasicDtls.setCheckboxHO(auditGradingQsnBasicDtls.getCheckbox());
	    		auditGradingQsnBasicDtls.setCheckboxValueHO(BankAuditConstant.NO);
	    		auditGradingQsnBasicDtls.setDisplaySequenceId(auditGradingQsnBasicDtls.getDispSeqNo());
	    		if(!BankAuditUtil.isEmptyString(maintGradingQsnBasicDtls.getDisplayValueKey())){
		    		String displayValueKey = maintGradingQsnBasicDtls.getDisplayValueKey();				 
					Object displayValueKeyObject = org.apache.commons.beanutils.PropertyUtils.getSimpleProperty(auditGradingBasicDtlsDto, displayValueKey);
					if(displayValueKeyObject!=null && !"".equals(displayValueKeyObject.toString())){ 
						auditGradingQsnBasicDtls.setQsnValue(displayValueKeyObject.toString());
					} 			
	    		}
	    		if(BankAuditConstant.GRADING_QSN_DISPLAY_TYPE_DYNAMIC.equalsIgnoreCase(maintGradingQsnBasicDtls.getDisplayContentType())){
	    			auditGradingQsnBasicDtls.setQsnValueDynamicFetch(maintGradingQsnBasicDtls.getDisplayContent());		    			
	    			if(BankAuditConstant.UNIT_TYPE_HO.equalsIgnoreCase(userUnitType)){ 
	    				auditGradingQsnBasicDtls.setQsnValueDynamicUpdateStage1HO(maintGradingQsnBasicDtls.getDisplayContent());
					}else{
						auditGradingQsnBasicDtls.setQsnValueDynamicUpdateStage1(maintGradingQsnBasicDtls.getDisplayContent()); 
					}
	    			
	    		}
				auditGradingDao.save(auditGradingQsnBasicDtls);
			}
	    		    	
			for (MaintGradingQsnDtls maintGradingQsnDtls : maintGradingQsnDtlsList) {
				AuditGradingQsnDtls auditGradingQsnDtls = new AuditGradingQsnDtls();
				BeanUtils.copyProperties(maintGradingQsnDtls, auditGradingQsnDtls);
				
				auditGradingQsnDtls.setAuditId(auditId);
				auditGradingQsnDtls.setQsnContentType(maintGradingQsnDtls.getDisplayContentType());
				auditGradingQsnDtls.setQsnContent(maintGradingQsnDtls.getDisplayContent());				
				auditGradingQsnDtls.setQsnValueType(maintGradingQsnDtls.getDisplayValueType());				 
				auditGradingQsnDtls.setQsnValue(parameterMap.get(maintGradingQsnDtls.getDisplayValueRefId()));	 			
				String qsnDynamicValueKey = legalEntityCode+auditTypeCode+auditId+maintGradingQsnDtls.getDisplaySequenceRef();				
				auditGradingQsnDtls.setQsnValueDynamicFetch(qsnDynamicValueDtlsMap.get(qsnDynamicValueKey));				
				if(BankAuditConstant.UNIT_TYPE_HO.equalsIgnoreCase(userUnitType)){
					auditGradingQsnDtls.setQsnValueDynamicUpdateStage1HO(qsnDynamicValueDtlsMap.get(qsnDynamicValueKey));
				}else{
					auditGradingQsnDtls.setQsnValueDynamicUpdateStage1(qsnDynamicValueDtlsMap.get(qsnDynamicValueKey));
				}
				auditGradingQsnDtls.setCheckbox(maintGradingQsnDtls.getCheckbox());
				auditGradingQsnDtls.setCheckboxValue(BankAuditConstant.NO);
				auditGradingQsnDtls.setCheckboxHO(auditGradingQsnDtls.getCheckbox());
				auditGradingQsnDtls.setCheckboxValueHO(BankAuditConstant.NO);
				
				auditGradingDao.save(auditGradingQsnDtls);
	    	}
			
			auditGradingDao.insertParamDtlsIntoAuditGradingParamDtls(legalEntityCode, auditTypeCode, auditId);
			storeToAuditGradingParamCompositeRatingDtls(legalEntityCode, auditTypeCode, auditId);
			
			Map<String, Object> properties = new HashMap<String, Object>();
			properties.put("legalEntityCode", legalEntityCode);
			properties.put("auditTypeCode", auditTypeCode);
			properties.put("auditId", auditId);
			AuditSchedule auditSchedule = (AuditSchedule)auditGradingDao.getUniqueEntityByMatchingProperties(AuditSchedule.class, properties);			
			AuditScheduleStatus auditScheduleStatus = (AuditScheduleStatus)auditGradingDao.getUniqueEntityByMatchingProperties(AuditScheduleStatus.class, properties);
			if(auditScheduleStatus == null){
				auditScheduleStatus =  new AuditScheduleStatus();
				auditScheduleStatus.setLegalEntityCode(legalEntityCode);
				auditScheduleStatus.setAuditTypeCode(auditTypeCode);
				auditScheduleStatus.setAuditId(auditId);
				auditScheduleStatus.setUnitId(unitId);				
			}
			Date businessDate = businessDateService.getBusinessDateTimestampByLegalEntityCode(legalEntityCode);
			auditScheduleStatus.setGradingStatus(BankAuditConstant.GRADING_STATUS_IN_PROGRESS);
			String  gradingStatusRoHO = null;
			if(BankAuditConstant.UNIT_TYPE_RO.equalsIgnoreCase(userUnitType)){						
				auditScheduleStatus.setGradingMakerRO(userId);	
				auditScheduleStatus.setGradingMakerTimestampRO(businessDate);
				auditScheduleStatus.setGradingStatusRO(BankAuditConstant.GRADING_STATUS_RO_UNAUTH);
				gradingStatusRoHO = BankAuditConstant.GRADING_STATUS_RO_UNAUTH;
			}else{
				auditScheduleStatus.setGradingMakerHO(userId);
				auditScheduleStatus.setGradingMakerTimestampHO(businessDate);
				auditScheduleStatus.setGradingStatusHO(BankAuditConstant.GRADING_STATUS_HO_UNAUTH);
				gradingStatusRoHO = BankAuditConstant.GRADING_STATUS_HO_UNAUTH;
			} 
			auditGradingDao.flushSession();
			auditGradingDao.saveOrUpdate(auditScheduleStatus);
						
			properties.put("letterCode", BankAuditConstant.LETTER_CODE_IR_GRADING);
			AuditLetterUserInputsWrk  auditLetterUserInputsWrk = (AuditLetterUserInputsWrk) auditGradingDao.getUniqueEntityByMatchingProperties(AuditLetterUserInputsWrk.class, properties);
			auditLetterUserInputsWrk.setStatus(BankAuditConstant.GRADING_STATUS_IN_PROGRESS);
			auditLetterUserInputsWrk.setMaker(userId);
			auditLetterUserInputsWrk.setGradingStatus(gradingStatusRoHO);
			auditGradingDao.flushSession();
			auditGradingDao.update(auditLetterUserInputsWrk);	
			
			AuditScheduleStagesStatusHst auditScheduleStagesStatusHst = new AuditScheduleStagesStatusHst();
			auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING);
			auditScheduleStagesStatusHst.setStagesStatus(gradingStatusRoHO);
			auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_GRADING); 
			
			auditSchedule.setActionMakerId(userId);
			auditSchedule.setActionMakerRole(role); 
			auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);
 
    	}catch (Exception ex) { 
	    	logger.error(ex);
			return BankAuditConstant.FAILED;
		}
    	return BankAuditConstant.SUCCESS;
    }	
    
    @Override
	public AuditGradingDto getMyAuditGrading(Integer legalEntityCode, String auditTypeCode, String auditId, String userUnitType){
    	try{
    		if(BankAuditConstant.UNIT_TYPE_RO.equalsIgnoreCase(userUnitType)){
    			storeToAuditGradingParamCompositeRatingDtls(legalEntityCode, auditTypeCode, auditId);
    		}
	    	Map<String, Object> properties = new HashMap<String, Object>();
			properties.put("legalEntityCode", legalEntityCode);
			properties.put("auditTypeCode", auditTypeCode);
			properties.put("auditId", auditId);			
			AuditScheduleStatus auditScheduleStatus = (AuditScheduleStatus)auditGradingDao.getUniqueEntityByMatchingProperties(AuditScheduleStatus.class, properties);
			
			AuditGradingDto  auditGradingDto = auditGradingDao.getMyAuditGrading(legalEntityCode, auditTypeCode, auditId, userUnitType);
			auditGradingDto.setAuditScheduleStatus(auditScheduleStatus);		
		
			properties.put("letterCode", BankAuditConstant.LETTER_CODE_IR_GRADING);
			AuditLetterUserInputsWrk  auditLetterUserInputsWrk = (AuditLetterUserInputsWrk) auditGradingDao.getUniqueEntityByMatchingProperties(AuditLetterUserInputsWrk.class, properties);
			Map<String, String> parameterMap = interfaceParameterService.getProfileDetailsByAuditId(legalEntityCode, auditId, null);		
			
			auditGradingDto.setLegalEntityCode(legalEntityCode);
			auditGradingDto.setAuditTypeCode(auditTypeCode);
			auditGradingDto.setAuditId(auditId);
			auditGradingDto.setUnitId(auditScheduleStatus.getUnitId());
			if(auditLetterUserInputsWrk != null){
				auditGradingDto.setReviewerId(auditLetterUserInputsWrk.getReviewer());
				auditGradingDto.setGradingStatus(auditLetterUserInputsWrk.getGradingStatus());
			}else{
				AuditLetterUserInputs  auditLetterUserInputs = (AuditLetterUserInputs) auditGradingDao.getUniqueEntityByMatchingProperties(AuditLetterUserInputs.class, properties);
				auditGradingDto.setReviewerId(auditLetterUserInputs.getReviewer());
				auditGradingDto.setGradingStatus(auditLetterUserInputs.getGradingStatus());
			}
			auditGradingDto.setParameterMap(parameterMap);
	    	
	    	return auditGradingDto; 
    	}catch (Exception e) {
    		e.printStackTrace();
	    	logger.error(e);
			return null;
		}
    }
	 
    @Override
    public String saveAuditGrading(AuditGradingDto auditGradingDto){
    	 
    	Integer legalEntityCode = auditGradingDto.getLegalEntityCode();
    	String auditTypeCode = auditGradingDto.getAuditTypeCode();
    	String auditId = auditGradingDto.getAuditId();
    	String userId = auditGradingDto.getUserId(); 
    	String reviewerId = auditGradingDto.getReviewerId();
    	String userUnitType = auditGradingDto.getUserUnitType();
    	String gradingStatus = auditGradingDto.getGradingStatus();  
	    try{ 	
	    	AuditScheduleStatus  auditScheduleStatus =  auditGradingDto.getAuditScheduleStatus();
	    	Map<String, AuditGradingQsnDtls> auditGradingQsnDtlsMap = auditGradingDto.getAuditGradingQsnDtlsMap();
	    	Map<String, AuditGradingQsnBasicDtls> auditGradingQsnBasicDtlsMap = auditGradingDto.getAuditGradingQsnBasicDtlsMap();
	    	List<AuditGradingQsoDtlsRO> auditGradingQsoDtlsROList = auditGradingDto.getAuditGradingQsoDtlsROList();
	    	List<AuditGradingQsoDtlsHO> auditGradingQsoDtlsHOList = auditGradingDto.getAuditGradingQsoDtlsHOList();	    	
	    	List<AuditGradingParamDtls> auditGradingParamDtlsList = auditGradingDto.getAuditGradingParamDtlsList(); 
	    	AuditGradingQsnRemarks auditGradingQsnRemarks = auditGradingDto.getAuditGradingQsnRemarks();	 	    	
	    	Date businessDate = businessDateService.getBusinessDateTimestampByLegalEntityCode(legalEntityCode);
	    		    	
	    	Map<String, Object> properties = new HashMap<String, Object>();
			properties.put("legalEntityCode", legalEntityCode);
			properties.put("auditTypeCode", auditTypeCode);
			properties.put("auditId", auditId);
			AuditSchedule auditSchedule = (AuditSchedule)auditGradingDao.getUniqueEntityByMatchingProperties(AuditSchedule.class, properties);			 
			
			//auditSchedule.setUserId(userId);
			auditSchedule.setActionMakerRole(auditGradingDto.getRole());
			auditSchedule.setActionMakerId(userId);
			
			properties.put("letterCode", BankAuditConstant.LETTER_CODE_IR_GRADING);
    		AuditLetterUserInputsWrk  auditLetterUserInputsWrk = (AuditLetterUserInputsWrk) auditGradingDao.getUniqueEntityByMatchingProperties(AuditLetterUserInputsWrk.class, properties);
    		auditLetterUserInputsWrk.setGradingStatus(gradingStatus); 

			AuditScheduleStagesStatusHst auditScheduleStagesStatusHst = new AuditScheduleStagesStatusHst();
    		String gradingStatusRO = auditScheduleStatus.getGradingStatusRO(); 
    		String gradingStatusHO = auditScheduleStatus.getGradingStatusHO(); 
    		Map<String, Object> auditSchStagesStatusHstProperties = new HashMap<String, Object>();
			auditSchStagesStatusHstProperties.put("legalEntityCode", legalEntityCode);
			auditSchStagesStatusHstProperties.put("auditTypeCode", auditTypeCode);
			auditSchStagesStatusHstProperties.put("auditId", auditId);
			auditSchStagesStatusHstProperties.put("code", BankAuditConstant.LETTER_CODE_IR_GRADING);			
			auditSchStagesStatusHstProperties.put("actionType", BankAuditConstant.ACTION_TYPE_GRADING);
	    	if(BankAuditConstant.UNIT_TYPE_RO.equalsIgnoreCase(userUnitType)){
				auditScheduleStatus.setGradingStatusRO(gradingStatus);			
				if(BankAuditConstant.GRADING_STATUS_RO_UNAUTH.equalsIgnoreCase(gradingStatus)
						|| BankAuditConstant.GRADING_STATUS_RO_SUBMITTED.equalsIgnoreCase(gradingStatus)){
					auditScheduleStatus.setGradingMakerRO(userId);
					auditScheduleStatus.setGradingMakerTimestampRO(businessDate); 					
					if(BankAuditConstant.GRADING_STATUS_RO_SUBMITTED.equalsIgnoreCase(gradingStatus)){
						auditSchStagesStatusHstProperties.put("stagesStatus", gradingStatus);
						if(!BankAuditUtil.isEmptyString(reviewerId)){
							auditSchStagesStatusHstProperties.put("assigneeId", reviewerId);
							auditSchedule.setAssigneeId(reviewerId);
							auditScheduleStagesStatusHst.setAssigneeRole("G12"); 
						}						
						AuditScheduleStagesStatusHst  auditScheduleStagesStatusHstChk = 
								(AuditScheduleStagesStatusHst) auditGradingDao.getUniqueEntityByMatchingProperties(AuditScheduleStagesStatusHst.class, auditSchStagesStatusHstProperties);
						if(auditScheduleStagesStatusHstChk != null){ 
							auditScheduleStagesStatusHst.setId(auditScheduleStagesStatusHstChk.getId());
						} 
						auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING);
						auditScheduleStagesStatusHst.setStagesStatus(gradingStatus);
						auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_GRADING);						
						auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);		
					}
				}else{
					auditScheduleStatus.setGradingCheckerRO(userId);
					auditScheduleStatus.setGradingCheckerTimestampRO(businessDate); 
				}			
			}else if(BankAuditConstant.UNIT_TYPE_HO.equalsIgnoreCase(userUnitType)){
				auditScheduleStatus.setGradingStatusHO(gradingStatus);
				if(BankAuditConstant.GRADING_STATUS_HO_UNAUTH.equalsIgnoreCase(gradingStatus)
						|| BankAuditConstant.GRADING_STATUS_HO_SUBMITTED.equalsIgnoreCase(gradingStatus)){
					auditScheduleStatus.setGradingMakerHO(userId);
					auditScheduleStatus.setGradingMakerTimestampHO(businessDate);					
									
					auditSchStagesStatusHstProperties.put("stagesStatus", gradingStatus);
					if(BankAuditConstant.GRADING_STATUS_HO_UNAUTH.equalsIgnoreCase(gradingStatus)){						
						AuditScheduleStagesStatusHst  auditScheduleStagesStatusHstChk = 
								(AuditScheduleStagesStatusHst) auditGradingDao.getUniqueEntityByMatchingProperties(AuditScheduleStagesStatusHst.class, auditSchStagesStatusHstProperties);
						if(auditScheduleStagesStatusHstChk == null){ 
							auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING);
							auditScheduleStagesStatusHst.setStagesStatus(BankAuditConstant.GRADING_STATUS_HO_UNAUTH);
							auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_GRADING);
							auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);
						}
					}else{						 
						if(!BankAuditUtil.isEmptyString(reviewerId)){
							auditSchStagesStatusHstProperties.put("assigneeId", reviewerId);
							auditSchedule.setAssigneeId(reviewerId);
							auditScheduleStagesStatusHst.setAssigneeRole("G12"); 
						}						
						AuditScheduleStagesStatusHst  auditScheduleStagesStatusHstChk = 
								(AuditScheduleStagesStatusHst) auditGradingDao.getUniqueEntityByMatchingProperties(AuditScheduleStagesStatusHst.class, auditSchStagesStatusHstProperties);
						if(auditScheduleStagesStatusHstChk != null){ 
							auditScheduleStagesStatusHst.setId(auditScheduleStagesStatusHstChk.getId());
						} 
						auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING);
						auditScheduleStagesStatusHst.setStagesStatus(gradingStatus);
						auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_GRADING);						
						auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);					 
					}					
				}else{
					auditScheduleStatus.setGradingStatus(BankAuditConstant.GRADING_STATUS_CLOSED);
					auditScheduleStatus.setGradingCheckerHO(userId);
					auditScheduleStatus.setGradingCheckerTimestampHO(businessDate);
				}
			}else{
				return BankAuditConstant.FAILED; 
			}
	    	
	    	auditGradingDao.saveOrUpdate(auditScheduleStatus);
	    	if(auditGradingQsnRemarks!=null && auditGradingQsnRemarks.getMaker()!=null){
	    		User user  = userService.getUserByLegalEntityCodeAndUserId(legalEntityCode, userId);
	    		if(user!=null){
	    			auditGradingQsnRemarks.setDesignation(user.getDesignation());
	    		}
	    		auditGradingQsnRemarks.setMakerTimestamp(businessDate);
	    		auditGradingQsnRemarks.setUserUnitType(userUnitType);
	    		auditGradingDao.saveOrUpdate(auditGradingQsnRemarks);	    	 	    	
	    	}
	    	
	    	if(BankAuditConstant.UNIT_TYPE_HO.equalsIgnoreCase(userUnitType)){
	    		List<AuditGradingParamCompositeRatingDtls> auditGradingParamCompositeRatingDtlsList =  auditGradingDto.getAuditGradingParamCompositeRatingDtlsList();
		    	for (AuditGradingParamCompositeRatingDtls auditGradingParamCompositeRatingDtls : auditGradingParamCompositeRatingDtlsList) {
		    		auditGradingDao.saveOrUpdate(auditGradingParamCompositeRatingDtls);
				}
	    	}
	    		    	
	    	if(BankAuditConstant.GRADING_STATUS_RO_UNAUTH.equalsIgnoreCase(gradingStatus)
	    			|| BankAuditConstant.GRADING_STATUS_HO_UNAUTH.equalsIgnoreCase(gradingStatus)){   		
	    		
	    		if(BankAuditConstant.GRADING_STATUS_RO_UNAUTH.equalsIgnoreCase(gradingStatus)
	    				&& BankAuditConstant.UNIT_TYPE_RO.equalsIgnoreCase(userUnitType)){
	    			auditGradingDao.deleteAuditGradingQsoDtlsRO(legalEntityCode, auditTypeCode, auditId);
		    		for(AuditGradingQsoDtlsRO auditGradingQsoDtlsRO : auditGradingQsoDtlsROList){
		    			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsRO);
		    		}
	    		}else if(BankAuditConstant.GRADING_STATUS_HO_UNAUTH.equalsIgnoreCase(gradingStatus)
	    				&& BankAuditConstant.UNIT_TYPE_HO.equalsIgnoreCase(userUnitType)){
	    			auditGradingDao.deleteAuditGradingQsoDtlsHO(legalEntityCode, auditTypeCode, auditId);
	    			for(AuditGradingQsoDtlsHO auditGradingQsoDtlsHO : auditGradingQsoDtlsHOList){
		    			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsHO);
		    		}
	    		}		    	
	    		
	    		for(Map.Entry<String, AuditGradingQsnDtls> auditGradingQsnDtls: auditGradingQsnDtlsMap.entrySet()){
	    			auditGradingDao.saveOrUpdate(auditGradingQsnDtls.getValue());
	    		}
	    		
	    		for(Map.Entry<String, AuditGradingQsnBasicDtls> auditGradingQsnBasicDtls: auditGradingQsnBasicDtlsMap.entrySet()){
	    			auditGradingDao.saveOrUpdate(auditGradingQsnBasicDtls.getValue());
	    		} 		
	    		
	    		for(AuditGradingParamDtls auditGradingParamDtls : auditGradingParamDtlsList){
	    			auditGradingDao.saveOrUpdate(auditGradingParamDtls);
	    		} 	    		    		
	    		
	    	}else if(BankAuditConstant.GRADING_STATUS_RO_SUBMITTED.equalsIgnoreCase(gradingStatus)
	    			|| BankAuditConstant.GRADING_STATUS_HO_SUBMITTED.equalsIgnoreCase(gradingStatus)){
	    		
	    		auditLetterUserInputsWrk.setReviewer(reviewerId);
	    		auditGradingDao.saveOrUpdate(auditLetterUserInputsWrk);	    	 
	    		if(BankAuditConstant.UNIT_TYPE_RO.equalsIgnoreCase(userUnitType)){    			
	    			
	    			if(BankAuditConstant.GRADING_STATUS_RO_UNAUTH.equalsIgnoreCase(gradingStatusRO)){
	    				auditGradingDao.deleteAuditGradingQsoDtlsRO(legalEntityCode, auditTypeCode, auditId);
	    			}
	    			for(AuditGradingQsnDtls  auditGradingQsnDtls: auditGradingQsnDtlsMap.values()){ 
	    				if(BankAuditUtil.isEmptyString(auditGradingQsnDtls.getQsnValueDynamicUpdateRO())){
	    					auditGradingQsnDtls.setQsnValueDynamicUpdateRO(auditGradingQsnDtls.getQsnValueDynamicUpdateStage1());
	    					auditGradingQsnDtls.setQsnReferenceRO(auditGradingQsnDtls.getQsnReferenceStage1());
	    				}
	        			auditGradingDao.saveOrUpdate(auditGradingQsnDtls);
	        		}
	    			
	    			for(AuditGradingQsnBasicDtls auditGradingQsnBasicDtls: auditGradingQsnBasicDtlsMap.values()){
	    				if(BankAuditUtil.isEmptyString(auditGradingQsnBasicDtls.getQsnValueDynamicUpdateRO())){
	    					auditGradingQsnBasicDtls.setQsnValueDynamicUpdateRO(auditGradingQsnBasicDtls.getQsnValueDynamicUpdateStage1());
	    					auditGradingQsnBasicDtls.setQsnReferenceRO(auditGradingQsnBasicDtls.getQsnReferenceStage1());
	    				}
		    			auditGradingDao.saveOrUpdate(auditGradingQsnBasicDtls);
		    		}
	    			
	    			for(AuditGradingQsoDtlsRO auditGradingQsoDtlsRO : auditGradingQsoDtlsROList){
	    				if(BankAuditUtil.isEmptyString(auditGradingQsoDtlsRO.getQsoValueDynamicUpdateRO())){
	    					auditGradingQsoDtlsRO.setQsoValueDynamicUpdateRO(auditGradingQsoDtlsRO.getQsoValueDynamicUpdateStage1());	    						    					
	    					//auditGradingQsoDtls.setStatusStage1RO(BankAuditConstant.STATUS_AUTH); //uncomment at time add delete qso
	    				}
	    				if(!BankAuditConstant.STATUS_DEL.equalsIgnoreCase(auditGradingQsoDtlsRO.getStatus())
	    						&& BankAuditConstant.GRADING_STATUS_RO_UNAUTH.equalsIgnoreCase(gradingStatusRO)){
    						auditGradingQsoDtlsRO.setStatus(BankAuditConstant.STATUS_AUTH);    						
    					}/*if(BankAuditConstant.STATUS_DEL.equalsIgnoreCase(auditGradingQsoDtlsRO.getStatus())){
    						//auditGradingQsoDtlsRO.setQsoSequenceId(auditGradingQsoDtlsRO.getQsoSequenceId()+"-"+random.nextInt(10000)+""+(random.nextFloat()));
    					}*/
	        			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsRO);
	        		}
	        		
	        		for(AuditGradingParamDtls auditGradingParamDtls : auditGradingParamDtlsList){
	        			if(auditGradingParamDtls.getScoreEffectiveRO()==null){
	        				auditGradingParamDtls.setScoreEffectiveRO(auditGradingParamDtls.getScoreEffective());
	        			}
	        			auditGradingDao.saveOrUpdate(auditGradingParamDtls);
	        		}	        		  	        		 
	    		}else{
	    			
	    			if(BankAuditConstant.GRADING_STATUS_HO_UNAUTH.equalsIgnoreCase(gradingStatusHO)){
	    				auditGradingDao.deleteAuditGradingQsoDtlsHO(legalEntityCode, auditTypeCode, auditId);
	    			}
	    			for(AuditGradingQsnDtls  auditGradingQsnDtls: auditGradingQsnDtlsMap.values()){  
	    				if((BankAuditUtil.isEmptyString(auditScheduleStatus.getGradingStatusRO()) 
	    						|| BankAuditUtil.isEmptyString(auditScheduleStatus.getGradingMakerRO()))
	    						&& BankAuditUtil.isEmptyString(auditGradingQsnDtls.getQsnValueDynamicUpdateHO())){
	    					auditGradingQsnDtls.setQsnValueDynamicUpdateHO(auditGradingQsnDtls.getQsnValueDynamicUpdateStage1HO());
	    					auditGradingQsnDtls.setQsnReferenceHO(auditGradingQsnDtls.getQsnReferenceStage1HO());
	    				}     				
	        			auditGradingDao.saveOrUpdate(auditGradingQsnDtls);
	        		}
	    			
	    			for(AuditGradingQsnBasicDtls auditGradingQsnBasicDtls: auditGradingQsnBasicDtlsMap.values()){
	    				if((BankAuditUtil.isEmptyString(auditScheduleStatus.getGradingStatusRO()) 
	    						|| BankAuditUtil.isEmptyString(auditScheduleStatus.getGradingMakerRO()))
	    						&& BankAuditUtil.isEmptyString(auditGradingQsnBasicDtls.getQsnValueDynamicUpdateHO())){
	    					auditGradingQsnBasicDtls.setQsnValueDynamicUpdateHO(auditGradingQsnBasicDtls.getQsnValueDynamicUpdateStage1HO());
	    					auditGradingQsnBasicDtls.setQsnReferenceHO(auditGradingQsnBasicDtls.getQsnReferenceStage1HO());
	    				}     				
	        			auditGradingDao.saveOrUpdate(auditGradingQsnBasicDtls);
		    		}
	    			
	    			for(AuditGradingQsoDtlsHO auditGradingQsoDtlsHO : auditGradingQsoDtlsHOList){ 
	    				if(BankAuditUtil.isEmptyString(auditGradingQsoDtlsHO.getQsoValueDynamicUpdateHO())){
	    					auditGradingQsoDtlsHO.setQsoValueDynamicUpdateHO(auditGradingQsoDtlsHO.getQsoValueDynamicUpdateStage1HO());	    					
	    					//auditGradingQsoDtls.setStatusStage1HO(BankAuditConstant.STATUS_AUTH);//uncomment at time add delete qso
	    				} 	
	    				if(!BankAuditConstant.STATUS_DEL.equalsIgnoreCase(auditGradingQsoDtlsHO.getStatus())
	    						&& BankAuditConstant.GRADING_STATUS_HO_UNAUTH.equalsIgnoreCase(gradingStatusHO)){
    						auditGradingQsoDtlsHO.setStatus(BankAuditConstant.STATUS_AUTH);    						
    					}/*if(BankAuditConstant.STATUS_DEL.equalsIgnoreCase(auditGradingQsoDtlsHO.getStatus())){
    						//auditGradingQsoDtlsHO.setQsoSequenceId(auditGradingQsoDtlsHO.getQsoSequenceId()+"-"+random.nextInt(10000)+""+(random.nextFloat()));
    					}*/
	        			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsHO);
	        		}
	        		
	        		for(AuditGradingParamDtls auditGradingParamDtls : auditGradingParamDtlsList){ 
	        			if((BankAuditUtil.isEmptyString(auditScheduleStatus.getGradingStatusRO())
	    						|| BankAuditUtil.isEmptyString(auditScheduleStatus.getGradingMakerRO()))
	        					&& auditGradingParamDtls.getScoreEffectiveHO() == null){
	        				auditGradingParamDtls.setScoreEffectiveHO(auditGradingParamDtls.getScoreEffective()); 
	        			}
	        			auditGradingDao.saveOrUpdate(auditGradingParamDtls);
	        		}	
	    		}	    		
	    	}else if(BankAuditConstant.GRADING_STATUS_RO_AUTH.equalsIgnoreCase(gradingStatus)
	    			|| BankAuditConstant.GRADING_STATUS_HO_AUTH.equalsIgnoreCase(gradingStatus)){
	    		 
	    		if(BankAuditConstant.UNIT_TYPE_RO.equalsIgnoreCase(userUnitType)){
	    			
	    			//auditGradingDao.deleteAuditGradingQsoDtlsRO(legalEntityCode, auditTypeCode, auditId);
	    			auditLetterUserInputsWrk.setReviewer(null); 
	    			auditGradingDao.saveOrUpdate(auditLetterUserInputsWrk);
	    			
	    			AuditLetterUserInputsWrk  auditLetterUserInputsWrkGradComp = new  AuditLetterUserInputsWrk();
		    		BeanUtils.copyProperties(auditLetterUserInputsWrk, auditLetterUserInputsWrkGradComp);
		    		auditLetterUserInputsWrkGradComp.setStatus(BankAuditConstant.GRADING_COMPLIANCE_STATUS_IN_PROGRESS);
		    		auditLetterUserInputsWrkGradComp.setGradingComplianceStatus(BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_UNAUTH);
		    		auditLetterUserInputsWrkGradComp.setLetterCode(BankAuditConstant.LETTER_CODE_IR_GRADING_RO_COMPLIANCE);
		    		auditGradingDao.save(auditLetterUserInputsWrkGradComp);	
	    			
	    			for(AuditGradingQsnDtls  auditGradingQsnDtls: auditGradingQsnDtlsMap.values()){ 
	    				//auditGradingQsnDtls.setQsnValueDynamicUpdateHO(auditGradingQsnDtls.getQsnValueDynamicUpdateRO());
	    				auditGradingQsnDtls.setQsnValueDynamicUpdateStage1HO(auditGradingQsnDtls.getQsnValueDynamicFetch());
	        			auditGradingDao.saveOrUpdate(auditGradingQsnDtls);
	        		}
	    			
	    			for(AuditGradingQsnBasicDtls  auditGradingQsnBasicDtls: auditGradingQsnBasicDtlsMap.values()){ 
	    				//auditGradingQsnBasicDtls.setQsnValueDynamicUpdateHO(auditGradingQsnBasicDtls.getQsnValueDynamicUpdateRO());
	    				auditGradingQsnBasicDtls.setQsnValueDynamicUpdateStage1HO(auditGradingQsnBasicDtls.getQsnValueDynamicFetch());
	        			auditGradingDao.saveOrUpdate(auditGradingQsnBasicDtls);
	        		}
	        		
	        		for(AuditGradingQsoDtlsRO auditGradingQsoDtlsRO : auditGradingQsoDtlsROList){
	        			//auditGradingQsoDtls.setQsoValueDynamicUpdateHO(auditGradingQsoDtls.getQsoValueDynamicUpdateRO());
	        			//auditGradingQsoDtlsRO.setStatusRO(BankAuditConstant.STATUS_AUTH);
	        			if(!BankAuditConstant.STATUS_DEL.equalsIgnoreCase(auditGradingQsoDtlsRO.getStatus())){
	        				auditGradingQsoDtlsRO.setStatus(BankAuditConstant.STATUS_AUTH);
	        				///auditGradingQsoDtlsRO.setQsoSequenceId(auditGradingQsoDtlsRO.getQsoSequenceId()+"-"+random.nextInt(10000)+""+(random.nextFloat()));
    					}
	        			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsRO);
	        		}
	        		
	        		for(AuditGradingParamDtls auditGradingParamDtls : auditGradingParamDtlsList){
	        			//auditGradingParamDtls.setScoreEffectiveHO(auditGradingParamDtls.getScoreEffectiveRO());
	        			auditGradingDao.saveOrUpdate(auditGradingParamDtls);
	        		}	        		  
	    		}else{	   
	    			
	    			AuditLetterUserInputs  auditLetterUserInputs = new  AuditLetterUserInputs();
		    		BeanUtils.copyProperties(auditLetterUserInputsWrk, auditLetterUserInputs);
		    		auditLetterUserInputs.setStatus(BankAuditConstant.STATUS_AUTH);
		    		auditLetterUserInputs.setGradingStatus(BankAuditConstant.GRADING_STATUS_CLOSED);
		    		auditGradingDao.saveOrUpdate(auditLetterUserInputs);		    		
		    		auditGradingDao.delete(auditLetterUserInputsWrk);
		    		//auditGradingDao.deleteAuditGradingQsoDtlsHO(legalEntityCode, auditTypeCode, auditId);
		    		
		    		AuditLetterUserInputsWrk  auditLetterUserInputsWrkGradComp = new  AuditLetterUserInputsWrk();
		    		BeanUtils.copyProperties(auditLetterUserInputs, auditLetterUserInputsWrkGradComp);
		    		auditLetterUserInputsWrkGradComp.setStatus(BankAuditConstant.GRADING_COMPLIANCE_STATUS_IN_PROGRESS);
		    		auditLetterUserInputsWrkGradComp.setGradingStatus(BankAuditConstant.GRADING_STATUS_HO_AUTH);
		    		auditLetterUserInputsWrkGradComp.setGradingComplianceStatus(BankAuditConstant.GRADING_HO_COMPLIANCE_STATUS_UNAUTH);
		    		auditLetterUserInputsWrkGradComp.setLetterCode(BankAuditConstant.LETTER_CODE_IR_GRADING_HO_COMPLIANCE);
		    		auditLetterUserInputsWrkGradComp.setReviewer(null);
		    		auditGradingDao.save(auditLetterUserInputsWrkGradComp);		    		
		    		
	    			for(AuditGradingQsnDtls  auditGradingQsnDtls: auditGradingQsnDtlsMap.values()){  
	        			auditGradingDao.saveOrUpdate(auditGradingQsnDtls);
	        		}
	    			
	    			for(AuditGradingQsnBasicDtls  auditGradingQsnBasicDtls: auditGradingQsnBasicDtlsMap.values()){  
	        			auditGradingDao.saveOrUpdate(auditGradingQsnBasicDtls);
	        		}
	        		
	        		for(AuditGradingQsoDtlsHO auditGradingQsoDtlsHO : auditGradingQsoDtlsHOList){ 	        			 
	        			if(!BankAuditConstant.STATUS_DEL.equalsIgnoreCase(auditGradingQsoDtlsHO.getStatus())){
	        				auditGradingQsoDtlsHO.setStatus(BankAuditConstant.STATUS_AUTH);
	        				//auditGradingQsoDtlsHO.setQsoSequenceId(auditGradingQsoDtlsHO.getQsoSequenceId()+"-"+random.nextInt(10000)+""+(random.nextFloat()));
    					}
	        			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsHO);
	        		}
	        		
	        		for(AuditGradingParamDtls auditGradingParamDtls : auditGradingParamDtlsList){ 
	        			auditGradingDao.saveOrUpdate(auditGradingParamDtls);
	        		}	        		  
	    		}	  
	    		
	    		auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING);
				auditScheduleStagesStatusHst.setStagesStatus(gradingStatus);
				auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_GRADING);
				auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);
	    	} 
	    	
	    }catch(Exception e){
	    	e.printStackTrace();
	    	logger.error(e);
	    	return BankAuditConstant.FAILED; 
	    }
	    return BankAuditConstant.SUCCESS; 
    }
    
    @Override
    public MaintGradingParamScoreMatrix getGradingParamScoreMatrixValue(Integer legalEntityCode, String auditTypeCode, Double score){
    	return auditGradingDao.getGradingParamScoreMatrixValue(legalEntityCode, auditTypeCode, score);
    } 
    
    @Override
    public AuditGradingDto getMyAuditGradingCompliance(Integer legalEntityCode, String auditTypeCode, String auditId, String letterCode){
	   try{ 	
	    	Map<String, Object> properties = new HashMap<String, Object>();
			properties.put("legalEntityCode", legalEntityCode);
			properties.put("auditTypeCode", auditTypeCode);
			properties.put("auditId", auditId);			
			AuditScheduleStatus auditScheduleStatus = (AuditScheduleStatus)auditGradingDao.getUniqueEntityByMatchingProperties(AuditScheduleStatus.class, properties);
			
			AuditGradingDto  auditGradingDto = auditGradingDao.getMyAuditGradingCompliance(legalEntityCode, auditTypeCode, auditId);
			auditGradingDto.setAuditScheduleStatus(auditScheduleStatus);		
	
			properties.put("letterCode", letterCode);
			AuditLetterUserInputsWrk  auditLetterUserInputsWrk = (AuditLetterUserInputsWrk) auditGradingDao.getUniqueEntityByMatchingProperties(AuditLetterUserInputsWrk.class, properties);
			 
			auditGradingDto.setLegalEntityCode(legalEntityCode);
			auditGradingDto.setAuditTypeCode(auditTypeCode);
			auditGradingDto.setAuditId(auditId);
			auditGradingDto.setUnitId(auditScheduleStatus.getUnitId());
			
			if(auditLetterUserInputsWrk != null){
				auditGradingDto.setReviewerId(auditLetterUserInputsWrk.getReviewer());
				auditGradingDto.setGradingStatus(auditLetterUserInputsWrk.getGradingStatus());
				auditGradingDto.setGradingComplianceStatus(auditLetterUserInputsWrk.getGradingComplianceStatus());
			}else{
				AuditLetterUserInputs  auditLetterUserInputs = (AuditLetterUserInputs) auditGradingDao.getUniqueEntityByMatchingProperties(AuditLetterUserInputs.class, properties);
				auditGradingDto.setReviewerId(auditLetterUserInputs.getReviewer());
				auditGradingDto.setGradingStatus(auditLetterUserInputs.getGradingStatus());
				auditGradingDto.setGradingComplianceStatus(auditLetterUserInputs.getGradingComplianceStatus());
			}

			return auditGradingDto;
	    }catch (Exception e) {
			e.printStackTrace();
	    	logger.error(e);
			return null;
		}
    }
    
    @Override
    public String saveAuditGradingCompliance(AuditGradingDto auditGradingDto){
   	 
	   	Integer legalEntityCode = auditGradingDto.getLegalEntityCode();
	   	String auditTypeCode = auditGradingDto.getAuditTypeCode();
	   	String auditId = auditGradingDto.getAuditId();
	   	String userId = auditGradingDto.getUserId(); 
	   	String reviewerId = auditGradingDto.getReviewerId();
	   	String userUnitType = auditGradingDto.getUserUnitType();
	   	String gradingStatus = auditGradingDto.getGradingStatus(); 
	   	String gradingComplianceStatus = auditGradingDto.getGradingComplianceStatus();
	   	
	   	AuditScheduleStatus  auditScheduleStatus =  auditGradingDto.getAuditScheduleStatus();  
    	List<AuditGradingQsoDtlsRO> auditGradingQsoDtlsROList = auditGradingDto.getAuditGradingQsoDtlsROList();
    	List<AuditGradingQsoDtlsHO> auditGradingQsoDtlsHOList = auditGradingDto.getAuditGradingQsoDtlsHOList();	    	
    	
    	Date businessDate = businessDateService.getBusinessDateTimestampByLegalEntityCode(legalEntityCode);
    	
    	Map<String, Object> properties = new HashMap<String, Object>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("auditTypeCode", auditTypeCode);
		properties.put("auditId", auditId); 
		
		//I am adding two records for grading compliance 1:RO 2:HO
		try{ 
			if(BankAuditConstant.GRADING_STATUS_RO_AUTH.equalsIgnoreCase(gradingStatus) 
					|| BankAuditConstant.GRADING_STATUS_HO_AUTH.equalsIgnoreCase(gradingStatus)){
				AuditSchedule auditSchedule = (AuditSchedule)auditGradingDao.getUniqueEntityByMatchingProperties(AuditSchedule.class, properties);			 
				if(BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_AUTH.equalsIgnoreCase(gradingComplianceStatus)
					|| BankAuditConstant.GRADING_HO_COMPLIANCE_STATUS_AUTH.equalsIgnoreCase(gradingComplianceStatus)){	
					
					auditSchedule.setActionMakerRole(auditGradingDto.getRole());
					auditSchedule.setActionMakerId(userId);					
					AuditScheduleStagesStatusHst auditScheduleStagesStatusHst = new AuditScheduleStagesStatusHst();
					if(BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_AUTH.equalsIgnoreCase(gradingComplianceStatus)){
						auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING_RO_COMPLIANCE);
					}else{
						auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING_HO_COMPLIANCE);
					}
					auditScheduleStagesStatusHst.setStagesStatus(gradingComplianceStatus);
					auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_GRADING);
					auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);
				}else{
					
					Map<String, Object> auditSchStagesStatusHstProperties = new HashMap<String, Object>();
					auditSchStagesStatusHstProperties.put("legalEntityCode", legalEntityCode);
					auditSchStagesStatusHstProperties.put("auditTypeCode", auditTypeCode);
					auditSchStagesStatusHstProperties.put("auditId", auditId);
					//auditSchStagesStatusHstProperties.put("code", BankAuditConstant.LETTER_CODE_IR_GRADING_RO_COMPLIANCE);			
					auditSchStagesStatusHstProperties.put("actionType", BankAuditConstant.ACTION_TYPE_GRADING);
					
					AuditScheduleStagesStatusHst auditScheduleStagesStatusHst = new AuditScheduleStagesStatusHst();
					if(BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_UNAUTH.equalsIgnoreCase(gradingComplianceStatus)
							|| BankAuditConstant.GRADING_HO_COMPLIANCE_STATUS_UNAUTH.equalsIgnoreCase(gradingComplianceStatus)){						
						auditSchedule.setActionMakerId(userId);
						auditSchedule.setActionMakerRole(auditGradingDto.getRole());
						
						if(BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_UNAUTH.equalsIgnoreCase(gradingComplianceStatus)){
							auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING_RO_COMPLIANCE); 
							auditSchStagesStatusHstProperties.put("code", BankAuditConstant.LETTER_CODE_IR_GRADING_RO_COMPLIANCE);	
						}else{
							auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING_HO_COMPLIANCE);
							auditSchStagesStatusHstProperties.put("code", BankAuditConstant.LETTER_CODE_IR_GRADING_HO_COMPLIANCE);	
						}
						
						auditSchStagesStatusHstProperties.put("stagesStatus", gradingComplianceStatus);
						AuditScheduleStagesStatusHst  auditScheduleStagesStatusHstChk = 
								(AuditScheduleStagesStatusHst) auditGradingDao.getUniqueEntityByMatchingProperties(AuditScheduleStagesStatusHst.class, auditSchStagesStatusHstProperties);
						if(auditScheduleStagesStatusHstChk == null){												 							
							auditScheduleStagesStatusHst.setStagesStatus(gradingComplianceStatus);
							auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_GRADING);
							auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);
						}						
					}else if(BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_SUBMITTED.equalsIgnoreCase(gradingComplianceStatus)
							|| BankAuditConstant.GRADING_HO_COMPLIANCE_STATUS_SUBMITTED.equalsIgnoreCase(gradingComplianceStatus)){
																		
						if(!BankAuditUtil.isEmptyString(reviewerId)){
							auditSchStagesStatusHstProperties.put("assigneeId", reviewerId);
							auditSchedule.setAssigneeId(reviewerId);
							auditScheduleStagesStatusHst.setAssigneeRole("G12"); 
						}
						if(BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_SUBMITTED.equalsIgnoreCase(gradingComplianceStatus)){
							auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING_RO_COMPLIANCE);
							auditSchStagesStatusHstProperties.put("code", BankAuditConstant.LETTER_CODE_IR_GRADING_RO_COMPLIANCE);	
						}else{
							auditScheduleStagesStatusHst.setCode(BankAuditConstant.LETTER_CODE_IR_GRADING_HO_COMPLIANCE);
							auditSchStagesStatusHstProperties.put("code", BankAuditConstant.LETTER_CODE_IR_GRADING_HO_COMPLIANCE);	
						}
						
						auditSchStagesStatusHstProperties.put("stagesStatus", gradingComplianceStatus);
						AuditScheduleStagesStatusHst  auditScheduleStagesStatusHstChk = 
								(AuditScheduleStagesStatusHst) auditGradingDao.getUniqueEntityByMatchingProperties(AuditScheduleStagesStatusHst.class, auditSchStagesStatusHstProperties);
						if(auditScheduleStagesStatusHstChk != null){ 
							auditScheduleStagesStatusHst.setId(auditScheduleStagesStatusHstChk.getId());
						} 						
								
						auditSchedule.setActionMakerId(userId);
						auditSchedule.setActionMakerRole(auditGradingDto.getRole()); 
						auditScheduleStagesStatusHst.setStagesStatus(gradingComplianceStatus);
						auditScheduleStagesStatusHst.setActionType(BankAuditConstant.ACTION_TYPE_GRADING);						
						auditScheduleStagesStatusHstService.saveAuditStagesStatus(auditSchedule, auditScheduleStagesStatusHst);	
						
					}
				}
			}
			
		   	if(BankAuditConstant.GRADING_STATUS_RO_AUTH.equalsIgnoreCase(gradingStatus)){ 
		   		
		   		properties.put("letterCode", BankAuditConstant.LETTER_CODE_IR_GRADING_RO_COMPLIANCE);
		   		properties.put("gradingStatus", BankAuditConstant.GRADING_STATUS_RO_AUTH);
		   		AuditLetterUserInputsWrk  auditLetterUserInputsWrk = (AuditLetterUserInputsWrk) auditGradingDao.getUniqueEntityByMatchingProperties(AuditLetterUserInputsWrk.class, properties);
				auditLetterUserInputsWrk.setGradingComplianceStatus(gradingComplianceStatus);
				
	   			auditScheduleStatus.setGradingROComplianceStatus(gradingComplianceStatus);
		 
				if(gradingComplianceStatus==null 
		   				|| BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_UNAUTH.equalsIgnoreCase(gradingComplianceStatus)){ 
			   		auditScheduleStatus.setGradingROComplianceMaker(userId);
			   		auditScheduleStatus.setGradingROComplianceMakerTimestamp(businessDate);
		   			auditGradingDao.saveOrUpdate(auditLetterUserInputsWrk);		   			
		   			for(AuditGradingQsoDtlsRO auditGradingQsoDtlsRO : auditGradingQsoDtlsROList){					 
		    			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsRO);
		    		}
		   			
		   		}else if( BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_SUBMITTED.equalsIgnoreCase(gradingComplianceStatus) ){
		   			auditLetterUserInputsWrk.setReviewer(reviewerId);
		   			
		   			auditScheduleStatus.setGradingROComplianceMaker(userId);
			   		auditScheduleStatus.setGradingROComplianceMakerTimestamp(businessDate);
		   			
			   		auditGradingDao.saveOrUpdate(auditLetterUserInputsWrk);		   			
		   			for(AuditGradingQsoDtlsRO auditGradingQsoDtlsRO : auditGradingQsoDtlsROList){	
		   				if(BankAuditUtil.isEmptyString(auditGradingQsoDtlsRO.getQsoComplianceRO())){
		   					auditGradingQsoDtlsRO.setQsoComplianceRO(auditGradingQsoDtlsRO.getQsoComplianceStage1RO());
		   				}
		    			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsRO);
		    		}
		   		}else if(BankAuditConstant.GRADING_RO_COMPLIANCE_STATUS_AUTH.equalsIgnoreCase(gradingComplianceStatus)){   			 
			   		auditScheduleStatus.setGradingROComplianceChecker(userId);
			   		auditScheduleStatus.setGradingROComplianceCheckerTimestamp(businessDate);
			   		
		   			AuditLetterUserInputs  auditLetterUserInputs = new  AuditLetterUserInputs();
		    		BeanUtils.copyProperties(auditLetterUserInputsWrk, auditLetterUserInputs);
		    		auditLetterUserInputs.setStatus(BankAuditConstant.STATUS_AUTH);
		    		auditLetterUserInputs.setGradingStatus(BankAuditConstant.GRADING_STATUS_CLOSED);
		    		auditLetterUserInputs.setGradingComplianceStatus(BankAuditConstant.GRADING_COMPLIANCE_STATUS_CLOSED);
		    		auditGradingDao.saveOrUpdate(auditLetterUserInputs);		    		
		    		auditGradingDao.delete(auditLetterUserInputsWrk);
		    		
		    		for(AuditGradingQsoDtlsRO auditGradingQsoDtlsRO : auditGradingQsoDtlsROList){ 
		    			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsRO);
		    		}   			
		   		}
				auditGradingDao.saveOrUpdate(auditScheduleStatus);
		   	}else if(BankAuditConstant.GRADING_STATUS_HO_AUTH.equalsIgnoreCase(gradingStatus)){
		   		
		   		properties.put("letterCode", BankAuditConstant.LETTER_CODE_IR_GRADING_HO_COMPLIANCE);
		   		properties.put("gradingStatus", BankAuditConstant.GRADING_STATUS_HO_AUTH);
		   		AuditLetterUserInputsWrk  auditLetterUserInputsWrk = (AuditLetterUserInputsWrk) auditGradingDao.getUniqueEntityByMatchingProperties(AuditLetterUserInputsWrk.class, properties);
				auditLetterUserInputsWrk.setGradingComplianceStatus(gradingComplianceStatus);
	
	   			auditScheduleStatus.setGradingHOComplianceStatus(gradingComplianceStatus);
		 
				if(gradingComplianceStatus==null 
		   				|| BankAuditConstant.GRADING_HO_COMPLIANCE_STATUS_UNAUTH.equalsIgnoreCase(gradingComplianceStatus)){ 
			   		auditScheduleStatus.setGradingHOComplianceMaker(userId);
			   		auditScheduleStatus.setGradingHOComplianceMakerTimestamp(businessDate);
		   			auditGradingDao.saveOrUpdate(auditLetterUserInputsWrk);		   			
		   			for(AuditGradingQsoDtlsHO auditGradingQsoDtlsHO : auditGradingQsoDtlsHOList){					 
		    			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsHO);
		    		}
		   			
		   		}else if( BankAuditConstant.GRADING_HO_COMPLIANCE_STATUS_SUBMITTED.equalsIgnoreCase(gradingComplianceStatus) ){
		   			auditLetterUserInputsWrk.setReviewer(reviewerId);
		   			
		   			auditScheduleStatus.setGradingHOComplianceMaker(userId);
			   		auditScheduleStatus.setGradingHOComplianceMakerTimestamp(businessDate);
		   			
			   		auditGradingDao.saveOrUpdate(auditLetterUserInputsWrk);		   			
		   			for(AuditGradingQsoDtlsHO auditGradingQsoDtlsHO : auditGradingQsoDtlsHOList){	
		   				if(BankAuditUtil.isEmptyString(auditGradingQsoDtlsHO.getQsoComplianceHO())){
		   					auditGradingQsoDtlsHO.setQsoComplianceHO(auditGradingQsoDtlsHO.getQsoComplianceStage1HO());
		   				}
		    			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsHO);
		    		}
		   		}else if(BankAuditConstant.GRADING_HO_COMPLIANCE_STATUS_AUTH.equalsIgnoreCase(gradingComplianceStatus)){   			 
			   		auditScheduleStatus.setGradingHOComplianceChecker(userId);
			   		auditScheduleStatus.setGradingHOComplianceCheckerTimestamp(businessDate);
			   		
		   			AuditLetterUserInputs  auditLetterUserInputs = new  AuditLetterUserInputs();
		    		BeanUtils.copyProperties(auditLetterUserInputsWrk, auditLetterUserInputs);
		    		auditLetterUserInputs.setStatus(BankAuditConstant.STATUS_AUTH);
		    		auditLetterUserInputs.setGradingStatus(BankAuditConstant.GRADING_STATUS_CLOSED);
		    		auditLetterUserInputs.setGradingComplianceStatus(BankAuditConstant.GRADING_COMPLIANCE_STATUS_CLOSED);
		    		auditGradingDao.saveOrUpdate(auditLetterUserInputs);		    		
		    		auditGradingDao.delete(auditLetterUserInputsWrk);
		    		
		    		for(AuditGradingQsoDtlsHO auditGradingQsoDtlsHO : auditGradingQsoDtlsHOList){ 
		    			auditGradingDao.saveOrUpdate(auditGradingQsoDtlsHO);
		    		}   			
		   		}
				auditGradingDao.saveOrUpdate(auditScheduleStatus);
		   	}
	   	}catch (Exception e) {
	   		e.printStackTrace();
	    	logger.error(e);
	    	return BankAuditConstant.FAILED; 
		}
    	return BankAuditConstant.SUCCESS;
    }
    
    private void storeToAuditGradingParamCompositeRatingDtls(Integer legalEntityCode, String auditTypeCode, String auditId){    	
		List<AuditGradingParamCompositeRatingDtls> auditGradingParamCompositeRatingDtlsList =	auditGradingDao.getCompositeRatingCategoryScore(legalEntityCode, auditTypeCode, auditId);
		AuditRating auditRating = auditGradingDao.getAuditRating(legalEntityCode, auditTypeCode, auditId);
			for (AuditGradingParamCompositeRatingDtls auditGradingParamCompositeRatingDtls : auditGradingParamCompositeRatingDtlsList) {
			if("Total".equalsIgnoreCase(auditGradingParamCompositeRatingDtls.getDisplayValueKeyRO())){
				auditGradingParamCompositeRatingDtls.setCategoryRo(auditRating.getCompositeRatingAftrOverlay());
				auditGradingParamCompositeRatingDtls.setScoreRo(auditRating.getCompositePrcntgAftrOverlay());	
			}
			auditGradingDao.saveOrUpdate(auditGradingParamCompositeRatingDtls);
		} 
    }
}
