package com.gx.obe.evaluation.step.checker;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.gx.obe.business.vo.InventoryPriceCheckResult;
import com.gx.obe.evaluation.step.inter.IChecker;
import com.gx.obe.util.utils.BigDecimalUtils;
import com.gx.obe.web.entity.CheckResult;
import com.gx.obe.web.entity.boq.BillTable;
import com.gx.obe.web.entity.boq.ConstructProject;
import com.gx.obe.web.entity.boq.MeasureTable;
import com.gx.obe.web.service.boq.BillTableService;
import com.gx.obe.web.service.boq.MeasureTableService;

/**
 * @Description: 清单报价检查
 * @author guoyr
 */
public class InventoryPriceChecker extends BaseChecker implements IChecker {
	
	private BillTableService billTableService = new BillTableService();
	private MeasureTableService measureTableService = new MeasureTableService();
	private List<InventoryPriceCheckResult> checkResultTreeList = new ArrayList<InventoryPriceCheckResult>();
	private List<InventoryPriceCheckResult> checkResultErrorList = new ArrayList<InventoryPriceCheckResult>();
	
	public void startCheck(ConstructProject constructProject) {
		checkResultTreeList.clear();
		checkResultErrorList.clear();
		// 获得工程项目
		if (null != constructProject) {
			
			// 获得单项工程
			List<ConstructProject> singleConstructionList = constructProject.getChildProjectList();
			if (null != singleConstructionList) {
				for (ConstructProject singleConstruction : singleConstructionList) {
					// 获得单位工程
					List<ConstructProject> unitConstructionList = singleConstruction.getChildProjectList();
					if (null != unitConstructionList) {
						for (ConstructProject unitConstruction : unitConstructionList) {
							
							InventoryPriceCheckResult unitResult = new InventoryPriceCheckResult(getEvaluationStep());
							unitResult.setName(singleConstruction.getProjectName() + "-" + unitConstruction.getProjectName());
							checkResultTreeList.add(unitResult);
							
							// 检查分布分项清单
							checkBillTable(unitResult, unitConstruction);
							// 检查措施清单
							checkMeasureTable(unitResult, unitConstruction);
						}
					}
				}
				
			}
			
		}
	}
	
	/**
	 * Description: 检查分布分项清单
	 * Create Date: Jul 3, 20145:41:49 PM<br/>
	 * Author : guoyr <br/>
	 * Modify Date: <br/>
	 * Modify By : <br/>
	 * 
	 * @param itemIndex
	 * @param parentItem
	 * @param projectId
	 * @return
	 */
	private void checkBillTable(InventoryPriceCheckResult parentCheckResult, ConstructProject constructProject) {
		
		List<BillTable> billTableList = billTableService.getBillTableQdAndDeList(constructProject.getId());
		for (BillTable qd : billTableList) {
			if (null != qd.getQuantity() && qd.getQuantity().compareTo(BigDecimal.ZERO) > 0) {
				List<BillTable> deList = qd.getChildBillList();
				if (null != deList && deList.size() > 0) {
					BigDecimal deSum = BigDecimal.ZERO;
					for (BillTable de : deList) {
						deSum = BigDecimalUtils.add(deSum, de.getTotal());
					}
					BigDecimal computerprice = BigDecimalUtils.div(deSum, qd.getQuantity(), 2);
					
					InventoryPriceCheckResult qdResult = new InventoryPriceCheckResult(getEvaluationStep());
					qdResult.setCode(qd.getBillCode());
					qdResult.setName(qd.getBillName());
					qdResult.setParent(parentCheckResult);
					qdResult.setQuantity(qd.getQuantity());
					qdResult.setPrice(qd.getPrice());
					qdResult.setComparePrice(computerprice);
					qdResult.setUnit(qd.getUnit());
					
					if (qdResult.getFlag() != 0) {
						checkResultErrorList.add(qdResult);
					}
					parentCheckResult.addChild(qdResult);
				}
			}
		}
	}
	
	/**
	 * Description: 检查分布分项清单
	 * Create Date: Jul 3, 20145:41:49 PM<br/>	
	 * Author : guoyr <br/>
	 * Modify Date: <br/>
	 * Modify By : <br/>
	 * 
	 * @param itemIndex
	 * @param parentItem
	 * @param projectId
	 * @return
	 */
	private void checkMeasureTable(InventoryPriceCheckResult parentCheckResult, ConstructProject constructProject) {
		
		List<MeasureTable> billTableList = measureTableService.getMeasureTableQdAndDeList(constructProject.getId());
		for (MeasureTable qd : billTableList) {
			if (null != qd.getQuantity() && qd.getQuantity().compareTo(BigDecimal.ZERO) > 0) {
				List<MeasureTable> deList = qd.getChildMeasureList();
				if (null != deList && deList.size() > 0) {
					BigDecimal deSum = BigDecimal.ZERO;
					for (MeasureTable de : deList) {
						deSum = BigDecimalUtils.add(deSum, de.getTotal());
					}
					BigDecimal computerprice = BigDecimalUtils.div(deSum, qd.getQuantity(), 2);
					
					InventoryPriceCheckResult qdResult = new InventoryPriceCheckResult(getEvaluationStep());
					qdResult.setCode(qd.getMeasureCode());
					qdResult.setName(qd.getMeasureName());
					qdResult.setParent(parentCheckResult);
					qdResult.setQuantity(qd.getQuantity());
					qdResult.setPrice(qd.getPrice());
					qdResult.setComparePrice(computerprice);
					qdResult.setUnit(qd.getUnit());
					
					if (qdResult.getFlag() != 0) {
						checkResultErrorList.add(qdResult);
					}
					parentCheckResult.addChild(qdResult);
				}
			}
		}
	}
	
	public int getErrorCount() {
		return checkResultErrorList.size();
	}
	
	@SuppressWarnings("unchecked")
	public <T> List<T> getCheckResultDetailTreeList() {
		return (List<T>) checkResultTreeList;
	}
	
	@SuppressWarnings("unchecked")
	public <T> List<T> getCheckResultErrorList() {
		return (List<T>) checkResultErrorList;
	}
	
	public CheckResult getCheckResult() {
		if (null != checkResult) return checkResult;
		checkResult = initCheckResult(checkResult);
		if (checkResultErrorList.size() > 0) {
			int maxCount = 0;
			int minCount = 0;
			for (InventoryPriceCheckResult result : checkResultErrorList) {
				if (result.getFlag() > 0) {
					maxCount++;
				} else if (result.getFlag() < 0) {
					minCount++;
				}
			}
			StringBuilder error = new StringBuilder();
			if (maxCount > 0) {
				
				error.append(maxCount);
				error.append("项清单的单价过高");
			} else if (minCount > 0) {
				if (error.length() > 0) {
					error.append("；");
				}
				error.append(maxCount);
				error.append("项清单的单价过低");
			}
			error.append("。");
			checkResult.setCheckResult(error.toString());
			checkResult.setErrorNum(checkResultErrorList.size());
			checkResult.setAccessment(com.gx.obe.components.core.enumeration.EvaluationStepEnum.UNQUALIFIED);
		} else {
			checkResult.setErrorNum(0);
			checkResult.setAccessment(com.gx.obe.components.core.enumeration.EvaluationStepEnum.QUALIFIED);
			checkResult.setCheckResult("无错误。");
		}
		
		return checkResult;
	}
	
}
