<?php

namespace App\Utils\Invoices;

/**
 * Determines the cashed status of a client invoice based on total value and cashed value.
 * @author Gabriel Grosu
 */
class DetermineClientInvoiceCashedStatus
{

	/**
	 * The invoice total value.
	 * @var float
	 */
	protected $invoiceTotal;

	/**
	 * The invoice tolerance, based on a configured percent.
	 * @var float
	 */
	protected $tolerancePercent;

	/**
	 *
	 * @param float $invoiceTotal
	 */
	public function __construct(float $invoiceTotal)
	{

		$this->invoiceTotal = round($invoiceTotal, 3); // rounds the the max decimals compared to all currencies

		$CFG = \Engine\Loader_Cfg::getInstance()->getGlobal();
		$this->tolerancePercent = $CFG['invoiceCashing']['statusTolerancePercent'];
	}

	/**
	 * Returns the cashed status: 'n' (not cashed), 'p' (partially cashed), 't' (totally cashed)
	 * and 'o' (over-cashed).
	 * @param float  $cashedValue
	 * @return string
	 */
	public function getStatus(float $cashedValue) :string
	{

		// cashing tolerance
		$statusTolerance = abs($this->invoiceTotal * $this->tolerancePercent);

		$cashedStatus = null;

		if ($this->invoiceTotal==0) { // if invoice is exactly 0
			$cashedStatus = 't';
		}
		// determine the cashed status
		elseif ($this->invoiceTotal>=0) { // invoice total is positive
			// cashed status is 'n'
			if ($cashedValue<$statusTolerance) $cashedStatus='n';
			// cashed status is 'p'
			elseif ($cashedValue<($this->invoiceTotal-$statusTolerance)) $cashedStatus='p';
			// cashed status is 't'
			elseif ($cashedValue<($this->invoiceTotal+$statusTolerance)) $cashedStatus='t';
			// cashed status is 'o'
			else $cashedStatus='o';
		} else { // invoice total is negative
			// cashed status is 'n'
			if ($cashedValue>-$statusTolerance) $cashedStatus='n';
			// cashed status is 'p'
			elseif ($cashedValue>($this->invoiceTotal+$statusTolerance)) $cashedStatus='p';
			// cashed status is 't'
			elseif ($cashedValue>($this->invoiceTotal-$statusTolerance)) $cashedStatus='t';
			// cashed status is 'o'
			else $cashedStatus='o';
		}

		return $cashedStatus;

	}

}
