<?php

  /**
   * Invoice payments implementation
   *
   * @package activeCollab.modules.invoicing
   * @subpackage models
   */
  class IInvoicePaymentsImplementation extends IPaymentsImplementation {
    
    /**
     * Construct invoice payment implementation
     * 
     * @param Invoice $object
     */
    function __construct(Invoice $object) {
      if($object instanceof Invoice) {
        parent::__construct($object);
      } else {
        throw new InvalidInstanceError('object', $object, 'Invoice');
      } // if
    } // __construct
     
    /**
     * Return amount left for paying
     * 
     * @return float
     */
    function getAmountToPay() {
      $taxed_total = str_replace(',','.',strval($this->object->getTaxedTotal()));
      $paid_amount = str_replace(',','.',strval($this->getPaidAmount()));
      
      if(function_exists('bcsub')) {
        $left_to_pay = bcsub($taxed_total,$paid_amount,3);
      } else {
        $left_to_pay = $taxed_total - $paid_amount;
      }//if
     
      if($left_to_pay < 0) {
        return 0; 
      } else {
        return $left_to_pay;
      } // if
    } // getAmountToPay
    
    /**
     * Return % amount left for paying
     * 
     * @return float
     */
    function getPercentPaid() {
      return (float) number_format(($this->getPaidAmount() * 100) / $this->object->getTaxedTotal(), 2, '.', '');
    } // getPercentPaid
    
    /**
     * Change invoice status
     * 
     * @param User $user
     * @param Payment $payment
     */
    function changeStatus(User $by, $payment = null) {
      try {
        DB::beginWork('Change invoice status @ ' . __CLASS__);
        
        if($this->getAmountToPay() == 0 && $this->object->getStatus() == INVOICE_STATUS_ISSUED) {
          $this->gag(); // Make sure that no notifications are sent, we'll send notifications with markAsPaid() invoice method
          $this->object->markAsPaid($by, $payment); // Mark as paid
        } elseif($this->getAmountToPay() > 0 && $this->object->getStatus() == INVOICE_STATUS_PAID) {
          $this->object->setStatus(INVOICE_STATUS_ISSUED, $this->object->getIssuedBy(), $this->object->getIssuedOn()); // Revert to issued
          $this->object->save();
        } // if
        
        DB::commit('Invoice status changed @ ' . __CLASS__);
      } catch(Exception $e) {
        DB::rollback('Failed to update invoice status @ ' . __CLASS__);
        throw $e;
      } // try
    } // changeStatus
    
    /**
     * Check can payment be paid
     * 
     * @param float $amount_to_pay
     * @return boolean
     */
    function canMarkAsPaid($amount_to_pay) {
      $will_be_paid = $this->getPaidAmount() + $amount_to_pay;
      if($this->getAmountToPay() == 0 || $this->object->getTaxedTotal() < $will_be_paid) {
        throw new Error(lang("If you add this payment you will run over maximum payment amount. No payment added"));
      } // if
      
      return true;
    } // canMarkAsPaid
    
  }