/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.workreceiptsregister.service;

import java.math.BigDecimal;
import java.util.*;

import com.jeeplus.common.utils.DateUtils;
import com.jeeplus.common.utils.MenuStatusEnum;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.projectrecord.entity.ProjectRecords;
import com.jeeplus.modules.projectrecord.service.ProjectRecordsService;
import com.jeeplus.modules.sys.dao.OfficeDao;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.jeeplus.modules.workinvoicedetail.entity.WorkInvoiceDetail;
import com.jeeplus.modules.workinvoicedetail.service.WorkInvoiceDetailService;
import com.jeeplus.modules.workreceiptsregister.entity.*;
import com.jeeplus.modules.workreimbursementcount.entity.WorkInvoiceCompany;
import com.jeeplus.modules.workreimbursementcount.entity.WorkInvoiceOffice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jeeplus.common.persistence.Page;
import com.jeeplus.common.service.CrudService;
import com.jeeplus.modules.workreceiptsregister.dao.WorkReceiptsRegisterDao;

/**
 * 收入登记Service
 * @author ssrh
 * @version 2018-05-21
 */
@Service
@Transactional(readOnly = true)
public class WorkReceiptsRegisterService extends CrudService<WorkReceiptsRegisterDao, WorkReceiptsRegister> {

    @Autowired
    private WorkReceiptsRegisterDetailService registerDetailService;
    @Autowired
    private WorkInvoiceDetailService invoiceDetailService;
    @Autowired
    private OfficeDao officeDao;
    @Autowired
    private ProjectRecordsService projectRecordsService;

	public WorkReceiptsRegister get(String id) {
		WorkReceiptsRegister workReceiptsRegister = super.get(id);
		if(workReceiptsRegister.getExt().equals("0")){
		    if(StringUtils.isNotBlank(workReceiptsRegister.getProject().getId())){
                ProjectRecords queryProjectUsers = projectRecordsService.getQueryProjectUsers(workReceiptsRegister.getProject().getId());
                workReceiptsRegister.setProject(queryProjectUsers);
            }
        }
		return workReceiptsRegister;
	}
	
	public List<WorkReceiptsRegister> findList(WorkReceiptsRegister workReceiptsRegister) {
		return super.findList(workReceiptsRegister);
	}
	
	public Page<WorkReceiptsRegister> findPage(Page<WorkReceiptsRegister> page, WorkReceiptsRegister workReceiptsRegister) {
        if(!UserUtils.getUser().isAdmin()) {
            String dataScopeSql = dataScopeFilter(workReceiptsRegister.getCurrentUser(), "o", "u", "s", MenuStatusEnum.WORK_RECEIPTSREGISTER.getValue());
            workReceiptsRegister.getSqlMap().put("dsf", dataScopeSql);
        }
//        if(StringUtils.isBlank(workReceiptsRegister.getStatus())){
////            workReceiptsRegister.setStatus("0");
////        }
		return super.findPage(page, workReceiptsRegister);
	}
	
	@Transactional(readOnly = false)
	public void save(WorkReceiptsRegister workReceiptsRegister) {
	    if (workReceiptsRegister.getOffice()==null||StringUtils.isBlank(workReceiptsRegister.getOffice().getId())){
	        workReceiptsRegister.setOffice(UserUtils.getSelectOffice());
        }
        if(workReceiptsRegister.getComp()==null||StringUtils.isBlank(workReceiptsRegister.getComp().getId())){
	        workReceiptsRegister.setComp(UserUtils.getSelectCompany());
        }
		super.save(workReceiptsRegister);
	}
	
	@Transactional(readOnly = false)
	public void delete(WorkReceiptsRegister workReceiptsRegister) {
		super.delete(workReceiptsRegister);
	}

	@Transactional(readOnly = false)
    public void saveDetail(WorkReceiptsRegister workReceiptsRegister) throws Exception {
        if(workReceiptsRegister.getRegisterAmt()!=null&&Double.valueOf(workReceiptsRegister.getRegisterAmt()).equals(Double.valueOf(workReceiptsRegister.getArrivalAmt()))){
            workReceiptsRegister.setStatus("1");
        }else {
            workReceiptsRegister.setStatus("0");
        }
        //保存收入信息
        workReceiptsRegister.preUpdate();
        super.save(workReceiptsRegister);
        for (WorkReceiptsRegisterDetail registerDetail : workReceiptsRegister.getRegisterDetailList()) {
            if(registerDetail.getInvoice()==null||StringUtils.isBlank(registerDetail.getInvoice().getId())){
                continue;
            }
            WorkReceiptsRegisterDetail oldRegisterDetail = new WorkReceiptsRegisterDetail();
            if(StringUtils.isNotBlank(registerDetail.getId())){
                oldRegisterDetail = registerDetailService.get(registerDetail.getId());
            }
            //更新发票信息
            if(!registerDetail.getStatus().equals(oldRegisterDetail.getStatus())&&!"3".equals(registerDetail.getStatus())){
                WorkInvoiceDetail invoiceDetail = invoiceDetailService.get(registerDetail.getInvoice().getId());
                BigDecimal incomeMoney = new BigDecimal(invoiceDetail.getIncomeMoney());
                if("2".equals(registerDetail.getStatus())){
                    incomeMoney = incomeMoney.subtract(new BigDecimal(registerDetail.getRegisterAmt()));
                    registerDetail.setRegisterId(workReceiptsRegister.getId());
                    registerDetailService.save(registerDetail);
                }else {
                    incomeMoney=incomeMoney.add(new BigDecimal(registerDetail.getRegisterAmt()));
                    int isF = incomeMoney.compareTo(new BigDecimal(invoiceDetail.getTotalMoney()));
                    if(isF>0){
                        throw new Exception(String.format("保存收入信息失败，发票余额不足。发票号：%s，登记金额：%s",registerDetail.getInvoice().getNumber(),registerDetail.getRegisterAmt()));
                    }
                }
                invoiceDetail.setIncomeMoney(incomeMoney.toString());
                invoiceDetailService.updateIncomeMoney(invoiceDetail);
                /*if(i<=0){
                    throw new Exception(String.format("保存收入信息失败，发票余额不足。发票号：%s，登记金额：%s",registerDetail.getInvoice().getNumber(),registerDetail.getRegisterAmt()));
                }*/
            }

            if("1".equals(registerDetail.getDelFlag())&& DateUtils.getStartOfMonth().compareTo(registerDetail.getRegisterDate())<=0){
                logger.info("本月内收入，删除。发票号：{}",registerDetail.getInvoice().getNumber());
                registerDetailService.delete(registerDetail);
            }else if(StringUtils.isBlank(registerDetail.getId())){
                //保存登记明细
                registerDetail.setRegisterId(workReceiptsRegister.getId());
                registerDetailService.save(registerDetail);
            }
        }
    }

    public List<WorkReceiptsRegisterCompany> findCompanyList(WorkReceiptsRegisterCompany workReceiptsRegisterCompany, Map orientData, List xAxisData, Map yAxisData) {
        String companyId=workReceiptsRegisterCompany.getCompanyId();
        if (StringUtils.isBlank(companyId)){
            companyId=UserUtils.getSelectCompany().getId();
            workReceiptsRegisterCompany.setCompanyId(companyId);
        }
        List<WorkReceiptsRegisterCompany> list = findCompany(workReceiptsRegisterCompany,companyId,orientData,xAxisData,yAxisData);
        return list;
    }
    public List<WorkReceiptsRegisterCompany> findBranchList(WorkReceiptsRegisterCompany workReceiptsRegisterCompany, Map orientData, List xAxisData, Map yAxisData) {
        String companyId=workReceiptsRegisterCompany.getCompanyId();
        if (StringUtils.isBlank(companyId)){
            companyId= UserUtils.getSelectBranchOffice();
            workReceiptsRegisterCompany.setCompanyId(companyId);
        }
        List<WorkReceiptsRegisterCompany> list = findCompany(workReceiptsRegisterCompany,companyId,orientData,xAxisData,yAxisData);
        return list;
    }
    public  List<WorkReceiptsRegisterCompany> findCompany(WorkReceiptsRegisterCompany workReceiptsRegisterCompany,String companyId, Map orientData, List xAxisData, Map yAxisData) {
	    if(StringUtils.isBlank(workReceiptsRegisterCompany.getReceiptDate())){
	        workReceiptsRegisterCompany.setReceiptDate(DateUtils.formatDate(new Date(),"yyyy"));
        }
        List listSign=new ArrayList<>();
        List<WorkReceiptsRegisterCompany> list = dao.findCompanyList(workReceiptsRegisterCompany);
        for (int i=0 ; i<list.size();i++) {
            WorkReceiptsRegisterCompany company = list.get(i);
            if(company.getId().equals(companyId)){
                company.setSign("1");
            }else{
                company.setSign("2");
            }
            listSign.add(company);
        }
        this.caculateAmt("1",listSign);
        this.createPieData("1",listSign,orientData,xAxisData,yAxisData);

        return listSign;
    }

    private void createPieData(String flag,List<WorkReceiptsRegisterBase> list, Map map, List xAxisData, Map yAxisData) {
	    if(list==null||map==null||xAxisData==null||yAxisData==null)return;;
        if(list!=null&&list.size()>0){
            List<Double> rLists = new ArrayList<>();
            for (int i=0;i<list.size()-1;i++) {
                WorkReceiptsRegisterBase registerCompany = list.get(i);
                if("1".equals(flag)){
                    map.put(registerCompany.getName(),registerCompany.getReceiptAmt());
                    xAxisData.add(registerCompany.getName());
                }else if("2".equals(flag)){
                    map.put(registerCompany.getName(),registerCompany.getReceiptAmt());
                    xAxisData.add(registerCompany.getName());
                }else if("3".equals(flag)){
                    WorkReceiptsRegisterMonth registerMonth = (WorkReceiptsRegisterMonth) registerCompany;
                    map.put(registerMonth.getDatestr(),registerMonth.getReceiptAmt());
                    xAxisData.add(registerMonth.getDatestr());
                }
                rLists.add(registerCompany.getReceiptAmt());
            }
            yAxisData.put("收入统计",rLists);
        }
    }

    private void caculateAmt(String flag,List<WorkReceiptsRegisterBase> list) {
	    if (list==null){
	        list = new ArrayList<>();
        }
        BigDecimal totalAmt = new BigDecimal("0");
        Iterator<WorkReceiptsRegisterBase> iterator = list.iterator();
        while (iterator.hasNext()){
            WorkReceiptsRegisterBase registerCompany = iterator.next();
            if (registerCompany==null){
                iterator.remove();
                continue;
            }
            if(registerCompany.getReceiptAmt()==null){
                registerCompany.setReceiptAmt(0.00);
            };
            BigDecimal realAmt = new BigDecimal(registerCompany.getReceiptAmt());
            if(registerCompany.getInAmt()!=null&&registerCompany.getInAmt()>0){
                realAmt = realAmt.add(new BigDecimal(registerCompany.getInAmt()));
            }
            if(registerCompany.getOutAmt()!=null&&registerCompany.getOutAmt()>0){
                realAmt = realAmt.subtract(new BigDecimal(registerCompany.getOutAmt()));
            }
            registerCompany.setReceiptAmt(realAmt.doubleValue());
            totalAmt = totalAmt.add(realAmt);
        }
        if("3".equals(flag)){
            WorkReceiptsRegisterMonth total = new WorkReceiptsRegisterMonth();
            total.setReceiptAmt(totalAmt.doubleValue());
            total.setDatestr("合计");
            list.add(total);
        }else {
            WorkReceiptsRegisterCompany total = new WorkReceiptsRegisterCompany();
            Office office = new Office();
            total.setName("合计");
            total.setCompany(office);
            total.setOffice(office);
            total.setReceiptAmt(totalAmt.doubleValue());
            list.add(total);
        }
    }

    public List<WorkReceiptsRegisterOffice> findOfficeList(WorkReceiptsRegisterOffice workReceiptsRegisterOffice, Map orientData, List xAxisData, Map yAxisData) {
        if(StringUtils.isBlank(workReceiptsRegisterOffice.getReceiptDate())){
            workReceiptsRegisterOffice.setReceiptDate(DateUtils.formatDate(new Date(),"yyyy"));
        }
        List<WorkReceiptsRegisterOffice> list = dao.findOfficeList(workReceiptsRegisterOffice);
        List listSum=new ArrayList<>();
        if(list!=null&&list.size()>0){
            for(WorkReceiptsRegisterOffice workReceiptsRegisterOffice1:list){
                WorkReceiptsRegisterOffice workReceiptsRegisterOffice2=new WorkReceiptsRegisterOffice();
                workReceiptsRegisterOffice2.setCompanyId(workReceiptsRegisterOffice1.getId());
                workReceiptsRegisterOffice2.setReceiptDate(workReceiptsRegisterOffice.getReceiptDate());
                WorkReceiptsRegisterOffice w= dao.findOfficeListSum(workReceiptsRegisterOffice2);
                if(w.getId()!=null){
                    workReceiptsRegisterOffice1.setReceiptAmt(w.getReceiptAmt());
                    workReceiptsRegisterOffice1.setInAmt(w.getInAmt());
                    workReceiptsRegisterOffice1.setOutAmt(w.getOutAmt());
                }
                listSum.add(workReceiptsRegisterOffice1);
            }
        }
        this.caculateAmt("2",listSum);
        this.createPieData("2",listSum,orientData,xAxisData,yAxisData);
        return listSum;
    }

    public Page<WorkReceiptsRegisterInfo> findInfoPage(Page<WorkReceiptsRegisterInfo> page,WorkReceiptsRegisterInfo workReceiptsRegisterInfo) {
        if(StringUtils.isBlank(workReceiptsRegisterInfo.getReceiptDate())){
            workReceiptsRegisterInfo.setReceiptDate(DateUtils.formatDate(new Date(),"yyyy"));
        }
        if(workReceiptsRegisterInfo.getOffice()==null){
            workReceiptsRegisterInfo.setOffice(UserUtils.getSelectOffice());
        }
        workReceiptsRegisterInfo.setPage(page);
        List<WorkReceiptsRegisterInfo> list = dao.findInfoList(workReceiptsRegisterInfo);
        if(list!=null&&list.size()>0){
            Iterator<WorkReceiptsRegisterInfo> iterator = list.iterator();
            while (iterator.hasNext()){
                WorkReceiptsRegisterInfo registerInfo = iterator.next();
                if(StringUtils.isBlank(registerInfo.getInvoiceNum())&&registerInfo.getReceiptAmt()==null){
                    iterator.remove();
                }
            }
        }
        if(list!=null&&list.size()>0){
            WorkReceiptsRegisterInfo total = new WorkReceiptsRegisterInfo();
            BigDecimal totalAmt = new BigDecimal("0");
            for (WorkReceiptsRegisterInfo registerInfo : list) {
                totalAmt = totalAmt.add(new BigDecimal(registerInfo.getReceiptAmt()));
            }
            total.setInvoiceNum("合计");
            total.setClientName("-");
            total.setReceiptAmt(totalAmt.doubleValue());
            list.add(total);
        }
        page.setList(list);
        return page;
    }

    public List<WorkReceiptsRegisterMonth> findCompMonthList(WorkReceiptsRegisterCompany workReceiptsRegisterCompany, Map<String, Object> orientData, List<String> xAxisData, Map<String, List<Double>> yAxisData) {
        if(StringUtils.isBlank(workReceiptsRegisterCompany.getReceiptDate())){
            workReceiptsRegisterCompany.setReceiptDate(DateUtils.formatDate(new Date(),"yyyy"));
        }
        if(workReceiptsRegisterCompany.getCompany()==null){
            if(UserUtils.getUser().isAdmin()){
                workReceiptsRegisterCompany.setCompany(new Office("0"));
            }else {
                workReceiptsRegisterCompany.setCompany(UserUtils.getSelectCompany());
            }
        }
	    List list = dao.findCompMonthList(workReceiptsRegisterCompany);
	    this.caculateAmt("3",list);
        this.createPieData("3",list,orientData,xAxisData,yAxisData);
	    return list;
    }

    public List<WorkReceiptsRegisterMonth> findOfficeMonthList(WorkReceiptsRegisterOffice workReceiptsRegisterCompany, Map<String, Object> orientData, List<String> xAxisData, Map<String, List<Double>> yAxisData) {
        if(StringUtils.isBlank(workReceiptsRegisterCompany.getReceiptDate())){
            workReceiptsRegisterCompany.setReceiptDate(DateUtils.formatDate(new Date(),"yyyy"));
        }
        if(workReceiptsRegisterCompany.getCompany()==null){
            workReceiptsRegisterCompany.setCompany(UserUtils.getSelectCompany());
        }else {
            workReceiptsRegisterCompany.setCompany(officeDao.get(workReceiptsRegisterCompany.getCompany().getId()));
        }
        Office company = workReceiptsRegisterCompany.getCompany();
        if("0".equals(company.getParentId())){
            workReceiptsRegisterCompany.setBranchFlag(false);
        }else {
            workReceiptsRegisterCompany.setBranchFlag(true);
        }
        List list = dao.findOfficeMonthList(workReceiptsRegisterCompany);
	    this.caculateAmt("3",list);
        this.createPieData("3",list,orientData,xAxisData,yAxisData);
	    return list;
    }
}