<?php

namespace AppBundle\Entity\Billing;

use AppBundle\Annotation\ExportTranslate;
use AppBundle\Annotation\ExportSplitFields;
use AppBundle\Entity\AccessAndFunction\Access;
use AppBundle\Entity\Core\File;
use AppBundle\Entity\Core\Tagg;
use AppBundle\Enum\Billing\PaymentStateEnum;
use AppBundle\Enum\Billing\PaymentTypeEnum;
use Doctrine\ORM\Mapping as ORM;
use Dunglas\ApiBundle\Annotation\Iri;
use Sabre\VObject\Property\VCard\DateTime;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use AppBundle\Entity\Traits\TimestampableEntity;
use AppBundle\Entity\Traits\CreatorUpdaterEntity;
use AppBundle\Entity\Organization\Organization;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Annotation\DefaultField;


/**
 * Facture ou avoir (@see Bill, BillCredit)
 *
 * @Iri("http://schema.org/BillAccounting")
 */
#[ORM\Entity(repositoryClass: 'AppBundle\Entity\Billing\Repository\BillRepository')]
#[ORM\Table(name: 'BillAccounting')]
#[ORM\InheritanceType('SINGLE_TABLE')]
#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
#[ORM\DiscriminatorMap(['billaccounting' => 'BillAccounting', 'bill' => 'Bill', 'billcredit' => 'BillCredit', 'advancepayment' => 'AdvancePayment'])]
class BillAccounting implements BillAccountingInterface
{
    use TimestampableEntity;
    use CreatorUpdaterEntity;
    /**
     * @var int
     */
    #[ORM\Column(type: 'integer')]
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[Groups(['bill', 'billaccounting', 'billaccounting_list', 'bill_list', 'billcredit_list', 'billpayment_list', 'my_bills_show', 'advancepayment_list', 'advance_payment_schoolyear', 'build_bills', 'my_bills_show', 'advancepayment_list', 'advance_payment_schoolyear'])]
    private $id;
    /**
     * @var Organization
     *
     * @DefaultField
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Organization\Organization')]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting', 'bill', 'billcredit'])]
    private $organization;
    /**
     * @var Access
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\AccessAndFunction\Access', inversedBy: 'bills')]
    #[ORM\JoinColumn(nullable: false)]
    #[Assert\NotNull]
    #[Groups(['billaccounting', 'bill', 'advancepayment', 'billaccounting_list', 'bill_list', 'billpayment_list_bill', 'billcredit_list', 'advancepayment_list', 'build_bills', 'billcredit_list', 'advancepayment_list'])]
    private $access;
    /**
     * @var BillAccessDetail
     */
    #[Assert\Valid]
    #[ORM\OneToOne(targetEntity: 'AppBundle\Entity\Billing\BillAccessDetail', cascade: ['persist'], orphanRemoval: true, fetch: 'EAGER')]
    #[Groups(['billaccounting', 'bill', 'billaccounting_list', 'billpayment_list_bill', 'bill_list', 'billcredit_list', 'build_bills'])]
    private $accessDetail;
    /**
     * @var string
     *
     *
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['bill', 'billaccounting'])]
    private $reference;
    /**
     * @var int
     */
    #[ORM\Column(type: 'integer', nullable: true)]
    #[Groups(['bill', 'billaccounting', 'build_bills'])]
    private $customerReference;
    /**
     * @var string
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['billaccounting', 'bill', 'advancepayment', 'billaccounting_list', 'bill_list', 'billaccounting_list_bill', 'billcredit_list', 'billpayment_list_bill', 'my_bills_show_bills', 'advancepayment_list', 'advancepayment_list_bill', 'build_bills', 'my_bills_show_bills', 'advancepayment_list', 'advancepayment_list_bill'])]
    private $billNumber;
    /**
     * @var int
     */
    #[ORM\Column(type: 'integer', nullable: true)]
    #[Groups(['bill', 'billaccounting', 'build_bills'])]
    private $billNumberInteger;
    /**
     * @var int
     */
    #[ORM\Column(type: 'integer', nullable: true)]
    #[Groups(['bill', 'billaccounting'])]
    private $billCreditInteger;
    /**
     * @var \DateTime
     */
    #[ORM\Column(type: 'date', nullable: true)]
    #[Assert\Date]
    #[Groups(['billaccounting', 'bill', 'advancepayment', 'billaccounting_list', 'bill_list', 'billpayment_list_bill', 'my_bills_show_bills', 'billcredit_list', 'advancepayment_list', 'build_bills', 'billcredit_list', 'advancepayment_list'])]
    private $billingDate;
    /**
     * @var string
     *
     *
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['billaccounting', 'bill'])]
    private $object;
    /**
     * @var string
     */
    #[ORM\Column(type: 'text', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['billaccounting', 'bill', 'build_bills'])]
    private $comments;
    /**
     * @var ArrayCollection<BillLine>
     */
    #[Assert\Valid]
    #[ORM\OneToMany(targetEntity: 'BillLine', mappedBy: 'bill', cascade: ['persist'], orphanRemoval: true)]
    #[Groups(['billaccounting', 'bill_billline', 'billaccounting_list', 'billpayment_list_bill', 'bill_list', 'billaccounting_list_bill', 'billcredit_list_bill', 'build_bills'])]
    private $billLines;
    /**
     * @var ArrayCollection<BillCredit>
     */
    #[Assert\Valid]
    #[ORM\OneToMany(targetEntity: 'BillCredit', mappedBy: 'bill', cascade: ['persist'], orphanRemoval: true)]
    #[Groups(['billaccounting', 'bill_billcredit', 'billaccounting_list', 'bill_list', 'advancepayment_list', 'advance_payment_schoolyear'])]
    private $billCredits;
    /**
     * @var ArrayCollection<BillPayment>
     */
    #[Assert\Valid]
    #[ORM\OneToMany(targetEntity: 'BillPayment', mappedBy: 'bill', cascade: ['persist'], orphanRemoval: true)]
    #[Groups(['billaccounting', 'bill_billpayment', 'build_bills'])]
    private $billPayments;
    /**
     * @var float
     */
    #[Assert\Type(type: 'float')]
    #[Groups(['billaccounting', 'bill', 'billaccounting_list', 'bill_list', 'my_bills_show_bills', 'advancepayment_list', 'my_bills_show_bills', 'advancepayment_list', 'build_bills'])]
    private $totalAmountSet;
    /**
     * @var float
     */
    #[Assert\Type(type: 'float')]
    #[Groups(['billaccounting', 'bill', 'billaccounting_list', 'bill_list', 'my_bills_show_bills', 'advancepayment_list'])]
    private $totalPending;
    /**
     * @var float
     */
    #[Assert\Type(type: 'float')]
    #[Groups(['billaccounting', 'bill', 'billaccounting_list', 'bill_list', 'my_bills_show_bills', 'my_bills_show', 'build_bills'])]
    private $totalRemainingDue;
    /**
     * @var string
     * @ExportTranslate(true)
     */
    #[Assert\Type(type: 'string')]
    #[Groups(['billaccounting', 'bill', 'billaccounting_list', 'bill_list', 'my_bills_show_bills', 'advancepayment_list'])]
    private $paymentState;
    /**
     * @var array
     */
    #[ORM\Column(type: 'json_array', nullable: true)]
    #[Groups(['billaccounting', 'bill', 'build_bills'])]
    private $reductionTotal;
    /**
     * @var BillPeriod
     */
    #[Assert\Valid]
    #[ORM\OneToOne(targetEntity: 'AppBundle\Entity\Billing\BillPeriod', cascade: ['persist'], orphanRemoval: true, fetch: 'EAGER')]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting', 'bill', 'billaccounting_list', 'bill_list', 'billpayment_list_bill', 'billcredit_list', 'billaccounting_billperiod', 'advancepayment_list', 'build_bills', 'billcredit_list', 'billaccounting_billperiod', 'advancepayment_list'])]
    private $billPeriod;
    /**
     * @var BillTotalDetail
     */
    #[Assert\Valid]
    #[ORM\OneToOne(targetEntity: 'AppBundle\Entity\Billing\BillTotalDetail', cascade: ['persist'], orphanRemoval: true, fetch: 'EAGER')]
    #[Groups(['billaccounting', 'bill', 'advancepayment', 'billaccounting_list', 'bill_list', 'my_bills_show_bills', 'billcredit_list', 'build_bills'])]
    private $totalDetail;
    /**
     * @var File
     */
    #[Assert\Valid]
    #[ORM\OneToOne(targetEntity: 'AppBundle\Entity\Core\File', cascade: ['persist'], fetch: 'EAGER')]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting', 'bill', 'billaccounting_list', 'bill_list', 'billcredit_list', 'my_bills_show_bills'])]
    private $file;
    /**
     * @var string
     */
    #[Groups(['billaccounting', 'billaccounting_list', 'bill'])]
    private $billAccountingNumber;
    /**
     * @var string
     * @ExportTranslate(true)
     */
    #[Groups(['billaccounting', 'billaccounting_list'])]
    private $type;
    /**
     * @var Bill
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Billing\BillAccounting', inversedBy: 'billCredits')]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting', 'billcredit', 'billaccounting_list', 'billcredit_list', 'advancepayment_list', 'advance_payment_schoolyear'])]
    private $bill;
    /**
     * @var string
     */
    #[ORM\Column(type: 'text', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['billaccounting', 'billcredit', 'billcredit_list'])]
    private $message;
    /**
     * @var string
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['billaccounting', 'billcredit', 'billaccounting_list', 'billcredit_list'])]
    private $billCreditNumber;
    /**
     * @var ArrayCollection<BillingIntangibleExcludeDate>
     */
    #[Assert\Valid]
    #[ORM\OneToMany(targetEntity: 'BillingIntangibleExcludeDate', mappedBy: 'bill', cascade: ['persist'], orphanRemoval: true)]
    #[Groups(['billaccounting', 'bill'])]
    private $billingIntangibleExcludeDate;
    /**
     * @var Pes
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Billing\Pes', inversedBy: 'bills', cascade: ['persist'])]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting_list', 'billaccounting_pes'])]
    private $pes;
    /**
     * @var BergerLevrault
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Billing\BergerLevrault', inversedBy: 'bills', cascade: ['persist'])]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting_list'])]
    private $bergerLevrault;
    /**
     * @var BergerLevrault
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Billing\Ciril', inversedBy: 'bills', cascade: ['persist'])]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting_list'])]
    private $ciril;
    /**
     * @var Jvs
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Billing\Jvs', inversedBy: 'bills', cascade: ['persist'])]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting_list', 'billaccounting_jvs'])]
    private $jvs;
    /**
     * @var Jvs
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Billing\SddBank', inversedBy: 'bills', cascade: ['persist'])]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting_list'])]
    private $sddBank;
    /**
     * @var Jvs
     */
    #[ORM\ManyToOne(targetEntity: 'AppBundle\Entity\Billing\SddRegie', inversedBy: 'bills', cascade: ['persist'])]
    #[ORM\JoinColumn(nullable: true)]
    #[Groups(['billaccounting_list'])]
    private $sddRegie;
    /**
     * @var bool
     */
    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Assert\Type(type: 'boolean')]
    #[Assert\NotNull]
    #[Groups(['billaccounting'])]
    private $old = false;
    /**
     * @var array
     */
    #[Groups(['billaccounting', 'billaccounting_list', 'billpayment_list_bill', 'bill_list'])]
    private $listStudents;
    /**
     * @var bool
     */
    #[ORM\Column(type: 'boolean', options: ['default' => false])]
    #[Assert\Type(type: 'boolean')]
    #[Assert\NotNull]
    #[Groups(['billaccounting', 'bill', 'build_bills'])]
    private $sepaSampling= false;
    /**
     * @var \DateTime
     */
    #[ORM\Column(type: 'date', nullable: true)]
    #[Assert\Date]
    #[Groups(['billaccounting', 'bill', 'billaccounting_list', 'bill_list', 'billpayment_list_bill', 'build_bills'])]
    private $samplingDate;
    /**
     * @var \DateTime
     */
    #[ORM\Column(type: 'date', nullable: true)]
    #[Assert\Date]
    #[Groups(['bill', 'billaccounting', 'billaccounting_list', 'bill_list', 'my_bills_show_bills'])]
    private $availabilityDate;
    /**
     * @var string
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Groups(['bill'])]
    protected $payfipPaymentToken;
    /**
     * @var string
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Groups(['bill', 'build_bills'])]
    protected $enforceableTitle;
    /**
     * @var \DateTime
     */
    #[ORM\Column(type: 'date', nullable: true)]
    #[Assert\Date]
    #[Groups(['bill', 'billaccounting', 'billaccounting_list', 'bill_list', 'my_bills_show_bills'])]
    private $limitPaymentDate;
    /**
     * @var int
     */
    #[ORM\Column(type: 'integer', nullable: true)]
    #[Groups(['advancepayment', 'advancepayment_list'])]
    private $startSchoolYear;
    /**
     * @var string
     */
    #[ORM\Column(type: 'string', nullable: true)]
    #[Assert\Type(type: 'string')]
    #[Groups(['advancepayment', 'advancepayment_list'])]
    private $label;
    /**
     * @var bool
     */
    #[Assert\Type(type: 'boolean')]
    #[Groups(['advancepayment_list'])]
    private $isApplied;
    /**
     * @var ArrayCollection<Tagg>
     */
    #[ORM\ManyToMany(targetEntity: 'AppBundle\Entity\Core\Tagg', cascade: ['persist'], inversedBy: 'billAccountings')]
    #[Assert\Valid]
    #[ORM\JoinTable(name: 'tag_billAccounting', joinColumns: [], inverseJoinColumns: [])]
    #[ORM\JoinColumn(name: 'billAccounting_id', referencedColumnName: 'id')]
    #[ORM\JoinColumn(name: 'tag_id', referencedColumnName: 'id')]
    #[Groups(['billaccounting_tags', 'manage_tags', 'billaccounting_list', 'bill_list', 'billcredit_list', 'advancepayment_list'])]
    private $tags;
    /**
     * @var string
     *
     */
    #[Groups(['template', 'billaccounting_list'])]
    private $studentsTagsTemplate;
    /**
     * @var \DateTime
     */
    #[ORM\Column(type: 'datetime', nullable: true)]
    #[Assert\Date]
    private $payfipUrlDateTime;
    /**
     * The constructor
     */
    public function __construct() {
        $this->billLines = new ArrayCollection();
        $this->billCredits = new ArrayCollection();
        $this->billPayments = new ArrayCollection();
        $this->billingIntangibleExcludeDate = new ArrayCollection();
        $this->tags = new ArrayCollection();
    }
    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Sets id
     *
     * @param int $id
     * @return this
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }
    /**
     * Set reference
     *
     * @param string $reference
     *
     * @return Bill
     */
    public function setReference($reference)
    {
        $this->reference = $reference;

        return $this;
    }
    /**
     * Get reference
     *
     * @return string
     */
    public function getReference()
    {
        return $this->reference;
    }
    /**
     * Set billingDate
     *
     * @param \DateTime $billingDate
     *
     * @return Bill
     */
    public function setBillingDate($billingDate)
    {
        $this->billingDate = $billingDate;

        return $this;
    }
    /**
     * Get billingDate
     *
     * @return \DateTime
     */
    public function getBillingDate()
    {
        return $this->billingDate ? $this->billingDate->format('Y-m-d') : $this->billingDate;
    }
    /**
     * Set object
     *
     * @param string $object
     *
     * @return Bill
     */
    public function setObject($object)
    {
        $this->object = $object;

        return $this;
    }
    /**
     * Get object
     *
     * @return string
     */
    public function getObject()
    {
        return $this->object;
    }
    /**
     * Set comments
     *
     * @param string $comments
     *
     * @return Bill
     */
    public function setComments($comments)
    {
        $this->comments = $comments;

        return $this;
    }
    /**
     * Get comments
     *
     * @return string
     */
    public function getComments()
    {
        return $this->comments;
    }
    /**
     * Set totalPrice
     *
     * @param float $totalPrice
     *
     * @return Bill
     */
    public function setTotalPrice($totalPrice)
    {
        $this->totalPrice = floatval($totalPrice);

        return $this;
    }
    /**
     * Get totalPrice
     *
     * @return float
     */
    public function getTotalPrice()
    {
        return $this->totalPrice;
    }
    /**
     * Add billLine
     *
     * @param \AppBundle\Entity\Billing\BillLine $billLine
     *
     * @return BillAccounting
     */
    public function addBillLine(\AppBundle\Entity\Billing\BillLine $billLine)
    {
        $billLine->setBill($this);
        $this->billLines[] = $billLine;

        return $this;
    }
    /**
     * Remove billLine
     *
     * @param \AppBundle\Entity\Billing\BillLine $billLine
     */
    public function removeBillLine(\AppBundle\Entity\Billing\BillLine $billLine)
    {
        $this->billLines->removeElement($billLine);
    }
    /**
     * Get billLines
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBillLines()
    {
        return $this->billLines;
    }
    /**
     * Set totalVat
     *
     * @param float $totalVat
     *
     * @return Bill
     */
    public function setTotalVat($totalVat)
    {
        $this->totalVat = floatval($totalVat);

        return $this;
    }
    /**
     * Get totalVat
     *
     * @return float
     */
    public function getTotalVat()
    {
        return $this->totalVat;
    }
    /**
     * Set access
     *
     * @param \AppBundle\Entity\AccessAndFunction\Access $access
     *
     * @return Bill
     */
    public function setAccess(\AppBundle\Entity\AccessAndFunction\Access $access)
    {
        $this->access = $access;

        return $this;
    }
    /**
     * Get access
     *
     * @return \AppBundle\Entity\AccessAndFunction\Access
     */
    public function getAccess()
    {
        return $this->access;
    }
    /**
     * Add billCredit
     *
     * @param \AppBundle\Entity\Billing\BillCredit $billCredit
     *
     * @return Bill
     */
    public function addBillCredit(\AppBundle\Entity\Billing\BillCredit $billCredit)
    {
        $this->billCredits[] = $billCredit;
        $billCredit->setBill($this);
        return $this;
    }
    /**
     * Remove billCredit
     *
     * @param \AppBundle\Entity\Billing\BillCredit $billCredit
     */
    public function removeBillCredit(\AppBundle\Entity\Billing\BillCredit $billCredit)
    {
        $this->billCredits->removeElement($billCredit);
    }
    /**
     * Get billCredits
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBillCredits()
    {
        return $this->billCredits;
    }
    /**
     * Add billPayment
     *
     * @param \AppBundle\Entity\Billing\BillPayment $billPayment
     *
     * @return Bill
     */
    public function addBillPayment(\AppBundle\Entity\Billing\BillPayment $billPayment)
    {
        $billPayment->setBill($this);
        $this->billPayments[] = $billPayment;

        return $this;
    }
    /**
     * Remove billPayment
     *
     * @param \AppBundle\Entity\Billing\BillPayment $billPayment
     */
    public function removeBillPayment(\AppBundle\Entity\Billing\BillPayment $billPayment)
    {
        $this->billPayments->removeElement($billPayment);
    }
    /**
     * Get billPayments
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBillPayments()
    {
        return $this->billPayments;
    }
    /**
     * Get totalAmountSet
     *
     * @return float
     */
    public function getTotalAmountSet()
    {
        if(!is_null($this->getBill()) && get_class($this) !== AdvancePayment::class){
            return 0;
        }
        $totalAmountSet = 0;
        $billPayments = $this->getBillPayments();
        foreach ($billPayments as $billPayment) {
            if($billPayment->getIsAcquired()){
                $totalAmountSet += $billPayment->getAmount();
            }
            foreach ($billPayment->getBillDebitBalances() as $billDebitBalances) {
                if(!$billDebitBalances->getIsUsed())
                    $totalAmountSet -= $billDebitBalances->getAmount();
            }
        }
        return $totalAmountSet;
    }
    /**
     * Get totalAmountSet
     *
     * @return float
     */
    public function getTotalPending()
    {
        if(!is_null($this->getBill())){
            return 0;
        }
        $totalPending = 0;

        $billPayments = $this->getBillPayments();
        foreach ($billPayments as $billPayment) {
            if(!$billPayment->getIsAcquired()){
                $totalPending += $billPayment->getAmount();
            }
        }
        return $totalPending;
    }
    /**
     * Get totalRemainingDue
     *
     * @return float
     */
    public function getTotalRemainingDue()
    {
        if(!is_null($this->getBill()) || count($this->getBillCredits()) > 0 ){
            return 0;
        }
        $totalRemainingDue = null;
        if($this->totalDetail && !is_null($this->totalDetail)){
            $totalRemainingDue = round(floatval($this->totalDetail->getTtc()) - $this->getTotalAmountSet(), 2);
        }
        return $totalRemainingDue;
    }
    /**
     * Gets paymentState.
     *
     * @return string
     */
    public function getPaymentState()
    {
        if(!is_null($this->getBill()) || get_class($this) === AdvancePayment::class){
            return PaymentStateEnum::SOLDIER;
        }
        if(count($this->getBillCredits()) > 0 ){
            return PaymentStateEnum::SOLDIER;
        }

        $today = new \DateTime();
        $totalAmountSet = 0;
        $delayed = false;

        $billPayments = $this->getBillPayments();
        foreach ($billPayments as $billPayment) {
            /** @var BillPayment $billPayment **/
            if($billPayment->getIsAcquired()){
                $totalAmountSet += $billPayment->getAmount();
            }elseif(new \DateTime($billPayment->getReceiptDate()) < $today){
                $delayed = true;
            }
            foreach ($billPayment->getBillDebitBalances() as $billDebitBalances) {
                if(!$billDebitBalances->getIsUsed())
                    $totalAmountSet -= $billDebitBalances->getAmount();
            }
        }
        if($this->totalDetail && !is_null($this->totalDetail) && number_format(round($totalAmountSet,2),2,'','') >= number_format($this->totalDetail->getTtc(),2,'','')){
            return PaymentStateEnum::SOLDIER;
        }elseif($delayed){
            return PaymentStateEnum::DELAYED;
        }
        return PaymentStateEnum::TO_CASH_IN;
    }
    /**
     * Set billNumber
     *
     * @param string $billNumber
     *
     * @return Bill
     */
    public function setBillNumber($billNumber)
    {
        $this->billNumber = $billNumber;

        return $this;
    }
    /**
     * Get billNumber
     *
     * @return string
     */
    public function getBillNumber()
    {
        return $this->billNumber;
    }
    /**
     * Set reductionTotal
     *
     * @param array $reductionTotal
     *
     * @return Bill
     */
    public function setReductionTotal($reductionTotal)
    {
        $this->reductionTotal = $reductionTotal;

        return $this;
    }
    /**
     * Get reductionTotal
     *
     * @return array
     */
    public function getReductionTotal()
    {
        return $this->reductionTotal;
    }
    /**
     * Set customerReference
     *
     * @param integer $customerReference
     *
     * @return Bill
     */
    public function setCustomerReference($customerReference)
    {
        $this->customerReference = $customerReference;

        return $this;
    }
    /**
     * Get customerReference
     *
     * @return integer
     */
    public function getCustomerReference()
    {
        return $this->customerReference;
    }
    /**
     * Set file
     *
     * @param \AppBundle\Entity\Core\File $file
     *
     * @return Bill
     */
    public function setFile(\AppBundle\Entity\Core\File $file = null)
    {
        $this->file = $file;

        return $this;
    }
    /**
     * Get file
     *
     * @return \AppBundle\Entity\Core\File
     */
    public function getFile()
    {
        return $this->file;
    }
    /**
     * get billAccountingNumber
     *
     * @return mixed
     */
    public function getBillAccountingNumber()
    {
        $billAccountingNumber = '';
        if(get_class($this) === Bill::class || get_class($this) === AdvancePayment::class){
            $pes =  $this->organization->getSettings() && array_key_exists('Pes', $this->organization->getSettings()->getModules()) ? $this->organization->getSettings()->getModules()['Pes'] : false;

            if($pes && $this->getBillNumberInteger()){
                $billAccountingNumber = str_pad($this->getBillNumberInteger(), 13, '0', STR_PAD_LEFT);
            }else{
                $billAccountingNumber = $this->billNumber;
            }
        }
        if(get_class($this) === BillCredit::class){
            $billAccountingNumber = $this->billCreditNumber;
        }
        return $billAccountingNumber;
    }
    /**
     * get billAccountingNumber
     *
     * @return mixed
     */
    public function getType()
    {
        $explodeClass = explode("\\",get_class($this));
        return lcfirst(end($explodeClass));
    }
    /**
     * Set organization
     *
     * @param \AppBundle\Entity\Organization\Organization $organization
     *
     * @return BillAccounting
     */
    public function setOrganization(\AppBundle\Entity\Organization\Organization $organization = null)
    {
        $this->organization = $organization;

        return $this;
    }
    /**
     * Get organization
     *
     * @return \AppBundle\Entity\Organization\Organization
     */
    public function getOrganization()
    {
        return $this->organization;
    }
    /**
     * Set message
     *
     * @param string $message
     *
     * @return BillCredit
     */
    public function setMessage($message)
    {
        $this->message = $message;

        return $this;
    }
    /**
     * Get message
     *
     * @return string
     */
    public function getMessage()
    {
        return $this->message;
    }
    /**
     * Set bill
     *
     * @param \AppBundle\Entity\Billing\BillAccounting $bill
     *
     * @return BillCredit
     */
    public function setBill(\AppBundle\Entity\Billing\BillAccounting $bill)
    {
        $this->bill = $bill;

        return $this;
    }
    /**
     * Get bill
     *
     * @return \AppBundle\Entity\Billing\Bill
     */
    public function getBill()
    {
        return $this->bill;
    }
    /**
     * Set billCreditNumber
     *
     * @param string $billCreditNumber
     *
     * @return BillCredit
     */
    public function setBillCreditNumber($billCreditNumber)
    {
        $this->billCreditNumber = $billCreditNumber;

        return $this;
    }
    /**
     * Get billCreditNumber
     *
     * @return string
     */
    public function getBillCreditNumber()
    {
        return $this->billCreditNumber;
    }
    /**
     * Add billingIntangibleExcludeDate
     *
     * @param \AppBundle\Entity\Billing\BillingIntangibleExcludeDate $billingIntangibleExcludeDate
     *
     * @return BillAccounting
     */
    public function addBillingIntangibleExcludeDate(\AppBundle\Entity\Billing\BillingIntangibleExcludeDate $billingIntangibleExcludeDate)
    {
        $billingIntangibleExcludeDate->setBill($this);
        $this->billingIntangibleExcludeDate[] = $billingIntangibleExcludeDate;

        return $this;
    }
    /**
     * Remove billingIntangibleExcludeDate
     *
     * @param \AppBundle\Entity\Billing\BillingIntangibleExcludeDate $billingIntangibleExcludeDate
     */
    public function removeBillingIntangibleExcludeDate(\AppBundle\Entity\Billing\BillingIntangibleExcludeDate $billingIntangibleExcludeDate)
    {
        $this->billingIntangibleExcludeDate->removeElement($billingIntangibleExcludeDate);
    }
    /**
     * Get billingIntangibleExcludeDate
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBillingIntangibleExcludeDate()
    {
        return $this->billingIntangibleExcludeDate;
    }
    /**
     * Set pes
     *
     * @param \AppBundle\Entity\Billing\Pes $pes
     *
     * @return BillAccounting
     */
    public function setPes(\AppBundle\Entity\Billing\Pes $pes = null)
    {
        $this->pes = $pes;

        return $this;
    }
    /**
     * Get pes
     *
     * @return \AppBundle\Entity\Billing\Pes
     */
    public function getPes()
    {
        return $this->pes;
    }
    /**
     * Set sddBank
     *
     * @param \AppBundle\Entity\Billing\SddBank $sddBank
     *
     * @return BillAccounting
     */
    public function setSddBank(SddBank $sddBank = null)
    {
        $this->sddBank = $sddBank;

        return $this;
    }
    /**
     * Get SddBank
     *
     * @return \AppBundle\Entity\Billing\SddBank
     */
    public function getSddBank()
    {
        return $this->sddBank;
    }
    /**
     * Set SddRegie
     *
     * @param \AppBundle\Entity\Billing\SddRegie $sddRegie
     *
     * @return BillAccounting
     */
    public function setSddRegie(SddRegie $sddRegie= null)
    {
        $this->sddRegie = $sddRegie;

        return $this;
    }
    /**
     * Get SddRegie
     *
     * @return \AppBundle\Entity\Billing\SddRegie
     */
    public function getSddRegie()
    {
        return $this->sddRegie;
    }
    /**
     * Set old
     *
     * @param boolean $old
     *
     * @return BillAccounting
     */
    public function setOld($old)
    {
        $this->old = $old;

        return $this;
    }
    /**
     * Get old
     *
     * @return boolean
     */
    public function getOld()
    {
        return $this->old;
    }
    /**
     * Set period
     *
     * @param \AppBundle\Entity\Billing\BillPeriod $period
     *
     * @return BillAccounting
     */
    public function setBillPeriod(\AppBundle\Entity\Billing\BillPeriod $billPeriod = null)
    {
        $this->billPeriod = $billPeriod;

        return $this;
    }
    /**
     * Get period
     *
     * @return \AppBundle\Entity\Billing\BillPeriod
     */
    public function getBillPeriod()
    {
        return $this->billPeriod;
    }
    /**
     * Set totalDetail
     *
     * @param \AppBundle\Entity\Billing\BillTotalDetail $totalDetail
     *
     * @return BillAccounting
     */
    public function setTotalDetail(\AppBundle\Entity\Billing\BillTotalDetail $totalDetail = null)
    {
        $this->totalDetail = $totalDetail;

        return $this;
    }
    /**
     * Get totalDetail
     *
     * @return \AppBundle\Entity\Billing\BillTotalDetail
     */
    public function getTotalDetail()
    {
        return $this->totalDetail;
    }
    /**
     * Set accessDetail
     *
     * @param \AppBundle\Entity\Billing\BillAccessDetail $accessDetail
     *
     * @return BillAccounting
     */
    public function setAccessDetail(\AppBundle\Entity\Billing\BillAccessDetail $accessDetail = null)
    {
        $this->accessDetail = $accessDetail;

        return $this;
    }
    /**
     * Get accessDetail
     *
     * @return \AppBundle\Entity\Billing\BillAccessDetail
     */
    public function getAccessDetail()
    {
        return $this->accessDetail;
    }
    /**
     * get listStudents
     *
     * @return array
     */
    public function getListStudents()
    {
        $students = [];
        foreach($this->getBillLines() as $billLine){
            if(!empty($billLine->getAccess()))
                $students[] = $billLine->getAccess()->getPerson()->getFullNameTemplate();
        }

        return array_values(array_unique($students));
    }
    /**
     * Set billNumberInteger
     *
     * @param integer $billNumberInteger
     *
     * @return BillAccounting
     */
    public function setBillNumberInteger($billNumberInteger)
    {
        $this->billNumberInteger = $billNumberInteger;

        return $this;
    }
    /**
     * Get billNumberInteger
     *
     * @return integer
     */
    public function getBillNumberInteger()
    {
        return $this->billNumberInteger;
    }
    /**
     * Set billCreditInteger
     *
     * @param integer $billCreditInteger
     *
     * @return BillAccounting
     */
    public function setBillCreditInteger($billCreditInteger)
    {
        $this->billCreditInteger = $billCreditInteger;

        return $this;
    }
    /**
     * Get billCreditInteger
     *
     * @return integer
     */
    public function getBillCreditInteger()
    {
        return $this->billCreditInteger;
    }
    /**
     * Set sepaSampling
     *
     * @param boolean $sepaSampling
     *
     * @return BillAccounting
     */
    public function setSepaSampling($sepaSampling)
    {
        $this->sepaSampling = $sepaSampling;

        return $this;
    }
    /**
     * Get sepaSampling
     *
     * @return boolean
     */
    public function getSepaSampling()
    {
        return $this->sepaSampling;
    }
    /**
     * Set bergerLevrault
     *
     * @param \AppBundle\Entity\Billing\BergerLevrault $bergerLevrault
     *
     * @return BillAccounting
     */
    public function setBergerLevrault(\AppBundle\Entity\Billing\BergerLevrault $bergerLevrault = null)
    {
        $this->bergerLevrault = $bergerLevrault;

        return $this;
    }
    /**
     * Get bergerLevrault
     *
     * @return \AppBundle\Entity\Billing\BergerLevrault
     */
    public function getBergerLevrault()
    {
        return $this->bergerLevrault;
    }
    /**
     * Set samplingDate
     *
     * @param \DateTime $samplingDate
     *
     * @return BillAccounting
     */
    public function setSamplingDate($samplingDate)
    {
        $this->samplingDate = $samplingDate;

        return $this;
    }
    /**
     * Get samplingDate
     *
     * @return \DateTime
     */
    public function getSamplingDate()
    {
        return $this->samplingDate;
    }
    /**
     * Set availabilityDate
     *
     * @param \DateTime $availabilityDate
     *
     * @return BillAccounting
     */
    public function setAvailabilityDate($availabilityDate)
    {
        $this->availabilityDate = $availabilityDate;

        return $this;
    }
    /**
     * Get availabilityDate
     *
     * @return \DateTime
     */
    public function getAvailabilityDate()
    {
        return $this->availabilityDate;
    }
    /**
     * Set limitPaymentDate
     *
     * @param \DateTime $limitPaymentDate
     *
     * @return BillAccounting
     */
    public function setLimitPaymentDate($limitPaymentDate)
    {
        $this->limitPaymentDate = $limitPaymentDate;

        return $this;
    }
    /**
     * Get limitPaymentDate
     *
     * @return \DateTime
     */
    public function getLimitPaymentDate()
    {
        return $this->limitPaymentDate;
    }
    /**
     * Set payfipPaymentToken
     *
     * @param string $payfipPaymentToken
     *
     * @return BillAccounting
     */
    public function setPayfipPaymentToken($payfipPaymentToken)
    {
        $this->payfipPaymentToken = $payfipPaymentToken;

        return $this;
    }
    /**
     * Get payfipPaymentToken
     *
     * @return string
     */
    public function getPayfipPaymentToken()
    {
        return $this->payfipPaymentToken;
    }
    /**
     * Set jvs
     *
     * @param \AppBundle\Entity\Billing\Jvs $jvs
     *
     * @return BillAccounting
     */
    public function setJvs(\AppBundle\Entity\Billing\Jvs $jvs = null)
    {
        $this->jvs = $jvs;

        return $this;
    }
    /**
     * Get jvs
     *
     * @return \AppBundle\Entity\Billing\Jvs
     */
    public function getJvs()
    {
        return $this->jvs;
    }
    /**
     * Set enforceableTitle
     *
     * @param string $enforceableTitle
     *
     * @return BillAccounting
     */
    public function setEnforceableTitle($enforceableTitle)
    {
        $this->enforceableTitle = $enforceableTitle;

        return $this;
    }
    /**
     * Get enforceableTitle
     *
     * @return string
     */
    public function getEnforceableTitle()
    {
        return $this->enforceableTitle;
    }
    public function setStartSchoolYear($startSchoolYear)
    {
        $this->startSchoolYear = $startSchoolYear;

        return $this;
    }
    /**
     * Get startSchoolYear
     *
     * @return integer
     */
    public function getStartSchoolYear()
    {
        return $this->startSchoolYear;
    }
    /**
     * Set label
     *
     * @param string $label
     *
     * @return BillAccounting
     */
    public function setLabel($label = null)
    {
        $this->label = $label;

        return $this;
    }
    /**
     * Get label
     *
     * @return string
     */
    public function getLabel()
    {
        return $this->label;
    }
    /**
     * Gets paymentState.
     *
     * @return bool
     */
    public function getIsApplied()
    {
        return !empty($this->getBill());

    }
    /**
     * Add tag
     *
     * @param \AppBundle\Entity\Core\Tagg $tag
     *
     * @return BillAccounting
     */
    public function addTag(\AppBundle\Entity\Core\Tagg $tag)
    {
        $this->tags[] = $tag;

        return $this;
    }
    /**
     * Remove tag
     *
     * @param \AppBundle\Entity\Core\Tagg $tag
     */
    public function removeTag(\AppBundle\Entity\Core\Tagg $tag)
    {
        $this->tags->removeElement($tag);
    }
    /**
     * Get tags
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getTags()
    {
        return $this->tags;
    }
    /**
     * Gets students tags.
     *
     * @return array
     */
    public function getStudentsTagsTemplate()
    {
        $tags = [];

        foreach ($this->getBillLines() as $billLine){
            $access = $billLine->getAccess();
            if(!empty($access)){
                foreach ($access->getTags() as $billLineAcesstags){
                    $tags[] = $billLineAcesstags->getLabel();
                }
            }
        }

        if(!empty($this->getBill())){
            foreach ($this->getBill()->getBillLines() as $billLine){
                $access = $billLine->getAccess();
                if(!empty($access)){
                    foreach ($access->getTags() as $billLineAcesstags){
                        $tags[] = $billLineAcesstags->getLabel();
                    }
                }
            }
        }



        return array_unique($tags);
    }
    /**
     * Set ciril
     *
     * @param \AppBundle\Entity\Billing\Ciril $ciril
     *
     * @return BillAccounting
     */
    public function setCiril(\AppBundle\Entity\Billing\Ciril $ciril = null)
    {
        $this->ciril = $ciril;

        return $this;
    }
    /**
     * Get ciril
     *
     * @return \AppBundle\Entity\Billing\Ciril
     */
    public function getCiril()
    {
        return $this->ciril;
    }
    /**
     * Set payfipUrlDateTime
     *
     * @param \DateTime $payfipUrlDateTime
     *
     * @return BillAccounting
     */
    public function setPayfipUrlDateTime($payfipUrlDateTime)
    {
        $this->payfipUrlDateTime = $payfipUrlDateTime;

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