<?php

namespace RxConnexionBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use RxConnexionBundle\Entity\Base\BaseEntity;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
use JMS\Serializer\Annotation\Groups;
use JMS\Serializer\Annotation\MaxDepth;

/**
 * @ORM\Entity(repositoryClass="RxConnexionBundle\Repository\PatientPaymentRepository")
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table(name="patient_payment", indexes={
 *     @ORM\Index(name="IDX_000AAA", columns={"created_by"}),
 *     })
 */
class PatientPaymentEntity extends BaseEntity
{
    const PAY_TYPE_AMEX = 'Amex';
    const PAY_TYPE_CASH = 'Cash';
    const PAY_TYPE_CHEQUE = 'Cheque';
    const PAY_TYPE_CREDIT = 'Credit';
    const PAY_TYPE_DEBIT_CARD = 'Debit Card';
    const PAY_TYPE_DIRECT_DEPOSIT = 'Direct Deposit';
    const PAY_TYPE_MASTER_CARD = 'Master Card';
    const PAY_TYPE_OTHER = 'Other';
    const PAY_TYPE_VISA = 'Visa';
    const PAY_TYPE_FINANCING = 'Financing';
    const PAY_TYPE_WAIVER = 'Waiver';
    const PAYMENT_STATUS_POSTED = 'Posted';
    const PAYMENT_STATUS_VOID = 'Void';
    const PAYMENT_STATUS_PENDING = 'Pending';
    const PAYMENT_STATUS_REFUNDED = 'Refunded';
    const PAYMENT_AUTO_GENERATED_NOTE_FOR_FINANCING = 'Financing Bill Auto-Generated Payment';

    /**
     * @ORM\Column(name="pay_type", type="string", length=20)
     * @Groups("forAudit")
     */
    protected $payType;

    /**
     * @ORM\Column(name="pay_type_for_print", type="string", length=20)
     * @Groups("forAudit")
     */
    protected $payTypeForPrint;

    /**
     * @ORM\Column(name="pay_date", type="datetime")
     * @Groups("forAudit")
     */
    protected $payDate;

    /**
     * @ORM\Column(name="amount", type="decimal", precision=12, scale=2)
     * @Groups("forAudit")
     */
    protected $amount;

    /**
     * @ORM\Column(name="bill_due_amount", type="decimal", precision=12, scale=2, nullable=true)
     * @Groups("forAudit")
     */
    protected $billDueAmount;

    /**
     * @ORM\Column(name="bill_paid_amount", type="decimal", precision=12, scale=2, nullable=true)
     * @Groups("forAudit")
     */
    protected $billPaidAmount;

    /**
     * @ORM\Column(name="bill_bal_amount", type="decimal", precision=12, scale=2, nullable=true)
     * @Groups("forAudit")
     */
    protected $billBalAmount;

    /**
     * @ORM\Column(name="note", type="text", nullable=true)
     * @Groups("forAudit")
     */
    protected $note;

    /**
     * @ORM\Column(name="prev_sys_invoice_no", type="integer", nullable=true)
     */
    protected $prevSysInvoiceNo;

    /**
     * @ORM\Column(name="prev_sys_invoice_branch", type="string", length=20, nullable=true)
     */
    protected $prevSysInvoiceBranch;

    /**
     * @ORM\Column(name="is_deleted", type="boolean")
     */
    protected $isDeleted;

    /**
     * @ORM\Column(name="new_invoice_no_for_financing", type="integer", nullable=true)
     * @Groups("forAudit")
     */
    protected $newInvoiceNoForFinancing;

    /**
     * @ORM\Column(name="payment_status", type="string", nullable=true)
     * @Groups("forAudit")
     */
    protected $paymentStatus;

    /**
     * @ORM\ManyToOne(targetEntity="PatientEntity", inversedBy="patientPayments")
     * @ORM\JoinColumn(name="patient_id", referencedColumnName="id")
     * @Groups("forAudit")
     * @MaxDepth(1)
     */
    protected $patient;

    /**
     * @ORM\ManyToOne(targetEntity="PatientBillingEntity", inversedBy="patientPayments")
     * @ORM\JoinColumn(name="patient_billing_id", referencedColumnName="id")
     * @Groups("forAudit")
     * @MaxDepth(1)
     */
    protected $patientBilling;

    /**
     * @ORM\ManyToOne(targetEntity="PatientRentalEntity", inversedBy="patientPayments")
     * @ORM\JoinColumn(name="patient_rental_id", referencedColumnName="id")
     * @Groups("forAudit")
     * @MaxDepth(1)
     */
    protected $patientRental;

    /**
     * @ORM\ManyToOne(targetEntity="FinancingCompanyEntity", inversedBy="patientPayments")
     * @ORM\JoinColumn(name="financing_company_id", referencedColumnName="id")
     * @Groups("forAudit")
     * @MaxDepth(1)
     */
    protected $financingCompany;

    /**
     * @ORM\OneToOne(targetEntity="PatientBillingEntity", mappedBy="patientPaymentFinancing")
     */
    protected $patientBillingFinancing;

    /**
     * @ORM\OneToMany(targetEntity="PatientPaymentBreakdownEntity", mappedBy="patientPayment")
     */
    protected $patientPaymentBreakdowns;

    /**
     * @ORM\OneToMany(targetEntity="RxConnexionBundle\Entity\AccountingBillingEntity", mappedBy="patientPayment", cascade={"remove"})
     */
    protected $accountingBillings;

    /*--------------------------------------------------------------------------------------------------------*/
    /*					Use Defined Methods         														  */
    /*--------------------------------------------------------------------------------------------------------*/

    /**
     * Set createdAt
     *
     * @ORM\PrePersist
     */
    public function setCreatedAtValue()
    {
        parent::setCreatedAtValue();
        $this->isDeleted = 0;
        if(!$this->patientBilling->getIsPaymentPlan()){
            $this->paymentStatus = PatientPaymentEntity::PAYMENT_STATUS_POSTED;
        }
    }

    /**
     * @ORM\PrePersist
     */
    public function prePersist() {

        $this->billDueAmount = $this->patientBilling->getAmountDue();
        $this->billPaidAmount = $this->patientBilling->getAmountPaid();
        $this->billBalAmount = $this->patientBilling->getAmountBalance();
    }

    /**
     * @ORM\PostPersist
     */
    public function postPersist() {
        $this->patientBilling->addPatientPayment($this);
    }

    /**
     * @ORM\PreRemove
     */
    public function preRemove() {

        $this->patientBilling->removePatientPayment($this);
        $this->patientBilling->setAmountsValue();
    }

    /**
     * @ORM\PreFlush
     */
    public function preFlush() {
        $this->patientBilling->setAmountsValue();
        $this->patientBilling->updateBillingStatus();
    }

    /*--------------------------------------------------------------------------------------------------------*/
    /*					Use Defined Setters and Getters														  */
    /*--------------------------------------------------------------------------------------------------------*/

    /**
     * Get paymentNoParsed
     *
     * @return string
     */
    public function getPaymentNoParsed() {

        return sprintf('%006d', $this->id);
    }

    /**
     * get payDateAsString
     *
     * @return string
     */
    public function getPayDateAsString() {

        $dttst = new DateTimeToStringTransformer();

        return !empty($this->payDate) ? date('m/d/Y', strtotime($dttst->transform($this->payDate))) : '';
    }

    /*--------------------------------------------------------------------------------------------------------*/
    /*					Setters and Getters																	  */
    /*--------------------------------------------------------------------------------------------------------*/

    /**
     * Set payType
     *
     * @param string $payType
     *
     * @return PatientPaymentEntity
     */
    public function setPayType($payType)
    {
        $this->payType = $payType;

        return $this;
    }

    /**
     * Get payType
     *
     * @return string
     */
    public function getPayType()
    {
        return $this->payType;
    }

    /**
     * Set payDate
     *
     * @param \DateTime $payDate
     *
     * @return PatientPaymentEntity
     */
    public function setPayDate($payDate)
    {
        $this->payDate = empty($payDate) ? NULL : new \DateTime($payDate);

        return $this;
    }

    /**
     * Get payDate
     *
     * @return \DateTime
     */
    public function getPayDate()
    {
        return $this->payDate;
    }

    /**
     * Set amount
     *
     * @param string $amount
     *
     * @return PatientPaymentEntity
     */
    public function setAmount($amount)
    {
        $this->amount = floatval(str_replace(',', '', $amount));

        return $this;
    }

    /**
     * Get amount
     *
     * @return string
     */
    public function getAmount()
    {
        return $this->amount;
    }

    /**
     * Set billBalAmount
     *
     * @param string $billBalAmount
     *
     * @return PatientPaymentEntity
     */
    public function setBillBalAmount($billBalAmount)
    {
        $this->billBalAmount = floatval(str_replace(',', '', $billBalAmount));

        return $this;
    }

    /**
     * Get billBalAmount
     *
     * @return string
     */
    public function getBillBalAmount()
    {
        return $this->billBalAmount;
    }

    /**
     * Set note
     *
     * @param string $note
     *
     * @return PatientPaymentEntity
     */
    public function setNote($note)
    {
        $this->note = $note;

        return $this;
    }

    /**
     * Get note
     *
     * @return string
     */
    public function getNote()
    {
        return $this->note;
    }

    /**
     * Set patient
     *
     * @param \RxConnexionBundle\Entity\PatientEntity $patient
     *
     * @return PatientPaymentEntity
     */
    public function setPatient(\RxConnexionBundle\Entity\PatientEntity $patient = null)
    {
        $this->patient = $patient;

        return $this;
    }

    /**
     * Get patient
     *
     * @return \RxConnexionBundle\Entity\PatientEntity
     */
    public function getPatient()
    {
        return $this->patient;
    }

    /**
     * Set patientBilling
     *
     * @param \RxConnexionBundle\Entity\PatientBillingEntity $patientBilling
     *
     * @return PatientPaymentEntity
     */
    public function setPatientBilling(\RxConnexionBundle\Entity\PatientBillingEntity $patientBilling = null)
    {
        $this->patientBilling = $patientBilling;

        return $this;
    }

    /**
     * Get patientBilling
     *
     * @return \RxConnexionBundle\Entity\PatientBillingEntity
     */
    public function getPatientBilling()
    {
        return $this->patientBilling;
    }

    /**
     * Set billDueAmount
     *
     * @param string $billDueAmount
     *
     * @return PatientPaymentEntity
     */
    public function setBillDueAmount($billDueAmount)
    {
        $this->billDueAmount = floatval(str_replace(',', '', $billDueAmount));

        return $this;
    }

    /**
     * Get billDueAmount
     *
     * @return string
     */
    public function getBillDueAmount()
    {
        return $this->billDueAmount;
    }

    /**
     * Set billPaidAmount
     *
     * @param string $billPaidAmount
     *
     * @return PatientPaymentEntity
     */
    public function setBillPaidAmount($billPaidAmount)
    {
        $this->billPaidAmount = floatval(str_replace(',', '', $billPaidAmount));

        return $this;
    }

    /**
     * Get billPaidAmount
     *
     * @return string
     */
    public function getBillPaidAmount()
    {
        return $this->billPaidAmount;
    }

    /**
     * Set isDeleted
     *
     * @param boolean $isDeleted
     *
     * @return PatientPaymentEntity
     */
    public function setIsDeleted($isDeleted)
    {
        $this->isDeleted = $isDeleted;

        return $this;
    }

    /**
     * Get isDeleted
     *
     * @return boolean
     */
    public function getIsDeleted()
    {
        return $this->isDeleted;
    }

    /**
     * Set financingCompany
     *
     * @param \RxConnexionBundle\Entity\FinancingCompanyEntity $financingCompany
     *
     * @return PatientPaymentEntity
     */
    public function setFinancingCompany(\RxConnexionBundle\Entity\FinancingCompanyEntity $financingCompany = null)
    {
        $this->financingCompany = $financingCompany;

        return $this;
    }

    /**
     * Get financingCompany
     *
     * @return \RxConnexionBundle\Entity\FinancingCompanyEntity
     */
    public function getFinancingCompany()
    {
        return $this->financingCompany;
    }

    /**
     * Set newInvoiceNoForFinancing
     *
     * @param integer $newInvoiceNoForFinancing
     *
     * @return PatientPaymentEntity
     */
    public function setNewInvoiceNoForFinancing($newInvoiceNoForFinancing)
    {
        $this->newInvoiceNoForFinancing = !empty($newInvoiceNoForFinancing) ? $newInvoiceNoForFinancing : NULL;

        return $this;
    }

    /**
     * Get newInvoiceNoForFinancing
     *
     * @return integer
     */
    public function getNewInvoiceNoForFinancing()
    {
        return $this->newInvoiceNoForFinancing;
    }

    /**
     * Set patientBillingFinancing
     *
     * @param \RxConnexionBundle\Entity\PatientBillingEntity $patientBillingFinancing
     *
     * @return PatientPaymentEntity
     */
    public function setPatientBillingFinancing(\RxConnexionBundle\Entity\PatientBillingEntity $patientBillingFinancing = null)
    {
        $this->patientBillingFinancing = $patientBillingFinancing;

        return $this;
    }

    /**
     * Get patientBillingFinancing
     *
     * @return \RxConnexionBundle\Entity\PatientBillingEntity
     */
    public function getPatientBillingFinancing()
    {
        return $this->patientBillingFinancing;
    }

    /**
     * Set paymentStatus
     *
     * @param string $paymentStatus
     *
     * @return PatientPaymentEntity
     */
    public function setPaymentStatus($paymentStatus)
    {
        $this->paymentStatus = $paymentStatus;

        return $this;
    }

    /**
     * Get paymentStatus
     *
     * @return string
     */
    public function getPaymentStatus()
    {
        return $this->paymentStatus;
    }

    /**
     * Set prevSysInvoiceNo
     *
     * @param integer $prevSysInvoiceNo
     *
     * @return PatientPaymentEntity
     */
    public function setPrevSysInvoiceNo($prevSysInvoiceNo)
    {
        $this->prevSysInvoiceNo = !empty($prevSysInvoiceNo) ? $prevSysInvoiceNo : NULL;

        return $this;
    }

    /**
     * Get prevSysInvoiceNo
     *
     * @return integer
     */
    public function getPrevSysInvoiceNo()
    {
        return $this->prevSysInvoiceNo;
    }

    /**
     * Set prevSysInvoiceBranch
     *
     * @param string $prevSysInvoiceBranch
     *
     * @return PatientPaymentEntity
     */
    public function setPrevSysInvoiceBranch($prevSysInvoiceBranch)
    {
        $this->prevSysInvoiceBranch = $prevSysInvoiceBranch;

        return $this;
    }

    /**
     * Get prevSysInvoiceBranch
     *
     * @return string
     */
    public function getPrevSysInvoiceBranch()
    {
        return $this->prevSysInvoiceBranch;
    }

    /**
     * Set payTypeForPrint
     *
     * @param string $payTypeForPrint
     *
     * @return PatientPaymentEntity
     */
    public function setPayTypeForPrint($payTypeForPrint)
    {
        $this->payTypeForPrint = $payTypeForPrint;

        return $this;
    }

    /**
     * Get payTypeForPrint
     *
     * @return string
     */
    public function getPayTypeForPrint()
    {
        return $this->payTypeForPrint;
    }

    /**
     * Set patientRental
     *
     * @param \RxConnexionBundle\Entity\PatientRentalEntity $patientRental
     *
     * @return PatientPaymentEntity
     */
    public function setPatientRental(\RxConnexionBundle\Entity\PatientRentalEntity $patientRental = null)
    {
        $this->patientRental = $patientRental;

        return $this;
    }

    /**
     * Get patientRental
     *
     * @return \RxConnexionBundle\Entity\PatientRentalEntity
     */
    public function getPatientRental()
    {
        return $this->patientRental;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->patientPaymentBreakdowns = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add patientPaymentBreakdown
     *
     * @param \RxConnexionBundle\Entity\PatientPaymentBreakdownEntity $patientPaymentBreakdown
     *
     * @return PatientPaymentEntity
     */
    public function addPatientPaymentBreakdown(\RxConnexionBundle\Entity\PatientPaymentBreakdownEntity $patientPaymentBreakdown)
    {
        $this->patientPaymentBreakdowns[] = $patientPaymentBreakdown;

        return $this;
    }

    /**
     * Remove patientPaymentBreakdown
     *
     * @param \RxConnexionBundle\Entity\PatientPaymentBreakdownEntity $patientPaymentBreakdown
     */
    public function removePatientPaymentBreakdown(\RxConnexionBundle\Entity\PatientPaymentBreakdownEntity $patientPaymentBreakdown)
    {
        $this->patientPaymentBreakdowns->removeElement($patientPaymentBreakdown);
    }

    /**
     * Get patientPaymentBreakdowns
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getPatientPaymentBreakdowns()
    {
        return $this->patientPaymentBreakdowns;
    }

    /**
     * Set accountingBillings
     *
     * @param \RxConnexionBundle\Entity\AccountingBillingEntity $accountingBillings
     *
     * @return PatientPaymentEntity
     */
    public function setAccountingBillings(\RxConnexionBundle\Entity\AccountingBillingEntity $accountingBillings = null)
    {
        $this->accountingBillings = $accountingBillings;

        return $this;
    }

    /**
     * Get accountingBillings
     *
     * @return \RxConnexionBundle\Entity\AccountingBillingEntity
     */
    public function getAccountingBillings()
    {
        return $this->accountingBillings;
    }

    /**
     * Add accountingBilling
     *
     * @param \RxConnexionBundle\Entity\AccountingBillingEntity $accountingBilling
     *
     * @return PatientPaymentEntity
     */
    public function addAccountingBilling(\RxConnexionBundle\Entity\AccountingBillingEntity $accountingBilling)
    {
        $this->accountingBillings[] = $accountingBilling;

        return $this;
    }

    /**
     * Remove accountingBilling
     *
     * @param \RxConnexionBundle\Entity\AccountingBillingEntity $accountingBilling
     */
    public function removeAccountingBilling(\RxConnexionBundle\Entity\AccountingBillingEntity $accountingBilling)
    {
        $this->accountingBillings->removeElement($accountingBilling);
    }
}
