diff --git a/project/composer.json b/project/composer.json index 13a682b..e7a399c 100644 --- a/project/composer.json +++ b/project/composer.json @@ -4,9 +4,14 @@ "minimum-stability": "stable", "prefer-stable": true, "require": { - "php": ">=7.4", + "php": ">=8.1", "ext-ctype": "*", + "ext-curl": "*", + "ext-dom": "*", "ext-iconv": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-simplexml": "*", "doctrine/annotations": "^1.0", "doctrine/doctrine-bundle": "^2.5", "doctrine/doctrine-migrations-bundle": "^3.2", @@ -20,7 +25,7 @@ "symfony/doctrine-messenger": "5.4.*", "symfony/dotenv": "5.4.*", "symfony/expression-language": "5.4.*", - "symfony/flex": "^1.17|^2", + "symfony/flex": "^1.21", "symfony/form": "5.4.*", "symfony/framework-bundle": "5.4.*", "symfony/http-client": "5.4.*", @@ -45,12 +50,7 @@ "symfony/webpack-encore-bundle": "^1.14", "symfony/yaml": "5.4.*", "twig/extra-bundle": "^2.12|^3.0", - "twig/twig": "^2.12|^3.0", - "ext-curl": "*", - "ext-json": "*", - "ext-simplexml": "*", - "ext-dom": "*", - "ext-libxml": "*" + "twig/twig": "^2.12|^3.0" }, "config": { "allow-plugins": { diff --git a/project/composer.lock b/project/composer.lock index eef9fa9..dd4f7ae 100644 --- a/project/composer.lock +++ b/project/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c7d5407f0c4f5f2541c1ca93c55b048e", + "content-hash": "7f8576ede293dfe8fab8567bc5745665", "packages": [ { "name": "doctrine/annotations", @@ -4159,16 +4159,16 @@ }, { "name": "symfony/flex", - "version": "v1.18.5", + "version": "v1.21.6", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "10e438f53a972439675dc720706f0cd5c0ed94f1" + "reference": "06b58a5e5b4c6528fb12e0fac5fea0db3f1e7ae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/10e438f53a972439675dc720706f0cd5c0ed94f1", - "reference": "10e438f53a972439675dc720706f0cd5c0ed94f1", + "url": "https://api.github.com/repos/symfony/flex/zipball/06b58a5e5b4c6528fb12e0fac5fea0db3f1e7ae8", + "reference": "06b58a5e5b4c6528fb12e0fac5fea0db3f1e7ae8", "shasum": "" }, "require": { @@ -4204,7 +4204,7 @@ "description": "Composer plugin for Symfony", "support": { "issues": "https://github.com/symfony/flex/issues", - "source": "https://github.com/symfony/flex/tree/v1.18.5" + "source": "https://github.com/symfony/flex/tree/v1.21.6" }, "funding": [ { @@ -4220,7 +4220,7 @@ "type": "tidelift" } ], - "time": "2022-02-16T17:26:46+00:00" + "time": "2024-03-02T08:16:37+00:00" }, { "name": "symfony/form", @@ -8976,10 +8976,15 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=7.2.5", + "php": ">=7.4", "ext-ctype": "*", - "ext-iconv": "*" + "ext-curl": "*", + "ext-dom": "*", + "ext-iconv": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-simplexml": "*" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } diff --git a/project/src/Enum/MarketNames.php b/project/src/Enum/MarketNames.php new file mode 100644 index 0000000..96197d1 --- /dev/null +++ b/project/src/Enum/MarketNames.php @@ -0,0 +1,22 @@ +name))) { + $ret = $case; + break; + } + } + + return $ret; + } +} \ No newline at end of file diff --git a/project/src/Helper/Currency.php b/project/src/Helper/Currency.php index a35ada7..de99588 100644 --- a/project/src/Helper/Currency.php +++ b/project/src/Helper/Currency.php @@ -7,7 +7,7 @@ use Doctrine\ORM\EntityManager; class Currency { - public static array $currencies = ["USD","GBP","PLN","EUR","CAD"]; + public static array $currencies = ["USD","GBP","PLN","EUR","CAD","AUD"]; public static array $currenciesCrypto = ["USDT"]; private static string $apiUrl = "https://api.nbp.pl/api/exchangerates/rates/a/:code/:date/?format=json"; private EntityManager $manager; @@ -30,7 +30,6 @@ class Currency } $dateTime->modify("-$minusDay days"); $dateStr = $dateTime->format("Ymd"); - if (isset($this->ratesPerDate[$currency]) && isset($this->ratesPerDate[$currency][$dateStr])) { return $this->ratesPerDate[$currency][$dateStr]; } diff --git a/project/src/Helper/DataNeed/DividendValues.php b/project/src/Helper/DataNeed/DividendValues.php index 4b2f8c1..40ea5e7 100644 --- a/project/src/Helper/DataNeed/DividendValues.php +++ b/project/src/Helper/DataNeed/DividendValues.php @@ -20,6 +20,7 @@ class DividendValues public static function searchForKeyName(string $val) : ?string { $ret=null; + $val = trim($val); foreach (self::$samples as $key => $sample) { foreach ($sample as $item) { if (strpos($val, $item) !== false) { diff --git a/project/src/Helper/Sheets/ReadSheet.php b/project/src/Helper/Sheets/ReadSheet.php index 8c84787..b4104f4 100644 --- a/project/src/Helper/Sheets/ReadSheet.php +++ b/project/src/Helper/Sheets/ReadSheet.php @@ -2,17 +2,20 @@ declare(strict_types=1); namespace App\Helper\Sheets; +use App\Enum\MarketNames; use PhpOffice\PhpSpreadsheet\IOFactory; class ReadSheet { private string $filePath; private array $arr=[]; + private ?MarketNames $marketNames; - public function __construct(string $file) + public function __construct(string $file, ?MarketNames $marketNames) { if (file_exists($file)){ $this->filePath = $file; + $this->marketNames = $marketNames; } } @@ -27,10 +30,12 @@ class ReadSheet return false; } $fileType = explode(".", $this->filePath)[1]; - $reader = IOFactory::createReader(ucfirst($fileType)); $reader->setLoadAllSheets(); $reader->setReadDataOnly(true); + if ($this->marketNames && $this->marketNames === MarketNames::EXANTE) { + $reader->setInputEncoding("UTF-16"); + } if ($delimiter) { $reader->setDelimiter($delimiter); } diff --git a/project/src/Logic/Dividends/DividendsData.php b/project/src/Logic/Dividends/DividendsData.php index 4f670c2..b1a47ca 100644 --- a/project/src/Logic/Dividends/DividendsData.php +++ b/project/src/Logic/Dividends/DividendsData.php @@ -104,6 +104,6 @@ final class DividendsData */ public function setCurrency(string $currency): void { - $this->currency = $currency; + $this->currency = trim($currency); } } \ No newline at end of file diff --git a/project/src/Logic/Dividends/DividendsSummary.php b/project/src/Logic/Dividends/DividendsSummary.php index fb39b62..d2566a2 100644 --- a/project/src/Logic/Dividends/DividendsSummary.php +++ b/project/src/Logic/Dividends/DividendsSummary.php @@ -81,13 +81,15 @@ class DividendsSummary 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(); } diff --git a/project/src/Logic/Dividends/ExanteSheet.php b/project/src/Logic/Dividends/ExanteSheet.php index 8ac92b9..5e8fd67 100644 --- a/project/src/Logic/Dividends/ExanteSheet.php +++ b/project/src/Logic/Dividends/ExanteSheet.php @@ -14,10 +14,11 @@ class ExanteSheet extends SheetDataAll continue; } foreach ($rawDatum as $key => $value) { - if (strpos($value, "Comment") !== false) { + $value = strtolower($value); + if (str_contains($value, "comment")) { $commentKey = $key; } - if (strpos($value, "Operation type") !== false) { + if (str_contains($value, "operation type")) { $operationKey = $key; } } @@ -27,10 +28,15 @@ class ExanteSheet extends SheetDataAll if ($index<2) { continue; } - if (strtolower($rawDatum[$operationKey]) === "tax") { + $operationType = strtolower($rawDatum[$operationKey]); + + if (!str_contains($operationType,"dividend")) { continue; } $comment = $rawDatum[$commentKey]; + if (!str_contains($comment, "dividend")) { + continue; + } $separate = explode(" ",$comment); $tax = intval(str_replace(["(","-","%",")"],"",$separate[16])); $value = floatval(str_replace(["(",")"],"",$separate[10])); @@ -44,10 +50,6 @@ class ExanteSheet extends SheetDataAll $dividendObj->setValue($value); $ret[] = $dividendObj; } - if ($commentKey === -1) { - trigger_error(var_export("false",true)); - return []; - } return $ret; } diff --git a/project/src/Logic/Dividends/IbkrSheet.php b/project/src/Logic/Dividends/IbkrSheet.php index fa51e59..f7f863e 100644 --- a/project/src/Logic/Dividends/IbkrSheet.php +++ b/project/src/Logic/Dividends/IbkrSheet.php @@ -28,9 +28,8 @@ class IbkrSheet extends SheetDataAll $dividendArr = []; $taxArr = []; $test = []; - foreach ($this->getRawData() as $index => $rawDatum) { - if ($index < 1) { + if ($index < 2) { continue; } $row=[]; @@ -50,18 +49,29 @@ class IbkrSheet extends SheetDataAll } } } - foreach ($dividendArr as $groupId => $dividend) { + if (!isset($taxArr[$groupId])) { + continue; + } $taxGet = $taxArr[$groupId]['amount']; // $dividend['amount'] += $taxGet; $taxPercentage = intval(round(abs($taxGet) / $dividend['amount'], 2) * 100); + if ($taxPercentage === 14) { + $taxPercentage = 15; + } $separate = explode(" ", $dividend['description']); $perShare = floatval($separate[4]); if (!$perShare) { $perShare = floatval($separate[5]); } + if (!$perShare) { + continue; + } $date = explode(";", $dividend['date'])[0]; - $date = substr($date, 0, 4) . "-" . substr($date, 4, 2) . "-" . substr($date, 6, 2); + if (substr_count($date, "-") !== 2) { + $date = substr($date, 0, 4) . "-" . substr($date, 4, 2) . "-" . substr($date, 6, 2); + } +// trigger_error(var_export($date,true)); $dividendObj = new DividendsData(); $dividendObj->setCount(intval($dividend['amount'] / $perShare)); $dividendObj->setIsin($dividend['isin']); diff --git a/project/src/Logic/Dividends/SheetDataAll.php b/project/src/Logic/Dividends/SheetDataAll.php index a9f2749..8df5538 100644 --- a/project/src/Logic/Dividends/SheetDataAll.php +++ b/project/src/Logic/Dividends/SheetDataAll.php @@ -2,6 +2,8 @@ namespace App\Logic\Dividends; +use function Symfony\Component\Translation\t; + abstract class SheetDataAll { protected int $countData; diff --git a/project/src/Services/DividendsService.php b/project/src/Services/DividendsService.php index 3ac877e..78286f4 100644 --- a/project/src/Services/DividendsService.php +++ b/project/src/Services/DividendsService.php @@ -2,6 +2,7 @@ declare(strict_types=1); namespace App\Services; +use App\Enum\MarketNames; use App\Helper\Sheets\ReadSheet; use App\Logic\Dividends\DividendsSummary; use App\Logic\Dividends\ExanteSheet; @@ -18,21 +19,27 @@ class DividendsService extends MasterServices foreach ($this->allFiles as $file) { $extension = pathinfo($file)['extension']; - $isExante = strpos($file, "exante") !== false; - $isIbkr = strpos($file, "ibkr") !== false; + $market = MarketNames::tryFromCase($file); + + + $isExante = str_contains($file, "exante"); + $isIbkr = str_contains($file, "ibkr"); + + if (in_array($extension, ['xlsx','csv'])) { - if ($isExante) { + if ($market === MarketNames::EXANTE) { $delimiter = ";"; + $delimiter = null; } else { $delimiter = null; } - $reader = new ReadSheet($file); + $reader = new ReadSheet($file, $market); if ($reader->takeFile($delimiter)) { /** @var SheetData $item */ foreach ($reader->getAll() as $val) { - if ($isExante) { + if ($market === MarketNames::EXANTE) { $item = new ExanteSheet($val); - } elseif ($isIbkr) { + } elseif ($market === MarketNames::IBKR) { $item = new IbkrSheet($val); } else { diff --git a/project/templates/taxes/show.html.twig b/project/templates/taxes/show.html.twig index d633226..666869e 100644 --- a/project/templates/taxes/show.html.twig +++ b/project/templates/taxes/show.html.twig @@ -82,13 +82,13 @@ {% if errorDividend %}
| {{ curr }} | + {% for row in errorDividend %} +{{ row.currency }} | {% endfor %}
| {{ val }} | + {% for row in errorDividend %} +{{ row.value }} | {% endfor %}