diff --git a/project/assets/controllers/app_controller.js b/project/assets/controllers/app_controller.js index 4bca3b5..43dc43b 100644 --- a/project/assets/controllers/app_controller.js +++ b/project/assets/controllers/app_controller.js @@ -51,6 +51,7 @@ export default class extends Controller { this.resultTarget.innerHTML = ''; this.hideError(); this.stepValue = 1; + // window.history.pushState(null, null, "/"); } // ---- pliki ---- @@ -93,7 +94,8 @@ export default class extends Controller { const res = await fetch(this.endpointUrl, { method: 'POST', body: fd }); if (!res.ok) throw new Error('Błąd serwera (' + res.status + ')'); - + // const hashSummary = res.url.replace(/^https?:\/\/[^/]+\//, "/").replace(this.endpointUrl, ""); + // window.history.pushState(null, null, hashSummary); this.resultTarget.innerHTML = await res.text(); this.stepValue = 3; } catch (err) { diff --git a/project/assets/styles/main.less b/project/assets/styles/main.less index 0168727..59e4693 100644 --- a/project/assets/styles/main.less +++ b/project/assets/styles/main.less @@ -1,3 +1,4 @@ +@import "table"; .main-container { font-family: 'Public Sans', system-ui, sans-serif; color: #1C1C1A; @@ -12,7 +13,7 @@ .card { position: relative; width: 100%; - max-width: 660px; + max-width: 750px; background: #FBFBF9; border: 1px solid #E6E5E0; border-radius: 18px; diff --git a/project/assets/styles/table.less b/project/assets/styles/table.less new file mode 100644 index 0000000..5a78288 --- /dev/null +++ b/project/assets/styles/table.less @@ -0,0 +1,38 @@ +.summaryTable { + .table-head { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; } + .table-title { font-size: 13px; font-weight: 600; } + + + .table-wrap { + border: 1px solid #E6E5E0; border-radius: 10px; overflow-x: auto; background: #FFFFFF; + + table { width: 100%; border-collapse: collapse; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 11.5px; } + th { + padding: 9px; font-weight: 600; color: #6B6A64; font-size: 10px; + text-transform: uppercase; letter-spacing: .03em; + border-bottom: 1px solid #E6E5E0; white-space: nowrap; background: #FAFAF7; + } + td { padding: 9px; border-bottom: 1px solid #F0EFEB; white-space: nowrap; } + tfoot tr { background: #FAFAF7; } + + + .foot-label { + font-family: 'Public Sans', sans-serif; font-size: 12px; font-weight: 600; + color: #6B6A64; text-transform: uppercase; letter-spacing: .04em; + } + .foot-value { text-align: right; font-weight: 700; color: #1C1C1A; font-size: 14px; } + + } + + .note { margin-top: 10px; font-size: 12px; color: #6B6A64; } + .actions { display: flex; gap: 10px; margin-top: 22px; } + .btn-accent { + color: #FFFFFF; border: none; border-radius: 9px; padding: 11px 18px; + font-size: 13.5px; font-weight: 600; cursor: pointer; font-family: inherit; + } + .btn-ghost { + background: none; border: 1px solid #E6E5E0; border-radius: 9px; padding: 11px 18px; + font-size: 13.5px; font-weight: 600; color: #3B3A36; cursor: pointer; font-family: inherit; + } + +} \ No newline at end of file diff --git a/project/src/Controller/TaxesController.php b/project/src/Controller/TaxesController.php index fba2863..c9631a2 100644 --- a/project/src/Controller/TaxesController.php +++ b/project/src/Controller/TaxesController.php @@ -23,57 +23,57 @@ use Symfony\Component\Validator\Constraints\File; class TaxesController extends AbstractController { - #[Route(path: '/taxes/{type}', name: 'app_taxes')] - public function index(Request $request, string $type): Response - { - if (!in_array($type, ["crypto", "dividend"])) { - return $this->redirectToRoute("homepage"); - } - - $a=[]; - $form = $this->createFormBuilder([]) - ->add("uploads",FileType::class, [ - 'data_class' => null, - 'multiple' => true, - 'attr'=>[ - 'multiple' => 'multiple', - ], - 'constraints' => [ - new All([ - 'constraints' => [ - new File([ - 'maxSize' => '2048k', - 'mimeTypes' => [ - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'application/atom+xml', - 'application/xml', - 'text/xml', - 'text/xml-external-parsed-entity', - 'text/csv', - 'text/plain', -// 'application/x-pdf', - ], - 'mimeTypesMessage' => 'Please upload a valid XLSX or XML document', - ]) - ] - ]) - ], - ]) - ->add("upload",SubmitType::class) - ->getForm(); - $form->handleRequest($request); - if ($form->isSubmitted() && $form->isValid()) { - $files = $form->get('uploads')->getData(); - $hash = $this->saveFiles($files); - return $this->redirectToRoute("app_taxes_{$type}_show",["hash" => $hash]); - } - - return $this->renderForm('taxes/index.html.twig', [ - 'controller_name' => 'TaxesController', - 'form' => $form, - 'sheet' => $a - ]); - } +// #[Route(path: '/taxes/{type}', name: 'app_taxes')] +// public function index(Request $request, string $type): Response +// { +// if (!in_array($type, ["crypto", "dividend"])) { +// return $this->redirectToRoute("homepage"); +// } +// +// $a=[]; +// $form = $this->createFormBuilder([]) +// ->add("uploads",FileType::class, [ +// 'data_class' => null, +// 'multiple' => true, +// 'attr'=>[ +// 'multiple' => 'multiple', +// ], +// 'constraints' => [ +// new All([ +// 'constraints' => [ +// new File([ +// 'maxSize' => '2048k', +// 'mimeTypes' => [ +// 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', +// 'application/atom+xml', +// 'application/xml', +// 'text/xml', +// 'text/xml-external-parsed-entity', +// 'text/csv', +// 'text/plain', +//// 'application/x-pdf', +// ], +// 'mimeTypesMessage' => 'Please upload a valid XLSX or XML document', +// ]) +// ] +// ]) +// ], +// ]) +// ->add("upload",SubmitType::class) +// ->getForm(); +// $form->handleRequest($request); +// if ($form->isSubmitted() && $form->isValid()) { +// $files = $form->get('uploads')->getData(); +// $hash = $this->saveFiles($files); +// return $this->redirectToRoute("app_taxes_{$type}_show",["hash" => $hash]); +// } +// +// return $this->renderForm('taxes/index.html.twig', [ +// 'controller_name' => 'TaxesController', +// 'form' => $form, +// 'sheet' => $a +// ]); +// } private function saveFiles(array $files) : string { @@ -99,28 +99,13 @@ class TaxesController extends AbstractController return $hash; } - #[Route(path: '/taxes/summary/{type}', name: 'app_taxes_summary', methods: ['POST'])] + #[Route(path: '/taxes/{type}', name: 'app_taxes_summary', methods: ['POST'])] public function takeSummary(string $type, Request $request, DividendsService $tax, ?MarketNames $market): Response { $files = $request->files->all()['pliki']; $hash = $this->saveFiles($files); if ($hash) { - $tax->setHash($hash); - if ($tax->readFiles($market)) { - $gen = $tax->generate(); -// dd($gen); - return $this->render("taxes/show.html.twig", [ - "taxes" => $gen->getSummaryByCountry(), - "errorDividend" => $gen->getErrorDividend(), - "errorString" => $gen->getErrorString(), - "rawCount" => $gen->takeCountRawData(), - "markets" => $gen->getMarkets(), - "markets_all" => MarketNames::cases(), - "hash_param" => $tax->takeHash(), - "current_market" => $market, - ]); - - } + return $this->redirectToRoute("app_taxes_{$type}_show", ["hash" => $hash]); } return $this->json([ "type" => $type, @@ -133,8 +118,10 @@ class TaxesController extends AbstractController { if ($tax->readFiles($market)) { $gen = $tax->generate(); -// dd($gen); - return $this->render("taxes/show.html.twig", [ + $taxes = $gen->getSummaryByCountry(); + $sum = $taxes['sum']; + unset($taxes['sum']); + return $this->render("taxes/table.html.twig", [ "taxes" => $gen->getSummaryByCountry(), "errorDividend" => $gen->getErrorDividend(), "errorString" => $gen->getErrorString(), @@ -143,6 +130,7 @@ class TaxesController extends AbstractController "markets_all" => MarketNames::cases(), "hash_param" => $tax->takeHash(), "current_market" => $market, + "sum" => $sum, ]); } return new Response("Brak danych do wyświetlenia."); diff --git a/project/src/Logic/Dividends/DividendsSummary.php b/project/src/Logic/Dividends/DividendsSummary.php index 7fcc6ab..f9be610 100644 --- a/project/src/Logic/Dividends/DividendsSummary.php +++ b/project/src/Logic/Dividends/DividendsSummary.php @@ -42,12 +42,19 @@ class DividendsSummary $this->countFromSheets(); if (count($this->allData) > 0) { - $sum = 0; - $profitSum = 0; + $summaryRow = [ + "tax" => 0, + "profit" => 0, + "origin" => 0, + "destiny" => 0, + ]; foreach ($this->allData as $key => $item) { $val = round($item['tax'], 2); - $sum += $val; - $profitSum += $item['incomeAll']; + $summaryRow["tax"] += $val; + $summaryRow["profit"] += $item['incomeAll']; + $summaryRow["origin"] += $item['destiny_tax']; + $summaryRow["destiny"] += $item['tax_cost']; + $return[$key] = [ "country" => \Locale::getDisplayRegion("-".$key), "income" => $item['incomeAll'], @@ -58,11 +65,11 @@ class DividendsSummary "incomesArray" => $item['incomes'] ]; } + $summaryRow = array_map(function ($item) { + return intval(ceil($item)); + }, $summaryRow); // > - $return['sum'] = [ - "tax" => intval(ceil($sum)), - "profit" => $profitSum - ]; + $return['sum'] = $summaryRow; } return $return; diff --git a/project/templates/taxes/table.html.twig b/project/templates/taxes/table.html.twig new file mode 100644 index 0000000..5f3b0f0 --- /dev/null +++ b/project/templates/taxes/table.html.twig @@ -0,0 +1,97 @@ +
+
+ + + + + + + {% if taxes|first.cost is defined %} + + {% endif %} + {% if taxes|first.destiny_tax is defined %} + + {% endif %} + {% if taxes|first.tax_cost is defined %} + + {% endif %} + {% if taxes|first.profit is defined %} + + {% endif %} + + + + + {% for key,tax in taxes %} + {% if tax.country is defined %} + {% set colspan = tax|length %} + {% if tax.income > 0 %} + + + + + {% if tax.cost is defined %} + + {% endif %} + {% if tax.destiny_tax is defined %} + + {% endif %} + {% if tax.tax_cost is defined %} + + {% endif %} + {% if tax.profit is defined %} + + {% endif %} + + + {% if tax.incomesArray is defined and tax.incomesArray|length > 0 %} + {% set colspan = colspan-1 %} + {% for incomePerc,value in tax.incomesArray %} + + + + + + {% endfor %} + {% endif %} + {% endif %} + {% elseif key == "sum" %} + {# #} + {# #} + {# #} + {# #} + {# #} + {% else %} + + + + + {% endif %} + {% endfor %} + + + + + + + + + + + + + + +
L.p.CountryIncomeCostOrigin taxDeductable tax (15%)Profit/LossTax
{{ loop.index }}{{ tax.country }}{{ tax.income|price }}{{ tax.cost|price }}{{ tax.destiny_tax|price }}{{ tax.tax_cost|price }}{{ tax.profit|price }}{{ tax.tax|price }}
{{ incomePerc }}% - {{ value|price }}
Summary:{{ tax.profit|price("PLN",0) }}{{ tax.tax|price("PLN",0) }}
Summary:{{ tax|price("PLN",0) }}
Podsumowanie{{ sum.profit|price("PLN",0) }}{{ sum.origin|price("PLN",0) }}{{ sum.destiny|price("PLN",0) }}
Do zaplaty{{ sum.tax|price("PLN",0) }}
+
+ + {#{% if wynik.footNote %}#} +
Kwota do dopłaty w Polsce po uwzględnieniu podatku zapłaconego za granicą.
+ {#{% endif %}#} + +
+ {# #} + +
+ +
\ No newline at end of file