Files
taxes/project/src/Logic/Dividends/DividendsSummary.php
T
2026-04-13 12:14:49 +02:00

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;
}
}