add projekt cpn support

This commit is contained in:
Mateusz Gruszczyński
2026-07-13 14:47:07 +02:00
parent 47927f3ac3
commit 951b732db6
5 changed files with 162 additions and 10 deletions
+26 -9
View File
@@ -11,6 +11,7 @@ from .models import User, Vehicle, FuelEntry, CompanySettings, AppSetting, Orlen
from .services import calculate_costs, fetch_orlen_price, fetch_orlen_range, invoice_period, fetch_ure_stations, aggregate_ure_companies, POLISH_REGIONS
from .station_catalog import sync_station_catalog
from . import THEMES
from .vat import effective_vat_rate, global_vat_override, save_global_vat_override
main = Blueprint("main", __name__)
FUEL_TYPES = ("PB95", "PB98", "DIESEL", "LPG")
@@ -63,7 +64,8 @@ def dashboard():
totals = {"gross": Decimal("0"), "deductible_vat": Decimal("0"), "final_cost": Decimal("0"), "liters": Decimal("0")}
by_vehicle = defaultdict(lambda: {"gross": 0, "payable": 0, "liters": 0}); invoices = defaultdict(lambda: {"gross": 0, "payable": 0, "count": 0}); settlements = {}
for e in entries:
c = calculate_costs(e.gross, settings.vat_rate, settings.vat_deduction_percent)
vat_rate = effective_vat_rate(settings.vat_rate, e.fueled_at)
c = calculate_costs(e.gross, vat_rate, settings.vat_deduction_percent)
totals["gross"] += c["gross"]; totals["deductible_vat"] += c["deductible_vat"]; totals["final_cost"] += c["final_cost"]; totals["liters"] += Decimal(e.liters)
station_policy = e.station_company
normal_price = float(e.price_per_liter)
@@ -71,21 +73,21 @@ def dashboard():
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)
if uses_station_last_price:
payable_price = float(e.wholesale_price) * (1 + float(settings.vat_rate) / 100)
payable_price = float(e.wholesale_price) * (1 + float(vat_rate) / 100)
if rule:
net = payable_price / (1 + float(settings.vat_rate) / 100)
net = payable_price / (1 + float(vat_rate) / 100)
net = net * (1 - float(rule.discount_net_percent or 0) / 100) + float(rule.surcharge_net_per_liter or 0)
payable_price = net * (1 + float(settings.vat_rate) / 100)
payable_price = net * (1 + float(vat_rate) / 100)
payable_price = max(payable_price, 0)
payable_gross = float(e.liters) * payable_price
settlements[e.id] = {"normal_price": normal_price, "payable_price": payable_price, "normal_gross": e.gross, "payable_gross": payable_gross, "uses_last_price": uses_station_last_price}
settlements[e.id] = {"normal_price": normal_price, "payable_price": payable_price, "normal_gross": e.gross, "payable_gross": payable_gross, "uses_last_price": uses_station_last_price, "vat_rate": float(vat_rate)}
by_vehicle[e.vehicle.name]["gross"] += float(c["gross"]); by_vehicle[e.vehicle.name]["payable"] += payable_gross; by_vehicle[e.vehicle.name]["liters"] += float(e.liters)
if e.used_fuel_card:
key = invoice_period(e.fueled_at, settings.invoice_split_day) if split_enabled else "Cały miesiąc"
else:
key = "Poza kartą"
invoices[key]["gross"] += float(c["gross"]); invoices[key]["payable"] += payable_gross; invoices[key]["count"] += 1
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)
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"])
@login_required
@@ -200,13 +202,12 @@ def orlen_data():
chart = {}
for fuel in selected_fuels:
fuel_rows = [r for r in rows if r.fuel_type == fuel and (fuel != "LPG" or r.region in selected_regions)]
multiplier = 1 + float(settings.vat_rate) / 100 if include_vat else 1
chart_key = fuel if fuel != "LPG" else None
if fuel == "LPG":
for region in selected_regions:
chart[f"LPG · {region}"] = [{"date": r.effective_date.isoformat(), "value": round(float(r.price_per_liter) * multiplier, 4)} for r in fuel_rows if r.region == region]
chart[f"LPG · {region}"] = [{"date": r.effective_date.isoformat(), "value": round(float(r.price_per_liter) * (1 + float(effective_vat_rate(settings.vat_rate, r.effective_date)) / 100 if include_vat else 1), 4)} for r in fuel_rows if r.region == region]
else:
chart[fuel] = [{"date": r.effective_date.isoformat(), "value": round(float(r.price_per_liter) * multiplier, 4)} for r in fuel_rows]
chart[fuel] = [{"date": r.effective_date.isoformat(), "value": round(float(r.price_per_liter) * (1 + float(effective_vat_rate(settings.vat_rate, r.effective_date)) / 100 if include_vat else 1), 4)} for r in fuel_rows]
return render_template("orlen.html", rows=rows, chart=chart, selected_fuels=selected_fuels, selected_year=selected_year, settings=settings, fuel_types=FUEL_TYPES, include_vat=include_vat, regions=POLISH_REGIONS, selected_regions=selected_regions, show_lpg_regions=show_lpg_regions)
@main.post("/orlen/sync")
@@ -284,8 +285,24 @@ def admin_companies():
q=q,
regions=POLISH_REGIONS,
stations=stations,
vat_override=global_vat_override(),
)
@main.post("/admin/global-vat")
@login_required
@roles("admin")
def update_global_vat():
try:
save_global_vat_override(request.form)
db.session.commit()
response = ok_response("Zapisano globalne ustawienia VAT")
return response or redirect(url_for("main.admin_companies"))
except ValueError as exc:
db.session.rollback()
response = error_response(str(exc))
return response or redirect(url_for("main.admin_companies"))
@main.get("/admin/application")
@login_required
@roles("admin")