{% extends "layouts/base.twig" %} {% block title %}{{ translations.pricing }}{% endblock %} {% block head %} {% endblock %} {% block page_heading %}

{{ translations.pricing }}

{{ translations.product_pricing_subtitle }}

{% endblock %} {% block content %} {# ─── Nagłówek: sklep + statystyki ─── #}
{{ shop.getRepresentativeName() }}
{% if shop.getName() and shop.getName() != shop.getRepresentativeName() %} ({{ shop.getName() }}) {% endif %}
{% if shop.getCity() %} {{ shop.getZip() }} {{ shop.getCity() }}, {{ shop.getStreet() }} {{ shop.getStreetNum() }} {% endif %} {% if shop.getPhone() %} {{ shop.getPhone() }} {% endif %} {% if shop.getOpeningHours() and shop.getClosingHours() %} {{ shop.getOpeningHours() }} – {{ shop.getClosingHours() }} {% endif %}
{{ translations.products }}
{{ translations.without_max_price }}
{{ translations.avg_margin_on_max_price|default('Śred. marża (cena maks.)') }}
{# ─── Pasek filtrów okresu dostępności ─── #} {% if availability_periods is defined and availability_periods|length > 0 %}
{{ translations.availability_periods|default('Okresy dostępności') }}:
{# Badge "Wszystkie" — domyślnie aktywny #} {# Badge dla każdego unikalnego okresu (deduplikacja w PHP) #} {%- set today = 'now'|date('Y-m-d') -%} {%- set todayMD = 'now'|date('m-d') -%} {% for period in availability_periods %} {%- set startDate = period.getStartDate() -%} {%- set endDate = period.getEndDate() -%} {%- set isRecurring = period.isRecurring() -%} {%- set isActive = period.isActive() -%} {%- set fullName = period.getName() -%} {# Wyciągnij emoji z nazwy (pierwszy "wyraz") #} {%- set parts = fullName|split(' ', 2) -%} {%- set emoji = parts[0] -%} {%- set displayName = parts[1]|default(fullName) -%} {# Sprawdź czy okres jest aktualny #} {%- set isCurrent = false -%} {%- if isRecurring -%} {%- set startMD = startDate|date('m-d') -%} {%- set endMD = endDate|date('m-d') -%} {%- if startMD <= endMD -%} {%- set isCurrent = (todayMD >= startMD and todayMD <= endMD) -%} {%- else -%} {%- set isCurrent = (todayMD >= startMD or todayMD <= endMD) -%} {%- endif -%} {%- else -%} {%- set isCurrent = (today >= startDate and today <= endDate) -%} {%- endif -%} {% endfor %}
{{ translations.period_filter_hint|default('Kliknij badge aby filtrować produkty według okresu dostępności') }}
{% endif %} {# ─── Pasek filtrów kategorii ─── #} {% if categories is defined and categories|length > 0 %}
{{ translations.categories|default('Kategorie') }}:
{% for category in categories %} {% endfor %}
{% endif %} {# ─── Karta główna ─── #}

{{ translations.pricing }}

{{ translations.pricing_subtitle_hint|default('Ustaw maksymalną cenę sprzedaży dla każdego produktu') }}
{% if categories is defined and categories|length > 0 %}
{# ── Wiersz 1: grupy kolumn ── product(21) | cost(11=6+5) | margin(17=4+7+6) | max(26=20+6) | comp(25=12+13) Suma: 21+11+17+26+25 = 100% #} {# ── Wiersz 2: nazwy kolumn ── #} {% for category in categories %} {% for product in category.products %} {%- set raw = product.getRecipeCostGross()|default(0) -%} {%- set suggP = product.getSuggestedSalePrice()|default(0) -%} {%- set maxP = product.getMaxPortionPrice()|default(0) -%} {%- set expMargin = product.getExpectedMargin()|default(0) -%} {%- set margeOnMax = maxP > 0 ? ((maxP - raw) / maxP * 100)|round(0) : null -%} {%- set margeOnPortion = suggP > 0 ? ((suggP - raw) / suggP * 100)|round(0) : null -%} {%- set targetPrice = expMargin > 0 and raw > 0 ? raw / (1 - expMargin / 100) : null -%} {%- set cp = competitor_index[product.getId()]|default(null) -%} {# Zbierz ID okresów dostępności produktu #} {%- set periodIds = [] -%} {%- for period in product.getAvailabilityPeriods() -%} {%- set periodIds = periodIds|merge([period.getId()]) -%} {%- endfor -%} {# ── Nazwa ── #} {# ── Koszt produkcji ── #} {# ── VAT ── #} {# ── Oczekiwana marża ── #} {# ── Obecna cena sprzedaży ── #} {# ── Marża od ceny sprzedaży ── #} {# ── Maks. cena sprzedaży (edytowalna) ── #} {# ── Marża od ceny maks. ── #} {# ── Min / Max cena konkurencji ── #} {# ── Sugerowana maks. cena sprzedaży (max_konk * 0.95) ── #} {% endfor %} {% endfor %}
{{ translations.product }} {{ translations.cost_section|default('Koszt') }} {{ translations.margin_section|default('Marże') }} {{ translations.max_price_section|default('Cena maks. sklepu') }} {{ translations.competitor_section|default('Konkurencja') }}
{{ translations.raw_price }} {{ translations.vat|default('VAT') }} {{ translations.expected_margin_short|default('Oczek.') }} {{ translations.suggested_sale_price_short|default('Sug. c. sp.') }} {{ translations.current_margin_short|default('Marża sp.') }} {{ translations.max_sale_price_short }} {{ translations.margin_on_max|default('Marża maks.') }} {{ translations.competitor_price_range|default('Min / Max konk.') }} {{ translations.suggested_max_price|default('Suger. cena maks.') }}
{{ category.name }} {{ category.products|length }}
{{ product.getName() }} {% if product.getIsVegetarian() %} 🌿 {% endif %} {# Mikroznaczniki okresów dostępności #} {% if periodIds|length > 0 %}
{% for period in product.getAvailabilityPeriods() %} {%- set pParts = period.getName()|split(' ', 2) -%} {{ pParts[0]|raw }} {% endfor %}
{% endif %}
{% if raw > 0 %} {{ raw|number_format(2, ',', ' ') }} {% else %} {% endif %} {{ product.getTaxValPerc() }}% {% if expMargin > 0 %} {{ expMargin|number_format(0, ',', ' ') }}% {% else %} {% endif %} {% if suggP > 0 %} {{ suggP|number_format(2, ',', ' ') }} {% else %} {% endif %} {% if margeOnPortion is not null %} {%- set cls = margeOnPortion >= 50 ? 'marge-good' : (margeOnPortion >= 20 ? 'marge-ok' : 'marge-bad') -%} {{ margeOnPortion }}% {# delta względem oczekiwanej #} {% if expMargin > 0 %} {%- set delta = margeOnPortion - expMargin|round(0) -%}
{{ delta >= 0 ? '+' : '' }}{{ delta }}pp
{% endif %} {% else %} {% endif %}
{# Podpowiedź: cena wyliczona z oczekiwanej marży #} {% if targetPrice is not null %}
{{ translations.for_expected_margin|default('Dla') }} {{ expMargin|number_format(0) }}%: {{ targetPrice|number_format(2, ',', ' ') }}
{% endif %}
{% if margeOnMax is not null %} {%- set cls = margeOnMax >= 50 ? 'marge-good' : (margeOnMax >= 20 ? 'marge-ok' : 'marge-bad') -%} {{ margeOnMax }}% {# delta względem oczekiwanej #} {% if expMargin > 0 %} {%- set delta = margeOnMax - expMargin|round(0) -%}
{{ delta >= 0 ? '+' : '' }}{{ delta }}pp
{% endif %} {% else %} {% endif %}
{% if cp is not null %}
{{ cp.min|number_format(2, ',', ' ') }} / {{ cp.max|number_format(2, ',', ' ') }}
{# Lista obserwacji (max 3) #}
{% for obs in cp.observations|slice(0, 3) %}
{{ obs.competitor_name }} {{ obs.price|number_format(2, ',', ' ') }}
{% endfor %} {% if cp.count > 3 %}
+{{ cp.count - 3 }} {{ translations.more|default('więcej') }}
{% endif %}
{% else %} {% endif %}
{% if cp is not null %}
{{ cp.suggested_max|number_format(2, ',', ' ') }}
{{ translations.suggested_max_note|default('max konk. −5%') }}
{% if cp.suggested_max != maxP %} {% else %} ✓ {{ translations.applied|default('Zastosowana') }} {% endif %} {% else %} {% endif %}

{{ translations.no_results|default('Brak wyników dla podanych filtrów') }}

{% else %}
{{ translations.no_products }}
{{ translations.back }}
{% endif %}
{# ── Legenda ── #}
{{ translations.legend|default('Legenda:') }} ≥50%{{ translations.legend_good|default('Wysoka marża') }} 20-49%{{ translations.legend_ok|default('Dobra marża') }} <20%{{ translations.legend_bad|default('Niska marża') }} —%{{ translations.legend_target|default('Oczekiwana marża') }} +Xpp / −Xpp {{ translations.legend_delta|default('odchylenie od oczekiwanej marży') }}
{% endblock %} {% block scripts %} {% endblock %}