203 lines
6.3 KiB
PHP
203 lines
6.3 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace App\Logic\Dividends;
|
|
|
|
use App\Enum\MarketNames;
|
|
use App\Helper\Currency;
|
|
use Doctrine\ORM\EntityManager;
|
|
|
|
class DividendsSummary
|
|
{
|
|
/** @var SheetDataAll|array $sheetData */
|
|
private array $sheetData=[];
|
|
/** @var XMLReader|array $sheetData */
|
|
private array $xmlData=[];
|
|
private Currency $currencyObj;
|
|
/** @var array|DividendsData $error */
|
|
private ?array $errorDividend=null;
|
|
private ?array $errorString=null;
|
|
private array $allData=[];
|
|
private array $countryToCurrency=[];
|
|
private int $realCalculatedRows = 0;
|
|
/** @var array|MarketNames $markets */
|
|
private array $markets=[];
|
|
|
|
public function __construct(EntityManager $manager)
|
|
{
|
|
$this->currencyObj = new Currency($manager);
|
|
}
|
|
|
|
public function addMarket(?MarketNames $names)
|
|
{
|
|
$this->markets[] = $names ?? MarketNames::MBANK;
|
|
}
|
|
|
|
public function getMarkets(): array
|
|
{
|
|
return $this->markets;
|
|
}
|
|
public function getSummaryByCountry() : array
|
|
{
|
|
$return=[];
|
|
$this->countFromSheets();
|
|
|
|
if (count($this->allData) > 0) {
|
|
$sum = 0;
|
|
$profitSum = 0;
|
|
foreach ($this->allData as $key => $item) {
|
|
$val = round($item['tax'], 2);
|
|
$sum += $val;
|
|
$profitSum += $item['incomeAll'];
|
|
$return[$key] = [
|
|
"country" => \Locale::getDisplayRegion("-".$key),
|
|
"income" => $item['incomeAll'],
|
|
"currency" => $this->countryToCurrency[$key],
|
|
"tax" => $item['tax'],
|
|
"destiny_tax" => $item['destiny_tax'],
|
|
"tax_cost" => $item['tax_cost'],
|
|
"incomesArray" => $item['incomes']
|
|
];
|
|
}
|
|
// >
|
|
$return['sum'] = [
|
|
"tax" => intval(ceil($sum)),
|
|
"profit" => $profitSum
|
|
];
|
|
}
|
|
|
|
return $return;
|
|
}
|
|
|
|
private function countFromSheets() : void
|
|
{
|
|
if (!count($this->sheetData)) {
|
|
return;
|
|
}
|
|
$test=[];
|
|
$countryToCurrency=[];
|
|
/** @var SheetData $sheetDatum */
|
|
foreach ($this->sheetData as $sheetDatum) {
|
|
$all = $sheetDatum->getByCountry();
|
|
foreach ($all as $country => $item) {
|
|
/** @var DividendsData $val */
|
|
foreach ($item as $val) {
|
|
if (!isset($test[$country])){
|
|
$test[$country] = [
|
|
"incomeAll" => 0,
|
|
"tax" => 0,
|
|
"destiny_tax" => 0,
|
|
"tax_cost" => 0,
|
|
"incomes" => []
|
|
];
|
|
}
|
|
if (!isset($test[$country]['incomes'][$val->getTax()])) {
|
|
$test[$country]['incomes'][$val->getTax()] = 0;
|
|
}
|
|
if ($this->getRate($val) < 1) {
|
|
die("Rate for date: ".$val->getDateTime()->format("Y-m-d")." / ".$val->getCurrency() . " is 0");
|
|
}
|
|
$income = round($val->getCount()*$val->getValue()*$this->getRate($val),5);
|
|
$test[$country]['incomeAll'] += $income;
|
|
$test[$country]['tax'] += round($this->count($val),5);
|
|
$test[$country]['destiny_tax'] += round($this->count($val,true),5);
|
|
$test[$country]['tax_cost'] += round($this->countTaxPrice($val),5);
|
|
$test[$country]['incomes'][$val->getTax()] += $income;
|
|
if (!isset($countryToCurrency[$country])) {
|
|
$countryToCurrency[$country] = $val->getCurrency();
|
|
}
|
|
$this->realCalculatedRows++;
|
|
}
|
|
}
|
|
}
|
|
foreach ($test as &$item) {
|
|
ksort($item['incomes']);
|
|
}
|
|
unset($item);
|
|
$this->allData = $test;
|
|
$this->countryToCurrency = array_merge($this->countryToCurrency,$countryToCurrency);
|
|
}
|
|
|
|
private function getRate(DividendsData $data) : float
|
|
{
|
|
if (!Currency::isCurrencyExists($data->getCurrency())) {
|
|
$this->errorString[$data->getCurrency()] = "Currency: {$data->getCurrency()} is not supported! Please contact with administrator.";
|
|
return 0;
|
|
}
|
|
return $this->currencyObj->getRate($data->getCurrency(),$data->getDateTime());
|
|
}
|
|
|
|
private function count(DividendsData $data, bool $fromDestiny = false) : float
|
|
{
|
|
$value = round($data->getCount()*$data->getValue(),5);
|
|
$tax = 19;
|
|
if ($data->getTax() > 0) {
|
|
$tax = 4;
|
|
}
|
|
if ($fromDestiny) {
|
|
$tax = $data->getTax();
|
|
}
|
|
|
|
$valueTax = round($value * $tax / 100,5);
|
|
$rate = $this->getRate($data);
|
|
if ($rate > 0) {
|
|
return $valueTax * $rate;
|
|
}
|
|
$this->errorDividend[]=$data;
|
|
return 0;
|
|
}
|
|
|
|
private function countTaxPrice(DividendsData $data) : float
|
|
{
|
|
if ($data->getTax() == 0) {
|
|
return 0;
|
|
}
|
|
$value = round($data->getCount()*$data->getValue(),5);
|
|
$tax = min($data->getTax(),15);
|
|
$valueTax = round($value * $tax / 100,5);
|
|
$rate = $this->getRate($data);
|
|
if ($rate > 0) {
|
|
return $valueTax * $rate;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @param SheetDataAll $sheetData
|
|
*/
|
|
public function addSheetData(SheetDataAll $sheetData): void
|
|
{
|
|
$this->sheetData[] = $sheetData;
|
|
}
|
|
|
|
/**
|
|
* @param XMLReader $reader
|
|
*/
|
|
public function addXml(XMLReader $reader)
|
|
{
|
|
$this->xmlData[] = $reader;
|
|
}
|
|
|
|
public function takeCountRawData(): array
|
|
{
|
|
$rowCount = 0;
|
|
/** @var SheetData $sheetDatum */
|
|
foreach ($this->sheetData as $sheetDatum) {
|
|
$rowCount += $sheetDatum->getCount();
|
|
}
|
|
return [
|
|
'countSheet' => count($this->sheetData),
|
|
'countRows' => $rowCount,
|
|
'realCountRows' => $this->realCalculatedRows
|
|
];
|
|
}
|
|
|
|
public function getErrorDividend(): ?array
|
|
{
|
|
return $this->errorDividend;
|
|
}
|
|
public function getErrorString(): ?array
|
|
{
|
|
return $this->errorString;
|
|
}
|
|
|
|
} |