mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-05-18 17:31:35 +00:00
Displays the total BOM price for N builds on the project info page, using the existing price-tier logic from PricedetailHelper. The user can adjust the number of builds via a small form; the unit price is also shown when N > 1. New backend: - ProjectBuildHelper gains calculateTotalBuildPrice(), calculateUnitBuildPrice(), roundedTotalBuildPrice(), and roundedUnitBuildPrice() — bulk-order quantities are factored in so that price tiers apply correctly across N builds. - ProjectController::info() now reads ?n= and passes number_of_builds to the template. Template (_info.html.twig): - Adds price badge (hidden when no pricing data is available). - Adds number-of-builds form that reloads the info page.
103 lines
5 KiB
Twig
103 lines
5 KiB
Twig
{% import "helper.twig" as helper %}
|
|
|
|
<div class="row mt-2">
|
|
<div class="col-md-8">
|
|
<div class="row">
|
|
<div class="col-md-3 col-lg-4 col-4 mt-auto mb-auto">
|
|
{% if project.masterPictureAttachment %}
|
|
<a href="{{ entity_url(project.masterPictureAttachment, 'file_view') }}" data-turbo="false" target="_blank" rel="noopener">
|
|
<img class="d-block w-100 img-fluid img-thumbnail bg-body-tertiary part-info-image" src="{{ entity_url(project.masterPictureAttachment, 'file_view') }}" alt="">
|
|
</a>
|
|
{% else %}
|
|
<img src="{{ asset('img/part_placeholder.svg') }}" class="img-fluid img-thumbnail bg-body-tertiary mb-2 " alt="Part main image" height="300" width="300">
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-9 col-lg-8 col-7">
|
|
<h3 class="w-fit" title="{% trans %}name.label{% endtrans %}">{{ project.name }}
|
|
{# You need edit permission to use the edit button #}
|
|
{% if is_granted('edit', project) %}
|
|
<a href="{{ entity_url(project, 'edit') }}"><i class="fas fa-fw fa-sm fa-edit"></i></a>
|
|
{% endif %}
|
|
</h3>
|
|
<h6 class="text-muted w-fit" title="{% trans %}description.label{% endtrans %}"><span>{{ project.description|format_markdown(true) }}</span></h6>
|
|
{% if project.buildPart %}
|
|
<h6>{% trans %}project.edit.associated_build_part{% endtrans %}:</h6>
|
|
<a href="{{ entity_url(project.buildPart) }}">{{ project.buildPart.name }}</a>
|
|
{% endif %}
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="col-md-4"> {# Sidebar panel with infos about last creation date, etc. #}
|
|
<div class="mb-3">
|
|
<span class="text-muted" title="{% trans %}lastModified{% endtrans %}">
|
|
<i class="fas fa-history fa-fw"></i> {{ helper.date_user_combination(project, true) }}
|
|
</span>
|
|
<br>
|
|
<span class="text-muted mt-1" title="{% trans %}createdAt{% endtrans %}">
|
|
<i class="fas fa-calendar-plus fa-fw"></i> {{ helper.date_user_combination(project, false) }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="mt-1">
|
|
<h6>
|
|
{{ helper.project_status_to_badge(project.status) }}
|
|
</h6>
|
|
</div>
|
|
<div class="mt-1">
|
|
<h6>
|
|
<span class="badge badge-primary bg-primary">
|
|
<i class="fa-solid fa-list-check fa-fw"></i>
|
|
{{ project.bomEntries | length }}
|
|
{% trans %}project.info.bom_entries_count{% endtrans %}
|
|
</span>
|
|
</h6>
|
|
</div>
|
|
{% set n = number_of_builds ?? 1 %}
|
|
{% set total_build_price = buildHelper.roundedTotalBuildPrice(project, n, app.user.currency ?? null) %}
|
|
{% set unit_build_price = buildHelper.roundedUnitBuildPrice(project, n, app.user.currency ?? null) %}
|
|
{% if total_build_price is not null %}
|
|
<div class="mt-1">
|
|
<h6>
|
|
<span class="badge badge-primary bg-success">
|
|
<i class="fa-solid fa-money-bill-wave fa-fw"></i>
|
|
{% trans %}project.info.total_build_price{% endtrans %}:
|
|
{{ total_build_price | format_money(app.user.currency ?? null, 2) }}
|
|
{% if n > 1 and unit_build_price is not null %}
|
|
<span class="ms-1">
|
|
({% trans %}project.info.per_unit_price{% endtrans %}: {{ unit_build_price | format_money(app.user.currency ?? null, 2) }})
|
|
</span>
|
|
{% endif %}
|
|
</span>
|
|
</h6>
|
|
</div>
|
|
{% endif %}
|
|
<form method="get" action="{{ path('project_info', {'id': project.id}) }}" class="mt-2">
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-text">{% trans %}project.builds.number_of_builds{% endtrans %}</span>
|
|
<input type="number" min="1" class="form-control" name="n" required value="{{ n }}">
|
|
<button class="btn btn-outline-secondary" type="submit">{% trans %}project.build.btn_build{% endtrans %}</button>
|
|
</div>
|
|
</form>
|
|
{% if project.children is not empty %}
|
|
<div class="mt-1">
|
|
<h6>
|
|
<span class="badge badge-primary bg-secondary">
|
|
<i class="fa-solid fa-folder-tree fa-fw"></i>
|
|
{{ project.children | length }}
|
|
{% trans %}project.info.sub_projects_count{% endtrans %}
|
|
</span>
|
|
</h6>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if project.comment is not empty %}
|
|
<div class="col-12 mt-2">
|
|
<h5>{% trans %}comment.label{% endtrans %}:</h5>
|
|
{{ project.comment|format_markdown }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|