From 72757cad55a3badecce975d057791938a6edad66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Tue, 14 Jul 2026 14:22:08 +0200 Subject: [PATCH] fix w kalkulacji last price --- app/domain/costs.py | 22 +++++ app/main.py | 149 ++++++++++++++++++------------- app/static/js/charts.js | 12 +-- app/templates/admin_reports.html | 43 ++++----- app/templates/dashboard.html | 17 ++-- 5 files changed, 143 insertions(+), 100 deletions(-) diff --git a/app/domain/costs.py b/app/domain/costs.py index 554d10b..918d51c 100644 --- a/app/domain/costs.py +++ b/app/domain/costs.py @@ -34,3 +34,25 @@ def calculate_net_price_costs(net_price, vat_rate=23, vat_deduction_percent=50): "deductible_vat": deductible_vat, "effective_cost": effective_cost, } + + +def calculate_net_price_comparison(retail_gross_price, settlement_net_price, liters=1, vat_rate=23): + """Compare retail and settlement prices on a net-to-net basis. + + Retail price is supplied gross (pump price), while settlement/Last Price is net. + VAT is excluded from the saving because recoverable tax is not a commercial saving. + """ + retail_gross = Decimal(str(retail_gross_price)) + settlement_net = Decimal(str(settlement_net_price)) + quantity = Decimal(str(liters)) + rate = Decimal(str(vat_rate)) / Decimal("100") + retail_net = retail_gross / (Decimal("1") + rate) + saving_per_liter = max(retail_net - settlement_net, Decimal("0")) + return { + "retail_net_price": retail_net, + "settlement_net_price": settlement_net, + "saving_net_per_liter": saving_per_liter, + "retail_net_total": retail_net * quantity, + "settlement_net_total": settlement_net * quantity, + "saving_net_total": saving_per_liter * quantity, + } diff --git a/app/main.py b/app/main.py index c372238..f850af9 100644 --- a/app/main.py +++ b/app/main.py @@ -12,7 +12,7 @@ from .services import calculate_costs, fetch_orlen_price, fetch_orlen_range, inv from .station_catalog import sync_station_catalog from . import THEMES from .vat import effective_vat_rate, global_vat_override, save_global_vat_override -from .domain.costs import calculate_net_price_costs +from .domain.costs import calculate_net_price_costs, calculate_net_price_comparison main = Blueprint("main", __name__) FUEL_TYPES = ("PB95", "PB98", "DIESEL", "LPG") @@ -103,7 +103,12 @@ def parse_fuel_entry_form(entry): def calculate_entry_settlement(entry, fallback_settings=None): - """Calculate retail, invoice and effective company cost for one fuel entry.""" + """Calculate retail, settlement and company costs for one fuel entry. + + Commercial saving is always calculated net-to-net: pump gross price is first + converted to net and then compared with Last Price net. VAT is reported + separately and never counted as a Last Price saving. + """ entry_settings = entry.vehicle.company or (entry.vehicle.owner.company if entry.vehicle and entry.vehicle.owner else None) or fallback_settings or CompanySettings.query.first() vat_rate = effective_vat_rate(entry_settings.vat_rate, entry.fueled_at) vat_deduction_percent = entry_settings.vat_deduction_percent @@ -112,35 +117,64 @@ def calculate_entry_settlement(entry, fallback_settings=None): fuel_card_id=entry.fuel_card_id, station_company_id=entry.station_company_id, ).first() if entry.used_fuel_card and entry.fuel_card_id and entry.station_company_id else None - uses_last_price = bool(rule and rule.use_orlen_last_price and entry.wholesale_price is not None) + policy = entry.vehicle.fuel_card_policy if entry.used_fuel_card else None + uses_last_price = bool( + entry.wholesale_price is not None and ( + (rule and rule.use_orlen_last_price) or (not rule and policy and policy.use_orlen_last_price) + ) + ) if uses_last_price: settlement_net = Decimal(entry.wholesale_price) else: settlement_net = retail_price / (Decimal("1") + Decimal(str(vat_rate)) / Decimal("100")) + + # A station-specific card rule has priority. The vehicle policy is a safe + # fallback for cards/stations without a dedicated rule. if rule: - settlement_net *= Decimal("1") - Decimal(rule.discount_net_percent or 0) / Decimal("100") - settlement_net += Decimal(rule.surcharge_net_per_liter or 0) + discount_percent = Decimal(rule.discount_net_percent or 0) + surcharge_per_liter = Decimal(rule.surcharge_net_per_liter or 0) + elif policy: + discount_percent = Decimal(policy.discount_percent or 0) + surcharge_per_liter = Decimal(policy.surcharge_per_liter or 0) + else: + discount_percent = Decimal("0") + surcharge_per_liter = Decimal("0") + discount_percent = min(max(discount_percent, Decimal("0")), Decimal("100")) + settlement_net *= Decimal("1") - discount_percent / Decimal("100") + settlement_net += surcharge_per_liter settlement_net = max(settlement_net, Decimal("0")) price_costs = calculate_net_price_costs(settlement_net, vat_rate, vat_deduction_percent) liters = Decimal(entry.liters) + comparison = calculate_net_price_comparison(retail_price, settlement_net, liters, vat_rate) retail_gross = retail_price * liters invoice_gross = price_costs["invoice_gross"] * liters deductible_vat = price_costs["deductible_vat"] * liters effective_cost = price_costs["effective_cost"] * liters - last_price_saving = retail_gross - invoice_gross if uses_last_price else Decimal("0") + saving_net = comparison["saving_net_total"] if uses_last_price else Decimal("0") + saving_net_per_liter = comparison["saving_net_per_liter"] if uses_last_price else Decimal("0") + gross_saving = max(retail_gross - invoice_gross, Decimal("0")) + gross_saving_per_liter = max(retail_price - price_costs["invoice_gross"], Decimal("0")) return { "liters": liters, "retail_price": retail_price, + "retail_net_price": comparison["retail_net_price"], "settlement_net": settlement_net, "invoice_price": price_costs["invoice_gross"], "effective_price": price_costs["effective_cost"], "retail_gross": retail_gross, + "retail_net_total": comparison["retail_net_total"], + "settlement_net_total": comparison["settlement_net_total"], "invoice_gross": invoice_gross, "deductible_vat": deductible_vat, "effective_cost": effective_cost, - "last_price_saving": last_price_saving, + "saving_net": saving_net, + "saving_net_per_liter": saving_net_per_liter, + "gross_saving": gross_saving, + "gross_saving_per_liter": gross_saving_per_liter, + "discount_percent": discount_percent, + "surcharge_per_liter": surcharge_per_liter, "uses_last_price": uses_last_price, "vat_rate": Decimal(str(vat_rate)), "vat_deduction_percent": Decimal(str(vat_deduction_percent)), @@ -163,57 +197,40 @@ def dashboard(): try: year, mon = map(int, month.split("-")) except ValueError: year, mon = datetime.now().year, datetime.now().month; month=f"{year:04d}-{mon:02d}" entries = FuelEntry.query.filter(FuelEntry.vehicle_id.in_(ids), extract("year", FuelEntry.fueled_at)==year, extract("month", FuelEntry.fueled_at)==mon).order_by(FuelEntry.fueled_at.desc()).all() if ids else [] - totals = {"gross": Decimal("0"), "deductible_vat": Decimal("0"), "final_cost": Decimal("0"), "liters": Decimal("0"), "last_price_saving": Decimal("0")} - by_vehicle = defaultdict(lambda: {"gross": 0, "payable": 0, "liters": 0}); invoices = defaultdict(lambda: {"gross": 0, "payable": 0, "count": 0}); settlements = {} + zero = Decimal("0") + totals = {"retail_gross": zero, "retail_net": zero, "settlement_net": zero, "invoice_gross": zero, "gross_saving": zero, "deductible_vat": zero, "final_cost": zero, "liters": zero, "saving_net": zero, "saving_base_net": zero} + by_vehicle = defaultdict(lambda: {"retail_gross": 0, "invoice_gross": 0, "gross_saving": 0, "retail_net": 0, "settlement_net": 0, "saving_net": 0, "effective": 0, "liters": 0}) + invoices = defaultdict(lambda: {"gross": 0, "payable": 0, "count": 0}); settlements = {} for e in entries: + row = calculate_entry_settlement(e, settings) + totals["retail_gross"] += row["retail_gross"] + totals["retail_net"] += row["retail_net_total"] + totals["settlement_net"] += row["settlement_net_total"] + totals["invoice_gross"] += row["invoice_gross"] + totals["gross_saving"] += row["gross_saving"] + totals["deductible_vat"] += row["deductible_vat"] + totals["final_cost"] += row["effective_cost"] + totals["liters"] += row["liters"] + totals["saving_net"] += row["saving_net"] + if row["uses_last_price"]: + totals["saving_base_net"] += row["retail_net_total"] + settlements[e.id] = {k: float(v) if isinstance(v, Decimal) else v for k, v in row.items()} + bucket = by_vehicle[e.vehicle.name] + bucket["retail_gross"] += float(row["retail_gross"]) + bucket["retail_net"] += float(row["retail_net_total"]) + bucket["settlement_net"] += float(row["settlement_net_total"]) + bucket["saving_net"] += float(row["saving_net"]) + bucket["invoice_gross"] += float(row["invoice_gross"]) + bucket["gross_saving"] += float(row["gross_saving"]) + bucket["effective"] += float(row["effective_cost"]) + bucket["liters"] += float(row["liters"]) entry_settings = e.vehicle.company or settings - vat_rate = effective_vat_rate(entry_settings.vat_rate, e.fueled_at) - vat_deduction_percent = entry_settings.vat_deduction_percent - normal_price = float(e.price_per_liter) - rule = FuelCardStationRule.query.filter_by(fuel_card_id=e.fuel_card_id, station_company_id=e.station_company_id).first() if e.used_fuel_card and e.fuel_card_id and e.station_company_id else None - uses_station_last_price = bool(rule and rule.use_orlen_last_price and e.wholesale_price is not None) - - # Last price is a NET station price. Discounts and surcharges are also net. - if uses_station_last_price: - settlement_net = Decimal(e.wholesale_price) - else: - settlement_net = Decimal(str(normal_price)) / (Decimal("1") + Decimal(str(vat_rate)) / Decimal("100")) - if rule: - settlement_net = settlement_net * (Decimal("1") - Decimal(rule.discount_net_percent or 0) / Decimal("100")) - settlement_net += Decimal(rule.surcharge_net_per_liter or 0) - settlement_net = max(settlement_net, Decimal("0")) - - price_costs = calculate_net_price_costs(settlement_net, vat_rate, vat_deduction_percent) - liters = Decimal(e.liters) - invoice_gross = price_costs["invoice_gross"] * liters - deductible_vat = price_costs["deductible_vat"] * liters - effective_gross = price_costs["effective_cost"] * liters - - totals["gross"] += invoice_gross - totals["deductible_vat"] += deductible_vat - totals["final_cost"] += effective_gross - totals["liters"] += liters - last_price_saving = Decimal(str(e.gross)) - invoice_gross if uses_station_last_price else Decimal("0") - totals["last_price_saving"] += last_price_saving - settlements[e.id] = { - "normal_price": normal_price, - "net_price": float(settlement_net), - "invoice_price": float(price_costs["invoice_gross"]), - "payable_price": float(price_costs["effective_cost"]), - "normal_gross": e.gross, - "invoice_gross": float(invoice_gross), - "payable_gross": float(effective_gross), - "uses_last_price": uses_station_last_price, - "last_price_saving": float(last_price_saving), - "vat_rate": float(vat_rate), - "vat_deduction_percent": float(vat_deduction_percent), - } - by_vehicle[e.vehicle.name]["gross"] += float(invoice_gross); by_vehicle[e.vehicle.name]["payable"] += float(effective_gross); by_vehicle[e.vehicle.name]["liters"] += float(liters) if e.used_fuel_card: - key = invoice_period(e.fueled_at, settings.invoice_split_day) if split_enabled else "Cały miesiąc" + key = invoice_period(e.fueled_at, entry_settings.invoice_split_day) if split_enabled else "Cały miesiąc" else: key = "Poza kartą" - invoices[key]["gross"] += float(invoice_gross); invoices[key]["payable"] += float(effective_gross); invoices[key]["count"] += 1 + invoices[key]["gross"] += float(row["invoice_gross"]); invoices[key]["payable"] += float(row["effective_cost"]); invoices[key]["count"] += 1 + totals["saving_percent"] = (totals["saving_net"] / totals["saving_base_net"] * Decimal("100")) if totals["saving_base_net"] else zero return render_template("dashboard.html", vehicles=vehicles, entries=entries, totals=totals, month=month, by_vehicle=dict(by_vehicle), invoices=dict(invoices), settings=settings, split_enabled=split_enabled, settlements=settlements, vat_override=global_vat_override()) @main.route("/vehicles", methods=["GET", "POST"]) @@ -554,32 +571,40 @@ def admin_reports(): entries = query.order_by(FuelEntry.fueled_at.asc()).all() zero = Decimal("0") - totals = {"retail": zero, "invoice": zero, "effective": zero, "vat_deducted": zero, "saving": zero, "liters": zero, "count": 0, "last_price_count": 0} - by_month = defaultdict(lambda: {"retail": 0.0, "invoice": 0.0, "effective": 0.0, "saving": 0.0, "liters": 0.0, "count": 0}) - by_vehicle = defaultdict(lambda: {"retail": 0.0, "invoice": 0.0, "effective": 0.0, "saving": 0.0, "liters": 0.0, "count": 0}) - by_company = defaultdict(lambda: {"retail": 0.0, "invoice": 0.0, "effective": 0.0, "saving": 0.0, "liters": 0.0, "count": 0}) + totals = {"retail_gross": zero, "retail_net": zero, "settlement_net": zero, "invoice": zero, "gross_saving": zero, "effective": zero, "vat_deducted": zero, "saving_net": zero, "saving_base_net": zero, "liters": zero, "count": 0, "last_price_count": 0} + by_month = defaultdict(lambda: {"retail_gross": 0.0, "invoice": 0.0, "gross_saving": 0.0, "retail_net": 0.0, "settlement_net": 0.0, "effective": 0.0, "saving_net": 0.0, "liters": 0.0, "count": 0}) + by_vehicle = defaultdict(lambda: {"retail_gross": 0.0, "invoice": 0.0, "gross_saving": 0.0, "retail_net": 0.0, "settlement_net": 0.0, "effective": 0.0, "saving_net": 0.0, "liters": 0.0, "count": 0}) + by_company = defaultdict(lambda: {"retail_gross": 0.0, "invoice": 0.0, "gross_saving": 0.0, "retail_net": 0.0, "settlement_net": 0.0, "effective": 0.0, "saving_net": 0.0, "liters": 0.0, "count": 0}) for entry in entries: row = calculate_entry_settlement(entry) - totals["retail"] += row["retail_gross"] + totals["retail_gross"] += row["retail_gross"] + totals["retail_net"] += row["retail_net_total"] + totals["settlement_net"] += row["settlement_net_total"] totals["invoice"] += row["invoice_gross"] + totals["gross_saving"] += row["gross_saving"] totals["effective"] += row["effective_cost"] totals["vat_deducted"] += row["deductible_vat"] - totals["saving"] += row["last_price_saving"] + totals["saving_net"] += row["saving_net"] + if row["uses_last_price"]: + totals["saving_base_net"] += row["retail_net_total"] totals["liters"] += row["liters"] totals["count"] += 1 totals["last_price_count"] += int(row["uses_last_price"]) company = entry.vehicle.company or entry.vehicle.owner.company keys = ((by_month, entry.fueled_at.strftime("%Y-%m")), (by_vehicle, entry.vehicle.name), (by_company, company.name if company else "Bez firmy")) for bucket, key in keys: - bucket[key]["retail"] += float(row["retail_gross"]) + bucket[key]["retail_gross"] += float(row["retail_gross"]) + bucket[key]["retail_net"] += float(row["retail_net_total"]) + bucket[key]["settlement_net"] += float(row["settlement_net_total"]) bucket[key]["invoice"] += float(row["invoice_gross"]) + bucket[key]["gross_saving"] += float(row["gross_saving"]) bucket[key]["effective"] += float(row["effective_cost"]) - bucket[key]["saving"] += float(row["last_price_saving"]) + bucket[key]["saving_net"] += float(row["saving_net"]) bucket[key]["liters"] += float(row["liters"]) bucket[key]["count"] += 1 - totals["saving_percent"] = (totals["saving"] / totals["retail"] * Decimal("100")) if totals["retail"] else zero + totals["saving_percent"] = (totals["saving_net"] / totals["saving_base_net"] * Decimal("100")) if totals["saving_base_net"] else zero return render_template( "admin_reports.html", companies=[c for c in companies if c], company_id=company_id, period=period, month=month, year=year, date_from=date_from_raw, date_to=date_to_raw, start_date=start_date, end_date=end_date, totals=totals, diff --git a/app/static/js/charts.js b/app/static/js/charts.js index 9225b60..ae6ce7d 100644 --- a/app/static/js/charts.js +++ b/app/static/js/charts.js @@ -10,8 +10,9 @@ const el=F.qs(`#${id}`);if(!el)return; const labels=Object.keys(data||{});destroy(id);empty(id,!labels.length);if(!labels.length)return; F.charts[id]=new Chart(el,{type:'bar',data:{labels,datasets:[ - {label:'Cena fakturowa (zł)',data:labels.map(k=>data[k].gross)}, - {label:'Koszt po VAT (zł)',data:labels.map(k=>data[k].payable)} + {label:'Detal brutto (zł)',data:labels.map(k=>data[k].retail_gross)}, + {label:'Do zapłaty brutto (zł)',data:labels.map(k=>data[k].invoice_gross)}, + {label:'Różnica brutto (zł)',data:labels.map(k=>data[k].gross_saving)} ]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{labels:{color:text()}}},scales:commonScales()}}); }; @@ -26,10 +27,9 @@ const el=F.qs(`#${id}`);if(!el)return; const labels=Object.keys(data||{});destroy(id);empty(id,!labels.length);if(!labels.length)return; F.charts[id]=new Chart(el,{type:'bar',data:{labels,datasets:[ - {label:'Detal z dystrybutora (zł)',data:labels.map(k=>data[k].retail)}, - {label:'Faktura wg rozliczenia (zł)',data:labels.map(k=>data[k].invoice)}, - {label:'Koszt po VAT (zł)',data:labels.map(k=>data[k].effective)}, - {label:'Oszczędność Last Price (zł)',data:labels.map(k=>data[k].saving)} + {label:'Detal brutto (zł)',data:labels.map(k=>data[k].retail_gross)}, + {label:'Do zapłaty brutto (zł)',data:labels.map(k=>data[k].invoice)}, + {label:'Różnica brutto (zł)',data:labels.map(k=>data[k].gross_saving)} ]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{labels:{color:text()}}},scales:commonScales()}}); }; })(); diff --git a/app/templates/admin_reports.html b/app/templates/admin_reports.html index 392e9bb..9c93d5e 100644 --- a/app/templates/admin_reports.html +++ b/app/templates/admin_reports.html @@ -1,32 +1,21 @@ {% extends 'base.html' %}{% block content %} -

Zestawienia kosztów

Rzeczywiste koszty, VAT i oszczędność wynikająca z rozliczenia Last Price.

+

Zestawienia kosztów

Porównanie detalu brutto z ostatecznymi kwotami faktur, rabatami, Last Price, VAT i kosztem po odliczeniu.

{% include '_admin_nav.html' %} -
-
- {% if current_user.role=='admin' %}
{% endif %} -
-
-
-
-
-
-
+
+{% if current_user.role=='admin' %}
{% endif %} +
+

Okres: {{start_date.strftime('%d.%m.%Y')}}–{{end_date.strftime('%d.%m.%Y')}}

-
Detal z dystrybutora{{'%.2f'|format(totals.retail)}} zł
-
Faktury Last Price*{{'%.2f'|format(totals.invoice)}} zł
-
Koszt po VAT{{'%.2f'|format(totals.effective)}} zł
-
Odliczony VAT{{'%.2f'|format(totals.vat_deducted)}} zł
-
Oszczędność Last Price{{'%.2f'|format(totals.saving)}} zł{{'%.2f'|format(totals.saving_percent)}}%
-
Tankowania / litry{{totals.count}} / {{'%.2f'|format(totals.liters)}} lLast Price: {{totals.last_price_count}}
+
Detal brutto{{'%.2f'|format(totals.retail_gross)}} zł
+
Do zapłaty brutto{{'%.2f'|format(totals.invoice)}} złpo rabatach i dopłatach
+
Różnica brutto do detalu{{'%.2f'|format(totals.gross_saving)}} złfaktura vs detal
+
Oszczędność Last Price netto{{'%.2f'|format(totals.saving_net)}} zł{{'%.2f'|format(totals.saving_percent)}}%
+
Koszt po VAT{{'%.2f'|format(totals.effective)}} złodliczono {{'%.2f'|format(totals.vat_deducted)}} zł VAT
+
Tankowania / litry{{totals.count}} / {{'%.2f'|format(totals.liters)}} lLast Price: {{totals.last_price_count}}
-
* Faktura Last Price oznacza kwotę obliczoną z ceny Last Price netto, powiększonej o stawkę VAT firmy. Oszczędność Last Price to różnica między wartością detaliczną z dystrybutora a fakturą Last Price brutto.
-

Koszty w czasie

Brak danych dla wybranego okresu.
-
-

Według pojazdu

{% for name,row in by_vehicle.items() %}{% else %}{% endfor %}
PojazdTank.LitryDetalFaktura*Koszt po VATOszczędność
{{name}}{{row.count}}{{'%.2f'|format(row.liters)}}{{'%.2f'|format(row.retail)}} zł{{'%.2f'|format(row.invoice)}} zł{{'%.2f'|format(row.effective)}} zł{{'%.2f'|format(row.saving)}} zł
Brak danych.
-

Według firmy

{% for name,row in by_company.items() %}{% else %}{% endfor %}
FirmaTank.LitryDetalFaktura*Koszt po VATOszczędność
{{name}}{{row.count}}{{'%.2f'|format(row.liters)}}{{'%.2f'|format(row.retail)}} zł{{'%.2f'|format(row.invoice)}} zł{{'%.2f'|format(row.effective)}} zł{{'%.2f'|format(row.saving)}} zł
Brak danych.
-
-{% endblock %}{% block scripts %}{% endblock %} +
Metoda: wykres porównuje detal brutto z ostateczną fakturą brutto po zastosowaniu reguły danej karty i stacji. Reguła stacji ma pierwszeństwo; gdy jej brak, używana jest polityka pojazdu. Last Price i oszczędność handlowa pozostają liczone netto, a VAT jest prezentowany osobno.
+

Kwoty brutto w czasie

Detal brutto, ostateczna kwota do zapłaty brutto i różnica dla każdego miesiąca.

Brak danych dla wybranego okresu.
+

Według pojazdu

{% for name,row in by_vehicle.items() %}{% else %}{% endfor %}
PojazdTank.LitryDetal bruttoDo zapłaty bruttoRóżnica bruttoOszczędność LP nettoKoszt po VAT
{{name}}{{row.count}}{{'%.2f'|format(row.liters)}}{{'%.2f'|format(row.retail_gross)}} zł{{'%.2f'|format(row.invoice)}} zł{{'%.2f'|format(row.gross_saving)}} zł{{'%.2f'|format(row.saving_net)}} zł{{'%.2f'|format(row.effective)}} zł
Brak danych.
+

Według firmy

{% for name,row in by_company.items() %}{% else %}{% endfor %}
FirmaTank.LitryDetal bruttoDo zapłaty bruttoRóżnica bruttoOszczędność LP nettoKoszt po VAT
{{name}}{{row.count}}{{'%.2f'|format(row.liters)}}{{'%.2f'|format(row.retail_gross)}} zł{{'%.2f'|format(row.invoice)}} zł{{'%.2f'|format(row.gross_saving)}} zł{{'%.2f'|format(row.saving_net)}} zł{{'%.2f'|format(row.effective)}} zł
Brak danych.
+{% endblock %}{% block scripts %}{% endblock %} diff --git a/app/templates/dashboard.html b/app/templates/dashboard.html index a236e29..60ae445 100644 --- a/app/templates/dashboard.html +++ b/app/templates/dashboard.html @@ -1,7 +1,14 @@ {% extends 'base.html' %}{% block content %} -

Podsumowanie kosztów

{{ settings.name }} · VAT do odliczenia {{ settings.vat_deduction_percent }}%
-{% if vat_override.enabled %}
{{ vat_override.name }}: globalny VAT {{ vat_override.rate }}%{% if vat_override.start %} od {{ vat_override.start.strftime('%d.%m.%Y') }}{% endif %}{% if vat_override.end %} do {{ vat_override.end.strftime('%d.%m.%Y') }}{% endif %}. Rozliczenia są liczone według daty tankowania.
{% endif %} -
Brutto{{ '%.2f'|format(totals.gross) }} zł
VAT odliczony{{ '%.2f'|format(totals.deductible_vat) }} zł
Koszt po VAT{{ '%.2f'|format(totals.final_cost) }} zł
Litry{{ '%.2f'|format(totals.liters) }} l
Oszczędność Last Price{{ '%.2f'|format(totals.last_price_saving) }} zł
-

Koszt według pojazdu

Cena fakturowa a rzeczywisty koszt po odliczeniu VAT.

Brak danych dla wybranego miesiąca.

Okresy faktur

{% if split_enabled %}Podział według dnia {{settings.invoice_split_day}}{% else %}Podział dzienny wyłączony{% endif %}{% for key,row in invoices.items() %}{% else %}{% endfor %}
OkresPozycjeFaktura*Koszt po VAT
{{key}}{{row.count}}{{'%.2f'|format(row.gross)}} zł{{'%.2f'|format(row.payable)}} zł
Brak danych
* Kwota faktury wynika z ceny Last Price netto + VAT firmy, gdy tankowanie podlega tej regule.
-

Tankowania

{% for e in entries %}{% set s=settlements[e.id] %}{% else %}{% endfor %}
DataAutoStacjaPaliwoLitryCena detal.Last price nettoKoszt po VATVATOszczędnośćRazem
{{e.fueled_at.strftime('%d.%m.%Y')}}{{e.vehicle.name}}{{e.station or '—'}}{{e.fuel_type}}{{e.liters}}{{'%.4f'|format(s.normal_price)}} zł/l{% if s.uses_last_price %}{{'%.4f'|format(s.net_price)}} zł/l{% elif e.wholesale_price %}{{'%.4f'|format(e.wholesale_price|float)}} zł/l{% else %}—{% endif %}{% if s.uses_last_price %}last price {% endif %}{{'%.4f'|format(s.payable_price)}} zł/l
faktura {{'%.4f'|format(s.invoice_price)}} zł/l
{{'%.2f'|format(s.vat_rate)}}%
odliczenie {{'%.0f'|format(s.vat_deduction_percent)}}%
{% if s.uses_last_price %}{{'%.2f'|format(s.last_price_saving)}} zł
dzięki Last Price{% else %}—{% endif %}
{{'%.2f'|format(s.normal_gross)}} zł
{{'%.2f'|format(s.payable_gross)}} zł
faktura {{'%.2f'|format(s.invoice_gross)}} zł
Brak tankowań w tym miesiącu.
+

Dashboard

Porównanie cen netto, faktur i kosztów po VAT.

+
+
Detal netto{{ '%.2f'|format(totals.retail_net) }} złcena z dystrybutora bez VAT
+
Do zapłaty brutto{{ '%.2f'|format(totals.invoice_gross) }} złpo rabatach i dopłatach
+
Różnica brutto do detalu{{ '%.2f'|format(totals.gross_saving) }} złkwota faktury vs detal
+
Faktury brutto{{ '%.2f'|format(totals.invoice_gross) }} złnetto + VAT firmy
+
Koszt po VAT{{ '%.2f'|format(totals.final_cost) }} złpo odliczeniu VAT
+
Litry / VAT odliczony{{ '%.2f'|format(totals.liters) }} l{{ '%.2f'|format(totals.deductible_vat) }} zł VAT
+
+
Wykres brutto: porównuje wartość po cenie detalicznej z ostateczną kwotą faktury brutto. Cena rozliczeniowa uwzględnia Last Price albo cenę detaliczną netto, następnie rabat procentowy i dopłatę przypisaną do karty/stacji. Oszczędność handlowa Last Price nadal jest liczona netto.
+

Kwoty brutto według pojazdu

Detal brutto, ostateczna kwota do zapłaty brutto oraz różnica. Rabaty i dopłaty użytkownika są uwzględniane.

Brak danych dla wybranego miesiąca.

Okresy faktur

{% if split_enabled %}Podział według ustawień firmy{% else %}Podział dzienny wyłączony{% endif %}{% for key,row in invoices.items() %}{% else %}{% endfor %}
OkresPozycjeFaktura*Koszt po VAT
{{key}}{{row.count}}{{'%.2f'|format(row.gross)}} zł{{'%.2f'|format(row.payable)}} zł
Brak danych
* Kwota brutto: cena rozliczeniowa netto + VAT właściwy dla firmy.
+

Tankowania

{% for e in entries %}{% set s=settlements[e.id] %}{% else %}{% endfor %}
DataAutoStacjaLitryDetal bruttoDetal nettoLast Price nettoOszczędność nettoFaktura bruttoKoszt po VAT
{{e.fueled_at.strftime('%d.%m.%Y')}}{{e.vehicle.name}}{{e.station or '—'}}{{e.liters}}{{'%.4f'|format(s.retail_price)}} zł/l
{{'%.2f'|format(s.retail_gross)}} zł
{{'%.4f'|format(s.retail_net_price)}} zł/l
{{'%.2f'|format(s.retail_net_total)}} zł
{% if s.uses_last_price %}Last Price
{{'%.4f'|format(s.settlement_net)}} zł/l{% else %}{{'%.4f'|format(s.settlement_net)}} zł/l{% endif %}
{{'%.2f'|format(s.settlement_net_total)}} zł
{% if s.uses_last_price %}{{'%.2f'|format(s.saving_net)}} zł
{{'%.4f'|format(s.saving_net_per_liter)}} zł/l{% else %}—{% endif %}
{{'%.4f'|format(s.invoice_price)}} zł/l
{{'%.2f'|format(s.invoice_gross)}} zł
VAT {{'%.2f'|format(s.vat_rate)}}%
{{'%.4f'|format(s.effective_price)}} zł/l
{{'%.2f'|format(s.effective_cost)}} zł
odliczenie VAT {{'%.0f'|format(s.vat_deduction_percent)}}%
Brak tankowań w tym miesiącu.
{% endblock %}{% block scripts %}{% endblock %}