<?php
 namespace App\PartnerBalance; abstract class GeneralAbstract { protected $idEntity; protected $currency; protected $tableName; protected $tableColumnIdEntity; protected $fullBalance = null; protected $tolerance = 0.0001; static protected $instance = []; final protected function __construct($idEntity) { if (!is_numeric($idEntity) and $idEntity<=0) { throw new \Exception('The entity id is not set for class `'.get_called_class().'`.'); } $this->setTableDetails(); if (!$this->tableName) { throw new \Exception('The table name for class `'.get_called_class().'` is not set.'); } if (!$this->tableColumnIdEntity) { throw new \Exception('The entity id table column for class `'.get_called_class().'` is not set.'); } $this->idEntity = $idEntity; } static public function getInstance($idEntity) { $currClass = get_called_class(); if (!static::$instance[$currClass][$idEntity]) { static::$instance[$currClass][$idEntity] = new static($idEntity); } return static::$instance[$currClass][$idEntity]; } abstract protected function setTableDetails(); public function getFullBalance() { if ($this->fullBalance===null) { $this->fullBalance = $this->getFullBalanceFromDb(false); } return $this->fullBalance; } public function getEquivBalance($currency=null, $currencyDate=TODAY_ISO, $currencyType=null) { $balDet = $this->getFullBalance(); if (!$balDet) { return 0; } if (!$currency) { $currency = \App\Config\Currencies::getInstance()->getDefaultCurrency(); } if (!$currencyType) { $currencyType = \App\Config\CurrencyTypes::getInstance()->getDefaultCurrencyType(); } $ttl = 0; foreach($balDet as $curr=>$val) { $ttl += \App\CurrencyExchange\Rates::getInstance($currencyDate, $currencyType)->convert($val, $curr, $currency); } return round($ttl, 3); } protected function getFullBalanceFromDb($selectForUpdate) { $db = \DB::getInstance(); $getBalancesSQL = "SELECT `currency`, `value` FROM `{$this->tableName}` WHERE `{$this->tableColumnIdEntity}`=?"; if ($selectForUpdate) { $getBalancesSQL .= " FOR UPDATE"; } $getBalancesEx = $db->Execute($getBalancesSQL, [$this->idEntity]); if (!$getBalancesEx) { throw new \DBException('Could not get entity balance for id = '.$this->idEntity.' ; class = '.get_called_class()); } $return = []; while ($row=$getBalancesEx->FetchRow()) { $return[$row['currency']] = (Float)$row['value']; } return $return; } public function getCurrencyBalance($currency) { $bals = $this->getFullBalance(); return (Float)$bals[$currency]; } protected function updateBalance($currency, $value) { if (!$value) { return true; } $bals = $this->getFullBalanceFromDb(true); if ($bals[$currency]) { $initialBalance = $bals[$currency]; } else { $initialBalance = 0; } $finalBalance = $initialBalance + $value; if (abs($finalBalance)<$this->tolerance) { $finalBalance = 0; } if (!$finalBalance) { $updateBalanceSQL = "DELETE FROM `{$this->tableName}` WHERE `{$this->tableColumnIdEntity}`=? AND currency=?"; $prepVals = [$this->idEntity, $currency]; } elseif ($initialBalance) { $updateBalanceSQL = "UPDATE `{$this->tableName}` SET value = ? WHERE `{$this->tableColumnIdEntity}`=? AND currency=?"; $prepVals = [$finalBalance, $this->idEntity, $currency]; } else { $updateBalanceSQL = "INSERT INTO `{$this->tableName}` (`{$this->tableColumnIdEntity}`, `currency`, `value`) VALUES (?, ?, ?)"; $prepVals = [$this->idEntity, $currency, $finalBalance]; } $db = \DB::getInstance(); $updateBalanceEx = $db->Execute($updateBalanceSQL, $prepVals); if (!$updateBalanceEx) { throw new \DBException('Failed to update entity balance for '.get_called_class()); } $this->fullBalance = null; } } 