package com.fp.person.rules.save;

import java.sql.Date;
import java.util.List;

import javax.persistence.EntityManager;

import com.fp.dto.data.SaveData;
import com.fp.dto.rules.TransactionRule;
import com.fp.dto.save.SaveRequest;
import com.fp.persistence.commondb.PersistenceHelper;
import com.fp.persistence.commondb.helper.FormatDates;
import com.fp.persistence.pcustomer.balance.TcustBalance;
import com.fp.persistence.pcustomer.balance.TcustBalanceKey;
import com.fp.persistence.pcustomer.balance.TcustPersonBalance;
import com.fp.persistence.pcustomer.balance.TcustPersonBalanceKey;
import com.fp.persistence.pcustomer.gene.TcustPerson;
import com.fp.persistence.pcustomer.gene.TcustPersonAddress;
import com.fp.persistence.pcustomer.gene.TcustPersonAddressKey;
import com.fp.persistence.pcustomer.gene.TcustPersonBankReference;
import com.fp.persistence.pcustomer.gene.TcustPersonBankReferenceKey;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pcustomer.gene.TcustPersonDetailKey;
import com.fp.persistence.pcustomer.gene.TcustPersonPersonalReference;
import com.fp.persistence.pcustomer.gene.TcustPersonPersonalReferenceKey;
import com.fp.persistence.pcustomer.gene.TcustPersonPhone;
import com.fp.persistence.pcustomer.gene.TcustPersonPhoneKey;
import com.fp.sessionbeans.helper.Sequence;

/**
 * Clase padre que se encarga de completar el personcode cuando se crea una nueva persona: juridica o natural
 * 
 * @author Wilson Sigcho
 * @version 2.1
 */
@SuppressWarnings("serial")
public abstract class CompletePersonAndCompany extends TransactionRule {

    /**
     * Metodo que devuelve la secuencia que le pertenece a una nueva persona.
     * 
     * @return Codigo de la nueva persona.
     * @throws Exception
     */
    protected Integer getPersonCode() throws Exception {
        Sequence sequence = new Sequence();
        Integer personcode = Integer.valueOf(sequence.getNextValue("PERSONCODE").toString());
        SaveData.getMap().put("PERSONCODE", personcode.toString());
        return personcode;
    }
    
    /**
     * Metodo que devuelve el internalcode que le pertenece a una nueva persona.
     * 
     * @return Codigo de la nueva persona.
     * @throws Exception
     */
    protected Integer getInternalCode() throws Exception {
        Sequence sequence = new Sequence();
        Integer internalcode = Integer.valueOf(sequence.getNextValue("INTERNALCODE").toString());        
        return internalcode;
    }

    /**
     * Metodo que crea un objeto de la clase TcustPerson
     * 
     * @param saveRequest Objeto que posee el save requerido.
     * @param personcode Codigo de la nueva persona.
     * @throws Exception
     */
    protected void createPerson(SaveRequest saveRequest, Integer personcode) throws Exception {
        TcustPerson tcustPerson = new TcustPerson();
        tcustPerson.setPk(personcode);
        EntityManager entityManager = PersistenceHelper.getEntityManager();
        entityManager.persist(tcustPerson);
//        saveRequest.putSaveBean("TCUSTPERSON", tcustPerson, 1);
    }

    /**
     * Completa el codigo de la persona en la tabla TcustPersonDetail
     * 
     * @param tcustPersonDetail Objeto que posee el registro a guardar en la tabla TcustPersonDetail.
     * @param personcode Codigo de la nueva persona a ser guardada.
     * @throws Exception
     */
    protected void completePersonDetail(SaveRequest pSaveRequest, TcustPersonDetail tcustPersonDetail, Integer personcode) throws Exception {
        TcustPersonDetailKey tcustPersonDetailKey = new TcustPersonDetailKey();
        tcustPersonDetailKey.setPersoncode(personcode);
        tcustPersonDetail.setPk(tcustPersonDetailKey);
    }

    /**
     * Metodo que completa informaci�n faltante
     * 
     * @param pSaveRequest
     * @param tcustPersonDetail
     */
    protected void completeAditionalInfo(SaveRequest pSaveRequest, TcustPersonDetail tcustPersonDetail) {
        if (tcustPersonDetail != null) {
            if (tcustPersonDetail.getBranchcode() != null) {
                return;
            }
            tcustPersonDetail.setCompanycode(pSaveRequest.getCompany());
            tcustPersonDetail.setBranchcode(pSaveRequest.getBranchCode());
            tcustPersonDetail.setOfficecode(pSaveRequest.getOfficeCode());
            tcustPersonDetail.setIngressuser(pSaveRequest.getUser());
            tcustPersonDetail.setRegisterdate((Date) pSaveRequest.get("accountingdate"));
        }
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla TcustPersonAddress
     * 
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    protected void completeAddress(List<Object> lDetail, Integer personcode) throws Exception {
        if (lDetail == null) {
            return;
        }
        for (Object object : lDetail) {
            TcustPersonAddress tcustPersonAddress = (TcustPersonAddress) object;
            if ((tcustPersonAddress != null) && (tcustPersonAddress.getPk().getPersoncode() == null)) {
                TcustPersonAddressKey tcustPersonAddressKey = new TcustPersonAddressKey();
                tcustPersonAddressKey.setAddressnumber(tcustPersonAddress.getPk().getAddressnumber());
                tcustPersonAddressKey.setPersoncode(personcode);
                tcustPersonAddress.setPk(tcustPersonAddressKey);
            }
        }
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla TcustPersonPhone
     * 
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    protected void completePhone(List<Object> lDetail, Integer personcode) throws Exception {
        if (lDetail == null) {
            return;
        }
        for (Object object : lDetail) {
            TcustPersonPhone tcustPersonPhone = (TcustPersonPhone) object;
            if ((tcustPersonPhone != null) && (tcustPersonPhone.getPk().getPersoncode() == null)) {
                TcustPersonPhoneKey tcustPersonPhoneKey = new TcustPersonPhoneKey();
                tcustPersonPhoneKey.setPersoncode(personcode);
                tcustPersonPhoneKey.setPhonesequence(tcustPersonPhone.getPk().getPhonesequence());
                tcustPersonPhone.setPk(tcustPersonPhoneKey);
            }
        }
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla TcustPersonBankReference
     * 
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    protected void completeBankReference(List<Object> lDetail, Integer personcode) throws Exception {
        if (lDetail == null) {
            return;
        }
        for (Object object : lDetail) {
            TcustPersonBankReference tcustPersonBankReference = (TcustPersonBankReference) object;
            if ((tcustPersonBankReference != null) && (tcustPersonBankReference.getPk().getPersoncode() == null)) {
                TcustPersonBankReferenceKey tcustPersonBankReferenceKey = new TcustPersonBankReferenceKey();
                tcustPersonBankReferenceKey.setPersoncode(personcode);
                tcustPersonBankReferenceKey.setReferencesequence(tcustPersonBankReference.getPk().getReferencesequence());
                tcustPersonBankReference.setPk(tcustPersonBankReferenceKey);
            }
        }
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla TcustPersonPersonalReference
     * 
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    protected void completePersonalReference(List<Object> lDetail, Integer personcode) throws Exception {
        if (lDetail == null) {
            return;
        }
        for (Object object : lDetail) {
            TcustPersonPersonalReference tcustPersonPersonalReference = (TcustPersonPersonalReference) object;
            if ((tcustPersonPersonalReference != null) && (tcustPersonPersonalReference.getPk().getPersoncode() == null)) {
                TcustPersonPersonalReferenceKey tcustPersonPersonalReferenceKey = new TcustPersonPersonalReferenceKey();
                tcustPersonPersonalReferenceKey.setPersoncode(personcode);
                tcustPersonPersonalReferenceKey.setReferencesequence(tcustPersonPersonalReference.getPk().getReferencesequence());
                tcustPersonPersonalReference.setPk(tcustPersonPersonalReferenceKey);
            }
        }
    }

    /**
     * Metodo que crea un objeto TcustBalance
     * 
     * @param saveRequest Objeto que posee el save requerido.
     * @param personcode Codigo de la persona.
     * @param balancedate Fecha de balance de la nueva persona.
     * @throws Exception
     */
    protected void createBalance(Integer personcode, Date balancedate, SaveRequest saveRequest) throws Exception {
        TcustBalanceKey tcustBalanceKey = new TcustBalanceKey();
        tcustBalanceKey.setPersoncode(personcode);
        tcustBalanceKey.setBalancedate(balancedate);
        TcustBalance tcustBalance = new TcustBalance(tcustBalanceKey);
        
        PersistenceHelper.save(tcustBalance);
//        saveRequest.putSaveBean("TCUSTBALANCE", tcustBalance, 1);
    }

    /**
     * 
     * @param tcustPersonBalance
     * @param personcode
     * @param saveRequest
     * @throws Exception
     */
    protected void completeBalance(TcustPersonBalance tcustPersonBalance, Integer personcode, SaveRequest saveRequest) throws Exception {
        if (tcustPersonBalance == null) {
            return;
        }
        if ((tcustPersonBalance != null) && (tcustPersonBalance.getPk().getPersoncode() == null)) {
            TcustBalanceKey tcustBalanceKey = new TcustBalanceKey(personcode, tcustPersonBalance.getPk().getBalancedate());
            TcustBalance tcustBalance = TcustBalance.find(PersistenceHelper.getEntityManager(), tcustBalanceKey);
            if (tcustBalance == null) {
                this.createBalance(personcode, tcustPersonBalance.getPk().getBalancedate(), saveRequest);
            }
            TcustPersonBalanceKey tcustPersonBalanceKey = new TcustPersonBalanceKey();
            tcustPersonBalanceKey.setPersoncode(personcode);
            tcustPersonBalanceKey.setBalancedate(tcustPersonBalance.getPk().getBalancedate());
            tcustPersonBalance.setPk(tcustPersonBalanceKey);
        }
    }

    /**
     * Metodo que verifica el codigo de balance caso contrario lo crea
     * 
     * @param personbalance Lista de objetos de TcustBalancePerson
     * @param pSaveRequest Objeto SaveRequest
     * @throws Exception
     */
    protected void balanceCode(TcustPersonBalance tcustPersonBalance, SaveRequest pSaveRequest) throws Exception {
        FinancialSituation financialSituation = new FinancialSituation();
        if (tcustPersonBalance == null) {
            return;
        }
        TcustPersonBalanceKey tcustPersonBalanceKey = new TcustPersonBalanceKey(tcustPersonBalance.getPk().getPersoncode(), tcustPersonBalance
                .getPk().getBalancedate(), tcustPersonBalance.getPk().getBalancecatalog(), tcustPersonBalance.getPk().getBalancecatalogcode(),
                FormatDates.getDefaultExpiryTimestamp());
        TcustPersonBalance tcustPersonBalanceAux = TcustPersonBalance.find(PersistenceHelper.getEntityManager(), tcustPersonBalanceKey);
        if ((tcustPersonBalanceAux != null) && (tcustPersonBalance.getPk().getDateto() == null) && (tcustPersonBalance.getDatefrom() == null)
                && (tcustPersonBalance.getRecordversion() == null)) {
            tcustPersonBalance.getPk().setDateto(FormatDates.getDefaultExpiryTimestamp());
            tcustPersonBalance.setRecordversion(tcustPersonBalanceAux.getRecordversion());
        }
        TcustBalanceKey tcustBalanceKey = new TcustBalanceKey(tcustPersonBalance.getPk().getPersoncode(), tcustPersonBalance.getPk().getBalancedate());
        TcustBalance tcustBalance = TcustBalance.find(PersistenceHelper.getEntityManager(), tcustBalanceKey);
        if (tcustBalance == null) {
            this.createBalance(tcustPersonBalance.getPk().getPersoncode(), tcustPersonBalance.getPk().getBalancedate(), pSaveRequest);
        }
        // List<TcustBalanceFinancial> listBalanceFinancial =
        financialSituation.completeFinancialSituation(tcustPersonBalance, pSaveRequest);
        // if (!listBalanceFinancial.isEmpty()) {
        // pSaveRequest.putSaveBean("TCUSTBALANCEFINANCIAL", listBalanceFinancial, 5);
        // }
    }
}
