add new table view
This commit is contained in:
@@ -51,6 +51,7 @@ export default class extends Controller {
|
|||||||
this.resultTarget.innerHTML = '';
|
this.resultTarget.innerHTML = '';
|
||||||
this.hideError();
|
this.hideError();
|
||||||
this.stepValue = 1;
|
this.stepValue = 1;
|
||||||
|
// window.history.pushState(null, null, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- pliki ----
|
// ---- pliki ----
|
||||||
@@ -93,7 +94,8 @@ export default class extends Controller {
|
|||||||
|
|
||||||
const res = await fetch(this.endpointUrl, { method: 'POST', body: fd });
|
const res = await fetch(this.endpointUrl, { method: 'POST', body: fd });
|
||||||
if (!res.ok) throw new Error('Błąd serwera (' + res.status + ')');
|
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.resultTarget.innerHTML = await res.text();
|
||||||
this.stepValue = 3;
|
this.stepValue = 3;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
@import "table";
|
||||||
.main-container {
|
.main-container {
|
||||||
font-family: 'Public Sans', system-ui, sans-serif;
|
font-family: 'Public Sans', system-ui, sans-serif;
|
||||||
color: #1C1C1A;
|
color: #1C1C1A;
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
.card {
|
.card {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 660px;
|
max-width: 750px;
|
||||||
background: #FBFBF9;
|
background: #FBFBF9;
|
||||||
border: 1px solid #E6E5E0;
|
border: 1px solid #E6E5E0;
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,57 +23,57 @@ use Symfony\Component\Validator\Constraints\File;
|
|||||||
|
|
||||||
class TaxesController extends AbstractController
|
class TaxesController extends AbstractController
|
||||||
{
|
{
|
||||||
#[Route(path: '/taxes/{type}', name: 'app_taxes')]
|
// #[Route(path: '/taxes/{type}', name: 'app_taxes')]
|
||||||
public function index(Request $request, string $type): Response
|
// public function index(Request $request, string $type): Response
|
||||||
{
|
// {
|
||||||
if (!in_array($type, ["crypto", "dividend"])) {
|
// if (!in_array($type, ["crypto", "dividend"])) {
|
||||||
return $this->redirectToRoute("homepage");
|
// return $this->redirectToRoute("homepage");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
$a=[];
|
// $a=[];
|
||||||
$form = $this->createFormBuilder([])
|
// $form = $this->createFormBuilder([])
|
||||||
->add("uploads",FileType::class, [
|
// ->add("uploads",FileType::class, [
|
||||||
'data_class' => null,
|
// 'data_class' => null,
|
||||||
'multiple' => true,
|
// 'multiple' => true,
|
||||||
'attr'=>[
|
// 'attr'=>[
|
||||||
'multiple' => 'multiple',
|
// 'multiple' => 'multiple',
|
||||||
],
|
// ],
|
||||||
'constraints' => [
|
// 'constraints' => [
|
||||||
new All([
|
// new All([
|
||||||
'constraints' => [
|
// 'constraints' => [
|
||||||
new File([
|
// new File([
|
||||||
'maxSize' => '2048k',
|
// 'maxSize' => '2048k',
|
||||||
'mimeTypes' => [
|
// 'mimeTypes' => [
|
||||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
// 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
'application/atom+xml',
|
// 'application/atom+xml',
|
||||||
'application/xml',
|
// 'application/xml',
|
||||||
'text/xml',
|
// 'text/xml',
|
||||||
'text/xml-external-parsed-entity',
|
// 'text/xml-external-parsed-entity',
|
||||||
'text/csv',
|
// 'text/csv',
|
||||||
'text/plain',
|
// 'text/plain',
|
||||||
// 'application/x-pdf',
|
//// 'application/x-pdf',
|
||||||
],
|
// ],
|
||||||
'mimeTypesMessage' => 'Please upload a valid XLSX or XML document',
|
// 'mimeTypesMessage' => 'Please upload a valid XLSX or XML document',
|
||||||
])
|
// ])
|
||||||
]
|
// ]
|
||||||
])
|
// ])
|
||||||
],
|
// ],
|
||||||
])
|
// ])
|
||||||
->add("upload",SubmitType::class)
|
// ->add("upload",SubmitType::class)
|
||||||
->getForm();
|
// ->getForm();
|
||||||
$form->handleRequest($request);
|
// $form->handleRequest($request);
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
// if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$files = $form->get('uploads')->getData();
|
// $files = $form->get('uploads')->getData();
|
||||||
$hash = $this->saveFiles($files);
|
// $hash = $this->saveFiles($files);
|
||||||
return $this->redirectToRoute("app_taxes_{$type}_show",["hash" => $hash]);
|
// return $this->redirectToRoute("app_taxes_{$type}_show",["hash" => $hash]);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return $this->renderForm('taxes/index.html.twig', [
|
// return $this->renderForm('taxes/index.html.twig', [
|
||||||
'controller_name' => 'TaxesController',
|
// 'controller_name' => 'TaxesController',
|
||||||
'form' => $form,
|
// 'form' => $form,
|
||||||
'sheet' => $a
|
// 'sheet' => $a
|
||||||
]);
|
// ]);
|
||||||
}
|
// }
|
||||||
|
|
||||||
private function saveFiles(array $files) : string
|
private function saveFiles(array $files) : string
|
||||||
{
|
{
|
||||||
@@ -99,28 +99,13 @@ class TaxesController extends AbstractController
|
|||||||
return $hash;
|
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
|
public function takeSummary(string $type, Request $request, DividendsService $tax, ?MarketNames $market): Response
|
||||||
{
|
{
|
||||||
$files = $request->files->all()['pliki'];
|
$files = $request->files->all()['pliki'];
|
||||||
$hash = $this->saveFiles($files);
|
$hash = $this->saveFiles($files);
|
||||||
if ($hash) {
|
if ($hash) {
|
||||||
$tax->setHash($hash);
|
return $this->redirectToRoute("app_taxes_{$type}_show", ["hash" => $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->json([
|
return $this->json([
|
||||||
"type" => $type,
|
"type" => $type,
|
||||||
@@ -133,8 +118,10 @@ class TaxesController extends AbstractController
|
|||||||
{
|
{
|
||||||
if ($tax->readFiles($market)) {
|
if ($tax->readFiles($market)) {
|
||||||
$gen = $tax->generate();
|
$gen = $tax->generate();
|
||||||
// dd($gen);
|
$taxes = $gen->getSummaryByCountry();
|
||||||
return $this->render("taxes/show.html.twig", [
|
$sum = $taxes['sum'];
|
||||||
|
unset($taxes['sum']);
|
||||||
|
return $this->render("taxes/table.html.twig", [
|
||||||
"taxes" => $gen->getSummaryByCountry(),
|
"taxes" => $gen->getSummaryByCountry(),
|
||||||
"errorDividend" => $gen->getErrorDividend(),
|
"errorDividend" => $gen->getErrorDividend(),
|
||||||
"errorString" => $gen->getErrorString(),
|
"errorString" => $gen->getErrorString(),
|
||||||
@@ -143,6 +130,7 @@ class TaxesController extends AbstractController
|
|||||||
"markets_all" => MarketNames::cases(),
|
"markets_all" => MarketNames::cases(),
|
||||||
"hash_param" => $tax->takeHash(),
|
"hash_param" => $tax->takeHash(),
|
||||||
"current_market" => $market,
|
"current_market" => $market,
|
||||||
|
"sum" => $sum,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return new Response("Brak danych do wyświetlenia.");
|
return new Response("Brak danych do wyświetlenia.");
|
||||||
|
|||||||
@@ -42,12 +42,19 @@ class DividendsSummary
|
|||||||
$this->countFromSheets();
|
$this->countFromSheets();
|
||||||
|
|
||||||
if (count($this->allData) > 0) {
|
if (count($this->allData) > 0) {
|
||||||
$sum = 0;
|
$summaryRow = [
|
||||||
$profitSum = 0;
|
"tax" => 0,
|
||||||
|
"profit" => 0,
|
||||||
|
"origin" => 0,
|
||||||
|
"destiny" => 0,
|
||||||
|
];
|
||||||
foreach ($this->allData as $key => $item) {
|
foreach ($this->allData as $key => $item) {
|
||||||
$val = round($item['tax'], 2);
|
$val = round($item['tax'], 2);
|
||||||
$sum += $val;
|
$summaryRow["tax"] += $val;
|
||||||
$profitSum += $item['incomeAll'];
|
$summaryRow["profit"] += $item['incomeAll'];
|
||||||
|
$summaryRow["origin"] += $item['destiny_tax'];
|
||||||
|
$summaryRow["destiny"] += $item['tax_cost'];
|
||||||
|
|
||||||
$return[$key] = [
|
$return[$key] = [
|
||||||
"country" => \Locale::getDisplayRegion("-".$key),
|
"country" => \Locale::getDisplayRegion("-".$key),
|
||||||
"income" => $item['incomeAll'],
|
"income" => $item['incomeAll'],
|
||||||
@@ -58,11 +65,11 @@ class DividendsSummary
|
|||||||
"incomesArray" => $item['incomes']
|
"incomesArray" => $item['incomes']
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
$summaryRow = array_map(function ($item) {
|
||||||
|
return intval(ceil($item));
|
||||||
|
}, $summaryRow);
|
||||||
// >
|
// >
|
||||||
$return['sum'] = [
|
$return['sum'] = $summaryRow;
|
||||||
"tax" => intval(ceil($sum)),
|
|
||||||
"profit" => $profitSum
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<div class="summaryTable">
|
||||||
|
<div class="table-wrap">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>L.p.</th>
|
||||||
|
<th>Country</th>
|
||||||
|
<th>Income</th>
|
||||||
|
{% if taxes|first.cost is defined %}
|
||||||
|
<th>Cost</th>
|
||||||
|
{% endif %}
|
||||||
|
{% if taxes|first.destiny_tax is defined %}
|
||||||
|
<th>Origin tax</th>
|
||||||
|
{% endif %}
|
||||||
|
{% if taxes|first.tax_cost is defined %}
|
||||||
|
<th>Deductable tax (15%)</th>
|
||||||
|
{% endif %}
|
||||||
|
{% if taxes|first.profit is defined %}
|
||||||
|
<th>Profit/Loss</th>
|
||||||
|
{% endif %}
|
||||||
|
<th>Tax</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for key,tax in taxes %}
|
||||||
|
{% if tax.country is defined %}
|
||||||
|
{% set colspan = tax|length %}
|
||||||
|
{% if tax.income > 0 %}
|
||||||
|
<tr class="{% if tax.profit is defined and tax.profit < 0 %}table-danger{% else %}table-success{% endif %}">
|
||||||
|
<td>{{ loop.index }}</td>
|
||||||
|
<td>{{ tax.country }}</td>
|
||||||
|
<td>{{ tax.income|price }}</td>
|
||||||
|
{% if tax.cost is defined %}
|
||||||
|
<td>{{ tax.cost|price }}</td>
|
||||||
|
{% endif %}
|
||||||
|
{% if tax.destiny_tax is defined %}
|
||||||
|
<td>{{ tax.destiny_tax|price }}</td>
|
||||||
|
{% endif %}
|
||||||
|
{% if tax.tax_cost is defined %}
|
||||||
|
<td>{{ tax.tax_cost|price }}</td>
|
||||||
|
{% endif %}
|
||||||
|
{% if tax.profit is defined %}
|
||||||
|
<td>{{ tax.profit|price }}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td>{{ tax.tax|price }}</td>
|
||||||
|
</tr>
|
||||||
|
{% if tax.incomesArray is defined and tax.incomesArray|length > 0 %}
|
||||||
|
{% set colspan = colspan-1 %}
|
||||||
|
{% for incomePerc,value in tax.incomesArray %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"></td>
|
||||||
|
<td>{{ incomePerc }}% - {{ value|price }}</td>
|
||||||
|
<td colspan="3"></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% elseif key == "sum" %}
|
||||||
|
{# <tr class="">#}
|
||||||
|
{# <td colspan="{{ colspan-2 }}">Summary:</td>#}
|
||||||
|
{# <td>{{ tax.profit|price("PLN",0) }}</td>#}
|
||||||
|
{# <td>{{ tax.tax|price("PLN",0) }}</td>#}
|
||||||
|
{# </tr>#}
|
||||||
|
{% else %}
|
||||||
|
<tr class="">
|
||||||
|
<td colspan="{{ colspan-1 }}">Summary:</td>
|
||||||
|
<td>{{ tax|price("PLN",0) }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="foot-label">Podsumowanie</td>
|
||||||
|
<td class="foot-label">{{ sum.profit|price("PLN",0) }}</td>
|
||||||
|
<td class="foot-label">{{ sum.origin|price("PLN",0) }}</td>
|
||||||
|
<td class="foot-label">{{ sum.destiny|price("PLN",0) }}</td>
|
||||||
|
<td colspan="1"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="foot-label">Do zaplaty</td>
|
||||||
|
<td class="foot-value" colspan="4">{{ sum.tax|price("PLN",0) }}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#{% if wynik.footNote %}#}
|
||||||
|
<div class="note">Kwota do dopłaty w Polsce po uwzględnieniu podatku zapłaconego za granicą.</div>
|
||||||
|
{#{% endif %}#}
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
{# <button type="button" class="btn-accent" style="background: {{ wynik.accent }}">Eksportuj do PIT</button>#}
|
||||||
|
<button type="button" class="btn-ghost" data-action="app#restart">Od nowa</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user