Merge remote-tracking branch 'origin/feature/create-assemblies' into feature/all-features

# Conflicts:
#	migrations/Version20250304154507.php
#	src/Controller/TypeaheadController.php
#	templates/assemblies/build/_form.html.twig
This commit is contained in:
Marcel Diegelmann 2025-10-16 15:33:36 +02:00
commit 1345974954
50 changed files with 105 additions and 3832 deletions

View file

@ -1,90 +0,0 @@
{% import "helper.twig" as helper %}
{{ form_start(form) }}
<table class="table table-sm table-responsive table-hover">
<thead>
<tr>
<th>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" data-multicheck-name="lots_check" {{ stimulus_controller('pages/checkbox_multicheck') }}>
</div>
</th>
<th>{% trans %}part.table.name{% endtrans %}</th>
<th>{% trans %}assembly.bom.mountnames{% endtrans %}</th>
<th class="text-end">{% trans %}assembly.build.required_qty{% endtrans %}</th>
</tr>
</thead>
<tbody>
{% for bom_entry in build_request.bomEntries %}
{# 1st row basic infos about the BOM entry #}
<tr class="{% if bom_entry.part is null or buildHelper.bOMEntryBuildable(bom_entry, number_of_builds) %}table-primary{% else %}table-danger{% endif %}">
<td style="width: 20px;">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" data-multicheck-name="lots_check" required>
{# <label class="form-check-label" for="checkbox_{{ loop.index }}"> #}
</div>
</td>
<td >
{% if bom_entry.part %}
<b><a target="_blank" href="{{ entity_url(bom_entry.part) }}">{{ bom_entry.part.name }}</a></b> {% if bom_entry.name %}({{ bom_entry.name }}){% endif %}
{% elseif bom_entry.referencedAssembly %}
<b><a target="_blank" href="{{ entity_url(bom_entry.referencedAssembly) }}">{{ 'assembly.build.form.referencedAssembly'|trans({'%name%': bom_entry.referencedAssembly.name}) }}</a></b> {% if bom_entry.name %}({{ bom_entry.name }}){% endif %}
{% else %}
<b>{{ bom_entry.name }}</b>
{% endif %}
</td>
<td>
{% for tag in bom_entry.mountnames|split(',') %}
<span class="badge bg-secondary badge-secondary" >{{ tag | trim }}</span>
{% endfor %}
</td>
<td class="text-end">
<b>{{ build_request.neededAmountForBOMEntry(bom_entry) | format_amount(bom_entry.part.partUnit ?? null) }}</b> {% trans %}assembly.builds.needed{% endtrans %}
(= {{ number_of_builds }} x {{ bom_entry.quantity | format_amount(bom_entry.part.partUnit ?? null) }})
</td>
</tr>
<tr>
<td colspan="4">
{% set lots = build_request.partLotsForBOMEntry(bom_entry) %}
{% if lots is not null %}
{% for lot in lots %}
{# @var lot \App\Entity\Parts\PartLot #}
<div class="mb-2 row">
<label class="col-form-label col-sm-4" for="category_admin_form_parent">
{% if lot.storageLocation %}
<small>{{ helper.structural_entity_link(lot.storageLocation) }}</small>
{% endif %}
{% if lot.name is not empty %}
(<small>{{ lot.name }}</small>)
{% endif %}
</label>
<div class="col-sm-6">
{{ form_errors(form["lot_"~lot.id]) }}
{{ form_widget(form["lot_"~lot.id]) }}
</div>
<div class="col-sm-2 mt-1 text-end">
/ <b>{{ lot.amount | format_amount(lot.part.partUnit) }}</b> {% trans %}assembly.builds.stocked{% endtrans %}
</div>
</div>
{% endfor %}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ form_row(form.comment) }}
<div {{ stimulus_controller('pages/dont_check_quantity_checkbox') }}>
{{ form_row(form.dontCheckQuantity) }}
</div>
{{ form_row(form.addBuildsToBuildsPart) }}
{% if form.buildsPartLot is defined %}
{{ form_row(form.buildsPartLot) }}
{% endif %}
{{ form_row(form.submit) }}
{{ form_end(form) }}

View file

@ -1,40 +0,0 @@
{% extends "main_card.html.twig" %}
{% block title %}{% trans %}assembly.info.builds.label{% endtrans %}: {{ number_of_builds }}x {{ assembly.name }}{% endblock %}
{% block card_title %}
<i class="fa-solid fa-bolt fa-fw"></i>
{% trans %}assembly.info.builds.label{% endtrans %}: <b>{{ number_of_builds }}x</b> <i>{{ assembly.name }}</i>
{% endblock %}
{% block card_content %}
{% set can_build = buildHelper.assemblyBuildable(assembly, number_of_builds) %}
{% import "components/assemblies.macro.html.twig" as assembly_macros %}
{% if assembly.status is not empty and assembly.status != "in_production" %}
<div class="alert alert-warning" role="alert">
<i class="fa-solid fa-triangle-exclamation fa-fw"></i> {% trans with {"%assembly_status%": ('assembly.status.'~assembly.status)|trans } %}assembly.builds.check_assembly_status{% endtrans %}
</div>
{% endif %}
<div class="alert {% if can_build %}alert-success{% else %}alert-danger{% endif %}" role="alert">
{% if not can_build %}
<h5><i class="fa-solid fa-circle-exclamation fa-fw"></i> {% trans %}assembly.builds.build_not_possible{% endtrans %}</h5>
<b>{% trans with {"%number_of_builds%": number_of_builds} %}assembly.builds.following_bom_entries_miss_instock_n{% endtrans %}</b>
<ul>
{% for bom_entry in buildHelper.nonBuildableAssemblyBomEntries(assembly, number_of_builds) %}
<li>{{ assembly_macros.assembly_bom_entry_with_missing_instock(bom_entry, number_of_builds) }}</li>
{% endfor %}
</ul>
{% else %}
<h5><i class="fa-solid fa-circle-check fa-fw"></i> {% trans %}assembly.builds.build_possible{% endtrans %}</h5>
<span>{% trans with {"%max_builds%": number_of_builds} %}assembly.builds.number_of_builds_possible{% endtrans %}</span>
{% endif %}
</div>
<p class="text-muted">{% trans %}assembly.build.help{% endtrans %}</p>
{% include 'assemblies/build/_form.html.twig' %}
{% endblock %}

View file

@ -1,40 +0,0 @@
{% set can_build = buildHelper.assemblyBuildable(assembly) %}
{% import "components/assemblies.macro.html.twig" as assembly_macros %}
{% if assembly.status is not empty and assembly.status != "in_production" %}
<div class="alert mt-2 alert-warning" role="alert">
<i class="fa-solid fa-triangle-exclamation fa-fw"></i> {% trans with {"%assembly_status%": ('assembly.status.'~assembly.status)|trans } %}assembly.builds.check_assembly_status{% endtrans %}
</div>
{% endif %}
<div class="alert mt-2 {% if can_build %}alert-success{% else %}alert-danger{% endif %}" role="alert">
{% if not can_build %}
<h5><i class="fa-solid fa-circle-exclamation fa-fw"></i> {% trans %}assembly.builds.build_not_possible{% endtrans %}</h5>
<b>{% trans %}assembly.builds.following_bom_entries_miss_instock{% endtrans %}</b>
<ul>
{% for bom_entry in buildHelper.nonBuildableAssemblyBomEntries(assembly) %}
<li>{{ assembly_macros.assembly_bom_entry_with_missing_instock(bom_entry) }}</li>
{% endfor %}
</ul>
{% else %}
<h5><i class="fa-solid fa-circle-check fa-fw"></i> {% trans %}assembly.builds.build_possible{% endtrans %}</h5>
<span>{% trans with {"%max_builds%": buildHelper.maximumBuildableCount(assembly)} %}assembly.builds.number_of_builds_possible{% endtrans %}</span>
{% endif %}
</div>
<form method="get" action="{{ path('assembly_build', {"id": assembly.iD }) }}">
<div class="row mt-2">
<div class="col-4">
<div class="input-group mb-3">
<input type="number" min="1" class="form-control" placeholder="{% trans %}assembly.builds.number_of_builds{% endtrans %}" name="n" required>
<input type="hidden" name="_redirect" value="{{ uri_without_host(app.request) }}">
<button class="btn btn-outline-secondary" type="submit" id="button-addon2">{% trans %}assembly.build.btn_build{% endtrans %}</button>
</div>
</div>
</div>
</form>
{% if assembly.buildPart %}
<p><b>{% trans %}assembly.builds.no_stocked_builds{% endtrans %}:</b> <a href="{{ entity_url(assembly.buildPart) }}">{{ assembly.buildPart.amountSum }}</a></p>
{% endif %}

View file

@ -1,8 +0,0 @@
{% macro assembly_bom_entry_with_missing_instock(assembly_bom_entry, number_of_builds = 1) %}
{# @var \App\Entity\AssemblySystem\AssemblyBOMEntry assembly_bom_entry #}
<b><a href="{{ entity_url(assembly_bom_entry.part) }}">{{ assembly_bom_entry.part.name }}</a></b>
{% if assembly_bom_entry.name %}&nbsp;({{ assembly_bom_entry.name }}){% endif %}:
<b>{{ assembly_bom_entry.part.amountSum | format_amount(assembly_bom_entry.part.partUnit) }}</b> {% trans %}assembly.builds.stocked{% endtrans %}
/
<b>{{ (assembly_bom_entry.quantity * number_of_builds) | format_amount(assembly_bom_entry.part.partUnit) }}</b> {% trans %}assembly.builds.needed{% endtrans %}
{% endmacro %}