+ {% set lots = build_request.partLotsForBOMEntry(bom_entry) %}
+ {% if lots is not null %}
+ {% for lot in lots %}
+ {# @var lot \App\Entity\Parts\PartLot #}
+
+
+{{ datatables.datatable(datatable, 'elements/datatables/datatables', 'assemblies') }}
\ No newline at end of file
diff --git a/templates/assemblies/info/_builds.html.twig b/templates/assemblies/info/_builds.html.twig
new file mode 100644
index 000000000..780c8c609
--- /dev/null
+++ b/templates/assemblies/info/_builds.html.twig
@@ -0,0 +1,40 @@
+{% 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" %}
+
+ {% trans with {"%assembly_status%": ('assembly.status.'~assembly.status)|trans } %}assembly.builds.check_assembly_status{% endtrans %}
+
+{% endif %}
+
+
+ {% if not can_build %}
+
{% trans %}assembly.builds.build_not_possible{% endtrans %}
+ {% trans %}assembly.builds.following_bom_entries_miss_instock{% endtrans %}
+
+ {% for bom_entry in buildHelper.nonBuildableAssemblyBomEntries(assembly) %}
+
+ {% endif %}
+
+ {% if assembly.comment is not empty %}
+
+
+ {{ assembly.comment|format_markdown }}
+
+
+ {% endif %}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/assemblies/info/_subassemblies.html.twig b/templates/assemblies/info/_subassemblies.html.twig
new file mode 100644
index 000000000..8c92c5e91
--- /dev/null
+++ b/templates/assemblies/info/_subassemblies.html.twig
@@ -0,0 +1,28 @@
+
+
+
+
{% trans %}name.label{% endtrans %}
+
{% trans %}description.label{% endtrans %}
+
# {% trans %}assembly.info.bom_entries_count{% endtrans %}
+
# {% trans %}assembly.info.sub_assemblies_count{% endtrans %}
+
+
+
+ {% for subassembly in assembly.children %}
+
{% set lots = build_request.partLotsForBOMEntry(bom_entry) %}
+ {% set assemblyBomEntriesWithoutPart = build_request.assemblyBomEntriesWithoutPart(bom_entry) %}
+ {% set assemblyBomEntriesWithPartNoStock = build_request.assemblyBomEntriesWithPartNoStock(bom_entry) %}
{% if lots is not null %}
+ {% set previousLabel = null %}
+
{% for lot in lots %}
{# @var lot \App\Entity\Parts\PartLot #}
+
+ {% set label = '' %}
+ {% if form["lot_"~lot.id].vars.label is defined and form["lot_"~lot.id].vars.label is not empty %}
+ {% set label = form["lot_"~lot.id].vars.label %}
+ {% endif %}
+
+ {% if label != '' and (previousLabel is null or label != previousLabel) %}
+
{% endfor %}
{% endif %}
+ {% if assemblyBomEntriesWithoutPart is not null %}
+ {% for bomEntryWithoutPart in assemblyBomEntriesWithoutPart %}
+
+
+
+
+ / {% trans %}project.builds.no_stock{% endtrans %}
+
+
+ {% endfor %}
+ {% endif %}
+ {% if assemblyBomEntriesWithPartNoStock is not null %}
+ {% for bomEntryWithPartNoStock in assemblyBomEntriesWithPartNoStock %}
+
+
+
+
+
+ / {% trans %}project.builds.no_stock{% endtrans %}
+
+
+
+ {% endfor %}
+ {% endif %}
{% endfor %}
diff --git a/tests/Entity/Attachments/AttachmentTest.php b/tests/Entity/Attachments/AttachmentTest.php
index 00a68d7d4..699648eb7 100644
--- a/tests/Entity/Attachments/AttachmentTest.php
+++ b/tests/Entity/Attachments/AttachmentTest.php
@@ -24,6 +24,8 @@
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Depends;
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\Attachments\AssemblyAttachment;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\AttachmentTypeAttachment;
@@ -81,6 +83,7 @@ public static function subClassesDataProvider(): \Iterator
yield [CategoryAttachment::class, Category::class];
yield [CurrencyAttachment::class, Currency::class];
yield [ProjectAttachment::class, Project::class];
+ yield [AssemblyAttachment::class, Assembly::class];
yield [FootprintAttachment::class, Footprint::class];
yield [GroupAttachment::class, Group::class];
yield [ManufacturerAttachment::class, Manufacturer::class];
diff --git a/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php b/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php
new file mode 100644
index 000000000..210e33018
--- /dev/null
+++ b/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php
@@ -0,0 +1,177 @@
+.
+ */
+namespace App\Tests\Helpers\Assemblies;
+
+use App\Entity\Parts\MeasurementUnit;
+use App\Entity\Parts\Part;
+use App\Entity\Parts\PartLot;
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\AssemblySystem\AssemblyBOMEntry;
+use App\Helpers\Assemblies\AssemblyBuildRequest;
+use PHPUnit\Framework\TestCase;
+
+class AssemblyBuildRequestTest extends TestCase
+{
+
+ /** @var MeasurementUnit $float_unit */
+ private MeasurementUnit $float_unit;
+
+ /** @var Assembly */
+ private Assembly $assembly1;
+ /** @var AssemblyBOMEntry */
+ private AssemblyBOMEntry $bom_entry1a;
+ /** @var AssemblyBOMEntry */
+ private AssemblyBOMEntry $bom_entry1b;
+ /** @var AssemblyBOMEntry */
+ private AssemblyBOMEntry $bom_entry1c;
+
+ private PartLot $lot1a;
+ private PartLot $lot1b;
+ private PartLot $lot2;
+
+ /** @var Part */
+ private Part $part1;
+ /** @var Part */
+ private Part $part2;
+
+
+ public function setUp(): void
+ {
+ $this->float_unit = new MeasurementUnit();
+ $this->float_unit->setName('float');
+ $this->float_unit->setUnit('f');
+ $this->float_unit->setIsInteger(false);
+ $this->float_unit->setUseSIPrefix(true);
+
+ //Setup some example parts and part lots
+ $this->part1 = new Part();
+ $this->part1->setName('Part 1');
+ $this->lot1a = new class extends PartLot {
+ public function getID(): ?int
+ {
+ return 1;
+ }
+ };
+ $this->part1->addPartLot($this->lot1a);
+ $this->lot1a->setAmount(10);
+ $this->lot1a->setDescription('Lot 1a');
+
+ $this->lot1b = new class extends PartLot {
+ public function getID(): ?int
+ {
+ return 2;
+ }
+ };
+ $this->part1->addPartLot($this->lot1b);
+ $this->lot1b->setAmount(20);
+ $this->lot1b->setDescription('Lot 1b');
+
+ $this->part2 = new Part();
+
+ $this->part2->setName('Part 2');
+ $this->part2->setPartUnit($this->float_unit);
+ $this->lot2 = new PartLot();
+ $this->part2->addPartLot($this->lot2);
+ $this->lot2->setAmount(2.5);
+ $this->lot2->setDescription('Lot 2');
+
+ $this->bom_entry1a = new AssemblyBOMEntry();
+ $this->bom_entry1a->setPart($this->part1);
+ $this->bom_entry1a->setQuantity(2);
+
+ $this->bom_entry1b = new AssemblyBOMEntry();
+ $this->bom_entry1b->setPart($this->part2);
+ $this->bom_entry1b->setQuantity(1.5);
+
+ $this->bom_entry1c = new AssemblyBOMEntry();
+ $this->bom_entry1c->setName('Non-part BOM entry');
+ $this->bom_entry1c->setQuantity(4);
+
+
+ $this->assembly1 = new Assembly();
+ $this->assembly1->setName('Assembly 1');
+ $this->assembly1->addBomEntry($this->bom_entry1a);
+ $this->assembly1->addBomEntry($this->bom_entry1b);
+ $this->assembly1->addBomEntry($this->bom_entry1c);
+ }
+
+ public function testInitialization(): void
+ {
+ //The values should be already prefilled correctly
+ $request = new AssemblyBuildRequest($this->assembly1, 10);
+ //We need totally 20: Take 10 from the first (maximum 10) and 10 from the second (maximum 20)
+ $this->assertEqualsWithDelta(10.0, $request->getLotWithdrawAmount($this->lot1a), PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(10.0, $request->getLotWithdrawAmount($this->lot1b), PHP_FLOAT_EPSILON);
+
+ //If the needed amount is higher than the maximum, we should get the maximum
+ $this->assertEqualsWithDelta(2.5, $request->getLotWithdrawAmount($this->lot2), PHP_FLOAT_EPSILON);
+ }
+
+ public function testGetNumberOfBuilds(): void
+ {
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+ $this->assertSame(5, $build_request->getNumberOfBuilds());
+ }
+
+ public function testGetAssembly(): void
+ {
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+ $this->assertEquals($this->assembly1, $build_request->getAssembly());
+ }
+
+ public function testGetNeededAmountForBOMEntry(): void
+ {
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+ $this->assertEqualsWithDelta(10.0, $build_request->getNeededAmountForBOMEntry($this->bom_entry1a), PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(7.5, $build_request->getNeededAmountForBOMEntry($this->bom_entry1b), PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(20.0, $build_request->getNeededAmountForBOMEntry($this->bom_entry1c), PHP_FLOAT_EPSILON);
+ }
+
+ public function testGetSetLotWithdrawAmount(): void
+ {
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+
+ //We can set the amount for a lot either via the lot object or via the ID
+ $build_request->setLotWithdrawAmount($this->lot1a, 2);
+ $build_request->setLotWithdrawAmount($this->lot1b->getID(), 3);
+
+ //And it should be possible to get the amount via the lot object or via the ID
+ $this->assertEqualsWithDelta(2.0, $build_request->getLotWithdrawAmount($this->lot1a->getID()), PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(3.0, $build_request->getLotWithdrawAmount($this->lot1b), PHP_FLOAT_EPSILON);
+ }
+
+ public function testGetWithdrawAmountSum(): void
+ {
+ //The sum of all withdraw amounts for an BOM entry (over all lots of the associated part) should be correct
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+
+ $build_request->setLotWithdrawAmount($this->lot1a, 2);
+ $build_request->setLotWithdrawAmount($this->lot1b, 3);
+
+ $this->assertEqualsWithDelta(5.0, $build_request->getWithdrawAmountSum($this->bom_entry1a), PHP_FLOAT_EPSILON);
+ $build_request->setLotWithdrawAmount($this->lot2, 1.5);
+ $this->assertEqualsWithDelta(1.5, $build_request->getWithdrawAmountSum($this->bom_entry1b), PHP_FLOAT_EPSILON);
+ }
+
+
+}
diff --git a/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php b/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php
new file mode 100644
index 000000000..c513ed8de
--- /dev/null
+++ b/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php
@@ -0,0 +1,117 @@
+.
+ */
+namespace App\Tests\Services\AssemblySystem;
+
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\AssemblySystem\AssemblyBOMEntry;
+use App\Entity\Parts\Part;
+use App\Entity\Parts\PartLot;
+use App\Services\AssemblySystem\AssemblyBuildHelper;
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+class AssemblyBuildHelperTest extends WebTestCase
+{
+ /** @var AssemblyBuildHelper */
+ protected $service;
+
+ protected function setUp(): void
+ {
+ self::bootKernel();
+ $this->service = self::getContainer()->get(AssemblyBuildHelper::class);
+ }
+
+ public function testGetMaximumBuildableCountForBOMEntryNonPartBomEntry(): void
+ {
+ $bom_entry = new AssemblyBOMEntry();
+ $bom_entry->setPart(null);
+ $bom_entry->setQuantity(10);
+ $bom_entry->setName('Test');
+
+ $this->expectException(\InvalidArgumentException::class);
+ $this->service->getMaximumBuildableCountForBOMEntry($bom_entry);
+ }
+
+ public function testGetMaximumBuildableCountForBOMEntry(): void
+ {
+ $assembly_bom_entry = new AssemblyBOMEntry();
+ $assembly_bom_entry->setQuantity(10);
+
+ $part = new Part();
+ $lot1 = new PartLot();
+ $lot1->setAmount(120);
+ $lot2 = new PartLot();
+ $lot2->setAmount(5);
+ $part->addPartLot($lot1);
+ $part->addPartLot($lot2);
+
+ $assembly_bom_entry->setPart($part);
+
+ //We have 125 parts in stock, so we can build 12 times the assembly (125 / 10 = 12.5)
+ $this->assertSame(12, $this->service->getMaximumBuildableCountForBOMEntry($assembly_bom_entry));
+
+
+ $lot1->setAmount(0);
+ //We have 5 parts in stock, so we can build 0 times the assembly (5 / 10 = 0.5)
+ $this->assertSame(0, $this->service->getMaximumBuildableCountForBOMEntry($assembly_bom_entry));
+ }
+
+ public function testGetMaximumBuildableCount(): void
+ {
+ $assembly = new Assembly();
+
+ $assembly_bom_entry1 = new AssemblyBOMEntry();
+ $assembly_bom_entry1->setQuantity(10);
+ $part = new Part();
+ $lot1 = new PartLot();
+ $lot1->setAmount(120);
+ $lot2 = new PartLot();
+ $lot2->setAmount(5);
+ $part->addPartLot($lot1);
+ $part->addPartLot($lot2);
+ $assembly_bom_entry1->setPart($part);
+ $assembly->addBomEntry($assembly_bom_entry1);
+
+ $assembly_bom_entry2 = new AssemblyBOMEntry();
+ $assembly_bom_entry2->setQuantity(5);
+ $part2 = new Part();
+ $lot3 = new PartLot();
+ $lot3->setAmount(10);
+ $part2->addPartLot($lot3);
+ $assembly_bom_entry2->setPart($part2);
+ $assembly->addBomEntry($assembly_bom_entry2);
+
+ $assembly->addBomEntry((new AssemblyBOMEntry())->setName('Non part entry')->setQuantity(1));
+
+ //Restricted by the few parts in stock of part2
+ $this->assertSame(2, $this->service->getMaximumBuildableCount($assembly));
+
+ $lot3->setAmount(1000);
+ //Now the build count is restricted by the few parts in stock of part1
+ $this->assertSame(12, $this->service->getMaximumBuildableCount($assembly));
+
+ $lot3->setAmount(0);
+ //Now the build count must be 0, as we have no parts in stock
+ $this->assertSame(0, $this->service->getMaximumBuildableCount($assembly));
+
+ }
+}
diff --git a/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php b/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php
new file mode 100644
index 000000000..b8aa0ddc3
--- /dev/null
+++ b/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php
@@ -0,0 +1,52 @@
+.
+ */
+namespace App\Tests\Services\AssemblySystem;
+
+use App\Entity\AssemblySystem\Assembly;
+use App\Services\AssemblySystem\AssemblyBuildPartHelper;
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+class AssemblyBuildPartHelperTest extends WebTestCase
+{
+ /** @var AssemblyBuildPartHelper */
+ protected $service;
+
+ protected function setUp(): void
+ {
+ self::bootKernel();
+ $this->service = self::getContainer()->get(AssemblyBuildPartHelper::class);
+ }
+
+ public function testGetPartInitialization(): void
+ {
+ $assembly = new Assembly();
+ $assembly->setName('Assembly 1');
+ $assembly->setDescription('Description 1');
+
+ $part = $this->service->getPartInitialization($assembly);
+ $this->assertSame('Assembly 1', $part->getName());
+ $this->assertSame('Description 1', $part->getDescription());
+ $this->assertSame($assembly, $part->getBuiltAssembly());
+ $this->assertSame($part, $assembly->getBuildPart());
+ }
+}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index 1f234450e..f5823e8d8 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -4741,6 +4741,18 @@ Pokud jste to provedli nesprávně nebo pokud počítač již není důvěryhodn
Název
+
+
+ project.bom.assembly
+ Sestava
+
+
+
+
+ project.bom.partOrAssembly
+ Výběr
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9786,6 +9798,18 @@ Element 3
Díl
+
+
+ project.bom.assembly
+ Baugruppe
+
+
+
+
+ project.bom.partOrAssembly
+ Auswahl
+
+ project.bom.add_entry
@@ -9864,6 +9888,42 @@ Element 3
Archivováno
+
+
+ assembly.edit.status
+ Stav
+
+
+
+
+ assembly.status.draft
+ Návrh
+
+
+
+
+ assembly.status.planning
+ Plánování
+
+
+
+
+ assembly.status.in_production
+ Ve výrobě
+
+
+
+
+ assembly.status.finished
+ Dokončeno
+
+
+
+
+ assembly.status.archived
+ Archivováno
+
+ part.new_build_part.error.build_part_already_exists
@@ -10140,6 +10200,12 @@ Element 3
k dispozici
+
+
+ project.builds.no_stock
+ není uveden žádný sklad
+
+ project.builds.needed
@@ -10212,6 +10278,12 @@ Element 3
Cílový inventář
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% požadováno)
+
+ project.builds.number_of_builds
@@ -13035,6 +13107,634 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Z bezpečnostních důvodů redigováno
+
+
+ part.table.name.value.for_part
+ %value% (Součást)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Sestava)
+
+
+
+
+ assembly.label
+ Sestava
+
+
+
+
+ assembly.caption
+ Sestava
+
+
+
+
+ perm.assemblies
+ Sestavy
+
+
+
+
+ assembly_bom_entry.label
+ Součásti
+
+
+
+
+ assembly.labelp
+ Sestavy
+
+
+
+
+ assembly.edit
+ Upravit sestavu
+
+
+
+
+ assembly.new
+ Nová sestava
+
+
+
+
+ assembly.edit.associated_build_part
+ Přidružená součást
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Přidat součást
+
+
+
+
+ assembly.edit.associated_build.hint
+ Tato součást představuje vyrobené instance sestavy. Zadejte, pokud jsou vyrobené instance potřeba. Pokud ne, počet součástí bude použit až při sestavení daného projektu.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importovat součásti
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Sestavy
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% součástí úspěšně importováno do sestavy.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Chyba ověření! Zkontrolujte svůj importovaný soubor!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Soubor nelze importovat. Zkontrolujte, zda jste vybrali správný typ souboru. Chybová zpráva: %message%
+
+
+
+
+ assembly.bom.quantity
+ Množství
+
+
+
+
+ assembly.bom.mountnames
+ Názvy osazení
+
+
+
+
+ assembly.bom.instockAmount
+ Stav na skladě
+
+
+
+
+ assembly.info.title
+ Info o sestavě
+
+
+
+
+ assembly.info.info.label
+ Informace
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Podskupina
+
+
+
+
+ assembly.info.builds.label
+ Sestavení
+
+
+
+
+ assembly.info.bom_add_parts
+ Přidat součásti
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Měli byste zkontrolovat, zda opravdu chcete sestavu postavit s tímto stavem!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Sestavení není možné: Nedostatek součástí
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Není dostatek součástí na skladě pro postavení tohoto projektu %number_of_builds% krát. Následující součásti nejsou skladem v dostatečném množství.
+
+
+
+
+ assembly.builds.build_possible
+ Sestavení je možné
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% kusů této sestavy.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Počet sestavení
+
+
+
+
+ assembly.build.btn_build
+ Sestavit
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Počet skladovaných vyrobených instancí
+
+
+
+
+ assembly.info.bom_entries_count
+ Součásti
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Podskupiny
+
+
+
+
+ assembly.builds.stocked
+ skladem
+
+
+
+
+ assembly.builds.needed
+ potřebné
+
+
+
+
+ assembly.add_parts_to_assembly
+ Přidat součásti do sestavy
+
+
+
+
+ assembly.bom.name
+ Název
+
+
+
+
+ assembly.bom.comment
+ Poznámky
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Není dostatek součástí na skladě pro sestavení této sestavy %number_of_builds% krát. Následující součásti nejsou skladem:
+
+
+
+
+ assembly.build.help
+ Vyberte, ze kterých zásob se mají brát potřebné součásti pro sestavení (a v jakém množství). Zaškrtněte políčko u každého dílu, pokud jste jej odebrali, nebo použijte horní políčko k výběru všech naráz.
+
+
+
+
+ assembly.build.required_qty
+ Požadované množství
+
+
+
+
+ assembly.import_bom
+ Importovat součásti do sestavy
+
+
+
+
+ assembly.bom.part
+ Součást
+
+
+
+
+ assembly.bom.add_entry
+ Přidat položku
+
+
+
+
+ assembly.bom.price
+ Cena
+
+
+
+
+ assembly.build.dont_check_quantity
+ Neověřovat množství
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Pokud je tato volba vybrána, budou vybraná množství odstraněna ze skladu bez ohledu na to, zda je méně nebo více součástí, než je skutečně potřeba pro sestavení sestavy.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Přidat vyrobené instance do součásti sestavy
+
+
+
+
+ assembly.bom_import.type
+ Typ
+
+
+
+
+ assembly.bom_import.type.json
+ JSON pro sestavu
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Smazat existující položky před importem
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Pokud je tato možnost vybrána, budou všechny již existující součásti sestavy smazány a nahrazeny importovanými daty součástí.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Šablona importu JSON pro sestavu
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Šablona importu CSV (KiCAD Pcbnew BOM) pro sestavu
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Název součásti v sestavě
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Unikátní číslo produktu u výrobce
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unikátní IPN součásti
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unikátní název součásti
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unikátní jméno výrobce
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Unikátní název kategorie
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Pole
+
Podmínka
+
Datový typ
+
Popis
+
+
+
+
+
quantity
+
Povinné
+
Číslo s plovoucí desetinnou čárkou (Float)
+
Musí být uvedeno a obsahovat hodnotu s plovoucí desetinnou čárkou (Float) větší než 0,0.
+
+
+
name
+
Volitelné
+
Řetězec (String)
+
Pokud je přítomen, musí být neprázdný řetězec.
+
+
+
part
+
Volitelné
+
Objekt/Array
+
+ Pokud je uvedeno, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID součástky v Part-DB.
+
+
+
part.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není zadáno part.mpnr nebo part.ipn.
+
+
+
part.mpnr
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není zadáno part.name nebo part.ipn.
+
+
+
part.ipn
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není zadáno part.name nebo part.mpnr.
+
+
+
part.description
+
Volitelné
+
Řetězec nebo null
+
Pokud je přítomen, musí být neprázdný řetězec nebo null.
+
+
+
part.manufacturer
+
Volitelné
+
Objekt/Array
+
+ Pokud je přítomen, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID výrobce.
+
+
+
manufacturer.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno manufacturer.id.
+
+
+
part.category
+
Volitelné
+
Objekt/Array
+
+ Pokud je přítomen, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID kategorie součástky.
+
+
+
category.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno category.id.
Volný údaj. Jedinečné identifikační číslo pro každou součástku.
+
+
+
Designator
+
Volitelný
+
Řetězec (String)
+
Volný údaj. Jedinečný referenční označovač součástky na desce plošných spojů, např. „R1“ pro rezistor 1. Používá se pro název osazení součástky v rámci skupiny součástek.
+
+
+
Package
+
Volitelný
+
Řetězec (String)
+
Volný údaj. Pouzdro nebo tvar součástky, např. „0805“ pro SMD rezistory.
+
+
+
Množství
+
Povinný
+
Celé číslo (Integer)
+
Počet identických součástek, které jsou potřeba k vytvoření jedné instance sestavy.
+
+
+
Určení
+
Povinný
+
Řetězec (String)
+
Popis nebo funkce součástky, např. hodnota rezistoru „10kΩ“ nebo hodnota kondenzátoru „100nF“. Používá se pro název položky v BOM.
+
+
+
Dodavatel a ref
+
Volitelný
+
Řetězec (String)
+
Volný údaj. Může obsahovat např. specifické údaje distributora.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (součást)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (sestava)
+
+
+
+
+ projects.build.form.part
+ Součást "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Sestava "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (potřebné množství: %quantity%)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ není skladem
+
+ project.bom_import.map_fields
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index d72589864..f231163a1 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -4748,6 +4748,18 @@ Bemærk også, at uden to-faktor-godkendelse er din konto ikke længere så godt
Navn
+
+
+ project.bom.assembly
+ Montering
+
+
+
+
+ project.bom.partOrAssembly
+ Valg
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9812,6 +9824,18 @@ Element 3
Komponent
+
+
+ project.bom.assembly
+ Baugruppe
+
+
+
+
+ project.bom.partOrAssembly
+ Auswahl
+
+ project.bom.add_entry
@@ -9890,6 +9914,42 @@ Element 3
Arkiveret
+
+
+ assembly.edit.status
+ Status
+
+
+
+
+ assembly.status.draft
+ Kladde
+
+
+
+
+ assembly.status.planning
+ Under planlægning
+
+
+
+
+ assembly.status.in_production
+ I produktion
+
+
+
+
+ assembly.status.finished
+ Ophørt
+
+
+
+
+ assembly.status.archived
+ Arkiveret
+
+ part.new_build_part.error.build_part_already_exists
@@ -10166,6 +10226,12 @@ Element 3
På lager
+
+
+ project.builds.no_stock
+ intet lager angivet
+
+ project.builds.needed
@@ -10238,6 +10304,12 @@ Element 3
Mål mængde
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% påkrævet)
+
+ project.builds.number_of_builds
@@ -12196,5 +12268,633 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Du forsøgte at fjerne/tilføje en mængde sat til nul! Der blev ikke foretaget nogen handling.
+
+
+ part.table.name.value.for_part
+ %value% (Del)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Samlingsenhed)
+
+
+
+
+ assembly.label
+ Samling
+
+
+
+
+ assembly.caption
+ Samling
+
+
+
+
+ perm.assemblies
+ Samlinger
+
+
+
+
+ assembly_bom_entry.label
+ Komponenter
+
+
+
+
+ assembly.labelp
+ Samlinger
+
+
+
+
+ assembly.edit
+ Rediger samling
+
+
+
+
+ assembly.new
+ Ny samling
+
+
+
+
+ assembly.edit.associated_build_part
+ Tilknyttet komponent
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Tilføj komponent
+
+
+
+
+ assembly.edit.associated_build.hint
+ Denne komponent repræsenterer de fremstillede instanser af samlingen. Angiv, hvis fremstillede instanser er påkrævet. Hvis ikke, vil antallet af komponenter først blive anvendt ved opbygning af det pågældende projekt.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importér komponenter
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Samlinger
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% komponent(er) blev importeret til samlingen med succes.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Valideringsfejl! Kontroller venligst den importerede fil!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Filen kunne ikke importeres. Kontrollér, at du har valgt den korrekte filtype. Fejlmeddelelse: %message%
+
+
+
+
+ assembly.bom.quantity
+ Mængde
+
+
+
+
+ assembly.bom.mountnames
+ Monteringsnavne
+
+
+
+
+ assembly.bom.instockAmount
+ Antal på lager
+
+
+
+
+ assembly.info.title
+ Samleinfo
+
+
+
+
+ assembly.info.info.label
+ Info
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Undergruppe
+
+
+
+
+ assembly.info.builds.label
+ Byggeri
+
+
+
+
+ assembly.info.bom_add_parts
+ Tilføj dele
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Du bør kontrollere, om du virkelig ønsker at bygge samlingen med denne status!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Opbygning ikke mulig: Ikke nok komponenter til rådighed
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Der er ikke nok dele på lager til at bygge dette projekt %number_of_builds% gange. Følgende dele mangler på lager:
+
+
+
+
+ assembly.builds.build_possible
+ Byggeri muligt
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% eksemplarer af denne samling.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Antal opbygninger
+
+
+
+
+ assembly.build.btn_build
+ Byg
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Antal lagrede byggede enheder
+
+
+
+
+ assembly.info.bom_entries_count
+ Komponenter
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Undergrupper
+
+
+
+
+ assembly.builds.stocked
+ på lager
+
+
+
+
+ assembly.builds.needed
+ nødvendig
+
+
+
+
+ assembly.add_parts_to_assembly
+ Tilføj dele til samlingen
+
+
+
+
+ assembly.bom.name
+ Navn
+
+
+
+
+ assembly.bom.comment
+ Notater
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Der er ikke nok dele på lager til at bygge denne samling %number_of_builds% gange. Følgende dele mangler på lager:
+
+
+
+
+ assembly.build.help
+ Vælg, hvilke lagre de nødvendige dele til bygningen skal tages fra (og i hvilken mængde). Marker afkrydsningsfeltet for hver delpost, når du har fjernet delene, eller brug det øverste afkrydsningsfelt for at markere alle på én gang.
+
+
+
+
+ assembly.build.required_qty
+ Krævet antal
+
+
+
+
+ assembly.import_bom
+ Importer dele til samling
+
+
+
+
+ assembly.bom.part
+ Del
+
+
+
+
+ assembly.bom.add_entry
+ Tilføj post
+
+
+
+
+ assembly.bom.price
+ Pris
+
+
+
+
+ assembly.build.dont_check_quantity
+ Tjek ikke mængder
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Hvis denne mulighed vælges, fjernes de valgte mængder fra lageret, uanset om der er mere eller mindre end nødvendigt for at bygge samlingen.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Tilføj byggede enheder til assemblies del
+
+
+
+
+ assembly.bom_import.type
+ Type
+
+
+
+
+ assembly.bom_import.type.json
+ JSON for en samling
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Slet eksisterende poster før import
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Hvis dette valg er markeret, slettes alle eksisterende komponentposter i samlingen og erstattes med de importerede.
+
+
+
+
+ assembly.import_bom.template.header.json
+ JSON-importskabelon til en samling
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Importskabelon CSV (KiCAD Pcbnew BOM) til en samling
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Delens navn i samlingen
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Unik produktnummer hos producenten
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unik IPN for delen
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unikt komponentnavn
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unikt producenter navn
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Kategoriens unikke navn
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Felt
+
Betingelse
+
Datatype
+
Beskrivelse
+
+
+
+
+
quantity
+
Påkrævet
+
Flydende tal (Float)
+
Skal være til stede og indeholde en flydende værdi (Float), der er større end 0,0.
+
+
+
name
+
Valgfri
+
String
+
Hvis til stede, skal det være en ikke-tom streng.
+
+
+
part
+
Valgfri
+
Objekt/Array
+
+ Hvis angivet, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Valgfri
+
Heltal (Integer)
+
Heltal (Integer) > 0. Matcher Part-DB's interne numeriske ID for komponenten.
+
+
+
part.name
+
Valgfri
+
String
+
Ikke-tom streng, hvis part.mpnr eller part.ipn ikke er givet.
+
+
+
part.mpnr
+
Valgfri
+
String
+
Ikke-tom streng, hvis part.name eller part.ipn ikke er givet.
+
+
+
part.ipn
+
Valgfri
+
String
+
Ikke-tom streng, hvis part.name eller part.mpnr ikke er givet.
+
+
+
part.description
+
Valgfri
+
String eller null
+
Hvis til stede, skal det være en ikke-tom streng eller null.
+
+
+
part.manufacturer
+
Valgfri
+
Objekt/Array
+
+ Hvis til stede, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+
Fri oplysning. Et unikt identifikationsnummer for hver komponent.
+
+
+
Designator
+
Valgfri
+
Streng
+
Fri oplysning. En unik referencebetegnelse for komponenten på printkortet, f.eks. "R1" for modstand 1. Bruges til navngivning af monteringssæt i komponentgruppen.
+
+
+
Package
+
Valgfri
+
Streng
+
Fri oplysning. Komponentenheden eller -formatet, f.eks. "0805" for SMD-modstande.
+
+
+
Antal
+
Påkrævet
+
Heltal (Integer)
+
Antallet af identiske komponenter, der kræves for at oprette en enkelt instans af samling.
+
+
+
Betegnelse
+
Påkrævet
+
Streng
+
Beskrivelse eller funktion for komponenten, f.eks. modstandsværdi "10kΩ" eller kondensatorværdi "100nF". Bruges til navnet i BOM-posten.
+
+
+
Leverandør og ref
+
Valgfri
+
Streng
+
Fri oplysning. Kan indeholde f.eks. distributørspecifik værdi.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (del)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (samling)
+
+
+
+
+ projects.build.form.part
+ Del "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Samling "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% nødvendig)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ ikke på lager
+
+
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index 9fb3f6ef6..c32bf46a7 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -4740,6 +4740,18 @@ Wenn Sie dies fehlerhafterweise gemacht haben oder ein Computer nicht mehr vertr
Name
+
+
+ part.table.name.value.for_part
+ %value% (Bauteil)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Baugruppe)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9788,6 +9800,18 @@ Element 1 -> Element 1.2
Bauteil
+
+
+ project.bom.assembly
+ Baugruppe
+
+
+
+
+ project.bom.partOrAssembly
+ Auswahl
+
+ project.bom.add_entry
@@ -9866,6 +9890,42 @@ Element 1 -> Element 1.2
Archiviert
+
+
+ assembly.edit.status
+ Status
+
+
+
+
+ assembly.status.draft
+ Entwurf
+
+
+
+
+ assembly.status.planning
+ In Planung
+
+
+
+
+ assembly.status.in_production
+ In Produktion
+
+
+
+
+ assembly.status.finished
+ Abgeschlossen
+
+
+
+
+ assembly.status.archived
+ Archiviert
+
+ part.new_build_part.error.build_part_already_exists
@@ -10142,6 +10202,12 @@ Element 1 -> Element 1.2
vorhanden
+
+
+ project.builds.no_stock
+ kein Lager angegeben
+
+ project.builds.needed
@@ -10214,6 +10280,12 @@ Element 1 -> Element 1.2
Ziel-Bestand
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% benötigt)
+
+ project.builds.number_of_builds
@@ -12851,6 +12923,622 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Externe Version anzeigen
+
+
+ assembly.label
+ Baugruppe
+
+
+
+
+ assembly.caption
+ Baugruppe
+
+
+
+
+ perm.assemblies
+ Baugruppen
+
+
+
+
+ assembly_bom_entry.label
+ Bauteile
+
+
+
+
+ assembly.labelp
+ Baugruppen
+
+
+
+
+ assembly.edit
+ Bearbeite Baugruppe
+
+
+
+
+ assembly.new
+ Neue Baugruppe
+
+
+
+
+ assembly.edit.associated_build_part
+ Verknüpftes Bauteil
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Bauteil hinzufügen
+
+
+
+
+ assembly.edit.associated_build.hint
+ Dieses Bauteil repräsentiert die gebauten Instanzen der Baugruppe. Anzugeben, sofern gebaute Instanzen benötigt werden. Wenn nein, werden die Stückzahlen bzgl. der Baugruppe erst beim Build des jeweiligen Projektes herangezogen.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Bauteile importieren
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Baugruppen
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% Part Einträge erfolgreich in Baugruppe importiert.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Validierungsfehler! Bitte überprüfen Sie die importierte Datei!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Datei konnte nicht importiert werden. Überprüfen Sie, dass Sie den richtigen Dateityp gewählt haben. Fehlermeldung: %message%
+
+
+
+
+ assembly.bom.quantity
+ Menge
+
+
+
+
+ assembly.bom.mountnames
+ Bestückungsnamen
+
+
+
+
+ assembly.bom.instockAmount
+ Bestand im Lager
+
+
+
+
+ assembly.info.title
+ Baugruppen-Info
+
+
+
+
+ assembly.info.info.label
+ Info
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Untergruppe
+
+
+
+
+ assembly.info.builds.label
+ Bau
+
+
+
+
+ assembly.info.bom_add_parts
+ Bauteile hinzufügen
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Sie sollten überprüfen, ob sie die Baugruppe mit diesem Status wirklich bauen wollen!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Bau nicht möglich: Nicht genügend Bauteile vorhanden
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Es sind nicht genügend Bauteile auf Lager, um dieses Projekt %number_of_builds% mal zu bauen. Von folgenden Bauteilen ist nicht genügend auf Lager.
+
+
+
+
+ assembly.builds.build_possible
+ Bau möglich
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% Exemplare dieser Baugruppe zu bauen.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Zu bauende Anzahl
+
+
+
+
+ assembly.build.btn_build
+ Bauen
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Anzahl gelagerter gebauter Instanzen
+
+
+
+
+ assembly.info.bom_entries_count
+ Bauteile
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Untergruppen
+
+
+
+
+ assembly.builds.stocked
+ vorhanden
+
+
+
+
+ assembly.builds.needed
+ benötigt
+
+
+
+
+ assembly.add_parts_to_assembly
+ Bauteile zur Baugruppe hinzufügen
+
+
+
+
+ assembly.bom.name
+ Name
+
+
+
+
+ assembly.bom.comment
+ Notizen
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Es sind nicht genügend Bauteile auf Lager, um diese Baugruppe %number_of_builds% mal zu bauen. Von folgenden Bauteilen ist nicht genügend auf Lager:
+
+
+
+
+ assembly.build.help
+ Wählen Sie aus, aus welchen Beständen die zum Bau notwendigen Bauteile genommen werden sollen (und in welcher Anzahl). Setzen Sie den Haken für jeden Part Eintrag, wenn sie die Bauteile entnommen haben, oder nutzen Sie die oberste Checkbox, um alle Haken auf einmal zu setzen.
+
+
+
+
+ assembly.build.required_qty
+ Benötigte Anzahl
+
+
+
+
+ assembly.import_bom
+ Importiere Parts für Baugruppe
+
+
+
+
+ assembly.bom.part
+ Bauteil
+
+
+
+
+ assembly.bom.add_entry
+ Eintrag hinzufügen
+
+
+
+
+ assembly.bom.price
+ Preis
+
+
+
+
+ assembly.build.dont_check_quantity
+ Mengen nicht überprüfen
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Wenn diese Option gewählt wird, werden die gewählten Mengen aus dem Lager entfernt, egal ob mehr oder weniger Bauteile sind, als für den Bau der Baugruppe eigentlich benötigt werden.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Gebaute Instanzen zum Bauteil der Baugruppe hinzufügen
+
+
+
+
+ assembly.bom_import.type
+ Typ
+
+
+
+
+ assembly.bom_import.type.json
+ JSON für eine Baugruppe
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Lösche existierende Bauteil-Einträge vor dem Import
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Wenn diese Option ausgewählt ist, werden alle bereits in der Baugruppe existierenden Bauteile gelöscht und mit den importierten Bauteildaten überschrieben.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Import-Vorlage JSON für eine Baugruppe
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Import-Vorlage CSV (KiCAD Pcbnew BOM) für eine Baugruppe
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Name des Bauteils in der Baugruppe
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Eindeutige Produktnummer innerhalb des Herstellers
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Eideutige IPN des Bauteils
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Eindeutiger Name des Bauteils
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Eindeutiger Name des Herstellers
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Eindeutiger Name der Kategorie
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
quantity
+
Pflichtfeld
+
Gleitkommazahl (Float)
+
Muss gegeben sein und enthält einen Gleitkommawert (Float), der größer als 0.0 ist.
+
+
+
name
+
Optional
+
String
+
Falls vorhanden, muss es ein nicht-leerer String sein.
+
+
+
part
+
Optional
+
Objekt/Array
+
+ Falls angegeben, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
+
+
+
part.name
+
Optional
+
String
+
Nicht-leerer String, falls keine part.mpnr- bzw. part.ipn-Angabe gegeben ist.
+
+
+
part.mpnr
+
Optional
+
String
+
Nicht-leerer String, falls keine part.name- bzw. part-ipn-Angabe gegeben ist.
+
+
+
part.ipn
+
Optional
+
String
+
Nicht-leerer String, falls keine part.name- bzw. part.mpnr-Angabe gegeben ist.
+
+
+
part.description
+
Optional
+
String oder null
+
Falls vorhanden, muss es ein nicht-leerer String sein oder null.
+
+
+
part.manufacturer
+
Optional
+
Objekt/Array
+
+ Falls vorhanden, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID des Herstellers.
+
+
+
manufacturer.name
+
Optional
+
String
+
Nicht-leerer String, falls keine manufacturer.id-Angabe gegeben ist.
+
+
+
part.category
+
Optional
+
Objekt/Array
+
+ Falls vorhanden, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID der Kategorie des Bauteils.
+
+
+
category.name
+
Optional
+
String
+
Nicht-leerer String, falls keine category.id-Angabe gegeben ist.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Erwartete Spalten:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Hinweis: Es findet keine Zuordnung zu konkreten Bauteilen aus der Kategorie-Verwaltung statt.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
Id
+
Optional
+
Ganzzahl (Integer)
+
Offene Angabe. Eine eindeutige Identifikationsnummer für jedes Bauteil.
+
+
+
Designator
+
Optional
+
String
+
Offene Angabe. Ein eindeutiger Referenzbezeichner des Bauteils auf der Leiterplatte, z.B. „R1“ für Widerstand 1. Wird für den Bestückungsnamen des Bauteil-Eintrags innerhalb der Bauteilgruppe verwendet.
+
+
+
Package
+
Optional
+
String
+
Offene Angabe. Das Gehäuse oder die Bauform des Bauteils, z.B. „0805“ für SMD-Widerstände.
+
+
+
Quantity
+
Pflichtfeld
+
Ganzzahl (Integer)
+
Anzahl der identischen Bauteile, die benötigt werden, um eine Instanz der Baugruppe zu erstellen.
+
+
+
Designation
+
Pflichtfeld
+
String
+
Beschreibung oder Funktion des Bauteils, z.B. Widerstandswert „10kΩ“ oder Kondensatorwert „100nF“. Wird für den Namen des BOM-Eintrags verwendet.
+
+
+
Supplier and ref
+
Optional
+
String
+
Offene Angabe. Kann z.B. Distributor spezifischen Wert enthalten.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Bauteil)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Baugruppe)
+
+
+
+
+ projects.build.form.part
+ Bauteil "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Baugruppe "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% benötigt)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ nicht auf Lager
+
+ part.table.actions.error
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index cc17d9be4..8fdb801b7 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -1535,5 +1535,693 @@
Επεξεργασία
+
+
+ part.table.name.value.for_part
+ %value% (Μέρος)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Συναρμολόγηση)
+
+
+
+
+ project.bom.assembly
+ Συναρμολόγηση
+
+
+
+
+ project.bom.partOrAssembly
+ Επιλογή
+
+
+
+
+ assembly.edit.status
+ Κατάσταση
+
+
+
+
+ assembly.status.draft
+ Προσχέδιο
+
+
+
+
+ assembly.status.planning
+ Υπό σχεδιασμό
+
+
+
+
+ assembly.status.in_production
+ Σε παραγωγή
+
+
+
+
+ assembly.status.finished
+ Ολοκληρώθηκε
+
+
+
+
+ assembly.status.archived
+ Αρχειοθετήθηκε
+
+
+
+
+ project.builds.no_stock
+ δεν έχει καθοριστεί απόθεμα
+
+
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% απαιτείται)
+
+
+
+
+ assembly.label
+ Σύνολο
+
+
+
+
+ assembly.caption
+ Σύνολο
+
+
+
+
+ perm.assemblies
+ Συναρμολογήσεις
+
+
+
+
+ assembly_bom_entry.label
+ Μέρη
+
+
+
+
+ assembly.labelp
+ Συναρμολογήσεις
+
+
+
+
+ assembly.edit
+ Επεξεργασία συνόλου
+
+
+
+
+ assembly.new
+ Νέο σύνολο
+
+
+
+
+ assembly.edit.associated_build_part
+ Σχετικό μέρος
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Προσθήκη μέρους
+
+
+
+
+ assembly.edit.associated_build.hint
+ Αυτό το μέρος αντιπροσωπεύει τις κατασκευασμένες εκδόσεις του συνόλου. Καταχωρίστε το εάν απαιτούνται κατασκευασμένες εκδόσεις. Εάν όχι, οι ποσότητες θα χρησιμοποιηθούν μόνο κατά την κατασκευή του εκάστοτε έργου.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Εισαγωγή μερών
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Συναρμολογήσεις
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% εγγραφές εξαρτημάτων εισήχθησαν με επιτυχία στο σύνολο.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Σφάλμα επικύρωσης! Ελέγξτε το εισαγόμενο αρχείο!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Το αρχείο δεν μπόρεσε να εισαχθεί. Ελέγξτε ότι έχετε επιλέξει τον σωστό τύπο αρχείου. Μήνυμα σφάλματος: %message%
+
+
+
+
+ assembly.bom.quantity
+ Ποσότητα
+
+
+
+
+ assembly.bom.mountnames
+ Ονόματα συναρμολόγησης
+
+
+
+
+ assembly.bom.instockAmount
+ Ποσότητα σε απόθεμα
+
+
+
+
+ assembly.info.title
+ Πληροφορίες συναρμολόγησης
+
+
+
+
+ assembly.info.info.label
+ Πληροφορίες
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Υποομάδες
+
+
+
+
+ assembly.info.builds.label
+ Κατασκευές
+
+
+
+
+ assembly.info.bom_add_parts
+ Προσθήκη εξαρτημάτων
+
+
+
+
+ assembly.builds.check_assembly_status
+ «%assembly_status%». Ελέγξτε εάν θέλετε πραγματικά να κατασκευάσετε τη συναρμολόγηση με αυτήν την κατάσταση!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Η κατασκευή δεν είναι δυνατή: Δεν υπάρχουν αρκετά διαθέσιμα εξαρτήματα
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Δεν υπάρχουν αρκετά εξαρτήματα σε απόθεμα για να κατασκευαστεί αυτό το έργο %number_of_builds% φορές. Λείπουν τα ακόλουθα εξαρτήματα:
+
+
+
+
+ assembly.builds.build_possible
+ Κατασκευή δυνατή
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% μονάδες αυτής της συναρμολόγησης.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Αριθμός κατασκευών
+
+
+
+
+ assembly.build.btn_build
+ Κατασκευή
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Αποθηκευμένα κατασκευασμένα κομμάτια
+
+
+
+
+ assembly.info.bom_entries_count
+ Εξαρτήματα
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Υποομάδες
+
+
+
+
+ assembly.builds.stocked
+ σε απόθεμα
+
+
+
+
+ assembly.builds.needed
+ απαιτούμενο
+
+
+
+
+ assembly.add_parts_to_assembly
+ Προσθήκη εξαρτημάτων στη συναρμολόγηση
+
+
+
+
+ assembly.bom.name
+ Όνομα
+
+
+
+
+ assembly.bom.comment
+ Σχόλια
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Δεν υπάρχουν αρκετά εξαρτήματα σε απόθεμα για να κατασκευαστεί αυτή η συναρμολόγηση %number_of_builds% φορές. Λείπουν τα ακόλουθα εξαρτήματα:
+
+
+
+
+ assembly.build.help
+ Επιλέξτε από ποια αποθέματα θα αφαιρεθούν τα αναγκαία για την κατασκευή εξαρτήματα (και σε ποια ποσότητα). Σημειώστε το πλαίσιο επιλογής για κάθε εξάρτημα όταν αφαιρέσετε τα εξαρτήματα ή χρησιμοποιήστε το ανώτερο πλαίσιο επιλογής για να τα ελέγξετε όλα ταυτόχρονα.
+
+
+
+
+ assembly.build.required_qty
+ Απαιτούμενη ποσότητα
+
+
+
+
+ assembly.import_bom
+ Εισαγωγή εξαρτημάτων συναρμολόγησης
+
+
+
+
+ assembly.bom.part
+ Εξάρτημα
+
+
+
+
+ assembly.bom.add_entry
+ Προσθήκη καταχώρησης
+
+
+
+
+ assembly.bom.price
+ Τιμή
+
+
+
+
+ assembly.build.dont_check_quantity
+ Μην ελέγχετε την ποσότητα
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Εάν επιλεγεί αυτή η επιλογή, οι επιλεγμένες ποσότητες θα αφαιρεθούν από το απόθεμα ανεξάρτητα από το αν είναι περισσότερο ή λιγότερο από το απαιτούμενο για την κατασκευή της συναρμολόγησης.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Προσθήκη κατασκευασμένων κομματιών στο τμήμα συναρμολόγησης
+
+
+
+
+ assembly.bom_import.type
+ Τύπος
+
+
+
+
+ assembly.bom_import.type.json
+ JSON για συναρμολόγηση
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Διαγραφή υπαρχόντων εξαρτημάτων πριν από την εισαγωγή
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Εάν επιλεγεί αυτή η επιλογή, όλα τα ήδη υπάρχοντα εξαρτήματα στη συναρμολόγηση θα διαγραφούν και θα αντικατασταθούν με τα δεδομένα εξαρτημάτων που εισάγονται.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Πρότυπο εισαγωγής JSON για συναρμολόγηση
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Πρότυπο εισαγωγής CSV (KiCAD Pcbnew BOM) για συναρμολόγηση
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Όνομα του εξαρτήματος στη συναρμολόγηση
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Μοναδικός αριθμός προϊόντος από τον κατασκευαστή
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Μοναδικός IPN του εξαρτήματος
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Μοναδικό όνομα εξαρτήματος
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Μοναδικό όνομα κατασκευαστή
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Μοναδικό όνομα κατηγορίας
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Πεδίο
+
Προϋπόθεση
+
Τύπος Δεδομένων
+
Περιγραφή
+
+
+
+
+
quantity
+
Υποχρεωτικό πεδίο
+
Αριθμός κινητής υποδιαστολής (Float)
+
Πρέπει να παρέχεται και να περιέχει τιμή κινητής υποδιαστολής (Float) μεγαλύτερη από 0.0.
+
+
+
name
+
Προαιρετικό
+
Κείμενο (String)
+
Εάν υπάρχει, πρέπει να είναι μη κενό κείμενο.
+
+
+
part
+
Προαιρετικό
+
Αντικείμενο/Πίνακας
+
+ Εάν παρέχεται, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) του εξαρτήματος στη βάση δεδομένων.
+
+
+
part.name
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.mpnr ή part.ipn.
+
+
+
part.mpnr
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.name ή part.ipn.
+
+
+
part.ipn
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.name ή part.mpnr.
+
+
+
part.description
+
Προαιρετικό
+
Κείμενο ή null
+
Εάν υπάρχει, πρέπει να είναι μη κενό κείμενο, ή null.
+
+
+
part.manufacturer
+
Προαιρετικό
+
Αντικείμενο/Πίνακας
+
+ Εάν υπάρχει, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) του κατασκευαστή.
+
+
+
manufacturer.name
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχεται η ένδειξη manufacturer.id.
+
+
+
part.category
+
Προαιρετικό
+
Αντικείμενο/Πίνακας
+
+ Εάν υπάρχει, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) της κατηγορίας του εξαρτήματος.
+
+
+
category.name
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχεται η ένδειξη category.id.
Ελεύθερη καταχώρηση. Μοναδικός αριθμός ταυτοποίησης για κάθε εξάρτημα.
+
+
+
Σχεδιαστής
+
Προαιρετικό
+
Συμβολοσειρά (String)
+
Ελεύθερη καταχώρηση. Μοναδικός αναγνωριστικός δείκτης του εξαρτήματος στην πλακέτα κυκλώματος, π.χ. "R1" για την αντίσταση 1. Χρησιμοποιείται για το όνομα του εξαρτήματος στο πλαίσιο της ομάδας εξαρτημάτων.
+
+
+
Συσκευασία
+
Προαιρετικό
+
Συμβολοσειρά (String)
+
Ελεύθερη καταχώρηση. Ο τύπος ή η μορφή του εξαρτήματος, π.χ. "0805" για αντιστάσεις SMD.
+
+
+
Ποσότητα
+
Υποχρεωτικό
+
Ακέραιος αριθμός (Integer)
+
Ο αριθμός των πανομοιότυπων εξαρτημάτων που απαιτούνται για τη δημιουργία μίας μονάδας του συνόλου.
+
+
+
Ορισμός
+
Υποχρεωτικό
+
Συμβολοσειρά (String)
+
Περιγραφή ή λειτουργία του εξαρτήματος, π.χ. αντίσταση "10kΩ" ή χωρητικότητα "100nF". Χρησιμοποιείται για το όνομα της εγγραφής στο BOM.
+
+
+
Προμηθευτής και παραπομπή
+
Προαιρετικό
+
Συμβολοσειρά (String)
+
Ελεύθερη καταχώρηση. Μπορεί να περιλαμβάνει, π.χ., ειδική τιμή από διανομέα.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Εξάρτημα)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Συναρμολόγηση)
+
+
+
+
+ projects.build.form.part
+ Εξάρτημα "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Συναρμολόγηση "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% απαιτείται)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ δεν υπάρχει στο απόθεμα
+
+
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index be1e63488..d267c89ac 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -4741,6 +4741,18 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
Name
+
+
+ part.table.name.value.for_part
+ %value% (Part)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Assembly)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9789,6 +9801,18 @@ Element 1 -> Element 1.2
Part
+
+
+ project.bom.assembly
+ Assembly
+
+
+
+
+ project.bom.partOrAssembly
+ Selection
+
+ project.bom.add_entry
@@ -9867,6 +9891,42 @@ Element 1 -> Element 1.2
Archived
+
+
+ assembly.edit.status
+ Project status
+
+
+
+
+ assembly.status.draft
+ Draft
+
+
+
+
+ assembly.status.planning
+ Planning
+
+
+
+
+ assembly.status.in_production
+ In production
+
+
+
+
+ assembly.status.finished
+ Finished
+
+
+
+
+ assembly.status.archived
+ Archived
+
+ part.new_build_part.error.build_part_already_exists
@@ -10143,6 +10203,12 @@ Element 1 -> Element 1.2
stocked
+
+
+ project.builds.no_stock
+ no stock specified
+
+ project.builds.needed
@@ -10215,6 +10281,12 @@ Element 1 -> Element 1.2
Target lot
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% needed)
+
+ project.builds.number_of_builds
@@ -12852,6 +12924,622 @@ Please note, that you can not impersonate a disabled user. If you try you will g
View external version
+
+
+ assembly.label
+ Assembly
+
+
+
+
+ assembly.caption
+ Assembly
+
+
+
+
+ assembly_bom_entry.label
+ Parts
+
+
+
+
+ perm.assemblies
+ Assemblies
+
+
+
+
+ assembly.labelp
+ Assemblies
+
+
+
+
+ assembly.edit
+ Edit assembly
+
+
+
+
+ assembly.new
+ New assembly
+
+
+
+
+ assembly.edit.associated_build_part
+ Associated builds part
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Add builds part
+
+
+
+
+ assembly.edit.associated_build.hint
+ This part represents the builds of this assembly. To indicate if built instances are required. If not, the number of pieces regarding the assembly are only used for the build of the respective project.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Import BOM
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Assemblies
+
+
+
+
+ assembly.bom_import.flash.success
+ Imported %count% parts in assembly successfully.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Validation error! Please check your data!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ File could not be imported. Please check that you have selected the right file type. Error message: %message%
+
+
+
+
+ assembly.bom.quantity
+ Quantity
+
+
+
+
+ assembly.bom.mountnames
+ Mount names
+
+
+
+
+ assembly.bom.instockAmount
+ Stocked amount
+
+
+
+
+ assembly.info.title
+ Assembly info
+
+
+
+
+ assembly.info.info.label
+ Info
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Sub-assemblies
+
+
+
+
+ assembly.info.builds.label
+ Build
+
+
+
+
+ assembly.info.bom_add_parts
+ Add part entries
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". You should check if you really want to build the assembly with this status!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Build not possible: Parts not stocked
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ You do not have enough parts stocked to build this assembly %number_of_builds% times. The following parts have missing instock:
+
+
+
+
+ assembly.builds.build_possible
+ Build possible
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% builds of this assembly.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Build amount
+
+
+
+
+ assembly.build.btn_build
+ Build
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Number of stocked builds
+
+
+
+
+ assembly.info.bom_entries_count
+ Part entries
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Sub-assemblies
+
+
+
+
+ assembly.builds.stocked
+ stocked
+
+
+
+
+ assembly.builds.needed
+ needed
+
+
+
+
+ assembly.add_parts_to_assembly
+ Add parts to assembly
+
+
+
+
+ assembly.bom.name
+ Name
+
+
+
+
+ assembly.bom.comment
+ Notes
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ You do not have enough parts stocked to build this assembly %number_of_builds% times. The following parts have missing instock:
+
+
+
+
+ assembly.build.help
+ Choose from which part lots the stock to build this assembly should be taken (and in which amount). Check the checkbox for each part, when you are finished withdrawing the parts, or use the top checkbox to check all boxes at once.
+
+
+
+
+ assembly.build.required_qty
+ Required quantity
+
+
+
+
+ assembly.import_bom
+ Import BOM for project
+
+
+
+
+ assembly.bom.part
+ Part
+
+
+
+
+ assembly.bom.add_entry
+ Add entry
+
+
+
+
+ assembly.bom.price
+ Price
+
+
+
+
+ assembly.build.dont_check_quantity
+ Do not check quantities
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ If this option is selected, the given withdraw quantities are used as given, no matter if more or less parts are actually required to build this assembly.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Add builds to assembly builds part
+
+
+
+
+ assembly.bom_import.type
+ Type
+
+
+
+
+ assembly.bom_import.type.json
+ JSON for one assembly
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Clear existing part entries before importing
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Selecting this option will remove all existing part entries in the assembly and overwrite them with the imported part data!
+
+
+
+
+ assembly.import_bom.template.header.json
+ Import template JSON format for one assembly
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Import template CSV format (KiCAD Pcbnew BOM) for one assembly
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Name of the part in the assembly
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Unique product number within the manufacturer
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unique IPN of the part
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unique name of the part
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unique name of the manufacturer
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Unique name of the category
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Field
+
Condition
+
Data type
+
Description
+
+
+
+
+
quantity
+
Required
+
Floating point (Float)
+
Must be provided and contains a floating-point value (Float) greater than 0.0.
+
+
+
name
+
Optional
+
String
+
If present, it must be a non-empty string.
+
+
+
part
+
Optional
+
Object/Array
+
+ If provided, it must be an object/array and at least one of the fields must be filled:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Optional
+
Integer
+
Integer > 0. Matches the Part-DB internal numeric ID of the component.
+
+
+
part.name
+
Optional
+
String
+
Non-empty string if no part.mpnr or part.ipn is provided.
+
+
+
part.mpnr
+
Optional
+
String
+
Non-empty string if no part.name or part.ipn is provided.
+
+
+
part.ipn
+
Optional
+
String
+
Non-empty string if no part.name or part.mpnr is provided.
+
+
+
part.description
+
Optional
+
String or null
+
If present, it must be a non-empty string or null.
+
+
+
part.manufacturer
+
Optional
+
Object/Array
+
+ If present, it must be an object/array and at least one of the fields must be filled:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optional
+
Integer
+
Integer > 0. Matches the internal numeric ID of the manufacturer.
+
+
+
manufacturer.name
+
Optional
+
String
+
Non-empty string if no manufacturer.id is provided.
+
+
+
part.category
+
Optional
+
Object/Array
+
+ If present, it must be an object/array and at least one of the fields must be filled:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Optional
+
Integer
+
Integer > 0. Matches the internal numeric ID of the component's category.
+
+
+
category.name
+
Optional
+
String
+
Non-empty string if no category.id is provided.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Expected Columns:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Note: No mapping is performed with specific components from category management.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Field
+
Condition
+
Data Type
+
Description
+
+
+
+
+
Id
+
Optional
+
Integer
+
Free-form field. A unique identification number for each component.
+
+
+
Designator
+
Optional
+
String
+
Free-form field. A unique reference designator of the component on the PCB, e.g., “R1” for resistor 1. Used for naming the placement in the component group.
+
+
+
Package
+
Optional
+
String
+
Free-form field. The casing or form factor of the component, e.g., “0805” for SMD resistors.
+
+
+
Quantity
+
Required
+
Integer
+
The number of identical components required to create a single instance of an assembly.
+
+
+
Designation
+
Required
+
String
+
The description or function of the component, e.g., resistor value “10kΩ” or capacitor value “100nF.” Used for the name in the BOM entry.
+
+
+
Supplier and ref
+
Optional
+
String
+
Free-form field. May include, for example, specific distributor information.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Part)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Assembly)
+
+
+
+
+ projects.build.form.part
+ Part "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Assembly "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% needed)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ not in stock
+
+ part.table.actions.error
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index fce38e52f..c3bf96368 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -4740,6 +4740,18 @@ Subelementos serán desplazados hacia arriba.
Nombre
+
+
+ part.table.name.value.for_part
+ %value% (Componente)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Ensamblaje)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9804,6 +9816,18 @@ Elemento 3
Componente
+
+
+ project.bom.assembly
+ Baugruppe
+
+
+
+
+ project.bom.partOrAssembly
+ Auswahl
+
+ project.bom.add_entry
@@ -9882,6 +9906,42 @@ Elemento 3
Archivado
+
+
+ assembly.edit.status
+ Estatus
+
+
+
+
+ assembly.status.draft
+ Esbozo
+
+
+
+
+ assembly.status.planning
+ En planificación
+
+
+
+
+ assembly.status.in_production
+ En producción
+
+
+
+
+ assembly.status.finished
+ Completado
+
+
+
+
+ assembly.status.archived
+ Archivado
+
+ part.new_build_part.error.build_part_already_exists
@@ -10158,6 +10218,12 @@ Elemento 3
Almacenado
+
+
+ project.builds.no_stock
+ no se ha especificado stock
+
+ project.builds.needed
@@ -10230,6 +10296,12 @@ Elemento 3
Lote objetivo
+
+
+ project.build.builds_part_lot_label
+ %name% (se requiere %quantity%)
+
+ project.builds.number_of_builds
@@ -12344,6 +12416,622 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Ver versión externa
+
+
+ assembly.label
+ Ensamblaje
+
+
+
+
+ assembly.caption
+ Ensamblaje
+
+
+
+
+ perm.assemblies
+ Ensamblajes
+
+
+
+
+ assembly_bom_entry.label
+ Componentes
+
+
+
+
+ assembly.labelp
+ Ensamblajes
+
+
+
+
+ assembly.edit
+ Editar ensamblaje
+
+
+
+
+ assembly.new
+ Nuevo ensamblaje
+
+
+
+
+ assembly.edit.associated_build_part
+ Componente asociado
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Añadir componente
+
+
+
+
+ assembly.edit.associated_build.hint
+ Este componente representa las instancias fabricadas del ensamblaje. Indique si se necesitan instancias fabricadas. De lo contrario, las cantidades del componente solo se utilizarán cuando se construya el proyecto correspondiente.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importar componentes
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Ensamblajes
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% componente(s) se importaron correctamente al ensamblaje.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ ¡Error de validación! ¡Revisa el archivo importado!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ No se pudo importar el archivo. Asegúrate de haber seleccionado el tipo de archivo correcto. Mensaje de error: %message%
+
+
+
+
+ assembly.bom.quantity
+ Cantidad
+
+
+
+
+ assembly.bom.mountnames
+ Nombres de montaje
+
+
+
+
+ assembly.bom.instockAmount
+ Cantidad en stock
+
+
+
+
+ assembly.info.title
+ Información del ensamblaje
+
+
+
+
+ assembly.info.info.label
+ Información
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Subconjuntos
+
+
+
+
+ assembly.info.builds.label
+ Construcciones
+
+
+
+
+ assembly.info.bom_add_parts
+ Añadir piezas
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". ¡Por favor, verifica si realmente deseas construir el ensamblaje con este estado!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Construcción no posible: No hay suficientes componentes disponibles
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ No hay suficientes piezas en stock para construir este proyecto %number_of_builds% veces. Faltan las siguientes piezas:
+
+
+
+
+ assembly.builds.build_possible
+ Construcción posible
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% unidades de este ensamblaje.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Número de construcciones
+
+
+
+
+ assembly.build.btn_build
+ Construir
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Unidades construidas almacenadas
+
+
+
+
+ assembly.info.bom_entries_count
+ Componentes
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Subconjuntos
+
+
+
+
+ assembly.builds.stocked
+ en stock
+
+
+
+
+ assembly.builds.needed
+ necesario
+
+
+
+
+ assembly.add_parts_to_assembly
+ Añadir piezas al ensamblaje
+
+
+
+
+ assembly.bom.name
+ Nombre
+
+
+
+
+ assembly.bom.comment
+ Comentarios
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ No hay suficientes piezas en stock para construir este ensamblaje %number_of_builds% veces. Faltan las siguientes piezas:
+
+
+
+
+ assembly.build.help
+ Seleccione de qué almacenes se tomarán las piezas necesarias para la construcción (y en qué cantidad). Marque la casilla de cada entrada una vez que haya quitado las piezas, o use la casilla superior para marcarlas todas a la vez.
+
+
+
+
+ assembly.build.required_qty
+ Cantidad requerida
+
+
+
+
+ assembly.import_bom
+ Importar piezas para ensamblaje
+
+
+
+
+ assembly.bom.part
+ Pieza
+
+
+
+
+ assembly.bom.add_entry
+ Añadir entrada
+
+
+
+
+ assembly.bom.price
+ Precio
+
+
+
+
+ assembly.build.dont_check_quantity
+ No verificar cantidades
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Si se selecciona esta opción, las cantidades seleccionadas se quitarán del inventario independientemente de si hay más o menos de lo necesario para construir el ensamblaje.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Añadir unidades construidas a la parte del ensamblaje
+
+
+
+
+ assembly.bom_import.type
+ Tipo
+
+
+
+
+ assembly.bom_import.type.json
+ JSON para un ensamblaje
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Eliminar entradas de componentes existentes antes de la importación
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Si esta opción está seleccionada, se eliminarán todos los componentes existentes en el ensamblaje y serán reemplazados por los datos de los componentes importados.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Plantilla de importación JSON para un ensamblaje
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Plantilla de importación CSV (KiCAD Pcbnew BOM) para un ensamblaje
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Nombre del componente en el ensamblaje
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Número de parte único dentro del fabricante
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ IPN único del componente
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Nombre único del componente
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Nombre único del fabricante
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Nombre único de la categoría
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Campo
+
Condición
+
Tipo de dato
+
Descripción
+
+
+
+
+
quantity
+
Obligatorio
+
Número decimal (Float)
+
Debe estar presente y contener un valor decimal (Float) mayor que 0.0.
+
+
+
name
+
Opcional
+
Cadena de texto (String)
+
Si está presente, debe ser una cadena de texto no vacía.
+
+
+
part
+
Opcional
+
Objeto/Array
+
+ Si se proporciona, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno del componente en la base de datos.
+
+
+
part.name
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona part.mpnr o part.ipn.
+
+
+
part.mpnr
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona part.name o part.ipn.
+
+
+
part.ipn
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona part.name o part.mpnr.
+
+
+
part.description
+
Opcional
+
Cadena de texto (String) o null
+
Si está presente, debe ser una cadena de texto no vacía o null.
+
+
+
part.manufacturer
+
Opcional
+
Objeto/Array
+
+ Si está presente, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno del fabricante.
+
+
+
manufacturer.name
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona manufacturer.id.
+
+
+
part.category
+
Opcional
+
Objeto/Array
+
+ Si está presente, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno de la categoría del componente.
+
+
+
category.name
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona category.id.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Columnas esperadas:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Nota: No se realiza una asociación con componentes específicos de la gestión de categorías.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Campo
+
Condición
+
Tipo de Datos
+
Descripción
+
+
+
+
+
Id
+
Opcional
+
Entero
+
Campo libre. Un número de identificación único para cada componente.
+
+
+
Designador
+
Opcional
+
Cadena de texto
+
Campo libre. Un designador de referencia único para el componente en la PCB, p. ej., "R1" para la resistencia 1. Se utiliza para nombrar la colocación en el grupo de componentes.
+
+
+
Package
+
Opcional
+
Cadena de texto
+
Campo libre. El formato o tipo de encapsulado del componente, p. ej., "0805" para resistencias SMD.
+
+
+
Cantidad
+
Obligatorio
+
Entero
+
El número de componentes idénticos necesarios para crear una instancia única de un ensamblaje.
+
+
+
Designación
+
Obligatorio
+
Cadena de texto
+
La descripción o función del componente, p. ej., el valor de la resistencia "10kΩ" o el valor del condensador "100nF". Se utiliza para el nombre en la entrada del BOM.
+
+
+
Proveedor y referencia
+
Opcional
+
Cadena de texto
+
Campo libre. Puede incluir, por ejemplo, información específica del distribuidor.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Componente)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Ensamblaje)
+
+
+
+
+ projects.build.form.part
+ Componente "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Ensamblaje "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% necesario)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ sin stock
+
+ part.table.actions.error
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 292dbafaa..5362f9390 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -4703,6 +4703,18 @@ Si vous avez fait cela de manière incorrecte ou si un ordinateur n'est plus fia
Nom
+
+
+ part.table.name.value.for_part
+ %value% (Componente)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblaggio)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -6947,7 +6959,7 @@ Si vous avez fait cela de manière incorrecte ou si un ordinateur n'est plus fia
company.edit.address.placeholder
- Ex. 99 exemple de rue
+ Ex. 99 exemple de rue
exemple de ville
@@ -9097,5 +9109,681 @@ exemple de ville
Si vous avez des questions à propos de Part-DB , rendez vous sur <a href="%href%" class="link-external" target="_blank">Github</a>
+
+
+ project.bom.assembly
+ Assemblage
+
+
+
+
+ project.bom.partOrAssembly
+ Sélection
+
+
+
+
+ assembly.edit.status
+ Statut
+
+
+
+
+ assembly.status.draft
+ Brouillon
+
+
+
+
+ assembly.status.planning
+ En planification
+
+
+
+
+ assembly.status.in_production
+ En production
+
+
+
+
+ assembly.status.finished
+ Terminé
+
+
+
+
+ assembly.status.archived
+ Archivé
+
+
+
+
+ project.builds.no_stock
+ aucun stock indiqué
+
+
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% requis)
+
+
+
+
+ assembly.label
+ Assemblage
+
+
+
+
+ assembly.caption
+ Assemblage
+
+
+
+
+ perm.assemblies
+ Assemblages
+
+
+
+
+ assembly_bom_entry.label
+ Composants
+
+
+
+
+ assembly.labelp
+ Assemblages
+
+
+
+
+ assembly.edit
+ Modifier l'assemblage
+
+
+
+
+ assembly.new
+ Nouvel assemblage
+
+
+
+
+ assembly.edit.associated_build_part
+ Composant associé
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Ajouter un composant
+
+
+
+
+ assembly.edit.associated_build.hint
+ Ce composant représente les instances fabriquées de l'assemblage. Indiquez si des instances fabriquées sont nécessaires. Sinon, les quantités des composants ne seront appliquées que lors de la construction du projet correspondant.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importer des composants
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Assemblages
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% composant(s) ont été importé(s) avec succès dans l'assemblage.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Erreur de validation ! Veuillez vérifier le fichier importé !
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Le fichier n'a pas pu être importé. Veuillez vérifier que vous avez sélectionné le bon type de fichier. Message d'erreur : %message%
+
+
+
+
+ assembly.bom.quantity
+ Quantité
+
+
+
+
+ assembly.bom.mountnames
+ Noms de montage
+
+
+
+
+ assembly.bom.instockAmount
+ Quantité en stock
+
+
+
+
+ assembly.info.title
+ Informations sur l'assemblage
+
+
+
+
+ assembly.info.info.label
+ Informations
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Sous-ensembles
+
+
+
+
+ assembly.info.builds.label
+ Constructions
+
+
+
+
+ assembly.info.bom_add_parts
+ Ajouter des pièces
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Vérifiez bien si vous souhaitez construire l'assemblage avec ce statut !]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Construction impossible : pièces insuffisantes disponibles
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Il n'y a pas suffisamment de pièces en stock pour construire ce projet %number_of_builds% fois. Les pièces suivantes manquent en stock :
+
+
+
+
+ assembly.builds.build_possible
+ Construction possible
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% unités de cet assemblage.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Nombre d'assemblages à construire
+
+
+
+
+ assembly.build.btn_build
+ Construire
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Nombre d'instances construites en stock
+
+
+
+
+ assembly.info.bom_entries_count
+ Composants
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Sous-ensembles
+
+
+
+
+ assembly.builds.stocked
+ en stock
+
+
+
+
+ assembly.builds.needed
+ nécessaire
+
+
+
+
+ assembly.add_parts_to_assembly
+ Ajouter des pièces à l'assemblage
+
+
+
+
+ assembly.bom.name
+ Nom
+
+
+
+
+ assembly.bom.comment
+ Commentaires
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Il n'y a pas suffisamment de pièces en stock pour construire cet assemblage %number_of_builds% fois. Les pièces suivantes manquent en stock :
+
+
+
+
+ assembly.build.help
+ Sélectionnez les stocks à partir desquels les pièces nécessaires à la construction seront prises (et en quelle quantité). Vérifiez chaque pièce en les retirant, ou utilisez la case supérieure pour les sélectionner toutes à la fois.
+
+
+
+
+ assembly.build.required_qty
+ Quantité requise
+
+
+
+
+ assembly.import_bom
+ Importer des pièces pour l'assemblage
+
+
+
+
+ assembly.bom.part
+ Pièce
+
+
+
+
+ assembly.bom.add_entry
+ Ajouter une ligne
+
+
+
+
+ assembly.bom.price
+ Prix
+
+
+
+
+ assembly.build.dont_check_quantity
+ Ne pas vérifier les quantités
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Si cette option est activée, les quantités sélectionnées seront retirées du stock, quelle que soit leur suffisance pour l’assemblage.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Ajouter les unités construites à la pièce assemblée
+
+
+
+
+ assembly.bom_import.type
+ Type
+
+
+
+
+ assembly.bom_import.type.json
+ JSON pour un assemblage
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Supprimer les entrées de pièces existantes avant l’importation
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Si cette option est cochée, toutes les pièces existantes dans l’assemblage seront supprimées et remplacées par les données importées.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Modèle d’importation JSON pour un assemblage
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Modèle d’importation CSV (KiCAD Pcbnew BOM) pour un assemblage
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Nom de la pièce dans l’assemblage
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Numéro unique de la pièce chez le fabricant
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Numéro IPN unique de la pièce
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Nom unique de la pièce
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Nom unique du fabricant
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Nom unique de la catégorie
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Champ
+
Condition
+
Type de données
+
Description
+
+
+
+
+
quantity
+
Obligatoire
+
Nombre décimal (Float)
+
Doit être présent et contenir une valeur décimale (Float) supérieure à 0,0.
+
+
+
name
+
Optionnel
+
Chaîne (String)
+
Si présent, doit être une chaîne non vide.
+
+
+
part
+
Optionnel
+
Objet/Tableau
+
+ Si fourni, doit être un objet/un tableau et au moins un des champs doit être rempli :
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Optionnel
+
Entier (Integer)
+
Entier (Integer) > 0. Correspond à l'ID numérique interne dans Part-DB du composant.
+
+
+
part.name
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si part.mpnr ou part.ipn ne sont pas fournis.
+
+
+
part.mpnr
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si part.name ou part.ipn ne sont pas fournis.
+
+
+
part.ipn
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si part.name ou part.mpnr ne sont pas fournis.
+
+
+
part.description
+
Optionnel
+
Chaîne ou null
+
Si présent, doit être une chaîne non vide ou null.
+
+
+
part.manufacturer
+
Optionnel
+
Objet/Tableau
+
+ Si présent, doit être un objet/un tableau et au moins un des champs doit être rempli :
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optionnel
+
Entier (Integer)
+
Entier (Integer) > 0. Correspond à l'ID numérique interne du fabricant.
+
+
+
manufacturer.name
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si manufacturer.id n'est pas fourni.
+
+
+
part.category
+
Optionnel
+
Objet/Tableau
+
+ Si présent, doit être un objet/un tableau et au moins un des champs doit être rempli :
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Optionnel
+
Entier (Integer)
+
Entier (Integer) > 0. Correspond à l'ID numérique interne de la catégorie du composant.
+
+
+
category.name
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si category.id n'est pas fourni.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Colonnes attendues :
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Remarque : Aucun mappage n'est effectué avec des composants spécifiques issus de la gestion des catégories.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Champ
+
Condition
+
Type de Données
+
Description
+
+
+
+
+
Id
+
Optionnel
+
Entier
+
Champ libre. Un numéro d'identification unique pour chaque composant.
+
+
+
Designeur
+
Optionnel
+
Chaîne
+
Champ libre. Une référence de désignation unique du composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé pour nommer la position au sein du groupe de composants.
+
+
+
Boîtier
+
Optionnel
+
Chaîne
+
Champ libre. Le type ou format d'encapsulation du composant, par exemple, "0805" pour des résistances CMS.
+
+
+
Quantité
+
Obligatoire
+
Entier
+
Le nombre de composants identiques nécessaires pour créer une instance unique d'un ensemble.
+
+
+
Désignation
+
Obligatoire
+
Chaîne
+
La description ou la fonction du composant, par exemple, la valeur de résistance "10kΩ" ou la valeur de condensateur "100nF". Utilisé comme nom dans l'entrée de la nomenclature (BOM).
+
+
+
Fournisseur et réf
+
Optionnel
+
Chaîne
+
Champ libre. Peut inclure, par exemple, des informations spécifiques au distributeur.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (pièce)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (assemblage)
+
+
+
+
+ projects.build.form.part
+ Pièce "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Assemblage "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% nécessaires)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ Non disponible en stock
+
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index 828304eba..0ea57d9f1 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -4742,6 +4742,18 @@ Se è stato fatto in modo errato o se un computer non è più attendibile, puoi
Nome
+
+
+ part.table.name.value.for_part
+ %value% (Componente)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblaggio)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9806,6 +9818,18 @@ Element 3
Componente
+
+
+ project.bom.assembly
+ Assemblaggio
+
+
+
+
+ project.bom.partOrAssembly
+ Selezione
+
+ project.bom.add_entry
@@ -9884,6 +9908,42 @@ Element 3
Archiviato
+
+
+ assembly.edit.status
+ Stato
+
+
+
+
+ assembly.status.draft
+ Bozza
+
+
+
+
+ assembly.status.planning
+ In pianificazione
+
+
+
+
+ assembly.status.in_production
+ In produzione
+
+
+
+
+ assembly.status.finished
+ Completato
+
+
+
+
+ assembly.status.archived
+ Archiviato
+
+ part.new_build_part.error.build_part_already_exists
@@ -10160,6 +10220,12 @@ Element 3
a magazzino
+
+
+ project.builds.no_stock
+ nessuna scorta specificata
+
+ project.builds.needed
@@ -10232,6 +10298,12 @@ Element 3
Lotto target
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% richiesti)
+
+ project.builds.number_of_builds
@@ -12346,6 +12418,622 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Visualizza la versione esterna
+
+
+ assembly.label
+ Assemblaggio
+
+
+
+
+ assembly.caption
+ Assemblaggio
+
+
+
+
+ perm.assemblies
+ Assemblaggi
+
+
+
+
+ assembly_bom_entry.label
+ Componenti
+
+
+
+
+ assembly.labelp
+ Assemblaggi
+
+
+
+
+ assembly.edit
+ Modifica assemblaggio
+
+
+
+
+ assembly.new
+ Nuovo assemblaggio
+
+
+
+
+ assembly.edit.associated_build_part
+ Componente associato
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Aggiungi componente
+
+
+
+
+ assembly.edit.associated_build.hint
+ Questo componente rappresenta le istanze fabbricate dell'assemblaggio. Specificare se sono necessarie istanze fabbricate. In caso contrario, le quantità di componenti verranno utilizzate solo durante la costruzione del progetto corrispondente.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importa componenti
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Assemblaggi
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% componente(i) importato(i) correttamente nell'assemblaggio.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Errore di convalida! Controlla il file importato!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Impossibile importare il file. Assicurati di aver selezionato il tipo di file corretto. Messaggio di errore: %message%
+
+
+
+
+ assembly.bom.quantity
+ Quantità
+
+
+
+
+ assembly.bom.mountnames
+ Nomi di montaggio
+
+
+
+
+ assembly.bom.instockAmount
+ Quantità in magazzino
+
+
+
+
+ assembly.info.title
+ Informazioni sul gruppo
+
+
+
+
+ assembly.info.info.label
+ Info
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Sotto-gruppi
+
+
+
+
+ assembly.info.builds.label
+ Costruzioni
+
+
+
+
+ assembly.info.bom_add_parts
+ Aggiungi componenti
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Controlla se vuoi davvero costruire il gruppo con questo stato!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Costruzione impossibile: componenti insufficienti disponibili
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Non ci sono abbastanza componenti in magazzino per costruire questo progetto %number_of_builds% volte. Mancano i seguenti componenti:
+
+
+
+
+ assembly.builds.build_possible
+ Costruzione possibile
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% unità di questo gruppo.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Numero di gruppi da costruire
+
+
+
+
+ assembly.build.btn_build
+ Costruire
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Numero di istanze costruite in magazzino
+
+
+
+
+ assembly.info.bom_entries_count
+ Componenti
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Sotto-gruppi
+
+
+
+
+ assembly.builds.stocked
+ disponibile
+
+
+
+
+ assembly.builds.needed
+ necessari
+
+
+
+
+ assembly.add_parts_to_assembly
+ Aggiungi componenti al gruppo
+
+
+
+
+ assembly.bom.name
+ Nome
+
+
+
+
+ assembly.bom.comment
+ Commenti
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Non ci sono abbastanza componenti in magazzino per costruire questo gruppo %number_of_builds% volte. Mancano i seguenti componenti:
+
+
+
+
+ assembly.build.help
+ Seleziona i magazzini da cui prelevare i componenti necessari per la costruzione (e in che quantità). Spunta ciascun componente una volta prelevato, oppure utilizza la casella superiore per selezionare tutto in una volta.
+
+
+
+
+ assembly.build.required_qty
+ Quantità necessaria
+
+
+
+
+ assembly.import_bom
+ Importa componenti per il gruppo
+
+
+
+
+ assembly.bom.part
+ Componente
+
+
+
+
+ assembly.bom.add_entry
+ Aggiungi voce
+
+
+
+
+ assembly.bom.price
+ Prezzo
+
+
+
+
+ assembly.build.dont_check_quantity
+ Non controllare le quantità
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Se abilitata, le quantità selezionate verranno rimosse dal magazzino indipendentemente dalla loro sufficienza per il gruppo.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Aggiungi istanze costruite al gruppo componenti
+
+
+
+
+ assembly.bom_import.type
+ Tipo
+
+
+
+
+ assembly.bom_import.type.json
+ JSON per un gruppo
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Elimina i componenti esistenti prima di importare
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Se abilitata, tutti i componenti esistenti verranno rimossi e sostituiti dai dati importati.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Template di importazione JSON per un gruppo
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Template di importazione CSV (KiCAD Pcbnew BOM) per un gruppo
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Nome del componente nel gruppo
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Numero univoco del componente del produttore
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ IPN univoco del componente
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Nome univoco del componente
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Nome univoco del produttore
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Nome univoco della categoria
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Campo
+
Condizione
+
Tipo di dato
+
Descrizione
+
+
+
+
+
quantity
+
Obbligatorio
+
Numero decimale (Float)
+
Deve essere presente e contenere un valore decimale (Float) maggiore di 0,0.
+
+
+
name
+
Opzionale
+
Stringa (String)
+
Se presente, deve essere una stringa non vuota.
+
+
+
part
+
Opzionale
+
Oggetto/Array
+
+ Se fornito, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno di Part-DB per il componente.
+
+
+
part.name
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se part.mpnr o part.ipn non sono forniti.
+
+
+
part.mpnr
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se part.name o part.ipn non sono forniti.
+
+
+
part.ipn
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se part.name o part.mpnr non sono forniti.
+
+
+
part.description
+
Opzionale
+
Stringa o null
+
Se presente, deve essere una stringa non vuota o null.
+
+
+
part.manufacturer
+
Opzionale
+
Oggetto/Array
+
+ Se presente, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno del produttore.
+
+
+
manufacturer.name
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se manufacturer.id non è fornito.
+
+
+
part.category
+
Opzionale
+
Oggetto/Array
+
+ Se presente, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno della categoria del componente.
+
+
+
category.name
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se category.id non è fornito.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Colonne previste:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Nota: Non viene eseguita alcuna mappatura con componenti specifici dalla gestione delle categorie.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Campo
+
Condizione
+
Tipo di Dati
+
Descrizione
+
+
+
+
+
Id
+
Opzionale
+
Intero
+
Campo libero. Un numero identificativo unico per ogni componente.
+
+
+
Designatore
+
Opzionale
+
Stringa
+
Campo libero. Un designatore di riferimento unico per il componente sul PCB, ad esempio, "R1" per il resistore 1. Utilizzato per nominare la posizione nel gruppo di componenti.
+
+
+
Package
+
Opzionale
+
Stringa
+
Campo libero. Il tipo o formato del contenitore del componente, ad esempio, "0805" per le resistenze SMD.
+
+
+
Quantità
+
Obbligatorio
+
Intero
+
Il numero di componenti identici necessari per creare una singola unità di assemblaggio.
+
+
+
Designazione
+
Obbligatorio
+
Stringa
+
La descrizione o la funzione del componente, ad esempio, il valore della resistenza "10kΩ" o il valore del condensatore "100nF". Utilizzato per il nome nell'entrata della lista dei materiali (BOM).
+
+
+
Fornitore e riferimento
+
Opzionale
+
Stringa
+
Campo libero. Può includere, ad esempio, informazioni specifiche del distributore.
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name%(部品)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name%(アセンブリ)
+
+
+
+
+ projects.build.form.part
+ 部品「%name%」
+
+
+
+
+ projects.build.form.assembly
+ アセンブリ「%name%」
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (必要数量: %quantity%)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ 在庫なし
+
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index 760533d7c..b7392b4d7 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -724,5 +724,729 @@
Weet u zeker dat u wilt doorgaan?
+
+
+ part.table.name.value.for_part
+ %value% (Onderdeel)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Samenstelling)
+
+
+
+
+ project.bom.assembly
+ Assemblage
+
+
+
+
+ project.bom.partOrAssembly
+ Selectie
+
+
+
+
+ assembly.edit.status
+ Κατάσταση
+
+
+
+
+ assembly.status.draft
+ Προσχέδιο
+
+
+
+
+ assembly.status.planning
+ Υπό σχεδιασμό
+
+
+
+
+ assembly.status.in_production
+ Σε παραγωγή
+
+
+
+
+ assembly.status.finished
+ Ολοκληρώθηκε
+
+
+
+
+ assembly.status.archived
+ Αρχειοθετήθηκε
+
+
+
+
+ project.builds.no_stock
+ geen voorraad opgegeven
+
+
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% vereist)
+
+
+
+
+ assembly.label
+ Assemblage
+
+
+
+
+ assembly.caption
+ Assemblage
+
+
+
+
+ perm.assemblies
+ Assemblages
+
+
+
+
+ assembly_bom_entry.label
+ Componenten
+
+
+
+
+ assembly.labelp
+ Assemblages
+
+
+
+
+ assembly.edit
+ Assemblage bewerken
+
+
+
+
+ assembly.new
+ Nieuwe assemblage
+
+
+
+
+ assembly.edit.associated_build_part
+ Geassocieerd onderdeel
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Onderdeel toevoegen
+
+
+
+
+ assembly.edit.associated_build.hint
+ Dit onderdeel vertegenwoordigt de vervaardigde exemplaren van de assemblage. Geef aan of vervaardigde exemplaren nodig zijn. Zo niet, dan worden de aantallen onderdelen alleen gebruikt bij het bouwen van het bijbehorende project.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Componenten importeren
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Assemblages
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% component(en) zijn succesvol geïmporteerd in de assemblage.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Validatiefout! Controleer het geïmporteerde bestand!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Het bestand kon niet worden geïmporteerd. Controleer of je het correcte bestandstype hebt geselecteerd. Foutmelding: %message%
+
+
+
+
+ assembly.bom.quantity
+ Aantal
+
+
+
+
+ assembly.bom.mountnames
+ Montagenamen
+
+
+
+
+ assembly.bom.instockAmount
+ Beschikbaar in voorraad
+
+
+
+
+ assembly.info.title
+ Assemblage-informatie
+
+
+
+
+ assembly.info.info.label
+ Informatie
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Subassemblages
+
+
+
+
+ assembly.info.builds.label
+ Bouw
+
+
+
+
+ assembly.info.bom_add_parts
+ Onderdelen toevoegen
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Bevestig dat je hiermee wilt doorgaan!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Bouwen is niet mogelijk: niet voldoende onderdelen beschikbaar
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Er zijn niet voldoende onderdelen in voorraad om %number_of_builds% keer te bouwen. De volgende onderdelen ontbreken:
+
+
+
+
+ assembly.builds.build_possible
+ Bouwen mogelijk
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% assemblages te bouwen.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Aantal te bouwen assemblages
+
+
+
+
+ assembly.build.btn_build
+ Bouwen
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Aantal geassembleerde onderdelen op voorraad
+
+
+
+
+ assembly.info.bom_entries_count
+ Onderdelen
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Subgroepen
+
+
+
+
+ assembly.builds.stocked
+ Op voorraad
+
+
+
+
+ assembly.builds.needed
+ Nodig
+
+
+
+
+ assembly.add_parts_to_assembly
+ Onderdelen toevoegen aan assemblage
+
+
+
+
+ assembly.bom.name
+ Naam
+
+
+
+
+ assembly.bom.comment
+ Notities
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Er zijn niet genoeg onderdelen op voorraad om deze assemblage %number_of_builds% keer te bouwen. Van de volgende onderdelen is er niet genoeg op voorraad:
+
+
+
+
+ assembly.build.help
+ Selecteer uit welke voorraden de benodigde onderdelen voor de bouw gehaald moeten worden (en in welke hoeveelheid). Vink elk onderdeel afzonderlijk aan als het is verwijderd, of gebruik de bovenste selectievak om alle selectievakjes in één keer aan te vinken.
+
+
+
+
+ assembly.build.required_qty
+ Benodigde hoeveelheid
+
+
+
+
+ assembly.import_bom
+ Importeer onderdelen voor assemblage
+
+
+
+
+ assembly.bom.part
+ Onderdeel
+
+
+
+
+ assembly.bom.add_entry
+ Voer item in
+
+
+
+
+ assembly.bom.price
+ Prijs
+
+
+
+
+ assembly.build.dont_check_quantity
+ Hoeveelheden niet controleren
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Als deze optie is geselecteerd, worden de geselecteerde hoeveelheden uit de voorraad verwijderd, ongeacht of er meer of minder onderdelen zijn dan nodig is voor de assemblage.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Gemaakte instanties toevoegen aan onderdeel van assemblage
+
+
+
+
+ assembly.build.required_qty
+ Benodigd aantal
+
+
+
+
+ assembly.build.yes_button
+ Ja
+
+
+
+
+ assembly.build.no_button
+ Nee
+
+
+
+
+ assembly.confirmation.required
+
+
+
+
+
+ assembly.build.success
+ De assemblage is succesvol gebouwd!
+
+
+
+
+ assembly.build.cancelled
+ De assemblage is geannuleerd.
+
+
+
+
+ assembly.bom_import.type
+ Type
+
+
+
+
+ assembly.bom_import.type.json
+ JSON voor assemblage
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Bestaande BOM wissen vóór importeren
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Wanneer dit is ingeschakeld, worden alle bestaande BOM-items verwijderd en vervangen door de geïmporteerde gegevens.
+
+
+
+
+ assembly.import_bom.template.header.json
+ JSON-sjabloon voor assemblage
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ CSV-sjabloon voor assemblage (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Naam van onderdeel in de assemblage
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Onderdeelnummer van de fabrikant
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unieke IPN van het onderdeel
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unieke naam van het onderdeel
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unieke naam van de fabrikant
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Unieke naam van de categorie
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Veld
+
Voorwaarde
+
Gegevenstype
+
Beschrijving
+
+
+
+
+
quantity
+
Verplicht veld
+
Kommagetal (Float)
+
Moet opgegeven zijn en bevat een kommagetal (Float) dat groter is dan 0,0.
+
+
+
name
+
Optioneel
+
String
+
Indien aanwezig, moet het een niet-lege string zijn.
+
+
+
part
+
Optioneel
+
Object/Array
+
+ Indien opgegeven, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Optioneel
+
Geheel getal (Integer)
+
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van het onderdeel in de Part-DB.
+
+
+
part.name
+
Optioneel
+
String
+
Niet-lege string, indien geen part.mpnr- of part.ipn-vermelding is gegeven.
+
+
+
part.mpnr
+
Optioneel
+
String
+
Niet-lege string, indien geen part.name- of part.ipn-vermelding is gegeven.
+
+
+
part.ipn
+
Optioneel
+
String
+
Niet-lege string, indien geen part.name- of part.mpnr-vermelding is gegeven.
+
+
+
part.description
+
Optioneel
+
String of null
+
Indien aanwezig, moet het een niet-lege string zijn of null.
+
+
+
part.manufacturer
+
Optioneel
+
Object/Array
+
+ Indien aanwezig, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optioneel
+
Geheel getal (Integer)
+
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van de fabrikant.
+
+
+
manufacturer.name
+
Optioneel
+
String
+
Niet-lege string, indien geen manufacturer.id-vermelding is gegeven.
+
+
+
part.category
+
Optioneel
+
Object/Array
+
+ Indien aanwezig, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Optioneel
+
Geheel getal (Integer)
+
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van de categorie van het onderdeel.
+
+
+
category.name
+
Optioneel
+
String
+
Niet-lege string, indien geen category.id-vermelding is gegeven.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Verwachte kolommen:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Opmerking: Er wordt geen mapping uitgevoerd met specifieke componenten uit de categoriebeheer.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Veld
+
Voorwaarde
+
Gegevenstype
+
Beschrijving
+
+
+
+
+
Id
+
Optioneel
+
Integer
+
Vrij veld. Een unieke identificatienummer voor elk onderdeel.
+
+
+
Ontwerper
+
Optioneel
+
Tekst
+
Vrij veld. Een unieke referentie-ontwerper voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Gebruikt voor de naamgeving van de plaatsing in de componentgroep.
+
+
+
Omhulsel
+
Optioneel
+
Tekst
+
Vrij veld. Het type of de vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden.
+
+
+
Aantal
+
Verplicht
+
Integer
+
Het aantal identieke onderdelen dat nodig is om een enkele instantie van een assemblage te maken.
+
+
+
Aanduiding
+
Verplicht
+
Tekst
+
De beschrijving of functie van het onderdeel, bijvoorbeeld de weerstandswaarde "10kΩ" of de condensatorwaarde "100nF". Wordt gebruikt als naam in de BOM-invoer.
+
+
+
Leverancier en referentie
+
Optioneel
+
Tekst
+
Vrij veld. Kan bijvoorbeeld informatie bevatten die specifiek is voor de distributeur.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Onderdeel)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Assemblage)
+
+
+
+
+ projects.build.form.part
+ Onderdelen "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Assemblage "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% benodigd)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ niet op voorraad
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index b769e2737..7290e5fe1 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -4745,6 +4745,18 @@ Jeśli zrobiłeś to niepoprawnie lub komputer nie jest już godny zaufania, mo
Nazwa
+
+
+ part.table.name.value.for_part
+ %value%(部品)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value%(アセンブリ)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9809,6 +9821,18 @@ Element 3
Komponent
+
+
+ project.bom.assembly
+ Zespół
+
+
+
+
+ project.bom.partOrAssembly
+ Wybór
+
+ project.bom.add_entry
@@ -9887,6 +9911,42 @@ Element 3
Zarchiwizowany
+
+
+ assembly.edit.status
+ Status
+
+
+
+
+ assembly.status.draft
+ Wersja robocza
+
+
+
+
+ assembly.status.planning
+ W planowaniu
+
+
+
+
+ assembly.status.in_production
+ W produkcji
+
+
+
+
+ assembly.status.finished
+ Zakończony
+
+
+
+
+ assembly.status.archived
+ Zarchiwizowany
+
+ part.new_build_part.error.build_part_already_exists
@@ -10163,6 +10223,12 @@ Element 3
dostępny
+
+
+ project.builds.no_stock
+ brak podanego stanu magazynowego
+
+ project.builds.needed
@@ -10235,6 +10301,12 @@ Element 3
Partia docelowa
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% wymagane)
+
+ project.builds.number_of_builds
@@ -12223,5 +12295,621 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Wygenerowany kod
+
+
+ assembly.label
+ Zespół
+
+
+
+
+ assembly.caption
+ Zespół
+
+
+
+
+ perm.assemblies
+ Zespoły
+
+
+
+
+ assembly_bom_entry.label
+ Komponenty
+
+
+
+
+ assembly.labelp
+ Zespoły
+
+
+
+
+ assembly.edit
+ Edytuj zespół
+
+
+
+
+ assembly.new
+ Nowy zespół
+
+
+
+
+ assembly.edit.associated_build_part
+ Powiązany komponent
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Dodaj komponent
+
+
+
+
+ assembly.edit.associated_build.hint
+ Ten komponent reprezentuje wyprodukowane instancje zespołu. Określ, czy są potrzebne wyprodukowane instancje. W przeciwnym razie ilości komponentów zostaną zastosowane tylko podczas budowy odpowiedniego projektu.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importuj komponenty
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Zespoły
+
+
+
+
+ assembly.bom_import.flash.success
+ Pomyślnie zaimportowano %count% komponent(ów) do zespołu.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Błąd walidacji! Sprawdź zaimportowany plik!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Nie udało się zaimportować pliku. Sprawdź, czy wybrano poprawny typ pliku. Komunikat błędu: %message%
+
+
+
+
+ assembly.bom.quantity
+ Ilość
+
+
+
+
+ assembly.bom.mountnames
+ Nazwy montażu
+
+
+
+
+ assembly.bom.instockAmount
+ Ilość na magazynie
+
+
+
+
+ assembly.info.title
+ Informacje o zespole
+
+
+
+
+ assembly.info.info.label
+ Informacje
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Podzespoły
+
+
+
+
+ assembly.info.builds.label
+ Budowa
+
+
+
+
+ assembly.info.bom_add_parts
+ Dodaj części
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Upewnij się, że chcesz zbudować zespół w tym statusie!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Budowa niemożliwa: niewystarczająca ilość części
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Brakuje wystarczającej ilości części na magazynie, aby zbudować ten projekt %number_of_builds% razy. Brakujące części to:
+
+
+
+
+ assembly.builds.build_possible
+ Budowa możliwa
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% egzemplarzy tego zespołu.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Liczba budowanych egzemplarzy
+
+
+
+
+ assembly.build.btn_build
+ Zbuduj
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Liczba zbudowanych i zmagazynowanych egzemplarzy
+
+
+
+
+ assembly.info.bom_entries_count
+ Elementy
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Podzespoły
+
+
+
+
+ assembly.builds.stocked
+ na magazynie
+
+
+
+
+ assembly.builds.needed
+ potrzebne
+
+
+
+
+ assembly.add_parts_to_assembly
+ Dodaj części do zespołu
+
+
+
+
+ assembly.bom.name
+ Nazwa
+
+
+
+
+ assembly.bom.comment
+ Uwagi
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Brakuje wystarczającej ilości części na magazynie, aby zbudować ten zespół %number_of_builds% razy. Brakujące części to:
+
+
+
+
+ assembly.build.help
+ Wybierz, z których magazynów mają być pobrane części potrzebne do budowy (i w jakiej ilości). Zaznacz każdą pozycję, jeśli części zostały pobrane, lub użyj głównego pola wyboru, aby zaznaczyć wszystkie na raz.
+
+
+
+
+ assembly.build.required_qty
+ Wymagana ilość
+
+
+
+
+ assembly.import_bom
+ Importuj części dla zespołu
+
+
+
+
+ assembly.bom.part
+ Część
+
+
+
+
+ assembly.bom.add_entry
+ Dodaj pozycję
+
+
+
+
+ assembly.bom.price
+ Cena
+
+
+
+
+ assembly.build.dont_check_quantity
+ Nie sprawdzaj ilości
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Jeśli opcja jest wybrana, zadeklarowana ilość zostanie odjęta z magazynu, niezależnie od tego, czy jest wystarczająca do budowy zespołu.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Dodaj zbudowane egzemplarze jako część zespołu
+
+
+
+
+ assembly.bom_import.type
+ Typ
+
+
+
+
+ assembly.bom_import.type.json
+ JSON dla zespołu
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Usuń istniejące dane przed importem
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Jeśli wybrano, wszystkie istniejące wpisy części zostaną usunięte i zastąpione danymi z importu.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Szablon importu JSON dla zespołu
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Szablon importu CSV (KiCAD Pcbnew BOM) dla zespołu
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Nazwa części w zespole
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Unikalny numer katalogowy producenta
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unikalny IPN części
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unikalna nazwa części
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unikalna nazwa producenta
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Unikalna nazwa kategorii
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Pole
+
Warunek
+
Typ danych
+
Opis
+
+
+
+
+
quantity
+
Wymagane
+
Typ zmiennoprzecinkowy (Float)
+
Musi być obecne i zawierać wartość zmiennoprzecinkową (Float) większą niż 0,0.
+
+
+
name
+
Opcjonalne
+
Ciąg znaków (String)
+
Jeśli obecne, musi być niepustym ciągiem znaków.
+
+
+
part
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli podane, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Opcjonalne
+
Liczba całkowita (Integer)
+
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu numerowi ID komponentu w Part-DB.
+
+
+
part.name
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli part.mpnr ani part.ipn nie są podane.
+
+
+
part.mpnr
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli part.name ani part.ipn nie są podane.
+
+
+
part.ipn
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli part.name ani part.mpnr nie są podane.
+
+
+
part.description
+
Opcjonalne
+
Ciąg znaków lub null
+
Jeśli obecne, musi być niepustym ciągiem znaków lub null.
+
+
+
part.manufacturer
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli obecne, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opcjonalne
+
Liczba całkowita (Integer)
+
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu identyfikatorowi numerowemu producenta.
+
+
+
manufacturer.name
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli manufacturer.id nie jest podane.
+
+
+
part.category
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli obecne, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Opcjonalne
+
Liczba całkowita (Integer)
+
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu numerowi ID kategorii komponentu.
+
+
+
category.name
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli category.id nie jest podane.
Произвольное поле. Уникальный идентификационный номер для каждого компонента.
+
+
+
Дизигнатор
+
Опционально
+
Строка
+
Произвольное поле. Уникальный референсный обозначитель компонента на печатной плате, например, "R1" для резистора 1. Используется для именования позиции в группе компонентов.
+
+
+
Корпус
+
Опционально
+
Строка
+
Произвольное поле. Тип или форм-фактор корпуса компонента, например, "0805" для SMD-резисторов.
+
+
+
Количество
+
Обязательно
+
Целое число
+
Количество одинаковых компонентов, необходимое для создания одной единицы сборки.
+
+
+
Обозначение
+
Обязательно
+
Строка
+
Описание или функция компонента, например, номинал резистора "10kΩ" или номинал конденсатора "100nF". Используется в качестве имени в позиции списка материалов (BOM).
+
+
+
Поставщик и ссылка
+
Опционально
+
Строка
+
Произвольное поле. Может содержать, например, информацию, специфичную для дистрибьютора.
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name%(零件)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name%(组件)
+
+
+
+
+ projects.build.form.part
+ 零件“%name%”
+
+
+
+
+ projects.build.form.assembly
+ 组件“%name%”
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name%(需数量:%quantity%)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ 库存不足
+
+
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index c298266af..06354533e 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -245,6 +245,12 @@
Musíte vybrat díl pro položku BOM dílu nebo nastavit název pro položku BOM bez dílu.
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Je povoleno vybrat pouze jednu součástku nebo sestavu. Upravit prosím svůj výběr!
+
+ project.bom_entry.name_already_in_bom
@@ -365,5 +371,23 @@
Neplatný kód. Zkontrolujte, zda je vaše ověřovací aplikace správně nastavena a zda je čas správně nastaven jak na serveru, tak na ověřovacím zařízení.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Tato součást již existuje ve skupině!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Již existuje součást s tímto názvem!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Musíte vybrat součást nebo nastavit název pro nesoučást!
+
+
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index 21149f0e7..9a9dea4cd 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -245,6 +245,12 @@
Du skal vælge en komponent eller angive et navn til en ikke-komponent styklistepost!
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
+
+ project.bom_entry.name_already_in_bom
@@ -341,5 +347,23 @@
Denne leverandørstregkodeværdi er allerede brugt til en anden beholdning. Stregkoden skal være unik!
+
+
+ assembly.bom_entry.part_already_in_bom
+ Denne del eksisterer allerede i gruppen!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Der findes allerede en del med dette navn!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Du skal vælge en del eller sætte et navn for en ikke-del!
+
+
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index 9c123fd85..6fde3419a 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -242,7 +242,13 @@
validator.project.bom_entry.name_or_part_needed
- Sie müssen ein Bauteil auswählen, oder einen Namen für ein nicht-Bauteil BOM-Eintrag setzen!
+ Sie müssen ein Bauteil bzw. eine Baugruppe auswählen, oder einen Namen für ein nicht-Bauteil BOM-Eintrag setzen!
+
+
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Es darf nur ein Bauteil oder eine Baugruppe ausgewählt werden. Bitte passen Sie Ihre Auswahl an!
@@ -365,5 +371,23 @@
Ungültiger Code. Überprüfen Sie, dass die Authenticator App korrekt eingerichtet ist und dass der Server und das Gerät beide die korrekte Uhrzeit eingestellt haben.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Dieses Bauteil existiert bereits in der Gruppe!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Es gibt bereits einen Bauteil mit diesem Namen!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Sie müssen ein Bauteil auswählen, oder einen Namen für ein nicht-Bauteil setzen!
+
+
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index 9ef5b3de4..ee27863c0 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -7,5 +7,29 @@
Ο εσωτερικός αριθμός εξαρτήματος πρέπει να είναι μοναδικός. {{ value }} χρησιμοποιείται ήδη!
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
+
+
+
+
+ assembly.bom_entry.part_already_in_bom
+ Αυτό το εξάρτημα υπάρχει ήδη στην ομάδα!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Υπάρχει ήδη ένα εξάρτημα με αυτό το όνομα!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Πρέπει να επιλέξετε ένα εξάρτημα ή να βάλετε ένα όνομα για ένα μη εξάρτημα!
+
+
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index 6ad144607..86525b6a8 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -242,7 +242,13 @@
validator.project.bom_entry.name_or_part_needed
- You have to choose a part for a part BOM entry or set a name for a non-part BOM entry.
+ You have to select a part or assembly, or set a name for a non-component Bom entry!
+
+
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Only one part or assembly may be selected. Please modify your selection!
@@ -365,5 +371,23 @@
Invalid code. Check that your authenticator app is set up correctly and that both the server and authentication device has the time set correctly.
+
+
+ assembly.bom_entry.part_already_in_bom
+ __assembly.bom_entry.part_already_in_bom
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ __assembly.bom_entry.name_already_in_bom
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ __validator.assembly.bom_entry.name_or_part_needed
+
+
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index e86ab9ccc..e9bf32597 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -203,5 +203,29 @@
L'emplacement de stockage a été marqué comme "Composant seul", par conséquent aucun nouveau composant ne peut être ajouté.
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Seule une pièce ou un assemblage peut être sélectionné. Veuillez ajuster votre sélection!
+
+
+
+
+ assembly.bom_entry.part_already_in_bom
+ Cette pièce existe déjà dans le groupe!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Il existe déjà une pièce avec ce nom!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Vous devez sélectionner une pièce ou attribuer un nom pour un non-élément !
+
+
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index 29e32a16c..9c9c3960c 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -245,6 +245,12 @@
Morate odabrati dio za unos u BOM ili postaviti naziv za unos koji nije dio.
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Dozvoljeno je odabrati samo jednu komponentu ili sklop. Molimo prilagodite svoj odabir!
+
+ project.bom_entry.name_already_in_bom
@@ -359,5 +365,23 @@
Neispravan kod. Provjerite je li vaša aplikacija za autentifikaciju ispravno postavljena i jesu li poslužitelj i uređaj za autentifikaciju ispravno postavili vrijeme.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Ovaj dio već postoji u grupi!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Već postoji dio s tim nazivom!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Morate odabrati dio ili unijeti naziv za nedio!
+
+
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index 7043f4f34..2f747bc5c 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -245,6 +245,12 @@
È necessario selezionare un componente o assegnare un nome ad una voce BOM che non indica un componente!
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ È consentito selezionare solo una parte o un assieme. Si prega di modificare la selezione!
+
+ project.bom_entry.name_already_in_bom
@@ -359,5 +365,23 @@
Codice non valido. Controlla che la tua app di autenticazione sia impostata correttamente e che sia il server che il dispositivo di autenticazione abbiano l'ora impostata correttamente.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Questa parte è già presente nel gruppo!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Esiste già una parte con questo nome!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ È necessario selezionare una parte o inserire un nome per un non-parte!
+
+
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index 01cc3f77b..0156ffefc 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -203,5 +203,29 @@
新しい部品を追加できません。保管場所は「1つの部品のみ」とマークされています。
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ 部品またはアセンブリのみ選択可能です。選択内容を調整してください!
+
+
+
+
+ assembly.bom_entry.part_already_in_bom
+ この部品はすでにグループに存在します!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ この名前の部品はすでに存在します!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ 部品を選択するか、非部品の名前を入力する必要があります!
+
+
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 6c9977983..2cc4aef43 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -245,6 +245,12 @@
Należy wybrać część dla wpisu BOM części lub ustawić nazwę dla wpisu BOM niebędącego częścią.
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Można wybrać tylko jedną część lub zespół. Proszę dostosować swój wybór!
+
+ project.bom_entry.name_already_in_bom
@@ -359,5 +365,23 @@
Nieprawidłowy kod. Sprawdź, czy aplikacja uwierzytelniająca jest poprawnie skonfigurowana i czy zarówno serwer, jak i urządzenie uwierzytelniające mają poprawnie ustawiony czas.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Ten element już istnieje w grupie!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Element o tej nazwie już istnieje!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Musisz wybrać element lub przypisać nazwę dla elementu niestandardowego!
+
+
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index 0f97c4781..4049b453e 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -245,6 +245,12 @@
Вам необходимо выбрать компонент или задать имя для BOM, не относящейся к компоненту!
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Можно выбрать только деталь или сборку. Пожалуйста, измените ваш выбор!
+
+ project.bom_entry.name_already_in_bom
@@ -359,5 +365,23 @@
Неверный код. Проверьте, что приложение аутентификации настроено правильно и что на сервере и устройстве аутентификации установлено правильное время.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Эта деталь уже существует в группе!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Деталь с таким названием уже существует!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Необходимо выбрать деталь или ввести название для недетали!
+
+
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 08c9f014e..3eab5c4e3 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -245,6 +245,12 @@
您必须为 BOM 条目选择部件,或为非部件 BOM 条目设置名称。
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ 只能选择一个零件或组件。请修改您的选择!
+
+ project.bom_entry.name_already_in_bom
@@ -347,5 +353,23 @@
由于技术限制,在32位系统中无法选择2038年1月19日之后的日期!
+
+
+ assembly.bom_entry.part_already_in_bom
+ 此零件已存在于组中!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ 具有此名称的零件已存在!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ 必须选择零件或为非零件指定名称!
+
+
From 31093abdcaf6109afe14d66081a7c6c26bcc6534 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 20 Mar 2025 09:55:48 +0100
Subject: [PATCH 02/83] =?UTF-8?q?Default-Sortierung=20f=C3=BCr=20Assemblie?=
=?UTF-8?q?s=20per=20YAML-Konfiguration=20einf=C3=BChren?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env | 8 ++++++
config/parameters.yaml | 4 +++
config/services.yaml | 3 ++
.../AssemblyBomEntriesDataTable.php | 28 +++++++++++--------
4 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/.env b/.env
index 982d4bbd0..201633989 100644
--- a/.env
+++ b/.env
@@ -60,6 +60,14 @@ ERROR_PAGE_ADMIN_EMAIL=''
# If this is set to true, solutions to common problems are shown on error pages. Disable this, if you do not want your users to see them...
ERROR_PAGE_SHOW_HELP=1
+##################################################################################
+# Part table settings
+##################################################################################
+
+# Configure which columns will be visible by default in the specific table (and in which order).
+# This is a comma separated list of column names. See documentation for available values.
+TABLE_ASSEMBLIES_DEFAULT_COLUMNS=quantity,manufacturer,name,description,category
+
###################################################################################
# SAML Single sign on-settings
diff --git a/config/parameters.yaml b/config/parameters.yaml
index 154fbd8a5..a993d2d5e 100644
--- a/config/parameters.yaml
+++ b/config/parameters.yaml
@@ -43,6 +43,10 @@ parameters:
######################################################################################################################
partdb.saml.enabled: '%env(bool:SAML_ENABLED)%' # If this is set to true, SAML authentication is enabled
+ ######################################################################################################################
+ # Table settings
+ ######################################################################################################################
+ partdb.table.assemblies.default_columns: '%env(trim:string:TABLE_ASSEMBLIES_DEFAULT_COLUMNS)%' # The default columns in assembly tables and their order
######################################################################################################################
# Miscellaneous
diff --git a/config/services.yaml b/config/services.yaml
index 17611ceab..80ca69771 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -170,6 +170,9 @@ services:
App\DataTables\Helpers\ColumnSortHelper:
shared: false # Service has a state so not share it between different tables
+ App\DataTables\AssemblyBomEntriesDataTable:
+ arguments:
+ $visible_columns: '%partdb.table.assemblies.default_columns%'
####################################################################################################################
# Label system
diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php
index 7149ed5f5..a953179a9 100644
--- a/src/DataTables/AssemblyBomEntriesDataTable.php
+++ b/src/DataTables/AssemblyBomEntriesDataTable.php
@@ -25,6 +25,7 @@
use App\DataTables\Column\EntityColumn;
use App\DataTables\Column\LocaleDateTimeColumn;
use App\DataTables\Column\MarkdownColumn;
+use App\DataTables\Helpers\ColumnSortHelper;
use App\DataTables\Helpers\PartDataTableHelper;
use App\Entity\Attachments\Attachment;
use App\Entity\Parts\Part;
@@ -41,14 +42,19 @@
class AssemblyBomEntriesDataTable implements DataTableTypeInterface
{
- public function __construct(protected TranslatorInterface $translator, protected PartDataTableHelper $partDataTableHelper, protected EntityURLGenerator $entityURLGenerator, protected AmountFormatter $amountFormatter)
- {
+ public function __construct(
+ protected TranslatorInterface $translator,
+ protected PartDataTableHelper $partDataTableHelper,
+ protected EntityURLGenerator $entityURLGenerator,
+ protected AmountFormatter $amountFormatter,
+ private string $visible_columns,
+ private ColumnSortHelper $csh
+ ){
}
-
public function configure(DataTable $dataTable, array $options): void
{
- $dataTable
+ $this->csh
//->add('select', SelectColumn::class)
->add('picture', TextColumn::class, [
'label' => '',
@@ -62,7 +68,6 @@ public function configure(DataTable $dataTable, array $options): void
])
->add('id', TextColumn::class, [
'label' => $this->translator->trans('part.table.id'),
- 'visible' => false,
])
->add('quantity', TextColumn::class, [
'label' => $this->translator->trans('assembly.bom.quantity'),
@@ -97,11 +102,12 @@ public function configure(DataTable $dataTable, array $options): void
->add('ipn', TextColumn::class, [
'label' => $this->translator->trans('part.table.ipn'),
'orderField' => 'NATSORT(part.ipn)',
- 'visible' => false,
'render' => function ($value, AssemblyBOMEntry $context) {
if($context->getPart() instanceof Part) {
return $context->getPart()->getIpn();
}
+
+ return '';
}
])
->add('description', MarkdownColumn::class, [
@@ -142,7 +148,6 @@ public function configure(DataTable $dataTable, array $options): void
])
->add('instockAmount', TextColumn::class, [
'label' => 'assembly.bom.instockAmount',
- 'visible' => false,
'render' => function ($value, AssemblyBOMEntry $context) {
if ($context->getPart() !== null) {
return $this->partDataTableHelper->renderAmount($context->getPart());
@@ -153,7 +158,6 @@ public function configure(DataTable $dataTable, array $options): void
])
->add('storageLocations', TextColumn::class, [
'label' => 'part.table.storeLocations',
- 'visible' => false,
'render' => function ($value, AssemblyBOMEntry $context) {
if ($context->getPart() !== null) {
return $this->partDataTableHelper->renderStorageLocations($context->getPart());
@@ -164,15 +168,17 @@ public function configure(DataTable $dataTable, array $options): void
])
->add('addedDate', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.addedDate'),
- 'visible' => false,
])
->add('lastModified', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.lastModified'),
- 'visible' => false,
])
;
- $dataTable->addOrderBy('name', DataTable::SORT_ASCENDING);
+ //Apply the user configured order and visibility and add the columns to the table
+ $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,
+ "TABLE_ASSEMBLIES_DEFAULT_COLUMNS");
+
+ $dataTable->addOrderBy('name');
$dataTable->createAdapter(ORMAdapter::class, [
'entity' => Attachment::class,
From 39d3c49e83bc0b4e220e35e19a463a40c33eaaf8 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 20 Mar 2025 10:02:30 +0100
Subject: [PATCH 03/83] =?UTF-8?q?configuration.md:=20Info=20f=C3=BCr=20Def?=
=?UTF-8?q?ault-Sortierung=20zu=20Assemblies=20einf=C3=BCgen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/configuration.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/docs/configuration.md b/docs/configuration.md
index d4b217816..efa3efd34 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -137,6 +137,10 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `storage_location`, `amount`, `minamount`, `partUnit`, `addedDate`, `lastModified`, `needs_review`, `favorite`, `manufacturing_status`, `manufacturer_product_number`, `mass`, `tags`, `attachments`, `edit`.
+* `TABLE_ASSEMBLIES_DEFAULT_COLUMNS`: The columns in assemblies tables, which are visible by default (when loading table for first
+ time).
+ Also specify the default order of the columns. This is a comma separated list of column names. Available columns
+ are: `name`, `id`, `quantity`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `mountnames`, `instockAmount`, `storageLocations`, `addedDate`, `lastModified`.
### History/Eventlog-related settings
From 618f0edb9eac4d948f4d5bd8779d0b99c30a9f53 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Wed, 2 Apr 2025 12:24:14 +0200
Subject: [PATCH 04/83] Anpassungen aus Benutzersicht, um den Fokus auf die
reine Baugruppen-Konfiguration zu legen
---
.../AdminPages/BaseAdminController.php | 2 +
src/Form/Type/AssemblySelectType.php | 1 -
templates/admin/assembly_admin.html.twig | 4 +-
templates/admin/base_admin.html.twig | 2 +-
templates/assemblies/info/_bom.html.twig | 22 ----
.../assemblies/info/_info_card.html.twig | 15 ---
templates/assemblies/info/_part.html.twig | 5 +
.../assemblies/info/_subassemblies.html.twig | 28 -----
templates/assemblies/info/info.html.twig | 100 ++++++++++--------
.../form/collection_types_layout.html.twig | 1 +
10 files changed, 66 insertions(+), 114 deletions(-)
delete mode 100644 templates/assemblies/info/_bom.html.twig
create mode 100644 templates/assemblies/info/_part.html.twig
delete mode 100644 templates/assemblies/info/_subassemblies.html.twig
diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php
index edc5917ac..8c8d7520d 100644
--- a/src/Controller/AdminPages/BaseAdminController.php
+++ b/src/Controller/AdminPages/BaseAdminController.php
@@ -232,6 +232,7 @@ protected function _edit(AbstractNamedDBElement $entity, Request $request, Entit
'timeTravel' => $timeTravel_timestamp,
'repo' => $repo,
'partsContainingElement' => $repo instanceof PartsContainingRepositoryInterface,
+ 'showParameters' => !($this instanceof AssemblyAdminController),
]);
}
@@ -382,6 +383,7 @@ protected function _new(Request $request, EntityManagerInterface $em, EntityImpo
'import_form' => $import_form,
'mass_creation_form' => $mass_creation_form,
'route_base' => $this->route_base,
+ 'showParameters' => !($this instanceof AssemblyAdminController),
]);
}
diff --git a/src/Form/Type/AssemblySelectType.php b/src/Form/Type/AssemblySelectType.php
index ee6cf7c2a..10e858f26 100644
--- a/src/Form/Type/AssemblySelectType.php
+++ b/src/Form/Type/AssemblySelectType.php
@@ -71,7 +71,6 @@ public function configureOptions(OptionsResolver $resolver): void
$resolver->setDefaults([
'class' => Assembly::class,
'choice_label' => 'name',
- 'placeholder' => 'None',
'compound' => true,
'error_bubbling' => false,
]);
diff --git a/templates/admin/assembly_admin.html.twig b/templates/admin/assembly_admin.html.twig
index d8b3ab257..57dde7d15 100644
--- a/templates/admin/assembly_admin.html.twig
+++ b/templates/admin/assembly_admin.html.twig
@@ -15,7 +15,7 @@
{% endblock %}
{% block additional_pills %}
-
{% endblock %}
\ No newline at end of file
diff --git a/templates/form/collection_types_layout.html.twig b/templates/form/collection_types_layout.html.twig
index def235000..0175aeaf6 100644
--- a/templates/form/collection_types_layout.html.twig
+++ b/templates/form/collection_types_layout.html.twig
@@ -44,6 +44,7 @@
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index f5823e8d8..cbe8833ea 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -13642,56 +13642,56 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Pole
-
Podmínka
-
Datový typ
-
Popis
-
+
+
Pole
+
Podmínka
+
Datový typ
+
Popis
+
Id
-
Volitelný
-
Celé číslo (Integer)
-
Volný údaj. Jedinečné identifikační číslo pro každou součástku.
+
Volitelné
+
Celé číslo
+
Volné pole. Unikátní identifikační číslo pro každou součástku.
Designator
-
Volitelný
-
Řetězec (String)
-
Volný údaj. Jedinečný referenční označovač součástky na desce plošných spojů, např. „R1“ pro rezistor 1. Používá se pro název osazení součástky v rámci skupiny součástek.
+
Volitelné
+
Řetězec
+
Volné pole. Unikátní referenční označení součástky na PCB, např. „R1“ pro rezistor 1. Používá se pro název umístění v rámci součástkové skupiny.
Package
-
Volitelný
-
Řetězec (String)
-
Volný údaj. Pouzdro nebo tvar součástky, např. „0805“ pro SMD rezistory.
+
Volitelné
+
Řetězec
+
Volné pole. Pouzdro nebo formát součástky, např. „0805“ pro SMD rezistory. Není použito pro záznam součástky v rámci sestavy.
-
Množství
-
Povinný
-
Celé číslo (Integer)
-
Počet identických součástek, které jsou potřeba k vytvoření jedné instance sestavy.
+
Quantity
+
Povinné pole
+
Celé číslo
+
Počet identických součástek potřebných k vytvoření jedné instance sestavy. Použito jako počet záznamu součástky v rámci sestavy.
-
Určení
-
Povinný
-
Řetězec (String)
-
Popis nebo funkce součástky, např. hodnota rezistoru „10kΩ“ nebo hodnota kondenzátoru „100nF“. Používá se pro název položky v BOM.
+
Designation
+
Povinné pole
+
Řetězec
+
Popis nebo funkce součástky, např. hodnota rezistoru „10kΩ“ nebo hodnota kondenzátoru „100nF“. Použito jako název záznamu součástky v rámci sestavy.
-
Dodavatel a ref
-
Volitelný
-
Řetězec (String)
-
Volný údaj. Může obsahovat např. specifické údaje distributora.
+
Supplier and ref
+
Volitelné
+
Řetězec
+
Volné pole. Může obsahovat např. specifické informace o distributorovi. Používá se jako poznámka k záznamu součástky v rámci sestavy.
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index f231163a1..2461f8c77 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -12803,56 +12803,56 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Felt
-
Betingelse
-
Datatype
-
Beskrivelse
-
+
+
Felt
+
Betingelse
+
Datatype
+
Beskrivelse
+
Id
-
Valgfri
-
Heltal (Integer)
-
Fri oplysning. Et unikt identifikationsnummer for hver komponent.
+
Valgfrit
+
Heltal
+
Fri tekst. Et unikt identifikationsnummer for hver komponent.
Designator
-
Valgfri
+
Valgfrit
Streng
-
Fri oplysning. En unik referencebetegnelse for komponenten på printkortet, f.eks. "R1" for modstand 1. Bruges til navngivning af monteringssæt i komponentgruppen.
+
Fri tekst. En unik referencebetegnelse for komponenten på PCB'en, f.eks. “R1” for modstand 1. Bruges som navnet på placeringen i komponentgruppen.
Package
-
Valgfri
+
Valgfrit
Streng
-
Fri oplysning. Komponentenheden eller -formatet, f.eks. "0805" for SMD-modstande.
+
Fri tekst. Komponentens kabinet eller formfaktor, f.eks. “0805” for SMD-modstande. Ikke inkluderet som komponentoplysning i samlingen.
-
Antal
+
Quantity
Påkrævet
-
Heltal (Integer)
-
Antallet af identiske komponenter, der kræves for at oprette en enkelt instans af samling.
+
Heltal
+
Antallet af identiske komponenter, der kræves for at oprette en enkelt forekomst af samlingen. Bruges som antal af komponentoplysning i samlingen.
-
Betegnelse
+
Designation
Påkrævet
Streng
-
Beskrivelse eller funktion for komponenten, f.eks. modstandsværdi "10kΩ" eller kondensatorværdi "100nF". Bruges til navnet i BOM-posten.
+
Beskrivelse eller funktion af komponenten, f.eks. modstandsværdi “10kΩ” eller kondensatorværdi “100nF”. Bruges som navnet på komponentoplysningen i samlingen.
-
Leverandør og ref
-
Valgfri
+
Supplier and ref
+
Valgfrit
Streng
-
Fri oplysning. Kan indeholde f.eks. distributørspecifik værdi.
+
Fri tekst. Kan indeholde, for eksempel, specifikke oplysninger fra en distributør. Bruges som en note til komponentoplysningen i samlingen.
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index c32bf46a7..bc0cac33f 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -13446,19 +13446,19 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Feld
-
Bedingung
-
Datentyp
-
Beschreibung
-
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
@@ -13471,31 +13471,31 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Designator
Optional
String
-
Offene Angabe. Ein eindeutiger Referenzbezeichner des Bauteils auf der Leiterplatte, z.B. „R1“ für Widerstand 1. Wird für den Bestückungsnamen des Bauteil-Eintrags innerhalb der Bauteilgruppe verwendet.
+
Offene Angabe. Ein eindeutiger Referenzbezeichner des Bauteils auf der Leiterplatte, z.B. „R1“ für Widerstand 1. Wird in den Bestückungsnamen des Bauteil-Eintrags in der Baugruppe übernommen.
Package
Optional
String
-
Offene Angabe. Das Gehäuse oder die Bauform des Bauteils, z.B. „0805“ für SMD-Widerstände.
+
Offene Angabe. Das Gehäuse oder die Bauform des Bauteils, z.B. „0805“ für SMD-Widerstände. Wird für ein Bauteil-Eintrag innerhalb der Baugruppe nicht übernommen.
Quantity
Pflichtfeld
Ganzzahl (Integer)
-
Anzahl der identischen Bauteile, die benötigt werden, um eine Instanz der Baugruppe zu erstellen.
+
Anzahl der identischen Bauteile, die benötigt werden, um eine Instanz der Baugruppe zu erstellen. Wird als Anzahl des Bauteil-Eintrags innerhalb der Baugruppe übernommen.
Designation
Pflichtfeld
String
-
Beschreibung oder Funktion des Bauteils, z.B. Widerstandswert „10kΩ“ oder Kondensatorwert „100nF“. Wird für den Namen des BOM-Eintrags verwendet.
+
Beschreibung oder Funktion des Bauteils, z.B. Widerstandswert „10kΩ“ oder Kondensatorwert „100nF“. Wird in den Namen des Bauteil-Eintrags innerhalb der Baugruppe übernommen.
Supplier and ref
Optional
String
-
Offene Angabe. Kann z.B. Distributor spezifischen Wert enthalten.
+
Offene Angabe. Kann z.B. Distributor spezifischen Wert enthalten. Wird als Notiz zum Bauteil-Eintrag innerhalb der Baugruppe übernommen.
Ελεύθερη καταχώρηση. Μοναδικός αριθμός ταυτοποίησης για κάθε εξάρτημα.
+
Ακέραιος
+
Πεδίο ελεύθερης μορφής. Ένας μοναδικός αριθμός ταυτοποίησης για κάθε εξάρτημα.
-
Σχεδιαστής
+
Designator
Προαιρετικό
-
Συμβολοσειρά (String)
-
Ελεύθερη καταχώρηση. Μοναδικός αναγνωριστικός δείκτης του εξαρτήματος στην πλακέτα κυκλώματος, π.χ. "R1" για την αντίσταση 1. Χρησιμοποιείται για το όνομα του εξαρτήματος στο πλαίσιο της ομάδας εξαρτημάτων.
+
Συμβολοσειρά
+
Πεδίο ελεύθερης μορφής. Ένας μοναδικός αναγνωριστικός δείκτης για το εξάρτημα στην πλακέτα PCB, π.χ. "R1" για τον αντιστάτη 1. Χρησιμοποιείται για την ονομασία της θέσης στην ομάδα εξαρτημάτων.
-
Συσκευασία
+
Package
Προαιρετικό
-
Συμβολοσειρά (String)
-
Ελεύθερη καταχώρηση. Ο τύπος ή η μορφή του εξαρτήματος, π.χ. "0805" για αντιστάσεις SMD.
+
Συμβολοσειρά
+
Πεδίο ελεύθερης μορφής. Η θήκη ή ο μορφολογικός τύπος του εξαρτήματος, π.χ. "0805" για τους SMD αντιστάτες. Δεν περιλαμβάνεται στις πληροφορίες εξαρτήματος της συναρμολόγησης.
-
Ποσότητα
-
Υποχρεωτικό
-
Ακέραιος αριθμός (Integer)
-
Ο αριθμός των πανομοιότυπων εξαρτημάτων που απαιτούνται για τη δημιουργία μίας μονάδας του συνόλου.
+
Quantity
+
Απαιτείται
+
Ακέραιος
+
Ο αριθμός πανομοιότυπων εξαρτημάτων που απαιτούνται για τη δημιουργία μιας μοναδικής παρουσίας της συναρμολόγησης. Χρησιμοποιείται ως ποσότητα στις πληροφορίες εξαρτήματος της συναρμολόγησης.
-
Ορισμός
-
Υποχρεωτικό
-
Συμβολοσειρά (String)
-
Περιγραφή ή λειτουργία του εξαρτήματος, π.χ. αντίσταση "10kΩ" ή χωρητικότητα "100nF". Χρησιμοποιείται για το όνομα της εγγραφής στο BOM.
+
Designation
+
Απαιτείται
+
Συμβολοσειρά
+
Η περιγραφή ή η λειτουργία του εξαρτήματος, π.χ. τιμή αντιστάτη "10kΩ" ή τιμή πυκνωτή "100nF". Χρησιμοποιείται ως το όνομα στις πληροφορίες εξαρτήματος της συναρμολόγησης.
-
Προμηθευτής και παραπομπή
+
Supplier and ref
Προαιρετικό
-
Συμβολοσειρά (String)
-
Ελεύθερη καταχώρηση. Μπορεί να περιλαμβάνει, π.χ., ειδική τιμή από διανομέα.
+
Συμβολοσειρά
+
Πεδίο ελεύθερης μορφής. Μπορεί να περιλαμβάνει, για παράδειγμα, συγκεκριμένες πληροφορίες για τον προμηθευτή. Χρησιμοποιείται ως σημείωση για τις πληροφορίες εξαρτήματος της συναρμολόγησης.
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index d267c89ac..8ac704001 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -13447,56 +13447,56 @@ Please note, that you can not impersonate a disabled user. If you try you will g
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Field
-
Condition
-
Data Type
-
Description
-
+
+
Field
+
Condition
+
Data Type
+
Description
+
Id
Optional
Integer
-
Free-form field. A unique identification number for each component.
+
Free-form field. A unique identification number for each part.
Designator
Optional
String
-
Free-form field. A unique reference designator of the component on the PCB, e.g., “R1” for resistor 1. Used for naming the placement in the component group.
+
Free-form field. A unique reference designator of the part on the PCB, e.g., “R1” for resistor 1. Used for the placement name of the part entry in the assembly.
Package
Optional
String
-
Free-form field. The casing or form factor of the component, e.g., “0805” for SMD resistors.
+
Free-form field. The case or form factor of the part, e.g., “0805” for SMD resistors. Not adopted for a part entry within the assembly.
Quantity
-
Required
+
Required field
Integer
-
The number of identical components required to create a single instance of an assembly.
+
The number of identical parts needed to create an instance of the assembly. Adopted as the quantity of the part entry within the assembly.
Designation
-
Required
+
Required field
String
-
The description or function of the component, e.g., resistor value “10kΩ” or capacitor value “100nF.” Used for the name in the BOM entry.
+
Description or function of the part, e.g., resistor value “10kΩ” or capacitor value “100nF.” Adopted into the name of the part entry within the assembly.
Supplier and ref
Optional
String
-
Free-form field. May include, for example, specific distributor information.
+
Free-form field. May, for example, contain distributor-specific information. Adopted as a note for the part entry within the assembly.
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index c3bf96368..0383f964f 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -12939,7 +12939,7 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
-
+ assembly.bom_import.template.kicad_pcbnew.table
@@ -12958,37 +12958,37 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Id
Opcional
Entero
-
Campo libre. Un número de identificación único para cada componente.
+
Campo libre. Un número único de identificación para cada componente.
-
Designador
+
Designator
Opcional
-
Cadena de texto
-
Campo libre. Un designador de referencia único para el componente en la PCB, p. ej., "R1" para la resistencia 1. Se utiliza para nombrar la colocación en el grupo de componentes.
+
Cadena
+
Campo libre. Un designador de referencia único para el componente en la PCB, por ejemplo, "R1" para la resistencia 1. Se utiliza como el nombre de ubicación en la entrada de componentes dentro del ensamblaje.
Package
Opcional
-
Cadena de texto
-
Campo libre. El formato o tipo de encapsulado del componente, p. ej., "0805" para resistencias SMD.
+
Cadena
+
Campo libre. El encapsulado o formato del componente, por ejemplo, "0805" para resistencias SMD. No se incluye en la entrada del componente dentro del ensamblaje.
-
Cantidad
-
Obligatorio
+
Quantity
+
Requerido
Entero
-
El número de componentes idénticos necesarios para crear una instancia única de un ensamblaje.
+
El número de componentes idénticos necesarios para crear una instancia del ensamblaje. Se usa como la cantidad en la entrada de componentes dentro del ensamblaje.
-
Designación
-
Obligatorio
-
Cadena de texto
-
La descripción o función del componente, p. ej., el valor de la resistencia "10kΩ" o el valor del condensador "100nF". Se utiliza para el nombre en la entrada del BOM.
+
Designation
+
Requerido
+
Cadena
+
Descripción o función del componente, por ejemplo, valor de resistencia "10kΩ" o valor de condensador "100nF". Se usa como el nombre de la entrada del componente dentro del ensamblaje.
-
Proveedor y referencia
+
Supplier and ref
Opcional
-
Cadena de texto
-
Campo libre. Puede incluir, por ejemplo, información específica del distribuidor.
+
Cadena
+
Campo libre. Puede contener, por ejemplo, información específica del distribuidor. Se usa como una nota en la entrada del componente dentro del ensamblaje.
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 5362f9390..320121909 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -9692,19 +9692,19 @@ exemple de ville
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Champ
-
Condition
-
Type de Données
-
Description
-
+
+
Champ
+
Condition
+
Type de Données
+
Description
+
@@ -9714,34 +9714,34 @@ exemple de ville
Champ libre. Un numéro d'identification unique pour chaque composant.
-
Designeur
+
Designator
Optionnel
Chaîne
-
Champ libre. Une référence de désignation unique du composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé pour nommer la position au sein du groupe de composants.
+
Champ libre. Une désignation de référence unique pour le composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé comme le nom de l'emplacement de l'entrée composant dans l'assemblage.
-
Boîtier
+
Package
Optionnel
Chaîne
-
Champ libre. Le type ou format d'encapsulation du composant, par exemple, "0805" pour des résistances CMS.
+
Champ libre. Le boîtier ou le format du composant, par exemple, "0805" pour les résistances CMS. Non inclus dans l'entrée composant pour l'assemblage.
-
Quantité
+
Quantity
Obligatoire
Entier
-
Le nombre de composants identiques nécessaires pour créer une instance unique d'un ensemble.
+
Le nombre de composants identiques nécessaires pour créer une instance de l'assemblage. Utilisé comme la quantité dans l'entrée composant de l'assemblage.
-
Désignation
+
Designation
Obligatoire
Chaîne
-
La description ou la fonction du composant, par exemple, la valeur de résistance "10kΩ" ou la valeur de condensateur "100nF". Utilisé comme nom dans l'entrée de la nomenclature (BOM).
+
La description ou la fonction du composant, par exemple, valeur de résistance "10kΩ" ou valeur de condensateur "100nF". Utilisé comme le nom dans l'entrée composant pour l'assemblage.
-
Fournisseur et réf
+
Supplier and ref
Optionnel
Chaîne
-
Champ libre. Peut inclure, par exemple, des informations spécifiques au distributeur.
+
Champ libre. Peut contenir par exemple des informations spécifiques sur le fournisseur. Utilisé comme une note dans l'entrée composant pour l'assemblage.
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index 0ea57d9f1..f6e3c9446 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -12941,56 +12941,56 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Campo
-
Condizione
-
Tipo di Dati
-
Descrizione
-
+
+
Campo
+
Condizione
+
Tipo di Dati
+
Descrizione
+
Id
Opzionale
Intero
-
Campo libero. Un numero identificativo unico per ogni componente.
+
Campo libero. Un numero identificativo univoco per ogni componente.
-
Designatore
+
Designator
Opzionale
Stringa
-
Campo libero. Un designatore di riferimento unico per il componente sul PCB, ad esempio, "R1" per il resistore 1. Utilizzato per nominare la posizione nel gruppo di componenti.
+
Campo libero. Un riferimento univoco al componente su PCB, ad esempio "R1" per il resistore 1. Utilizzato come nome della posizione nella voce componenti all'interno dell'assemblaggio.
Package
Opzionale
Stringa
-
Campo libero. Il tipo o formato del contenitore del componente, ad esempio, "0805" per le resistenze SMD.
+
Campo libero. L'involucro o il fattore di forma del componente, ad esempio "0805" per i resistori SMD. Non incluso nelle informazioni del componente nell'assemblaggio.
-
Quantità
+
Quantity
Obbligatorio
Intero
-
Il numero di componenti identici necessari per creare una singola unità di assemblaggio.
+
Il numero di componenti identici richiesti per creare un'istanza dell'assemblaggio. Utilizzato come quantità nella voce componenti dell'assemblaggio.
-
Designazione
+
Designation
Obbligatorio
Stringa
-
La descrizione o la funzione del componente, ad esempio, il valore della resistenza "10kΩ" o il valore del condensatore "100nF". Utilizzato per il nome nell'entrata della lista dei materiali (BOM).
+
Descrizione o funzione del componente, ad esempio valore resistore "10kΩ" o valore condensatore "100nF". Utilizzato come nome nella voce componenti dell'assemblaggio.
-
Fornitore e riferimento
+
Supplier and ref
Opzionale
Stringa
-
Campo libero. Può includere, ad esempio, informazioni specifiche del distributore.
+
Campo libero. Può contenere, ad esempio, informazioni specifiche del fornitore. Utilizzato come nota nelle informazioni del componente nell'assemblaggio.
Vrij veld. Een unieke identificatienummer voor elk onderdeel.
-
Ontwerper
+
Designator
Optioneel
-
Tekst
-
Vrij veld. Een unieke referentie-ontwerper voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Gebruikt voor de naamgeving van de plaatsing in de componentgroep.
+
String
+
Vrij veld. Een unieke referentienaam voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Wordt gebruikt als positioneringsnaam in de onderdelenlijst van de assemblage.
-
Omhulsel
+
Package
Optioneel
-
Tekst
-
Vrij veld. Het type of de vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden.
+
String
+
Vrij veld. De behuizing of vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden. Wordt niet opgenomen in de onderdelenlijst binnen de assemblage.
-
Aantal
-
Verplicht
+
Quantity
+
Vereist
Integer
-
Het aantal identieke onderdelen dat nodig is om een enkele instantie van een assemblage te maken.
+
Het aantal identieke onderdelen dat nodig is om een assemblage-instantie te creëren. Wordt gebruikt als hoeveelheid in de onderdelenlijst binnen de assemblage.
-
Aanduiding
-
Verplicht
-
Tekst
-
De beschrijving of functie van het onderdeel, bijvoorbeeld de weerstandswaarde "10kΩ" of de condensatorwaarde "100nF". Wordt gebruikt als naam in de BOM-invoer.
+
Designation
+
Vereist
+
String
+
De beschrijving of functie van het onderdeel, zoals weerstandwaarde "10kΩ" of condensatorwaarde "100nF". Wordt gebruikt als de naam in de onderdelenlijst binnen de assemblage.
-
Leverancier en referentie
+
Supplier and ref
Optioneel
-
Tekst
-
Vrij veld. Kan bijvoorbeeld informatie bevatten die specifiek is voor de distributeur.
+
String
+
Vrij veld. Kan bijvoorbeeld specifieke informatie over leveranciers bevatten. Wordt gebruikt als notitie in de onderdelenlijst binnen de assemblage.
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index 7290e5fe1..d1a095072 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -12818,19 +12818,19 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Pole
-
Warunek
-
Typ Danych
-
Opis
-
+
+
Pole
+
Warunek
+
Typ Danych
+
Opis
+
@@ -12840,34 +12840,34 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Pole dowolne. Unikalny numer identyfikacyjny dla każdego komponentu.
-
Designer
+
Designator
Opcjonalne
-
Łańcuch znaków
-
Pole dowolne. Unikalny oznacznik referencyjny komponentu na PCB, np. "R1" dla rezystora 1. Używany do nazewnictwa położenia w grupie komponentów.
+
Tekst
+
Pole dowolne. Jednoznaczny znacznik referencyjny komponentu na PCB, np. "R1" dla rezystora 1. Używane jako nazwa pozycji w pozycji komponentu w montażu.
-
Obudowa
+
Package
Opcjonalne
-
Łańcuch znaków
-
Pole dowolne. Typ lub forma obudowy komponentu, np. "0805" dla rezystorów SMD.
+
Tekst
+
Pole dowolne. Obudowa lub forma komponentu, np. "0805" dla rezystorów SMD. Niewykorzystywane w pozycji komponentu w montażu.
-
Ilość
+
Quantity
Wymagane
Liczba całkowita
-
Liczba identycznych komponentów potrzebnych do stworzenia jednej instancji złożenia.
+
Liczba identycznych komponentów potrzebna do utworzenia jednej instancji montażu. Używane jako ilość w pozycji komponentu w montażu.
-
Oznaczenie
+
Designation
Wymagane
-
Łańcuch znaków
-
Opis lub funkcja komponentu, np. wartość rezystora "10kΩ" lub wartość kondensatora "100nF". Używane jako nazwa w pozycji na liście materiałowej (BOM).
+
Tekst
+
Opis lub funkcja komponentu, np. wartość rezystora "10kΩ" lub wartość kondensatora "100nF". Używane jako nazwa w pozycji komponentu w montażu.
-
Dostawca i referencja
+
Supplier and ref
Opcjonalne
-
Łańcuch znaków
-
Pole dowolne. Może zawierać, np. informacje specyficzne dla dystrybutora.
+
Tekst
+
Pole dowolne. Może zawierać np. specyficzne informacje o dostawcy. Używane jako notatka w pozycji komponentu w montażu.
Произвольное поле. Уникальный идентификационный номер для каждого компонента.
+
Целое
+
Свободное поле. Уникальный идентификационный номер для каждого компонента.
-
Дизигнатор
-
Опционально
+
Package
+
Designator
Строка
-
Произвольное поле. Уникальный референсный обозначитель компонента на печатной плате, например, "R1" для резистора 1. Используется для именования позиции в группе компонентов.
+
Свободное поле. Уникальная ссылочная метка компонента на печатной плате, например, "R1" для резистора 1. Используется как наименование позиции в компоненте сборки.
-
Корпус
+
Package
Опционально
Строка
-
Произвольное поле. Тип или форм-фактор корпуса компонента, например, "0805" для SMD-резисторов.
+
Свободное поле. Тип корпуса или форм-фактор компонента, например, "0805" для SMD-резисторов. Не включается в информацию о компоненте сборки.
-
Количество
+
Quantity
Обязательно
-
Целое число
-
Количество одинаковых компонентов, необходимое для создания одной единицы сборки.
+
Целое
+
Количество одинаковых компонентов, необходимых для создания одной версии сборки. Используется как количество в информации о компоненте сборки.
-
Обозначение
+
Designation
Обязательно
Строка
-
Описание или функция компонента, например, номинал резистора "10kΩ" или номинал конденсатора "100nF". Используется в качестве имени в позиции списка материалов (BOM).
+
Описание или функция компонента, например, значение резистора "10kΩ" или значение конденсатора "100nF". Используется как наименование в информации о компоненте сборки.
-
Поставщик и ссылка
+
Supplier and ref
Опционально
Строка
-
Произвольное поле. Может содержать, например, информацию, специфичную для дистрибьютора.
+
Свободное поле. Может содержать, например, информацию о конкретных поставщиках. Используется как примечание в информации о компоненте сборки.
- {{ form_widget(form.assembly) }}
- {{ form_errors(form.assembly) }}
+
+ {% if form.vars.value is not null and form.vars.value.project is not null %}
+ {% set hasAssembly = false %}
+ {% if is_granted("@assemblies.read") or has_assembly(form.vars.value.project.bomEntries.toArray) %}
+
Id;Designator;Package;Quantity;Designation;Supplier and ref
+
+
+
Id
+
Designator
+
Package
+
Quantity
+
Designation
+
Supplier and ref
+
Note
+
Footprint
+
Value
+
Footprint
+
+
{{ 'assembly.bom_import.template.kicad_pcbnew.exptected_columns.note'|trans|raw }}
{{ 'assembly.bom_import.template.kicad_pcbnew.table'|trans|raw }}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index cbe8833ea..b0ec93321 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -13437,6 +13437,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
JSON pro sestavu
+
+
+ assembly.bom_import.type.csv
+ CSV pro sestavu
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -13461,6 +13467,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Šablona importu JSON pro sestavu
+
+
+ assembly.import_bom.template.header.csv
+ Importní šablona CSV pro sestavu
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -13520,24 +13532,26 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
quantity
-
Povinné
+
Povinné pole
Číslo s plovoucí desetinnou čárkou (Float)
-
Musí být uvedeno a obsahovat hodnotu s plovoucí desetinnou čárkou (Float) větší než 0,0.
+
Musí být vyplněno a obsahovat číselnou hodnotu (Float) větší než 0.0.
name
Volitelné
-
Řetězec (String)
-
Pokud je přítomen, musí být neprázdný řetězec.
+
Řetězec
+
Pokud je uvedeno, musí být neprázdný text. Název položky ve skupině.
part
Volitelné
Objekt/Array
- Pokud je uvedeno, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+ Pokud má být přiřazena součástka, musí být objektem/arrayem a alespoň jedno z následujících polí musí být vyplněno:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -13546,38 +13560,38 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
part.id
Volitelné
Celé číslo (Integer)
-
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID součástky v Part-DB.
+
Celé číslo > 0. Odpovídá internímu číselnému ID součástky v databázi.
-
part.name
+
part.mpnr
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není zadáno part.mpnr nebo part.ipn.
+
Řetězec
+
Neprázdný text, pokud není vyplněno part.id, part.ipn ani part.name.
-
part.mpnr
+
part.ipn
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není zadáno part.name nebo part.ipn.
+
Řetězec
+
Neprázdný text, pokud není vyplněno part.id, part.mpnr ani part.name.
-
part.ipn
+
part.name
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není zadáno part.name nebo part.mpnr.
+
Řetězec
+
Neprázdný text, pokud není vyplněno part.id, part.mpnr ani part.ipn.
part.description
Volitelné
Řetězec nebo null
-
Pokud je přítomen, musí být neprázdný řetězec nebo null.
+
Pokud je uvedeno, musí být neprázdný řetězec nebo null. Přepíše stávající hodnotu v součástce.
part.manufacturer
Volitelné
Objekt/Array
- Pokud je přítomen, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+ Pokud má být výrobce součástky upraven nebo má být součástka jednoznačně identifikována pomocí hodnoty part.mpnr, musí být objektem/arrayem a alespoň jedno z následujících polí musí být vyplněno:
manufacturer.id
manufacturer.name
@@ -13588,20 +13602,20 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
manufacturer.id
Volitelné
Celé číslo (Integer)
-
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID výrobce.
+
Celé číslo > 0. Odpovídá internímu číselnému ID výrobce.
manufacturer.name
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není uvedeno manufacturer.id.
+
Řetězec
+
Neprázdný text, pokud není uveden manufacturer.id.
part.category
Volitelné
Objekt/Array
- Pokud je přítomen, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+ Pokud má být kategorie součástky upravena, musí být objektem/arrayem a alespoň jedno z následujících polí musí být vyplněno:
category.id
category.name
@@ -13612,13 +13626,138 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
category.id
Volitelné
Celé číslo (Integer)
-
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID kategorie součástky.
+
Celé číslo > 0. Odpovídá internímu číselnému ID kategorie součástky.
category.name
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není uvedeno category.id.
Musí být vyplněno a obsahovat číselnou hodnotu (Float) větší než 0.0.
+
+
+
name
+
Volitelné
+
Řetězec
+
Název položky ve skupině.
+
+
+
Sloupce začínající part_
+
+ Pokud má být přiřazena součástka, jeden z následujících sloupců musí být uveden a vyplněn:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo > 0. Odpovídá internímu číselnému ID součástky v databázi.
+
+
+
part_mpnr
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_ipn nebo part_name.
+
+
+
part_ipn
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_mpnr nebo part_name.
+
+
+
part_name
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_mpnr nebo part_ipn.
+
+
+
part_description
+
Volitelné
+
Řetězec
+
Bude přeneseno do součástky a přepíše aktuální hodnotu, pokud je uveden neprázdný text.
+
+
+
Sloupce začínající part_manufacturer_
+
+ Pokud má být výrobce upraven nebo součástka jednoznačně identifikována pomocí part_mpnr, jeden z následujících sloupců musí být uveden a vyplněn:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo > 0. Odpovídá internímu číselnému ID výrobce.
+
+
+
part_manufacturer_name
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud není vyplněn sloupec part_manufacturer_id.
+
+
+
Sloupce začínající part.category_
+
+ Pokud má být kategorie upravena, jeden z následujících sloupců musí být uveden a vyplněn:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo > 0. Odpovídá internímu číselnému ID kategorie součástky.
+
+
+
part_category_name
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud není vyplněn sloupec part_category_id.
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index 2461f8c77..4322fd9f8 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -12598,6 +12598,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
JSON for en samling
+
+
+ assembly.bom_import.type.csv
+ CSV til en samling
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -12622,6 +12628,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
JSON-importskabelon til en samling
+
+
+ assembly.import_bom.template.header.csv
+ Importskabelon CSV til en samling
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -12681,64 +12693,66 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
quantity
-
Påkrævet
-
Flydende tal (Float)
-
Skal være til stede og indeholde en flydende værdi (Float), der er større end 0,0.
+
Påkrævet felt
+
Flydende punkt-tal (Float)
+
Skal være udfyldt og indeholde en flydende værdi (Float), der er større end 0.0.
name
-
Valgfri
-
String
-
Hvis til stede, skal det være en ikke-tom streng.
+
Valgfrit
+
Streng
+
Hvis det er angivet, skal det være en ikke-tom streng. Navn på posten inden for samlingen.
part
-
Valgfri
+
Valgfrit
Objekt/Array
- Hvis angivet, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+ Hvis en del skal tildeles, skal det være et objekt/array, og mindst et af følgende felter skal være udfyldt:
part.id
+
part.mpnr
+
part.ipn
part.name
part.id
-
Valgfri
+
Valgfrit
Heltal (Integer)
-
Heltal (Integer) > 0. Matcher Part-DB's interne numeriske ID for komponenten.
-
-
-
part.name
-
Valgfri
-
String
-
Ikke-tom streng, hvis part.mpnr eller part.ipn ikke er givet.
+
Heltal > 0. Tilsvarer den interne nummer-ID for delen i database.
part.mpnr
-
Valgfri
-
String
-
Ikke-tom streng, hvis part.name eller part.ipn ikke er givet.
+
Valgfrit
+
Streng
+
Ikke-tom streng, hvis ingen part.id-, part.ipn- eller part.name-værdi er angivet.
part.ipn
-
Valgfri
-
String
-
Ikke-tom streng, hvis part.name eller part.mpnr ikke er givet.
+
Valgfrit
+
Streng
+
Ikke-tom streng, hvis ingen part.id-, part.mpnr- eller part.name-værdi er angivet.
+
+
+
part.name
+
Valgfrit
+
Streng
+
Ikke-tom streng, hvis ingen part.id-, part.mpnr- eller part.ipn-værdi er angivet.
part.description
-
Valgfri
-
String eller null
-
Hvis til stede, skal det være en ikke-tom streng eller null.
+
Valgfrit
+
Streng eller null
+
Hvis angivet, skal det være en ikke-tom streng eller null. Værdien bliver overskrevet i delen.
part.manufacturer
-
Valgfri
+
Valgfrit
Objekt/Array
- Hvis til stede, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+ Hvis producenten af en del skal ændres eller entydigt søges ved hjælp af part.mpnr-værdien, skal det være et objekt/array og mindst et af følgende felter skal være udfyldt:
manufacturer.id
manufacturer.name
@@ -12747,22 +12761,22 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Heltal > 0. Tilsvarer den interne nummer-ID for producenten.
manufacturer.name
-
Valgfri
-
String
-
Ikke-tom streng, hvis manufacturer.id ikke er givet.
+
Valgfrit
+
Streng
+
Ikke-tom streng, hvis ingen manufacturer.id er angivet.
part.category
-
Valgfri
+
Valgfrit
Objekt/Array
- Hvis til stede, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+ Hvis en delens kategori skal ændres, skal det være et objekt/array, og mindst et af følgende felter skal være udfyldt:
category.id
category.name
@@ -12771,15 +12785,140 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Skal være udfyldt og indeholde en flydende værdi (Float), der er større end 0.0.
+
+
+
name
+
Valgfrit
+
Streng
+
Navnet på posten inden for samlingen.
+
+
+
Kolonner, der starter med part_
+
+ Hvis en del skal tildeles, skal en af følgende kolonner være angivet og udfyldt:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Valgfrit
+
Heltal (Integer)
+
Heltal > 0. Tilsvarer den interne nummer-ID for delen i databasen.
+
+
+
part_mpnr
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen af kolonnerne part_id, part_ipn, eller part_name er udfyldt.
+
+
+
part_ipn
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen af kolonnerne part_id, part_mpnr eller part_name er udfyldt.
+
+
+
part_name
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen af kolonnerne part_id, part_mpnr eller part_ipn er udfyldt.
+
+
+
part_description
+
Valgfrit
+
Streng
+
Vil blive overført og overskrive værdien for delen, hvis en ikke-tom streng er angivet.
+
+
+
Kolonner, der starter med part_manufacturer_
+
+ Hvis producenten for en del skal ændres eller søges entydigt ved hjælp af part_mpnr, skal en af følgende kolonner være angivet og udfyldt:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Valgfrit
+
Heltal (Integer)
+
Heltal > 0. Tilsvarer den interne nummer-ID for producenten.
+
+
+
part_manufacturer_name
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen part_manufacturer_id er udfyldt.
+
+
+
Kolonner, der starter med part.category_
+
+ Hvis en dels kategori skal ændres, skal en af følgende kolonner være angivet og udfyldt:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Valgfrit
+
Heltal (Integer)
+
Heltal > 0. Tilsvarer den interne nummer-ID for delens kategori.
+
+
+
part_category_name
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen part_category_id er udfyldt.
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index bc0cac33f..8377facc9 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -12986,7 +12986,7 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
assembly.edit.bom.import_bom
- Bauteile importieren
+ Importiere Bauteil-Liste
@@ -13241,6 +13241,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
JSON für eine Baugruppe
+
+
+ assembly.bom_import.type.csv
+ CSV für eine Baugruppe
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -13265,6 +13271,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Import-Vorlage JSON für eine Baugruppe
+
+
+ assembly.import_bom.template.header.csv
+ Import-Vorlage CSV für eine Baugruppe
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -13332,16 +13344,18 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
name
Optional
String
-
Falls vorhanden, muss es ein nicht-leerer String sein.
+
Falls vorhanden, muss es ein nicht-leerer String sein. Name des Eintrags innerhalb der Baugruppe.
part
Optional
Objekt/Array
- Falls angegeben, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+ Falls ein Bauteil zugeordnet werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -13353,35 +13367,35 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
-
part.name
+
part.mpnr
Optional
String
-
Nicht-leerer String, falls keine part.mpnr- bzw. part.ipn-Angabe gegeben ist.
+
Nicht-leerer String, falls keine part.id-, part-ipn- bzw. part.name-Angabe gegeben ist.
-
part.mpnr
+
part.ipn
Optional
String
-
Nicht-leerer String, falls keine part.name- bzw. part-ipn-Angabe gegeben ist.
+
Nicht-leerer String, falls keine part.id-, part.mpnr bzw. part.name-Angabe gegeben ist.
-
part.ipn
+
part.name
Optional
String
-
Nicht-leerer String, falls keine part.name- bzw. part.mpnr-Angabe gegeben ist.
+
Nicht-leerer String, falls keine part.id-, part.mpnr- bzw. part.ipn-Angabe gegeben ist.
part.description
Optional
String oder null
-
Falls vorhanden, muss es ein nicht-leerer String sein oder null.
+
Falls vorhanden, muss es ein nicht-leerer String sein oder null. Wird in das Bauteil übernommen, d.h. der dortige Wert überschrieben.
part.manufacturer
Optional
Objekt/Array
- Falls vorhanden, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+ Falls der Hersteller eines Bauteils mit angepasst werden oder das Bauteil anhand der part.mpnr-Angabe eindeutig gesucht werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
manufacturer.id
manufacturer.name
@@ -13405,7 +13419,7 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Optional
Objekt/Array
- Falls vorhanden, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+ Falls die Kategorie eine Bauteils mit angepasst werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
category.id
category.name
@@ -13430,6 +13444,131 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
+
+
+ assembly.bom_import.template.csv.exptected_columns
+ Mögliche Spalten:
+
+
+
+
+ assembly.bom_import.template.csv.table
+
+
+
+
+
Spalte
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
quantity
+
Pflichtfeld
+
Gleitkommazahl (Float)
+
Muss gegeben sein und enthält einen Gleitkommawert (Float), der größer als 0.0 ist.
+
+
+
name
+
Optional
+
String
+
Name des Eintrags innerhalb der Baugruppe.
+
+
+
Spalten beginnend mit part_
+
+ Falls ein Bauteil zugeordnet werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
+
+
+
part_mpnr
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_ipn- bzw. part_name-Spalte ausgefüllt gegeben ist.
+
+
+
part_ipn
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_mpnr- bzw. part_name-Spalte ausgefüllt gegeben ist.
+
+
+
part_name
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_mpnr- bzw. part_ipn-Spalte ausgefüllt gegeben ist.
+
+
+
part_description
+
Optional
+
String
+
Wird in das Bauteil übernommen, d.h. der dortige Wert überschrieben sofern ein nicht-leerer String gegeben ist.
+
+
+
Spalten beginnend mit part_manufacturer_
+
+ Falls der Hersteller eines Bauteils mit angepasst werden oder das Bauteil anhand der part_mpnr-Angabe eindeutig gesucht werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID des Herstellers.
+
+
+
part_manufacturer_name
+
Optional
+
String
+
Anzugeben, falls keine part_manufacturer_id-Spalte ausgefüllt gegeben ist.
+
+
+
Spalten beginnend mit part.category_
+
+ Falls die Kategorie eines Bauteils mit angepasst werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID der Kategorie des Bauteils.
+
+
+
part_category_name
+
Optional
+
String
+
Anzugeben, falls keine part_category_id-Spalte ausgefüllt gegeben ist.
+
+
+
+ ]]>
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index b54131896..c97f06304 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -1925,6 +1925,12 @@
JSON για συναρμολόγηση
+
+
+ assembly.bom_import.type.csv
+ CSV για μια συναρμολόγηση
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -1949,6 +1955,12 @@
Πρότυπο εισαγωγής JSON για συναρμολόγηση
+
+
+ assembly.import_bom.template.header.csv
+ Πρότυπο CSV εισαγωγής για μια συναρμολόγηση
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -2001,7 +2013,7 @@
Πεδίο
Προϋπόθεση
-
Τύπος Δεδομένων
+
Τύπος δεδομένων
Περιγραφή
@@ -2010,22 +2022,24 @@
quantity
Υποχρεωτικό πεδίο
Αριθμός κινητής υποδιαστολής (Float)
-
Πρέπει να παρέχεται και να περιέχει τιμή κινητής υποδιαστολής (Float) μεγαλύτερη από 0.0.
+
Πρέπει να είναι συμπληρωμένος και να περιέχει μια αριθμητική τιμή (Float) μεγαλύτερη από 0.0.
name
Προαιρετικό
-
Κείμενο (String)
-
Εάν υπάρχει, πρέπει να είναι μη κενό κείμενο.
+
Χαρακτηριστική ακολουθία (String)
+
Αν υπάρχει, πρέπει να είναι μη κενό κείμενο. Το όνομα του είδους μέσα στη συλλογή.
part
Προαιρετικό
Αντικείμενο/Πίνακας
- Εάν παρέχεται, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+ Αν πρόκειται να ανατεθεί ένα εξάρτημα, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα παρακάτω πεδία πρέπει να έχει συμπληρωθεί:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -2034,38 +2048,38 @@
part.id
Προαιρετικό
Ακέραιος αριθμός (Integer)
-
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) του εξαρτήματος στη βάση δεδομένων.
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID του εξαρτήματος στη βάση δεδομένων.
-
part.name
+
part.mpnr
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.mpnr ή part.ipn.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το part.id, part.ipn ή part.name.
-
part.mpnr
+
part.ipn
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.name ή part.ipn.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το part.id, part.mpnr ή part.name.
-
part.ipn
+
part.name
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.name ή part.mpnr.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το part.id, part.mpnr ή part.ipn.
part.description
Προαιρετικό
-
Κείμενο ή null
-
Εάν υπάρχει, πρέπει να είναι μη κενό κείμενο, ή null.
+
Χαρακτηριστική ακολουθία ή null
+
Αν υπάρχει, πρέπει να είναι μη κενό κείμενο ή null. Υπερισχύει της υπάρχουσας τιμής στο εξάρτημα.
part.manufacturer
Προαιρετικό
Αντικείμενο/Πίνακας
- Εάν υπάρχει, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+ Αν ο κατασκευαστής ενός εξαρτήματος χρειάζεται να αλλάξει ή να αναζητηθεί μονοσήμαντα μέσω της τιμής part.mpnr, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα παρακάτω πεδία να είναι συμπληρωμένα:
manufacturer.id
manufacturer.name
@@ -2076,20 +2090,20 @@
manufacturer.id
Προαιρετικό
Ακέραιος αριθμός (Integer)
-
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) του κατασκευαστή.
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID του κατασκευαστή.
manufacturer.name
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχεται η ένδειξη manufacturer.id.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το manufacturer.id.
part.category
Προαιρετικό
Αντικείμενο/Πίνακας
- Εάν υπάρχει, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+ Αν χρειάζεται να τροποποιηθεί η κατηγορία του εξαρτήματος, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα παρακάτω πεδία να είναι συμπληρωμένα:
category.id
category.name
@@ -2100,13 +2114,138 @@
category.id
Προαιρετικό
Ακέραιος αριθμός (Integer)
-
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) της κατηγορίας του εξαρτήματος.
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID της κατηγορίας εξαρτήματος.
category.name
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχεται η ένδειξη category.id.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το category.id.
Πρέπει να είναι συμπληρωμένος και να περιέχει μια αριθμητική τιμή (Float) μεγαλύτερη από 0.0.
+
+
+
name
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Το όνομα του είδους μέσα στη συλλογή.
+
+
+
Στήλες που ξεκινούν με part_
+
+ Αν χρειάζεται να αποδοθεί εξάρτημα, πρέπει να συμπληρωθεί μία από τις παρακάτω στήλες:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID του εξαρτήματος στη βάση δεδομένων.
+
+
+
part_mpnr
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσουν οι part_id, part_ipn ή part_name.
+
+
+
part_ipn
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσουν οι part_id, part_mpnr ή part_name.
+
+
+
part_name
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσουν οι part_id, part_mpnr ή part_ipn.
+
+
+
part_description
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία
+
Θα μεταφερθεί και θα αντικαταστήσει την τιμή στο εξάρτημα, αν δοθεί μια μη κενή ακολουθία.
+
+
+
Στήλες που ξεκινούν με part_manufacturer_
+
+ Αν ο κατασκευαστής του εξαρτήματος πρέπει να αλλάξει ή να αναζητηθεί μονοσήμαντα μέσω της part_mpnr, πρέπει να συμπληρωθεί μία από τις παρακάτω στήλες:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID του κατασκευαστή.
+
+
+
part_manufacturer_name
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσει το πεδίο part_manufacturer_id.
+
+
+
Στήλες που ξεκινούν με part.category_
+
+ Αν η κατηγορία του εξαρτήματος πρέπει να αλλάξει, πρέπει να συμπληρωθεί μία από τις παρακάτω στήλες:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID της κατηγορίας του εξαρτήματος.
+
+
+
part_category_name
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσει το πεδίο part_category_id.
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 8ac704001..f8d762f2f 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -12987,7 +12987,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
assembly.edit.bom.import_bom
- Import BOM
+ Import part list
@@ -13191,7 +13191,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
assembly.import_bom
- Import BOM for project
+ Import part list for assembly
@@ -13239,7 +13239,13 @@ Please note, that you can not impersonate a disabled user. If you try you will g
assembly.bom_import.type.json
- JSON for one assembly
+ JSON for an assembly
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV for an assembly
@@ -13266,6 +13272,12 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Import template JSON format for one assembly
+
+
+ assembly.import_bom.template.header.csv
+ Import template CSV format for one assembly
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -13318,31 +13330,33 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Field
Condition
-
Data type
+
Data Type
Description
quantity
-
Required
-
Floating point (Float)
-
Must be provided and contains a floating-point value (Float) greater than 0.0.
+
Mandatory
+
Floating point number (Float)
+
Must be provided and contains a floating point value (Float), which is greater than 0.0.
name
Optional
String
-
If present, it must be a non-empty string.
+
If present, it must be a non-empty string. Name of the entry within the assembly.
part
Optional
Object/Array
- If provided, it must be an object/array and at least one of the fields must be filled:
+ If a part is to be associated, it must be an object/array with at least one of the following fields filled out:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -13351,38 +13365,38 @@ Please note, that you can not impersonate a disabled user. If you try you will g
part.id
Optional
Integer
-
Integer > 0. Matches the Part-DB internal numeric ID of the component.
+
Integer > 0. Corresponds to the part database internal numeric ID of the part.
-
part.name
+
part.mpnr
Optional
String
-
Non-empty string if no part.mpnr or part.ipn is provided.
+
Non-empty string, if no part.id, part.ipn, or part.name is provided.
-
part.mpnr
+
part.ipn
Optional
String
-
Non-empty string if no part.name or part.ipn is provided.
+
Non-empty string, if no part.id, part.mpnr, or part.name is provided.
-
part.ipn
+
part.name
Optional
String
-
Non-empty string if no part.name or part.mpnr is provided.
+
Non-empty string, if no part.id, part.mpnr, or part.ipn is provided.
part.description
Optional
String or null
-
If present, it must be a non-empty string or null.
+
If provided, it must be a non-empty string or null. It will be transferred to the part, overwriting its current value.
part.manufacturer
Optional
Object/Array
- If present, it must be an object/array and at least one of the fields must be filled:
+ If the manufacturer of a part is to be adjusted or the part is to be uniquely identified using the part.mpnr, it must be an object/array with at least one of the following fields filled out:
manufacturer.id
manufacturer.name
@@ -13393,20 +13407,20 @@ Please note, that you can not impersonate a disabled user. If you try you will g
manufacturer.id
Optional
Integer
-
Integer > 0. Matches the internal numeric ID of the manufacturer.
+
Integer > 0. Corresponds to the internal numeric ID of the manufacturer.
manufacturer.name
Optional
String
-
Non-empty string if no manufacturer.id is provided.
+
Non-empty string, if no manufacturer.id is provided.
part.category
Optional
Object/Array
- If present, it must be an object/array and at least one of the fields must be filled:
+ If the category of a part is to be adjusted, it must be an object/array with at least one of the following fields filled out:
category.id
category.name
@@ -13417,13 +13431,138 @@ Please note, that you can not impersonate a disabled user. If you try you will g
category.id
Optional
Integer
-
Integer > 0. Matches the internal numeric ID of the component's category.
+
Integer > 0. Corresponds to the internal numeric ID of the part category.
Must be provided and contains a floating point value (Float), which is greater than 0.0.
+
+
+
name
+
Optional
+
String
+
Name of the entry within the assembly.
+
+
+
Columns starting with part_
+
+ If a part is to be associated, one of the following columns must be provided and filled out:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the part database internal numeric ID of the part.
+
+
+
part_mpnr
+
Optional
+
String
+
Must be provided if no part_id, part_ipn, or part_name column is filled out.
+
+
+
part_ipn
+
Optional
+
String
+
Must be provided if no part_id, part_mpnr, or part_name column is filled out.
+
+
+
part_name
+
Optional
+
String
+
Must be provided if no part_id, part_mpnr, or part_ipn column is filled out.
+
+
+
part_description
+
Optional
+
String
+
Will be transferred to the part, overwriting its current value if a non-empty string is provided.
+
+
+
Columns starting with part_manufacturer_
+
+ If the manufacturer of a part is to be adjusted or the part is to be uniquely identified using the part_mpnr, one of the following columns must be provided and filled out:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the manufacturer.
+
+
+
part_manufacturer_name
+
Optional
+
String
+
Must be provided if no part_manufacturer_id column is filled out.
+
+
+
Columns starting with part.category_
+
+ If the category of a part is to be adjusted, one of the following columns must be provided and filled out:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the part category.
+
+
+
part_category_name
+
Optional
+
String
+
Must be provided if no part_category_id column is filled out.
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index 0383f964f..ff1183f02 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -12734,6 +12734,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
JSON para un ensamblaje
+
+
+ assembly.bom_import.type.csv
+ CSV para un ensamblaje
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -12758,6 +12764,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Plantilla de importación JSON para un ensamblaje
+
+
+ assembly.import_bom.template.header.csv
+ Plantilla de importación CSV para un ensamblaje
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -12810,31 +12822,33 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Campo
Condición
-
Tipo de dato
+
Tipo de datos
Descripción
quantity
-
Obligatorio
-
Número decimal (Float)
-
Debe estar presente y contener un valor decimal (Float) mayor que 0.0.
+
Campo obligatorio
+
Número de punto flotante (Float)
+
Debe completarse y contener un valor flotante (Float) mayor a 0.0.
name
Opcional
-
Cadena de texto (String)
-
Si está presente, debe ser una cadena de texto no vacía.
+
Cadena
+
Si se especifica, debe ser una cadena no vacía. El nombre del elemento dentro del conjunto.
part
Opcional
Objeto/Array
- Si se proporciona, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+ Si se debe asignar una pieza, debe ser un objeto/array, y al menos uno de los siguientes campos debe completarse:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -12843,38 +12857,38 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
part.id
Opcional
Entero (Integer)
-
Entero (Integer) > 0. Corresponde al ID numérico interno del componente en la base de datos.
+
Entero > 0. Corresponde al ID interno numérico de la pieza en la base de datos.
-
part.name
+
part.mpnr
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona part.mpnr o part.ipn.
+
Cadena
+
Cadena no vacía si no se rellenan los campos part.id, part.ipn o part.name.
-
part.mpnr
+
part.ipn
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona part.name o part.ipn.
+
Cadena
+
Cadena no vacía si no se rellenan los campos part.id, part.mpnr o part.name.
-
part.ipn
+
part.name
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona part.name o part.mpnr.
+
Cadena
+
Cadena no vacía si no se rellenan los campos part.id, part.mpnr o part.ipn.
part.description
Opcional
-
Cadena de texto (String) o null
-
Si está presente, debe ser una cadena de texto no vacía o null.
+
Cadena o null
+
Si se especifica, debe ser una cadena no vacía o null. Este valor sobrescribirá el existente en la pieza.
part.manufacturer
Opcional
Objeto/Array
- Si está presente, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+ Si se desea cambiar el fabricante de la pieza o buscarlo de forma única utilizando el valor part.mpnr, debe ser un objeto/array y al menos uno de los siguientes campos debe completarse:
manufacturer.id
manufacturer.name
@@ -12885,20 +12899,20 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
manufacturer.id
Opcional
Entero (Integer)
-
Entero (Integer) > 0. Corresponde al ID numérico interno del fabricante.
+
Entero > 0. Corresponde al ID interno numérico del fabricante.
manufacturer.name
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona manufacturer.id.
+
Cadena
+
Cadena no vacía si no se proporciona el campo manufacturer.id.
part.category
Opcional
Objeto/Array
- Si está presente, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+ Si se desea cambiar la categoría de la pieza, debe ser un objeto/array y al menos uno de los siguientes campos debe completarse:
category.id
category.name
@@ -12909,13 +12923,138 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
category.id
Opcional
Entero (Integer)
-
Entero (Integer) > 0. Corresponde al ID numérico interno de la categoría del componente.
+
Entero > 0. Corresponde al ID interno numérico de la categoría de la pieza.
category.name
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona category.id.
+
Cadena
+
Cadena no vacía si no se proporciona el campo category.id.
Debe completarse y contener un valor flotante (Float) mayor a 0.0.
+
+
+
name
+
Opcional
+
Cadena
+
El nombre del elemento dentro del conjunto.
+
+
+
Columnas que comienzan con part_
+
+ Si se debe asignar una pieza, al menos una de las siguientes columnas debe completarse:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opcional
+
Entero (Integer)
+
Entero > 0. Corresponde al ID interno numérico de la pieza en la base de datos.
+
+
+
part_mpnr
+
Opcional
+
Cadena
+
Debe completarse si no se han rellenado las columnas part_id, part_ipn o part_name.
+
+
+
part_ipn
+
Opcional
+
Cadena
+
Debe completarse si no se han rellenado las columnas part_id, part_mpnr o part_name.
+
+
+
part_name
+
Opcional
+
Cadena
+
Debe completarse si no se han rellenado las columnas part_id, part_mpnr o part_ipn.
+
+
+
part_description
+
Opcional
+
Cadena
+
Se transferirá y reemplazará el valor de la descripción de la pieza si se proporciona una cadena no vacía.
+
+
+
Columnas que comienzan con part_manufacturer_
+
+ Si el fabricante de la pieza debe cambiarse o buscarse exclusivamente mediante part_mpnr, al menos una de las siguientes columnas debe completarse:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opcional
+
Entero (Integer)
+
Entero > 0. Corresponde al ID interno numérico del fabricante.
+
+
+
part_manufacturer_name
+
Opcional
+
Cadena
+
Debe completarse si no se ha proporcionado el campo part_manufacturer_id.
+
+
+
Columnas que comienzan con part.category_
+
+ Si se necesita modificar la categoría de la pieza, al menos una de las siguientes columnas debe completarse:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Opcional
+
Entero (Integer)
+
Entero > 0. Corresponde al ID interno numérico de la categoría de la pieza.
+
+
+
part_category_name
+
Opcional
+
Cadena
+
Debe completarse si no se ha proporcionado el campo part_category_id.
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 320121909..9cd293219 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -9487,6 +9487,12 @@ exemple de villeJSON pour un assemblage
+
+
+ assembly.bom_import.type.csv
+ CSV pour un assemblage
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -9511,6 +9517,12 @@ exemple de ville
Modèle d’importation JSON pour un assemblage
+
+
+ assembly.import_bom.template.header.csv
+ Modèle d'importation CSV pour un assemblage
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -9570,24 +9582,26 @@ exemple de ville
quantity
-
Obligatoire
-
Nombre décimal (Float)
-
Doit être présent et contenir une valeur décimale (Float) supérieure à 0,0.
+
Champ obligatoire
+
Nombre à virgule flottante (Float)
+
Doit être rempli et contenir une valeur décimale (Float) supérieure à 0.0.
name
Optionnel
-
Chaîne (String)
-
Si présent, doit être une chaîne non vide.
+
Chaîne
+
Si renseigné, doit être une chaîne non vide. Le nom de l'élément dans l'assemblage.
part
Optionnel
Objet/Tableau
- Si fourni, doit être un objet/un tableau et au moins un des champs doit être rempli :
+ Si une pièce doit être assignée, cela doit être un objet/tableau et au moins un des champs suivants doit être renseigné :
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -9596,38 +9610,38 @@ exemple de ville
part.id
Optionnel
Entier (Integer)
-
Entier (Integer) > 0. Correspond à l'ID numérique interne dans Part-DB du composant.
+
Nombre entier > 0. Correspond à l'ID interne numérique de la pièce dans la base de données.
-
part.name
+
part.mpnr
Optionnel
-
Chaîne (String)
-
Chaîne non vide si part.mpnr ou part.ipn ne sont pas fournis.
+
Chaîne
+
Chaîne non vide si part.id, part.ipn ou part.name ne sont pas renseignés.
-
part.mpnr
+
part.ipn
Optionnel
-
Chaîne (String)
-
Chaîne non vide si part.name ou part.ipn ne sont pas fournis.
+
Chaîne
+
Chaîne non vide si part.id, part.mpnr ou part.name ne sont pas renseignés.
-
part.ipn
+
part.name
Optionnel
-
Chaîne (String)
-
Chaîne non vide si part.name ou part.mpnr ne sont pas fournis.
+
Chaîne
+
Chaîne non vide si part.id, part.mpnr ou part.ipn ne sont pas renseignés.
part.description
Optionnel
Chaîne ou null
-
Si présent, doit être une chaîne non vide ou null.
+
Si renseignée, doit être une chaîne non vide ou null. Ce champ remplacera la valeur existante de la pièce.
part.manufacturer
Optionnel
Objet/Tableau
- Si présent, doit être un objet/un tableau et au moins un des champs doit être rempli :
+ Si le fabricant de la pièce doit être modifié ou recherché de manière unique à l'aide de la valeur part.mpnr, cela doit être un objet/tableau et au moins un des champs suivants doit être renseigné :
manufacturer.id
manufacturer.name
@@ -9638,20 +9652,20 @@ exemple de ville
manufacturer.id
Optionnel
Entier (Integer)
-
Entier (Integer) > 0. Correspond à l'ID numérique interne du fabricant.
+
Nombre entier > 0. Correspond à l'ID interne numérique du fabricant.
manufacturer.name
Optionnel
-
Chaîne (String)
-
Chaîne non vide si manufacturer.id n'est pas fourni.
+
Chaîne
+
Chaîne non vide si manufacturer.id n'est pas renseigné.
part.category
Optionnel
Objet/Tableau
- Si présent, doit être un objet/un tableau et au moins un des champs doit être rempli :
+ Si la catégorie de la pièce doit être modifiée, cela doit être un objet/tableau et au moins un des champs suivants doit être renseigné :
category.id
category.name
@@ -9662,13 +9676,138 @@ exemple de ville
category.id
Optionnel
Entier (Integer)
-
Entier (Integer) > 0. Correspond à l'ID numérique interne de la catégorie du composant.
+
Nombre entier > 0. Correspond à l'ID interne numérique de la catégorie de la pièce.
category.name
Optionnel
-
Chaîne (String)
-
Chaîne non vide si category.id n'est pas fourni.
+
Chaîne
+
Chaîne non vide si category.id n'est pas renseigné.
Doit être rempli et contenir une valeur décimale (Float) supérieure à 0.0.
+
+
+
name
+
Optionnel
+
Chaîne
+
Le nom de l'élément dans l'assemblage.
+
+
+
Colonnes commençant par part_
+
+ Si une pièce doit être assignée, au moins une des colonnes suivantes doit être renseignée :
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optionnel
+
Entier (Integer)
+
Nombre entier > 0. Correspond à l'ID interne numérique de la pièce dans la base de données.
+
+
+
part_mpnr
+
Optionnel
+
Chaîne
+
Doit être renseignée si les colonnes part_id, part_ipn ou part_name ne sont pas remplies.
+
+
+
part_ipn
+
Optionnel
+
Chaîne
+
Doit être renseignée si les colonnes part_id, part_mpnr ou part_name ne sont pas remplies.
+
+
+
part_name
+
Optionnel
+
Chaîne
+
Doit être renseignée si les colonnes part_id, part_mpnr ou part_ipn ne sont pas remplies.
+
+
+
part_description
+
Optionnel
+
Chaîne
+
Sera transférée et remplacera la valeur existante de la description si une chaîne non vide est fournie.
+
+
+
Colonnes commençant par part_manufacturer_
+
+ Si le fabricant de la pièce doit être modifié ou recherché uniquement via part_mpnr, au moins une des colonnes suivantes doit être renseignée :
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optionnel
+
Entier (Integer)
+
Nombre entier > 0. Correspond à l'ID interne numérique du fabricant.
+
+
+
part_manufacturer_name
+
Optionnel
+
Chaîne
+
Doit être renseignée si part_manufacturer_id n'est pas fourni.
+
+
+
Colonnes commençant par part.category_
+
+ Si la catégorie de la pièce doit être modifiée, au moins une des colonnes suivantes doit être renseignée :
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Optionnel
+
Entier (Integer)
+
Nombre entier > 0. Correspond à l'ID interne numérique de la catégorie de la pièce.
+
+
+
part_category_name
+
Optionnel
+
Chaîne
+
Doit être renseignée si part_category_id n'est pas fourni.
@@ -9679,75 +9818,75 @@ exemple de villeassembly.bom_import.template.kicad_pcbnew.exptected_columns
- Colonnes attendues :
+ Colonnes attendues:assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
- Remarque : Aucun mappage n'est effectué avec des composants spécifiques issus de la gestion des catégories.
- ]]>
+ Remarque: Aucun mappage n'est effectué avec des composants spécifiques issus de la gestion des catégories.
+ ]]>
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Champ
-
Condition
-
Type de Données
-
Description
-
-
-
-
-
Id
-
Optionnel
-
Entier
-
Champ libre. Un numéro d'identification unique pour chaque composant.
-
-
-
Designator
-
Optionnel
-
Chaîne
-
Champ libre. Une désignation de référence unique pour le composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé comme le nom de l'emplacement de l'entrée composant dans l'assemblage.
-
-
-
Package
-
Optionnel
-
Chaîne
-
Champ libre. Le boîtier ou le format du composant, par exemple, "0805" pour les résistances CMS. Non inclus dans l'entrée composant pour l'assemblage.
-
-
-
Quantity
-
Obligatoire
-
Entier
-
Le nombre de composants identiques nécessaires pour créer une instance de l'assemblage. Utilisé comme la quantité dans l'entrée composant de l'assemblage.
-
-
-
Designation
-
Obligatoire
-
Chaîne
-
La description ou la fonction du composant, par exemple, valeur de résistance "10kΩ" ou valeur de condensateur "100nF". Utilisé comme le nom dans l'entrée composant pour l'assemblage.
-
-
-
Supplier and ref
-
Optionnel
-
Chaîne
-
Champ libre. Peut contenir par exemple des informations spécifiques sur le fournisseur. Utilisé comme une note dans l'entrée composant pour l'assemblage.
Champ libre. Un numéro d'identification unique pour chaque composant.
+
+
+
Designator
+
Optionnel
+
Chaîne
+
Champ libre. Une désignation de référence unique pour le composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé comme le nom de l'emplacement de l'entrée composant dans l'assemblage.
+
+
+
Package
+
Optionnel
+
Chaîne
+
Champ libre. Le boîtier ou le format du composant, par exemple, "0805" pour les résistances CMS. Non inclus dans l'entrée composant pour l'assemblage.
+
+
+
Quantity
+
Obligatoire
+
Entier
+
Le nombre de composants identiques nécessaires pour créer une instance de l'assemblage. Utilisé comme la quantité dans l'entrée composant de l'assemblage.
+
+
+
Designation
+
Obligatoire
+
Chaîne
+
La description ou la fonction du composant, par exemple, valeur de résistance "10kΩ" ou valeur de condensateur "100nF". Utilisé comme le nom dans l'entrée composant pour l'assemblage.
+
+
+
Supplier and ref
+
Optionnel
+
Chaîne
+
Champ libre. Peut contenir par exemple des informations spécifiques sur le fournisseur. Utilisé comme une note dans l'entrée composant pour l'assemblage.
+
+
+
+ ]]>
+
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index f6e3c9446..8e39c0313 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -12736,6 +12736,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
JSON per un gruppo
+
+
+ assembly.bom_import.type.csv
+ CSV per un'assemblaggio
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -12760,6 +12766,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Template di importazione JSON per un gruppo
+
+
+ assembly.import_bom.template.header.csv
+ Modello di importazione CSV per un assemblaggio
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -12812,31 +12824,33 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Campo
Condizione
-
Tipo di dato
+
Tipo di dati
Descrizione
quantity
-
Obbligatorio
+
Campo obbligatorio
Numero decimale (Float)
-
Deve essere presente e contenere un valore decimale (Float) maggiore di 0,0.
+
Deve essere compilato e contenere un valore decimale (Float) maggiore di 0.0.
name
Opzionale
-
Stringa (String)
-
Se presente, deve essere una stringa non vuota.
+
Stringa
+
Se specificato, deve essere una stringa non vuota. Il nome del componente all'interno dell'assemblaggio.
part
Opzionale
Oggetto/Array
- Se fornito, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+ Se è necessario assegnare una parte, deve essere un Oggetto/Array e almeno uno dei seguenti campi deve essere compilato:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -12844,39 +12858,39 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
part.id
Opzionale
-
Intero (Integer)
-
Intero (Integer) > 0. Corrisponde all'ID numerico interno di Part-DB per il componente.
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico del componente nel database.
-
part.name
+
part.mpnr
Opzionale
-
Stringa (String)
-
Stringa non vuota se part.mpnr o part.ipn non sono forniti.
+
Stringa
+
Stringa non vuota se i campi part.id, part.ipn o part.name non sono compilati.
-
part.mpnr
+
part.ipn
Opzionale
-
Stringa (String)
-
Stringa non vuota se part.name o part.ipn non sono forniti.
+
Stringa
+
Stringa non vuota se i campi part.id, part.mpnr o part.name non sono compilati.
-
part.ipn
+
part.name
Opzionale
-
Stringa (String)
-
Stringa non vuota se part.name o part.mpnr non sono forniti.
+
Stringa
+
Stringa non vuota se i campi part.id, part.mpnr o part.ipn non sono compilati.
part.description
Opzionale
Stringa o null
-
Se presente, deve essere una stringa non vuota o null.
+
Se specificato, deve essere una stringa non vuota o null. Questo valore sovrascriverà quello esistente nella parte.
part.manufacturer
Opzionale
Oggetto/Array
- Se presente, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+ Se il produttore della parte deve essere cambiato o ricercato esclusivamente utilizzando il valore part.mpnr, deve essere un Oggetto/Array e almeno uno dei seguenti campi deve essere compilato:
manufacturer.id
manufacturer.name
@@ -12886,21 +12900,21 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
manufacturer.id
Opzionale
-
Intero (Integer)
-
Intero (Integer) > 0. Corrisponde all'ID numerico interno del produttore.
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico del produttore.
manufacturer.name
Opzionale
-
Stringa (String)
-
Stringa non vuota se manufacturer.id non è fornito.
+
Stringa
+
Stringa non vuota se il campo manufacturer.id non è compilato.
part.category
Opzionale
Oggetto/Array
- Se presente, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+ Se è necessario modificare la categoria della parte, deve essere un Oggetto/Array e almeno uno dei seguenti campi deve essere compilato:
category.id
category.name
@@ -12910,14 +12924,139 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
category.id
Opzionale
-
Intero (Integer)
-
Intero (Integer) > 0. Corrisponde all'ID numerico interno della categoria del componente.
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico della categoria della parte.
category.name
Opzionale
-
Stringa (String)
-
Stringa non vuota se category.id non è fornito.
+
Stringa
+
Stringa non vuota se il campo category.id non è compilato.
Deve essere compilato e contenere un valore decimale (Float) maggiore di 0.0.
+
+
+
name
+
Opzionale
+
Stringa
+
Il nome dell'elemento all'interno dell'assemblaggio.
+
+
+
Colonne che iniziano con part_
+
+ Se è necessario assegnare una parte, almeno una delle colonne seguenti deve essere compilata:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opzionale
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico del componente nel database.
+
+
+
part_mpnr
+
Opzionale
+
Stringa
+
Deve essere compilato se le colonne part_id, part_ipn o part_name non sono compilate.
+
+
+
part_ipn
+
Opzionale
+
Stringa
+
Deve essere compilato se le colonne part_id, part_mpnr o part_name non sono compilate.
+
+
+
part_name
+
Opzionale
+
Stringa
+
Deve essere compilato se le colonne part_id, part_mpnr o part_ipn non sono compilate.
+
+
+
part_description
+
Opzionale
+
Stringa
+
Sarà trasferita e sostituirà il valore esistente della descrizione se viene fornita una stringa non vuota.
+
+
+
Colonne che iniziano con part_manufacturer_
+
+ Se il produttore del componente deve essere modificato o ricercato esclusivamente tramite part_mpnr, almeno una delle seguenti colonne deve essere compilata:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opzionale
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico del produttore.
+
+
+
part_manufacturer_name
+
Opzionale
+
Stringa
+
Deve essere compilata se il campo part_manufacturer_id non è fornito.
+
+
+
Colonne che iniziano con part_category_
+
+ Se è necessario modificare la categoria della parte, almeno una delle seguenti colonne deve essere compilata:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Opzionale
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico della categoria del componente.
+
+
+
part_category_name
+
Opzionale
+
Stringa
+
Deve essere compilata se il campo part_category_id non è fornito.
@@ -12942,61 +13081,61 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Campo
-
Condizione
-
Tipo di Dati
-
Descrizione
-
-
-
-
-
Id
-
Opzionale
-
Intero
-
Campo libero. Un numero identificativo univoco per ogni componente.
-
-
-
Designator
-
Opzionale
-
Stringa
-
Campo libero. Un riferimento univoco al componente su PCB, ad esempio "R1" per il resistore 1. Utilizzato come nome della posizione nella voce componenti all'interno dell'assemblaggio.
-
-
-
Package
-
Opzionale
-
Stringa
-
Campo libero. L'involucro o il fattore di forma del componente, ad esempio "0805" per i resistori SMD. Non incluso nelle informazioni del componente nell'assemblaggio.
-
-
-
Quantity
-
Obbligatorio
-
Intero
-
Il numero di componenti identici richiesti per creare un'istanza dell'assemblaggio. Utilizzato come quantità nella voce componenti dell'assemblaggio.
-
-
-
Designation
-
Obbligatorio
-
Stringa
-
Descrizione o funzione del componente, ad esempio valore resistore "10kΩ" o valore condensatore "100nF". Utilizzato come nome nella voce componenti dell'assemblaggio.
-
-
-
Supplier and ref
-
Opzionale
-
Stringa
-
Campo libero. Può contenere, ad esempio, informazioni specifiche del fornitore. Utilizzato come nota nelle informazioni del componente nell'assemblaggio.
Campo libero. Un numero identificativo univoco per ogni componente.
+
+
+
Designator
+
Opzionale
+
Stringa
+
Campo libero. Un riferimento univoco al componente su PCB, ad esempio "R1" per il resistore 1. Utilizzato come nome della posizione nella voce componenti all'interno dell'assemblaggio.
+
+
+
Package
+
Opzionale
+
Stringa
+
Campo libero. L'involucro o il fattore di forma del componente, ad esempio "0805" per i resistori SMD. Non incluso nelle informazioni del componente nell'assemblaggio.
+
+
+
Quantity
+
Obbligatorio
+
Intero
+
Il numero di componenti identici richiesti per creare un'istanza dell'assemblaggio. Utilizzato come quantità nella voce componenti dell'assemblaggio.
+
+
+
Designation
+
Obbligatorio
+
Stringa
+
Descrizione o funzione del componente, ad esempio valore resistore "10kΩ" o valore condensatore "100nF". Utilizzato come nome nella voce componenti dell'assemblaggio.
+
+
+
Supplier and ref
+
Opzionale
+
Stringa
+
Campo libero. Può contenere, ad esempio, informazioni specifiche del fornitore. Utilizzato come nota nelle informazioni del componente nell'assemblaggio.
+
+
+ ]]>
+
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index f98e9c784..7cca59753 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -1150,6 +1150,12 @@
JSON voor assemblage
+
+
+ assembly.bom_import.type.csv
+ CSV voor een assemblage
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -1174,6 +1180,12 @@
JSON-sjabloon voor assemblage
+
+
+ assembly.import_bom.template.header.csv
+ CSV-importsjabloon voor een assemblage
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -1235,22 +1247,24 @@
quantity
Verplicht veld
Kommagetal (Float)
-
Moet opgegeven zijn en bevat een kommagetal (Float) dat groter is dan 0,0.
+
Moet worden ingevuld en een kommagetal (Float) bevatten dat groter is dan 0,0.
name
Optioneel
-
String
-
Indien aanwezig, moet het een niet-lege string zijn.
+
Tekst
+
Wanneer ingevuld, moet het een niet-lege tekst zijn. De naam van het item binnen de assemblage.
part
Optioneel
Object/Array
- Indien opgegeven, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+ Als een onderdeel moet worden toegewezen, moet dit een object/array zijn en moet ten minste één van de volgende velden worden ingevuld:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -1258,39 +1272,39 @@
part.id
Optioneel
-
Geheel getal (Integer)
-
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van het onderdeel in de Part-DB.
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van het onderdeel in de database.
-
part.name
+
part.mpnr
Optioneel
-
String
-
Niet-lege string, indien geen part.mpnr- of part.ipn-vermelding is gegeven.
+
Tekst
+
Niet-lege tekst, wanneer part.id, part.ipn of part.name niet zijn ingevuld.
-
part.mpnr
+
part.ipn
Optioneel
-
String
-
Niet-lege string, indien geen part.name- of part.ipn-vermelding is gegeven.
+
Tekst
+
Niet-lege tekst wanneer part.id, part.mpnr of part.name niet zijn ingevuld.
-
part.ipn
+
part.name
Optioneel
-
String
-
Niet-lege string, indien geen part.name- of part.mpnr-vermelding is gegeven.
+
Tekst
+
Niet-lege tekst, wanneer part.id, part.mpnr of part.ipn niet zijn ingevuld.
part.description
Optioneel
-
String of null
-
Indien aanwezig, moet het een niet-lege string zijn of null.
+
Tekst of null
+
Indien ingevuld, moet het een niet-lege tekst of null zijn. Deze waarde vervangt de bestaande waarde in het onderdeel.
part.manufacturer
Optioneel
Object/Array
- Indien aanwezig, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+ Als de fabrikant van het onderdeel moet worden gewijzigd of uniek moet worden opgezocht met de waarde part.mpnr, moet dit een object/array zijn en moet ten minste één van de volgende velden worden ingevuld:
manufacturer.id
manufacturer.name
@@ -1300,21 +1314,21 @@
manufacturer.id
Optioneel
-
Geheel getal (Integer)
-
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van de fabrikant.
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van de fabrikant.
manufacturer.name
Optioneel
-
String
-
Niet-lege string, indien geen manufacturer.id-vermelding is gegeven.
+
Tekst
+
Niet-lege tekst als manufacturer.id niet is ingevuld.
part.category
Optioneel
Object/Array
- Indien aanwezig, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+ Als de categorie van het onderdeel moet worden gewijzigd, moet dit een object/array zijn en moet ten minste één van de volgende velden worden ingevuld:
category.id
category.name
@@ -1324,14 +1338,139 @@
category.id
Optioneel
-
Geheel getal (Integer)
-
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van de categorie van het onderdeel.
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van de categorie van het onderdeel.
category.name
Optioneel
-
String
-
Niet-lege string, indien geen category.id-vermelding is gegeven.
Moet worden ingevuld en moet een kommagetal (Float) bevatten dat groter is dan 0,0.
+
+
+
name
+
Optioneel
+
Tekst
+
De naam van het item binnen de assemblage.
+
+
+
Kolommen die beginnen met part_
+
+ Als een onderdeel moet worden toegewezen, moet ten minste één van de volgende kolommen worden ingevuld:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optioneel
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van het onderdeel in de database.
+
+
+
part_mpnr
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_id, part_ipn of part_name niet zijn ingevuld.
+
+
+
part_ipn
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_id, part_mpnr of part_name niet zijn ingevuld.
+
+
+
part_name
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_id, part_mpnr of part_ipn niet zijn ingevuld.
+
+
+
part_description
+
Optioneel
+
Tekst
+
Wordt overgenomen en vervangt de bestaande waarde van de beschrijving als er een niet-lege tekst wordt opgegeven.
+
+
+
Kolommen die beginnen met part_manufacturer_
+
+ Als de fabrikant van een onderdeel moet worden gewijzigd of uniek moet worden gezocht via part_mpnr, moet ten minste één van de volgende kolommen worden ingevuld:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optioneel
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van de fabrikant.
+
+
+
part_manufacturer_name
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_manufacturer_id niet wordt opgegeven.
+
+
+
Kolommen die beginnen met part_category_
+
+ Als de categorie van een onderdeel moet worden gewijzigd, moet ten minste één van de volgende kolommen worden ingevuld:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Optioneel
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van de categorie van het onderdeel.
+
+
+
part_category_name
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_category_id niet wordt opgegeven.
@@ -1346,71 +1485,71 @@
-
- assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
-
- Opmerking: Er wordt geen mapping uitgevoerd met specifieke componenten uit de categoriebeheer.
- ]]>
-
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Opmerking: Er wordt geen mapping uitgevoerd met specifieke componenten uit de categoriebeheer.
+ ]]>
+
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Veld
-
Voorwaarde
-
Gegevenstype
-
Beschrijving
-
-
-
-
-
Id
-
Optioneel
-
Integer
-
Vrij veld. Een unieke identificatienummer voor elk onderdeel.
-
-
-
Designator
-
Optioneel
-
String
-
Vrij veld. Een unieke referentienaam voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Wordt gebruikt als positioneringsnaam in de onderdelenlijst van de assemblage.
-
-
-
Package
-
Optioneel
-
String
-
Vrij veld. De behuizing of vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden. Wordt niet opgenomen in de onderdelenlijst binnen de assemblage.
-
-
-
Quantity
-
Vereist
-
Integer
-
Het aantal identieke onderdelen dat nodig is om een assemblage-instantie te creëren. Wordt gebruikt als hoeveelheid in de onderdelenlijst binnen de assemblage.
-
-
-
Designation
-
Vereist
-
String
-
De beschrijving of functie van het onderdeel, zoals weerstandwaarde "10kΩ" of condensatorwaarde "100nF". Wordt gebruikt als de naam in de onderdelenlijst binnen de assemblage.
-
-
-
Supplier and ref
-
Optioneel
-
String
-
Vrij veld. Kan bijvoorbeeld specifieke informatie over leveranciers bevatten. Wordt gebruikt als notitie in de onderdelenlijst binnen de assemblage.
Vrij veld. Een unieke identificatienummer voor elk onderdeel.
+
+
+
Designator
+
Optioneel
+
String
+
Vrij veld. Een unieke referentienaam voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Wordt gebruikt als positioneringsnaam in de onderdelenlijst van de assemblage.
+
+
+
Package
+
Optioneel
+
String
+
Vrij veld. De behuizing of vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden. Wordt niet opgenomen in de onderdelenlijst binnen de assemblage.
+
+
+
Quantity
+
Vereist
+
Integer
+
Het aantal identieke onderdelen dat nodig is om een assemblage-instantie te creëren. Wordt gebruikt als hoeveelheid in de onderdelenlijst binnen de assemblage.
+
+
+
Designation
+
Vereist
+
String
+
De beschrijving of functie van het onderdeel, zoals weerstandwaarde "10kΩ" of condensatorwaarde "100nF". Wordt gebruikt als de naam in de onderdelenlijst binnen de assemblage.
+
+
+
Supplier and ref
+
Optioneel
+
String
+
Vrij veld. Kan bijvoorbeeld specifieke informatie over leveranciers bevatten. Wordt gebruikt als notitie in de onderdelenlijst binnen de assemblage.
+
+
+
+ ]]>
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index d1a095072..86894d998 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -12613,6 +12613,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
JSON dla zespołu
+
+
+ assembly.bom_import.type.csv
+ CSV dla zestawienia
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -12637,6 +12643,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Szablon importu JSON dla zespołu
+
+
+ assembly.import_bom.template.header.csv
+ Szablon importu CSV dla zespołu
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -12696,24 +12708,26 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
quantity
-
Wymagane
-
Typ zmiennoprzecinkowy (Float)
-
Musi być obecne i zawierać wartość zmiennoprzecinkową (Float) większą niż 0,0.
+
Pole obowiązkowe
+
Liczba zmiennoprzecinkowa (Float)
+
Musi być wypełnione i zawierać liczbę zmiennoprzecinkową (Float) większą niż 0,0.
name
Opcjonalne
-
Ciąg znaków (String)
-
Jeśli obecne, musi być niepustym ciągiem znaków.
+
Tekst
+
Jeśli określono, musi to być niepusty tekst. Nazwa elementu w ramach montażu.
part
Opcjonalne
Obiekt/Tablica
- Jeśli podane, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+ Jeśli konieczne jest przypisanie części, musi to być Obiekt/Tablica, a przynajmniej jedno z poniższych pól powinno być wypełnione:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -12721,39 +12735,39 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
part.id
Opcjonalne
-
Liczba całkowita (Integer)
-
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu numerowi ID komponentu w Part-DB.
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID części w bazie danych.
-
part.name
+
part.mpnr
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli part.mpnr ani part.ipn nie są podane.
+
Tekst
+
Niepusty tekst, jeśli pola part.id, part.ipn lub part.name nie są wypełnione.
-
part.mpnr
+
part.ipn
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli part.name ani part.ipn nie są podane.
+
Tekst
+
Niepusty tekst, jeśli pola part.id, part.mpnr lub part.name nie są wypełnione.
-
part.ipn
+
part.name
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli part.name ani part.mpnr nie są podane.
+
Tekst
+
Niepusty tekst, jeśli pola part.id, part.mpnr lub part.ipn nie są wypełnione.
part.description
Opcjonalne
-
Ciąg znaków lub null
-
Jeśli obecne, musi być niepustym ciągiem znaków lub null.
+
Tekst lub null
+
Jeśli określono, musi to być niepusty tekst lub null. Ta wartość nadpisze istniejącą wartość w części.
part.manufacturer
Opcjonalne
Obiekt/Tablica
- Jeśli obecne, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+ Jeśli producent części ma zostać zmieniony lub wyszukany unikalnie za pomocą wartości part.mpnr, musi to być Obiekt/Tablica i przynajmniej jedno z poniższych pól powinno być wypełnione:
manufacturer.id
manufacturer.name
@@ -12763,21 +12777,21 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
manufacturer.id
Opcjonalne
-
Liczba całkowita (Integer)
-
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu identyfikatorowi numerowemu producenta.
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID producenta.
manufacturer.name
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli manufacturer.id nie jest podane.
+
Tekst
+
Niepusty tekst, jeśli pole manufacturer.id nie jest wypełnione.
part.category
Opcjonalne
Obiekt/Tablica
- Jeśli obecne, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+ Jeśli konieczna jest zmiana kategorii części, musi to być Obiekt/Tablica i przynajmniej jedno z poniższych pól powinno być wypełnione:
category.id
category.name
@@ -12787,14 +12801,139 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
category.id
Opcjonalne
-
Liczba całkowita (Integer)
-
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu numerowi ID kategorii komponentu.
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID kategorii części.
category.name
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli category.id nie jest podane.
+
Tekst
+
Niepusty tekst, jeśli pole category.id nie jest wypełnione.
Musi być wypełnione i zawierać liczbę zmiennoprzecinkową (Float) większą niż 0,0.
+
+
+
name
+
Opcjonalne
+
Tekst
+
Nazwa elementu w ramach montażu.
+
+
+
Kolumny zaczynające się od part_
+
+ Jeśli konieczne jest przypisanie części, przynajmniej jedna z poniższych kolumn powinna być wypełniona:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opcjonalne
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID części w bazie danych.
+
+
+
part_mpnr
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, gdy kolumny part_id, part_ipn lub part_name nie są wypełnione.
+
+
+
part_ipn
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, gdy kolumny part_id, part_mpnr lub part_name nie są wypełnione.
+
+
+
part_name
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, gdy kolumny part_id, part_mpnr lub part_ipn nie są wypełnione.
+
+
+
part_description
+
Opcjonalne
+
Tekst
+
Zostanie przeniesione i zastąpi istniejącą wartość opisu, jeśli określono niepusty tekst.
+
+
+
Kolumny zaczynające się od part_manufacturer_
+
+ Jeśli producent części musi zostać zmieniony lub wyszukany unikalnie za pomocą part_mpnr, przynajmniej jedna z poniższych kolumn powinna być wypełniona:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opcjonalne
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID producenta.
+
+
+
part_manufacturer_name
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, jeśli part_manufacturer_id nie jest określony.
+
+
+
Kolumny zaczynające się od part_category_
+
+ Jeśli konieczna jest zmiana kategorii części, przynajmniej jedna z poniższych kolumn powinna być wypełniona:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Opcjonalne
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID kategorii części.
+
+
+
part_category_name
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, jeśli part_category_id nie jest określone.
@@ -12809,71 +12948,71 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
-
- assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
-
- Uwaga: Nie wykonano mapowania z określonymi komponentami z zarządzania kategoriami.
- ]]>
-
-
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Uwaga: Nie wykonano mapowania z określonymi komponentami z zarządzania kategoriami.
+ ]]>
+
+
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Pole
-
Warunek
-
Typ Danych
-
Opis
-
-
-
-
-
Id
-
Opcjonalne
-
Liczba całkowita
-
Pole dowolne. Unikalny numer identyfikacyjny dla każdego komponentu.
-
-
-
Designator
-
Opcjonalne
-
Tekst
-
Pole dowolne. Jednoznaczny znacznik referencyjny komponentu na PCB, np. "R1" dla rezystora 1. Używane jako nazwa pozycji w pozycji komponentu w montażu.
-
-
-
Package
-
Opcjonalne
-
Tekst
-
Pole dowolne. Obudowa lub forma komponentu, np. "0805" dla rezystorów SMD. Niewykorzystywane w pozycji komponentu w montażu.
-
-
-
Quantity
-
Wymagane
-
Liczba całkowita
-
Liczba identycznych komponentów potrzebna do utworzenia jednej instancji montażu. Używane jako ilość w pozycji komponentu w montażu.
-
-
-
Designation
-
Wymagane
-
Tekst
-
Opis lub funkcja komponentu, np. wartość rezystora "10kΩ" lub wartość kondensatora "100nF". Używane jako nazwa w pozycji komponentu w montażu.
-
-
-
Supplier and ref
-
Opcjonalne
-
Tekst
-
Pole dowolne. Może zawierać np. specyficzne informacje o dostawcy. Używane jako notatka w pozycji komponentu w montażu.
Pole dowolne. Unikalny numer identyfikacyjny dla każdego komponentu.
+
+
+
Designator
+
Opcjonalne
+
Tekst
+
Pole dowolne. Jednoznaczny znacznik referencyjny komponentu na PCB, np. "R1" dla rezystora 1. Używane jako nazwa pozycji w pozycji komponentu w montażu.
+
+
+
Package
+
Opcjonalne
+
Tekst
+
Pole dowolne. Obudowa lub forma komponentu, np. "0805" dla rezystorów SMD. Niewykorzystywane w pozycji komponentu w montażu.
+
+
+
Quantity
+
Wymagane
+
Liczba całkowita
+
Liczba identycznych komponentów potrzebna do utworzenia jednej instancji montażu. Używane jako ilość w pozycji komponentu w montażu.
+
+
+
Designation
+
Wymagane
+
Tekst
+
Opis lub funkcja komponentu, np. wartość rezystora "10kΩ" lub wartość kondensatora "100nF". Używane jako nazwa w pozycji komponentu w montażu.
+
+
+
Supplier and ref
+
Opcjonalne
+
Tekst
+
Pole dowolne. Może zawierać np. specyficzne informacje o dostawcy. Używane jako notatka w pozycji komponentu w montażu.
Поле должно быть заполнено и содержать дробное значение (Float), большее 0,0.
+
Обязательное поле
+
Число с плавающей точкой (Float)
+
Должно быть заполнено и содержать число с плавающей точкой (Float) больше 0,0.
name
-
Опциональное
-
Строка (String)
-
Если присутствует, должно быть непустой строкой.
+
Необязательное
+
Строка
+
Если указано, должно быть непустой строкой. Имя элемента внутри сборки.
part
-
Опциональное
+
Необязательное
Объект/Массив
- Если указано, должно быть объектом/массивом, и хотя бы одно из следующих полей должно быть заполнено:
+ Если необходимо назначить деталь, это должен быть объект/массив, и должно быть заполнено хотя бы одно из следующих полей:
part.id
+
part.mpnr
+
part.ipn
part.name
part.id
-
Опциональное
-
Целое число (Integer)
-
Целое число (Integer) > 0. Соответствует внутреннему цифровому идентификатору компонента в Part-DB.
-
-
-
part.name
-
Опциональное
-
Строка (String)
-
Непустая строка, если part.mpnr или part.ipn не указаны.
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому идентификатору детали в базе данных.
part.mpnr
-
Опциональное
-
Строка (String)
-
Непустая строка, если part.name или part.ipn не указаны.
+
Необязательное
+
Строка
+
Непустая строка, если part.id, part.ipn или part.name не указаны.
part.ipn
-
Опциональное
-
Строка (String)
-
Непустая строка, если part.name или part.mpnr не указаны.
+
Необязательное
+
Строка
+
Непустая строка, если part.id, part.mpnr или part.name не указаны.
+
+
+
part.name
+
Необязательное
+
Строка
+
Непустая строка, если part.id, part.mpnr или part.ipn не указаны.
part.description
-
Опциональное
+
Необязательное
Строка или null
-
Если присутствует, должно быть непустой строкой или null.
+
Если указано, должно быть непустой строкой или null. Это значение перезаписывает существующее значение в детали.
part.manufacturer
-
Опциональное
+
Необязательное
Объект/Массив
- Если присутствует, должно быть объектом/массивом, и хотя бы одно из следующих полей должно быть заполнено:
+ Если необходимо изменить производителя детали или уникально найти по значению part.mpnr, это должен быть объект/массив, и должно быть заполнено хотя бы одно из следующих полей:
manufacturer.id
manufacturer.name
@@ -12862,22 +12876,22 @@
manufacturer.id
-
Опциональное
-
Целое число (Integer)
-
Целое число (Integer) > 0. Соответствует внутреннему идентификатору производителя.
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому идентификатору производителя.
manufacturer.name
-
Опциональное
-
Строка (String)
+
Необязательное
+
Строка
Непустая строка, если manufacturer.id не указано.
part.category
-
Опциональное
+
Необязательное
Объект/Массив
- Если присутствует, должно быть объектом/массивом, и хотя бы одно из следующих полей должно быть заполнено:
+ Если необходимо изменить категорию детали, это должен быть объект/массив, и должно быть заполнено хотя бы одно из следующих полей:
category.id
category.name
@@ -12886,14 +12900,14 @@
category.id
-
Опциональное
-
Целое число (Integer)
-
Целое число (Integer) > 0. Соответствует внутреннему цифровому идентификатору категории компонента.
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому идентификатору категории детали.
Должно быть заполнено и содержать число с плавающей точкой (Float), больше 0,0.
+
+
+
name
+
Необязательное
+
Строка
+
Название элемента в рамках сборки.
+
+
+
Столбцы, начинающиеся с part_
+
+ Если необходимо назначить деталь, то хотя бы один из следующих столбцов должен быть заполнен:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому ID детали в базе данных.
+
+
+
part_mpnr
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_id, part_ipn или part_name не указаны.
+
+
+
part_ipn
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_id, part_mpnr или part_name не указаны.
+
+
+
part_name
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_id, part_mpnr или part_ipn не указаны.
+
+
+
part_description
+
Необязательное
+
Строка
+
Если указано, заменяет существующее значение описания деталя не пустой строкой.
+
+
+
Столбцы, начинающиеся с part_manufacturer_
+
+ Если необходимо указать производителя детали или найти деталь уникально по part_mpnr, должно быть заполнено хотя бы одно из следующих полей:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому ID производителя.
+
+
+
part_manufacturer_name
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_manufacturer_id не указано.
+
+
+
Столбцы, начинающиеся с part_category_
+
+ Если необходимо изменить категорию детали, должно быть заполнено хотя бы одно из следующих полей:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому ID категории детали.
+
+
+
part_category_name
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_category_id не указано.
+
+
+
+ ]]>
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
@@ -12909,71 +13048,71 @@
-
- assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
-
- Примечание: Сопоставление с конкретными компонентами из управления категориями не выполняется.
- ]]>
-
-
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Примечание: Сопоставление с конкретными компонентами из управления категориями не выполняется.
+ ]]>
+
+
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Поле
-
Условие
-
Тип данных
-
Описание
-
-
-
-
-
Id
-
Опционально
-
Целое
-
Свободное поле. Уникальный идентификационный номер для каждого компонента.
-
-
-
Package
-
Designator
-
Строка
-
Свободное поле. Уникальная ссылочная метка компонента на печатной плате, например, "R1" для резистора 1. Используется как наименование позиции в компоненте сборки.
-
-
-
Package
-
Опционально
-
Строка
-
Свободное поле. Тип корпуса или форм-фактор компонента, например, "0805" для SMD-резисторов. Не включается в информацию о компоненте сборки.
-
-
-
Quantity
-
Обязательно
-
Целое
-
Количество одинаковых компонентов, необходимых для создания одной версии сборки. Используется как количество в информации о компоненте сборки.
-
-
-
Designation
-
Обязательно
-
Строка
-
Описание или функция компонента, например, значение резистора "10kΩ" или значение конденсатора "100nF". Используется как наименование в информации о компоненте сборки.
-
-
-
Supplier and ref
-
Опционально
-
Строка
-
Свободное поле. Может содержать, например, информацию о конкретных поставщиках. Используется как примечание в информации о компоненте сборки.
Свободное поле. Уникальный идентификационный номер для каждого компонента.
+
+
+
Package
+
Designator
+
Строка
+
Свободное поле. Уникальная ссылочная метка компонента на печатной плате, например, "R1" для резистора 1. Используется как наименование позиции в компоненте сборки.
+
+
+
Package
+
Опционально
+
Строка
+
Свободное поле. Тип корпуса или форм-фактор компонента, например, "0805" для SMD-резисторов. Не включается в информацию о компоненте сборки.
+
+
+
Quantity
+
Обязательно
+
Целое
+
Количество одинаковых компонентов, необходимых для создания одной версии сборки. Используется как количество в информации о компоненте сборки.
+
+
+
Designation
+
Обязательно
+
Строка
+
Описание или функция компонента, например, значение резистора "10kΩ" или значение конденсатора "100nF". Используется как наименование в информации о компоненте сборки.
+
+
+
Supplier and ref
+
Опционально
+
Строка
+
Свободное поле. Может содержать, например, информацию о конкретных поставщиках. Используется как примечание в информации о компоненте сборки.
+ {{ form_widget(form.part) }}
{{ form_errors(form.part) }}
-
- {% if form.vars.value is not null and form.vars.value.project is not null %}
- {% set hasAssembly = false %}
- {% if is_granted("@assemblies.read") or has_assembly(form.vars.value.project.bomEntries.toArray) %}
-
+ {{ form_row(form.part) }}
{{ form_errors(form.part) }}
+
+ {% if form.vars.value is not null and form.vars.value.assembly is not null %}
+ {% if is_granted("@projects.read") or has_project(form.vars.value.assembly.bomEntries.toArray) %}
+
{% set lots = build_request.partLotsForBOMEntry(bom_entry) %}
- {% set assemblyBomEntriesWithoutPart = build_request.assemblyBomEntriesWithoutPart(bom_entry) %}
- {% set assemblyBomEntriesWithPartNoStock = build_request.assemblyBomEntriesWithPartNoStock(bom_entry) %}
{% if lots is not null %}
- {% set previousLabel = null %}
-
{% for lot in lots %}
{# @var lot \App\Entity\Parts\PartLot #}
-
- {% set label = '' %}
- {% if form["lot_"~lot.id].vars.label is defined and form["lot_"~lot.id].vars.label is not empty %}
- {% set label = form["lot_"~lot.id].vars.label %}
- {% endif %}
-
- {% if label != '' and (previousLabel is null or label != previousLabel) %}
-
{% endfor %}
{% endif %}
- {% if assemblyBomEntriesWithoutPart is not null %}
- {% for bomEntryWithoutPart in assemblyBomEntriesWithoutPart %}
-
-
-
-
- / {% trans %}project.builds.no_stock{% endtrans %}
-
-
- {% endfor %}
- {% endif %}
- {% if assemblyBomEntriesWithPartNoStock is not null %}
- {% for bomEntryWithPartNoStock in assemblyBomEntriesWithPartNoStock %}
-
-
-
-
-
- / {% trans %}project.builds.no_stock{% endtrans %}
-
{% endblock %}
\ No newline at end of file
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index f6e53eddd..72331a795 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -11046,6 +11046,18 @@ Element 3
Typ
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11064,6 +11076,319 @@ Element 3
Výběrem této možnosti odstraníte všechny existující položky BOM v projektu a přepíšete je importovaným souborem BOM!
+
+
+ project.import_bom.template.header.json
+ Šablona importu JSON
+
+
+
+
+ project.import_bom.template.header.csv
+ Šablona importu CSV
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ Šablona importu CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Název komponenty v projektu
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Jedinečné číslo produktu u výrobce
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ Jedinečné IPN součásti
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Jedinečný název součásti
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Jedinečný název výrobce
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Pole
+
Podmínka
+
Datový typ
+
Popis
+
+
+
+
+
quantity
+
Povinné
+
Desetinné číslo (Float)
+
Musí být zadáno a obsahovat desetinnou hodnotu (Float), která je větší než 0.0.
+
+
+
name
+
Volitelné
+
Řetězec (String)
+
Pokud je přítomen, musí být neprázdný řetězec. Název položky v kusovníku.
+
+
+
part
+
Volitelné
+
Objekt/Array
+
+ Pokud je potřeba přiřadit součástku, musí to být objekt/pole a musí být vyplněno alespoň jedno z následujících polí:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID součástky v Part-DB.
+
+
+
part.mpnr
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno part.id, part.ipn nebo part.name.
+
+
+
part.ipn
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno part.id, part.mpnr nebo part.name.
+
+
+
part.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno part.id, part.mpnr nebo part.ipn.
+
+
+
part.manufacturer
+
Volitelné
+
Objekt/Array
+
+ Pokud má být upraven výrobce součástky nebo pokud má být součástka nalezena jednoznačně na základě part.mpnr, musí to být objekt/pole a musí být vyplněno alespoň jedno z následujících polí:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID výrobce.
+
+
+
manufacturer.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno manufacturer.id.
Musí být uvedeno a obsahovat hodnotu desetinného čísla (Float) větší než 0.0.
+
+
+
name
+
Optional
+
String
+
Název položky v kusovníku.
+
+
+
Sloupce začínající part_
+
+ Pokud má být přiřazena součástka, musí být uveden a vyplněn alespoň jeden z následujících sloupců:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID součástky v Part-DB.
+
+
+
part_mpnr
+
Volitelné
+
Řetězec (String)
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_ipn nebo part_name.
+
+
+
part_ipn
+
Volitelné
+
Řetězec (String)
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_mpnr nebo part_name.
+
+
+
part_name
+
Volitelné
+
Řetězec (String)
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_mpnr nebo part_ipn.
+
+
+
Sloupce začínající part_manufacturer_
+
+ Pokud má být upraven výrobce dílu nebo má být díl jednoznačně identifikován podle hodnoty part_mpnr, musí být uveden a vyplněn alespoň jeden z následujících sloupců:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID výrobce.
+
+
+
part_manufacturer_name
+
Volitelné
+
Řetězec (String)
+
Musí být uvedeno, pokud není vyplněn sloupec part_manufacturer_id.
Volný údaj. Jedinečné identifikační číslo pro každou součástku.
+
+
+
Designator
+
Volitelné
+
Řetězec (String)
+
Volný údaj. Jedinečný referenční označovač součástky na desce plošných spojů, např. „R1“ pro odpor 1. Je převzat do osazovacího názvu záznamu součástky.
+
+
+
Package
+
Volitelné
+
Řetězec (String)
+
Volný údaj. Pouzdro nebo tvar součástky, např. „0805“ pro SMD odpory. Pro záznam součástky není převzato.
+
+
+
Quantity
+
Povinné pole
+
Celé číslo (Integer)
+
Počet identických komponent, které jsou potřebné k vytvoření instance. Je převzat jako počet položky komponenty.
+
+
+
Designation
+
Povinné pole
+
Řetězec (String)
+
Popis nebo funkce součástky, např. hodnota odporu „10kΩ“ nebo kapacita kondenzátoru „100nF“. Je převzato do názvu záznamu součástky.
+
+
+
Supplier and ref
+
Volitelné
+
Řetězec (String)
+
Volný údaj. Může obsahovat např. distribuční specifickou hodnotu. Je převzato jako poznámka ke záznamu součástky.
Skal være angivet og skal indeholde en decimaltalsværdi (Float), der er større end 0.0.
+
+
+
name
+
Valgfrit
+
String
+
Hvis til stede, skal det være en ikke-tom streng. Navnet på posten i stykliste.
+
+
+
part
+
Valgfrit
+
Objekt/Array
+
+ Hvis en komponent skal knyttes, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Valgfrit
+
Heltal (Integer)
+
Heltal (Integer) > 0. Svarer til det interne numeriske ID for komponenten i Part-DB.
+
+
+
part.mpnr
+
Valgfrit
+
String
+
En ikke-tom streng, hvis hverken part.id, part.ipn eller part.name er angivet.
+
+
+
part.ipn
+
Valgfrit
+
String
+
En ikke-tom streng, hvis hverken part.id, part.mpnr eller part.name er angivet.
+
+
+
part.name
+
Valgfrit
+
String
+
En ikke-tom streng, hvis hverken part.id, part.mpnr eller part.ipn er angivet.
+
+
+
part.manufacturer
+
Valgfrit
+
Objekt/Array
+
+ Hvis en komponents producent skal justeres, eller hvis komponenten skal findes entydigt via part.mpnr, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Valgfrit
+
Heltal (Integer)
+
Heltal (Integer) > 0. Svarer til producentens interne numeriske ID.
+
+
+
manufacturer.name
+
Valgfrit
+
String
+
En ikke-tom streng, hvis manufacturer.id ikke er angivet.
Skal være angivet og indeholde en decimaltalsværdi (Float), som er større end 0,0.
+
+
+
name
+
Optional
+
String
+
Hvis tilgængelig, skal det være en ikke-tom streng. Navnet på elementet inden for stykliste.
+
+
+
Kolonner, der begynder med part_
+
+ Hvis en komponent skal tildeles, skal mindst én af følgende kolonner være angivet og udfyldt:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Valgfri
+
Heltal (Integer)
+
Heltal (Integer) > 0. Svarer til den interne numeriske ID for komponenten i Part-DB.
+
+
+
part_mpnr
+
Valgfri
+
Streng (String)
+
Skal angives, hvis kolonnerne part_id, part_ipn eller part_name ikke er udfyldt.
+
+
+
part_ipn
+
Valgfri
+
Streng (String)
+
Skal angives, hvis kolonnerne part_id, part_mpnr eller part_name ikke er udfyldt.
+
+
+
part_name
+
Valgfri
+
Streng (String)
+
Skal angives, hvis kolonnerne part_id, part_mpnr eller part_ipn ikke er udfyldt.
+
+
+
Kolonner, der begynder med part_manufacturer_
+
+ Hvis komponentens producent skal ændres eller identificeres entydigt baseret på part_mpnr, skal mindst én af følgende kolonner være angivet og udfyldt:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Valgfri
+
Heltal (Integer)
+
Heltal (Integer) > 0. Svarer til den interne numeriske ID for producenten.
+
+
+
part_manufacturer_name
+
Valgfri
+
Streng (String)
+
Skal angives, hvis kolonnen part_manufacturer_id ikke er udfyldt.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Forventede kolonner:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Bemærk: Der sker ingen tilknytning til specifikke komponenter fra kategoristyringen.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Felt
+
Betingelse
+
Datatype
+
Beskrivelse
+
+
+
+
+
Id
+
Valgfrit
+
Heltal (Integer)
+
Fri opgave. Et entydigt identifikationsnummer for hver komponent.
+
+
+
Designator
+
Valgfrit
+
Streng (String)
+
Fri opgave. En entydig referencemarkering for komponenten på PCB'et, fx "R1" for modstand 1. Bliver overført til monteringsnavnet på komponentindgangen.
+
+
+
Package
+
Valgfrit
+
Streng (String)
+
Fri opgave. Komponentens pakning eller form, fx "0805" for SMD-modstande. Bliver ikke overført til komponentindgangen.
+
+
+
Quantity
+
Obligatorisk felt
+
Heltal (Integer)
+
Antallet af identiske komponenter, der kræves for at oprette en instans. Overtages som antallet af komponentposter.
+
+
+
Designation
+
Obligatorisk felt
+
Streng (String)
+
Beskrivelse eller funktion af komponenten, fx modstandsværdi "10kΩ" eller kondensatorværdi "100nF". Bliver overført til komponentindgangens navn.
+
+
+
Supplier and ref
+
Valgfrit
+
Streng (String)
+
Fri opgave. Kan eksempelvis indeholde en distributørspecifik værdi. Bliver overført som en note til komponentindgangen.
+
+
+
+ ]]>
+
+
+ project.bom_import.clear_existing_bom.help
@@ -12777,13 +13102,13 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
-
+ assembly.bom_import.template.csv.exptected_columnsMulige kolonner:
-
+ assembly.bom_import.template.csv.table
@@ -12808,7 +13133,7 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
name
Valgfrit
Streng
-
Navnet på posten inden for samlingen.
+
Navnet på posten inden for stykliste.
Kolonner, der starter med part_
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index c25fd7e77..a7137b26a 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -11060,6 +11060,18 @@ Element 1 -> Element 1.2
Typ
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11078,6 +11090,319 @@ Element 1 -> Element 1.2
Wenn diese Option ausgewählt ist, werden alle bereits im Projekt existierenden BOM Einträge gelöscht und mit den importierten BOM Daten überschrieben.
+
+
+ project.import_bom.template.header.json
+ Import-Vorlage JSON
+
+
+
+
+ project.import_bom.template.header.csv
+ Import-Vorlage CSV
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ Import-Vorlage CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Name des Bauteils im Projekt
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Eindeutige Produktnummer innerhalb des Herstellers
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ Eideutige IPN des Bauteils
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Eindeutiger Name des Bauteils
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Eindeutiger Name des Herstellers
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
quantity
+
Pflichtfeld
+
Gleitkommazahl (Float)
+
Muss gegeben sein und enthält einen Gleitkommawert (Float), der größer als 0.0 ist.
+
+
+
name
+
Optional
+
String
+
Falls vorhanden, muss es ein nicht-leerer String sein. Name des Eintrags innerhalb der Stückliste.
+
+
+
part
+
Optional
+
Objekt/Array
+
+ Falls ein Bauteil zugeordnet werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
+
+
+
part.mpnr
+
Optional
+
String
+
Nicht-leerer String, falls keine part.id-, part-ipn- bzw. part.name-Angabe gegeben ist.
+
+
+
part.ipn
+
Optional
+
String
+
Nicht-leerer String, falls keine part.id-, part.mpnr bzw. part.name-Angabe gegeben ist.
+
+
+
part.name
+
Optional
+
String
+
Nicht-leerer String, falls keine part.id-, part.mpnr- bzw. part.ipn-Angabe gegeben ist.
+
+
+
part.manufacturer
+
Optional
+
Objekt/Array
+
+ Falls der Hersteller eines Bauteils mit angepasst werden oder das Bauteil anhand der part.mpnr-Angabe eindeutig gesucht werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID des Herstellers.
+
+
+
manufacturer.name
+
Optional
+
String
+
Nicht-leerer String, falls keine manufacturer.id-Angabe gegeben ist.
Muss gegeben sein und enthält einen Gleitkommawert (Float), der größer als 0.0 ist.
+
+
+
name
+
Optional
+
String
+
Name des Eintrags innerhalb der Stückliste.
+
+
+
Spalten beginnend mit part_
+
+ Falls ein Bauteil zugeordnet werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
+
+
+
part_mpnr
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_ipn- bzw. part_name-Spalte ausgefüllt gegeben ist.
+
+
+
part_ipn
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_mpnr- bzw. part_name-Spalte ausgefüllt gegeben ist.
+
+
+
part_name
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_mpnr- bzw. part_ipn-Spalte ausgefüllt gegeben ist.
+
+
+
Spalten beginnend mit part_manufacturer_
+
+ Falls der Hersteller eines Bauteils mit angepasst werden oder das Bauteil anhand der part_mpnr-Angabe eindeutig gesucht werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID des Herstellers.
+
+
+
part_manufacturer_name
+
Optional
+
String
+
Anzugeben, falls keine part_manufacturer_id-Spalte ausgefüllt gegeben ist.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Erwartete Spalten:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Hinweis: Es findet keine Zuordnung zu konkreten Bauteilen aus der Kategorie-Verwaltung statt.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
Id
+
Optional
+
Ganzzahl (Integer)
+
Offene Angabe. Eine eindeutige Identifikationsnummer für jedes Bauteil.
+
+
+
Designator
+
Optional
+
String
+
Offene Angabe. Ein eindeutiger Referenzbezeichner des Bauteils auf der Leiterplatte, z.B. „R1“ für Widerstand 1. Wird in den Bestückungsnamen des Bauteil-Eintrags übernommen.
+
+
+
Package
+
Optional
+
String
+
Offene Angabe. Das Gehäuse oder die Bauform des Bauteils, z.B. „0805“ für SMD-Widerstände. Wird für ein Bauteil-Eintrag nicht übernommen.
+
+
+
Quantity
+
Pflichtfeld
+
Ganzzahl (Integer)
+
Anzahl der identischen Bauteile, die benötigt werden, um eine Instanz zu erstellen. Wird als Anzahl des Bauteil-Eintrags übernommen.
+
+
+
Designation
+
Pflichtfeld
+
String
+
Beschreibung oder Funktion des Bauteils, z.B. Widerstandswert „10kΩ“ oder Kondensatorwert „100nF“. Wird in den Namen des Bauteil-Eintrags übernommen.
+
+
+
Supplier and ref
+
Optional
+
String
+
Offene Angabe. Kann z.B. Distributor spezifischen Wert enthalten. Wird als Notiz zum Bauteil-Eintrag übernommen.
+
+
+
+ ]]>
+
+
+ project.bom_import.flash.invalid_file
@@ -13332,7 +13657,7 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
name
Optional
String
-
Falls vorhanden, muss es ein nicht-leerer String sein. Name des Eintrags innerhalb der Baugruppe.
+
Falls vorhanden, muss es ein nicht-leerer String sein. Name des Eintrags innerhalb der Stückliste.
part
@@ -13432,13 +13757,13 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
-
+ assembly.bom_import.template.csv.exptected_columnsMögliche Spalten:
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index a6dda3d47..3707e55dd 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -2116,13 +2116,13 @@
-
+ assembly.bom_import.template.csv.exptected_columnsΔυνατές στήλες:
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 763b6aff0..aa82784d9 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -11061,6 +11061,18 @@ Element 1 -> Element 1.2Type
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11073,6 +11085,319 @@ Element 1 -> Element 1.2
Clear existing BOM entries before importing
+
+
+ project.import_bom.template.header.json
+ JSON Import Template
+
+
+
+
+ project.import_bom.template.header.csv
+ CSV Import Template
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ CSV Import Template (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Component name in the project
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Unique product number within the manufacturer
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ Unique IPN of the component
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Unique name of the component
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Unique name of the manufacturer
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Field
+
Condition
+
Data Type
+
Description
+
+
+
+
+
quantity
+
Required
+
Decimal (Float)
+
Must be provided and contains a decimal value (Float) greater than 0.0.
+
+
+
name
+
Optional
+
String
+
If present, it must be a non-empty string. The name of the entry within the bill of materials.
+
+
+
part
+
Optional
+
Object/Array
+
+ If a component is to be assigned, it must be an object/array, and at least one of the following fields must be filled in:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the component in the Part-DB.
+
+
+
part.mpnr
+
Optional
+
String
+
A non-empty string if no part.id, part.ipn, or part.name is provided.
+
+
+
part.ipn
+
Optional
+
String
+
A non-empty string if no part.id, part.mpnr, or part.name is provided.
+
+
+
part.name
+
Optional
+
String
+
A non-empty string if no part.id, part.mpnr, or part.ipn is provided.
+
+
+
part.manufacturer
+
Optional
+
Object/Array
+
+ If a component's manufacturer is to be adjusted, or the component is to be unambiguously identified based on part.mpnr, it must be an object/array, and at least one of the following fields must be filled in:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the manufacturer.
+
+
+
manufacturer.name
+
Optional
+
String
+
A non-empty string if no manufacturer.id is provided.
Must be provided and contain a floating-point value (Float) greater than 0.0.
+
+
+
name
+
Optional
+
String
+
If available, it must be a non-empty string. The name of the entry within the bill of materials.
+
+
+
Columns starting with part_
+
+ If a component is to be assigned, at least one of the following columns must be provided and filled in:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the component in the Part-DB.
+
+
+
part_mpnr
+
Optional
+
String
+
Must be provided if the part_id, part_ipn, or part_name columns are not filled in.
+
+
+
part_ipn
+
Optional
+
String
+
Must be provided if the part_id, part_mpnr, or part_name columns are not filled in.
+
+
+
part_name
+
Optional
+
String
+
Must be provided if the part_id, part_mpnr, or part_ipn columns are not filled in.
+
+
+
Columns starting with part_manufacturer_
+
+ If the manufacturer of a component is to be adjusted or if the component is to be uniquely identified based on the part_mpnr, at least one of the following columns must be provided and filled in:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the manufacturer.
+
+
+
part_manufacturer_name
+
Optional
+
String
+
Must be provided if the part_manufacturer_id column is not filled in.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Expected columns:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Note: No assignment to specific components from the category management is performed.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Field
+
Condition
+
Data type
+
Description
+
+
+
+
+
Id
+
Optional
+
Integer
+
Free entry. A unique identification number for each component.
+
+
+
Designator
+
Optional
+
String
+
Free entry. A unique reference identifier of the component on the PCB, e.g., "R1" for resistor 1. It is adopted into the assembly name of the component entry.
+
+
+
Package
+
Optional
+
String
+
Free entry. The housing or package type of the component, e.g., "0805" for SMD resistors. It is not adopted into the component entry.
+
+
+
Quantity
+
Mandatory
+
Integer
+
The number of identical components required to create an instance. It is adopted as the quantity of the entry.
+
+
+
Designation
+
Mandatory
+
String
+
Description or function of the component, e.g., resistor value "10kΩ" or capacitor value "100nF". It is adopted into the name of the component entry.
+
+
+
Supplier and ref
+
Optional
+
String
+
Free entry. Can contain a distributor-specific value, for example. It is adopted as a note to the component entry.
+
+
+
+ ]]>
+
+
+ project.bom_import.clear_existing_bom.help
@@ -13433,13 +13758,13 @@ Please note, that you can not impersonate a disabled user. If you try you will g
-
+ assembly.bom_import.template.csv.exptected_columnsPossible columns:
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index 0b17cb8a6..1d4f12865 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -11076,6 +11076,18 @@ Elemento 3Tipo
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11088,6 +11100,319 @@ Elemento 3
Eliminar entradas BOM existentes antes de importar
+
+
+ project.import_bom.template.header.json
+ Plantilla de importación JSON
+
+
+
+
+ project.import_bom.template.header.csv
+ Plantilla de importación CSV
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ Plantilla de importación CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Nombre del componente en el proyecto
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Número de producto único del fabricante
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ IPN único del componente
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Nombre único del componente
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Nombre único del fabricante
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Campo
+
Condición
+
Tipo de Datos
+
Descripción
+
+
+
+
+
quantity
+
Requerido
+
Decimal (Float)
+
Debe ser proporcionado y contener un valor decimal (Float) mayor que 0.0.
+
+
+
name
+
Opcional
+
Cadena (String)
+
Si está presente, debe ser una cadena no vacía. El nombre del elemento dentro de la lista de materiales.
+
+
+
part
+
Opcional
+
Objeto/Array
+
+ Si se debe asignar un componente, debe ser un objeto/array, y al menos uno de los siguientes campos debe estar cumplimentado:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno del componente en la base de datos de componentes (Part-DB).
+
+
+
part.mpnr
+
Opcional
+
Cadena (String)
+
Una cadena no vacía si no se proporciona part.id, part.ipn o part.name.
+
+
+
part.ipn
+
Opcional
+
Cadena (String)
+
Una cadena no vacía si no se proporciona part.id, part.mpnr o part.name.
+
+
+
part.name
+
Opcional
+
Cadena (String)
+
Una cadena no vacía si no se proporciona part.id, part.mpnr o part.ipn.
+
+
+
part.manufacturer
+
Opcional
+
Objeto/Array
+
+ Si se debe ajustar el fabricante de un componente, o si el componente debe identificarse de manera unívoca en base a part.mpnr, debe ser un objeto/array, y al menos uno de los siguientes campos debe estar cumplimentado:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno del fabricante.
+
+
+
manufacturer.name
+
Opcional
+
Cadena (String)
+
Una cadena no vacía si no se proporciona manufacturer.id.
Debe proporcionarse y contener un valor decimal (Float) mayor que 0.0.
+
+
+
name
+
Optional
+
String
+
Si está disponible, debe ser una cadena no vacía. El nombre del elemento dentro de la lista de materiales.
+
+
+
Columnas que comienzan con part_
+
+ Si se va a asignar un componente, al menos una de las siguientes columnas debe proporcionarse y completarse:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opcional
+
Entero
+
Entero > 0. Corresponde al ID numérico interno del componente en la base de datos de partes (Part-DB).
+
+
+
part_mpnr
+
Opcional
+
Cadena (String)
+
Debe proporcionarse si las columnas part_id, part_ipn o part_name no están completas.
+
+
+
part_ipn
+
Opcional
+
Cadena (String)
+
Debe proporcionarse si las columnas part_id, part_mpnr o part_name no están completas.
+
+
+
part_name
+
Opcional
+
Cadena (String)
+
Debe proporcionarse si las columnas part_id, part_mpnr o part_ipn no están completas.
+
+
+
Columnas que comienzan con part_manufacturer_
+
+ Si el fabricante de un componente debe ajustarse o si el componente debe identificarse de forma única según el valor part_mpnr, al menos una de las siguientes columnas debe proporcionarse y completarse:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opcional
+
Entero
+
Entero > 0. Corresponde al ID numérico interno del fabricante.
+
+
+
part_manufacturer_name
+
Opcional
+
Cadena (String)
+
Debe proporcionarse si la columna part_manufacturer_id no está completa.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Columnas esperadas:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Nota: No se realiza ninguna asignación a componentes específicos desde la gestión de categorías.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Campo
+
Condición
+
Tipo de dato
+
Descripción
+
+
+
+
+
Id
+
Opcional
+
Entero
+
Entrada libre. Un número de identificación único para cada componente.
+
+
+
Designator
+
Opcional
+
Cadena (String)
+
Entrada libre. Un identificador de referencia único del componente en el PCB, por ejemplo, "R1" para la resistencia 1. Se adopta en el nombre de ensamblaje del registro del componente.
+
+
+
Package
+
Opcional
+
Cadena (String)
+
Entrada libre. El encapsulado o tipo de la carcasa del componente, por ejemplo, "0805" para resistencias SMD. No se adopta en el registro del componente.
+
+
+
Quantity
+
Obligatorio
+
Entero
+
El número de componentes idénticos necesarios para crear una instancia. Se toma como la cantidad de la entrada del componente.
+
+
+
Designation
+
Obligatorio
+
Cadena (String)
+
Descripción o función del componente, por ejemplo, valor de resistencia "10kΩ" o valor de condensador "100nF". Se adopta en el nombre del registro del componente.
+
+
+
Supplier and ref
+
Opcional
+
Cadena (String)
+
Entrada libre. Puede contener, por ejemplo, un valor específico del distribuidor. Se adopta como una nota en el registro del componente.
+
+
+
+ ]]>
+
+
+ project.bom_import.clear_existing_bom.help
@@ -12925,13 +13250,13 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
-
+ assembly.bom_import.template.csv.exptected_columnsColumnas posibles:
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 234dee6ef..67480c6a7 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -9481,6 +9481,18 @@ exemple de villeCSV pour un assemblage
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -9678,13 +9690,13 @@ exemple de ville
-
+ assembly.bom_import.template.csv.exptected_columnsColonnes possibles :
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index 57654f44e..1f56dfc93 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -11078,6 +11078,18 @@ Element 3Tipo
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11090,6 +11102,319 @@ Element 3
Cancellare le voci della BOM (lista dei materiali) esistenti prima dell'importazione
+
+
+ project.import_bom.template.header.json
+ Modello di importazione JSON
+
+
+
+
+ project.import_bom.template.header.csv
+ Modello di importazione CSV
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ Modello di importazione CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Nome del componente nel progetto
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Codice prodotto unico del produttore
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ IPN unico del componente
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Nome unico del componente
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Nome unico del produttore
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Campo
+
Condizione
+
Tipo di Dati
+
Descrizione
+
+
+
+
+
quantity
+
Obbligatorio
+
Decimale (Float)
+
Deve essere fornito e contenere un valore decimale (Float) maggiore di 0.0.
+
+
+
name
+
Opzionale
+
Stringa (String)
+
Se presente, deve essere una stringa non vuota. Il nome dell'elemento all'interno della distinta materiali.
+
+
+
part
+
Opzionale
+
Oggetto/Array
+
+ Se un componente deve essere assegnato, deve essere un oggetto/array e almeno uno dei seguenti campi deve essere compilato:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno del componente nel database delle parti (Part-DB).
+
+
+
part.mpnr
+
Opzionale
+
Stringa (String)
+
Una stringa non vuota se non sono forniti part.id, part.ipn o part.name.
+
+
+
part.ipn
+
Opzionale
+
Stringa (String)
+
Una stringa non vuota se non sono forniti part.id, part.mpnr o part.name.
+
+
+
part.name
+
Opzionale
+
Stringa (String)
+
Una stringa non vuota se non sono forniti part.id, part.mpnr o part.ipn.
+
+
+
part.manufacturer
+
Opzionale
+
Oggetto/Array
+
+ Se il produttore di un componente deve essere modificato o se è necessario identificare univocamente il componente basandosi su part.mpnr, deve essere un oggetto/array e almeno uno dei seguenti campi deve essere compilato:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno del produttore.
+
+
+
manufacturer.name
+
Opzionale
+
Stringa (String)
+
Una stringa non vuota se non è fornito manufacturer.id.
Deve essere fornita e contenere un valore decimale (Float) maggiore di 0.0.
+
+
+
name
+
Optional
+
String
+
Se disponibile, deve essere una stringa non vuota. Il nome della voce all'interno della distinta base.
+
+
+
Colonne che iniziano con part_
+
+ Se un componente deve essere assegnato, almeno una delle seguenti colonne deve essere fornita e compilata:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opzionale
+
Intero (Integer)
+
Intero > 0. Corrisponde all'ID numerico interno del componente nel database delle parti (Part-DB).
+
+
+
part_mpnr
+
Opzionale
+
Stringa (String)
+
Deve essere fornita se le colonne part_id, part_ipn o part_name non sono compilate.
+
+
+
part_ipn
+
Opzionale
+
Stringa (String)
+
Deve essere fornita se le colonne part_id, part_mpnr o part_name non sono compilate.
+
+
+
part_name
+
Opzionale
+
Stringa (String)
+
Deve essere fornita se le colonne part_id, part_mpnr o part_ipn non sono compilate.
+
+
+
Colonne che iniziano con part_manufacturer_
+
+ Se il produttore di un componente deve essere modificato o il componente deve essere identificato univocamente in base al valore part_mpnr, almeno una delle seguenti colonne deve essere fornita e compilata:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opzionale
+
Intero (Integer)
+
Intero > 0. Corrisponde all'ID numerico interno del produttore.
+
+
+
part_manufacturer_name
+
Opzionale
+
Stringa (String)
+
Deve essere fornita se la colonna part_manufacturer_id non è compilata.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Colonne previste:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Nota: Non viene effettuata alcuna associazione con componenti specifici dalla gestione delle categorie.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Campo
+
Condizione
+
Tipo di dato
+
Descrizione
+
+
+
+
+
Id
+
Opzionale
+
Numero intero
+
Valore libero. Un numero identificativo univoco per ciascun componente.
+
+
+
Designator
+
Opzionale
+
Stringa
+
Valore libero. Un identificatore di riferimento univoco del componente sul PCB, ad esempio "R1" per il resistore 1. Viene trasferito nel nome di montaggio del record del componente.
+
+
+
Package
+
Opzionale
+
Stringa
+
Valore libero. L'involucro o la forma del componente, ad esempio "0805" per i resistori SMD. Non viene trasferito nel record del componente.
+
+
+
Quantity
+
Campo obbligatorio
+
Numero intero
+
Il numero dei componenti identici necessari per creare un'istanza. Registrato come il numero della voce del componente.
+
+
+
Designation
+
Campo obbligatorio
+
Stringa
+
Descrizione o funzione del componente, ad esempio valore del resistore "10kΩ" o valore del condensatore "100nF". Viene trasferita nel nome del record del componente.
+
+
+
Supplier and ref
+
Opzionale
+
Stringa
+
Valore libero. Può contenere ad esempio un valore specifico del distributore. Viene trasferito come nota nel record del componente.
Musi być podane i zawierać wartość dziesiętną (Float) większą niż 0.0.
+
+
+
name
+
Opcjonalne
+
Ciąg (String)
+
Jeśli jest obecny, musi być niepustym ciągiem znaków. Nazwa elementu w wykazie materiałów.
+
+
+
part
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli komponent musi być przypisany, musi być obiektem/tablą i co najmniej jedno z następujących pól musi zostać wypełnione:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Opcjonalne
+
Całkowity (Integer)
+
Całkowity (Integer) > 0. Odpowiada wewnętrznemu numerycznemu identyfikatorowi komponentu w bazie danych części (Part-DB).
+
+
+
part.mpnr
+
Opcjonalne
+
Ciag (String)
+
Niepusty ciąg, jeśli part.id, part.ipn ani part.name nie zostały podane.
+
+
+
part.ipn
+
Opcjonalne
+
Ciag (String)
+
Niepusty ciąg, jeśli part.id, part.mpnr ani part.name nie zostały podane.
+
+
+
part.name
+
Opcjonalne
+
Ciag (String)
+
Niepusty ciąg, jeśli part.id, part.mpnr ani part.ipn nie zostały podane.
+
+
+
part.manufacturer
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli producent komponentu musi zostać dostosowany lub komponent musi zostać jednoznacznie zidentyfikowany na podstawie part.mpnr, musi być obiektem/tablą, a co najmniej jedno z następujących pól musi zostać wypełnione:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opcjonalne
+
Całkowity (Integer)
+
Całkowity (Integer) > 0. Odpowiada wewnętrznemu numerycznemu identyfikatorowi producenta.
+
+
+
manufacturer.name
+
Opcjonalne
+
Ciag (String)
+
Niepusty ciąg, jeśli manufacturer.id nie został podany.
Liczba identycznych komponentów potrzebnych do utworzenia instancji. Traktowane jako liczba wpisów komponentu.
+
+
+
name
+
Optional
+
String
+
Jeśli dostępny, musi być niepustym ciągiem znaków. Nazwa elementu w wykazie materiałów.
+
+
+
Kolumny zaczynające się od part_
+
+ Jeśli ma zostać przypisany komponent, co najmniej jedna z poniższych kolumn musi zostać podana i uzupełniona:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opcjonalna
+
Liczba całkowita (Integer)
+
Liczba całkowita > 0. Odpowiada wewnętrznemu ID numerycznemu komponentu w Part-DB.
+
+
+
part_mpnr
+
Opcjonalna
+
Cišg znaków (String)
+
Musi być podana, jeśli kolumny part_id, part_ipn ani part_name nie są podane.
+
+
+
part_ipn
+
Opcjonalna
+
Cišg znaków (String)
+
Musi być podana, jeśli kolumny part_id, part_mpnr ani part_name nie są podane.
+
+
+
part_name
+
Opcjonalna
+
Cišg znaków (String)
+
Musi być podana, jeśli kolumny part_id, part_mpnr ani part_ipn nie są podane.
+
+
+
Kolumny zaczynające się od part_manufacturer_
+
+ Jeśli producent komponentu ma zostać zmieniony lub komponent ma zostać jednoznacznie zidentyfikowany na podstawie wartości part_mpnr, co najmniej jedna z poniższych kolumn musi zostać podana i uzupełniona:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opcjonalna
+
Liczba całkowita (Integer)
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID producenta.
+
+
+
part_manufacturer_name
+
Opcjonalna
+
Cišg znaków (String)
+
Musi być podana, jeśli kolumna part_manufacturer_id nie jest uzupełniona.
Dowolna wartość. Unikalny numer identyfikacyjny dla każdego komponentu.
+
+
+
Designator
+
Opcjonalne
+
String
+
Dowolna wartość. Unikalny identyfikator referencyjny komponentu na płytce PCB, np. „R1” dla rezystora 1. Zostaje przeniesiony do nazwy montażowej wpisu komponentu.
+
+
+
Package
+
Opcjonalne
+
String
+
Dowolna wartość. Obudowa lub typ komponentu, np. „0805” dla rezystorów SMD. Nie zostaje przeniesiony do wpisu komponentu.
+
+
+
Quantity
+
Pole obowiązkowe
+
Liczba całkowita (Integer)
+
Liczba identycznych komponentów potrzebnych do stworzenia instancji zestawu. Zostaje przeniesiona jako ilość wpisu komponentu.
+
+
+
Designation
+
Pole obowiązkowe
+
String
+
Opis lub funkcja komponentu, np. wartość rezystora „10kΩ” lub wartość kondensatora „100nF”. Zostaje przeniesiony do nazwy wpisu komponentu.
+
+
+
Supplier and ref
+
Opcjonalne
+
String
+
Dowolna wartość. Może zawierać np. wartość specyficzną dla dystrybutora. Zostaje przeniesiona jako notatka do wpisu komponentu.
Должно быть указано и содержать дробное значение (Float), большее 0.0.
+
+
+
name
+
Опционально
+
Строка (String)
+
Если присутствует, должно быть непустой строкой. Название элемента в спецификации материалов.
+
+
+
part
+
Опционально
+
Объект/Массив
+
+ Если необходимо назначить компонент, он должен быть объектом/массивом, и должно быть заполнено хотя бы одно из следующих полей:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Опционально
+
Целое число (Integer)
+
Целое число (Integer) > 0. Соответствует внутреннему числовому идентификатору компонента в базе данных компонентов (Part-DB).
+
+
+
part.mpnr
+
Опционально
+
Строка (String)
+
Непустая строка, если не указаны part.id, part.ipn или part.name.
+
+
+
part.ipn
+
Опционально
+
Строка (String)
+
Непустая строка, если не указаны part.id, part.mpnr или part.name.
+
+
+
part.name
+
Опционально
+
Строка (String)
+
Непустая строка, если не указаны part.id, part.mpnr или part.ipn.
+
+
+
part.manufacturer
+
Опционально
+
Объект/Массив
+
+ Если необходимо указать производителя компонента или однозначно идентифицировать компонент на основе part.mpnr, он должен быть объектом/массивом, и хотя бы одно из следующих полей должно быть заполнено:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Опционально
+
Целое число (Integer)
+
Целое число (Integer) > 0. Соответствует внутреннему числовому идентификатору производителя.
Количество идентичных компонентов, необходимых для создания экземпляра. Считается количеством записей компонента.
+
+
+
name
+
Optional
+
String
+
Если доступно, должна быть непустая строка. Название элемента в спецификации материалов.
+
+
+
Колонки, начинающиеся с part_
+
+ Если нужно назначить компонент, должна быть указана и заполнена по крайней мере одна из следующих колонок:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Необязательная
+
Целое число (Integer)
+
Целое > 0. Соответствует внутреннему числовому ID компонента в базе данных компонентов (Part-DB).
+
+
+
part_mpnr
+
Необязательная
+
Строка (String)
+
Должна быть указана, если колонки part_id, part_ipn или part_name не заполнены.
+
+
+
part_ipn
+
Необязательная
+
Строка (String)
+
Должна быть указана, если колонки part_id, part_mpnr или part_name не заполнены.
+
+
+
part_name
+
Необязательная
+
Строка (String)
+
Должна быть указана, если колонки part_id, part_mpnr или part_ipn не заполнены.
+
+
+
Колонки, начинающиеся с part_manufacturer_
+
+ Если требуется указать производителя компонента или уникально идентифицировать компонент на основе значения part_mpnr, должна быть указана и заполнена по крайней мере одна из следующих колонок:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Необязательная
+
Целое число (Integer)
+
Целое > 0. Соответствует внутреннему числовому ID производителя.
+
+
+
part_manufacturer_name
+
Необязательная
+
Строка (String)
+
Должна быть указана, если колонка part_manufacturer_id не заполнена.
Свободный ввод. Уникальный идентификационный номер для каждого компонента.
+
+
+
Designator
+
Необязательно
+
Строка (String)
+
Свободный ввод. Уникальный идентификатор компонента на печатной плате, например, «R1» для резистора 1. Добавляется в название сборочного узла записи компонента.
+
+
+
Package
+
Необязательно
+
Строка (String)
+
Свободный ввод. Корпус или тип компонента, например, «0805» для SMD резисторов. Не добавляется в запись компонента.
+
+
+
Quantity
+
Обязательно
+
Целое число (Integer)
+
Число идентичных компонентов, необходимых для создания экземпляра сборки. Добавляется как количество записи компонента.
+
+
+
Designation
+
Обязательно
+
Строка (String)
+
Описание или функция компонента, например, значение резистора «10kΩ» или значение конденсатора «100nF». Добавляется в название записи компонента.
+
+
+
Supplier and ref
+
Необязательно
+
Строка (String)
+
Свободный ввод. Может содержать дистрибьюторское значение, например. Добавляется как примечание к записи компонента.
+
+
+ ]]>
+
+
+ project.bom_import.clear_existing_bom.help
@@ -12789,13 +13114,13 @@ Element 3
-
+ assembly.bom_import.template.csv.exptected_columns可用列:
-
+ assembly.bom_import.template.csv.table
From 90678b42fb8ac1546eddeb918636b0207be3e1f0 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 24 Jun 2025 11:07:20 +0200
Subject: [PATCH 14/83] =?UTF-8?q?Part-=C3=9Cbersicht=20sowie=20-Detailansi?=
=?UTF-8?q?cht=20um=20Assembly=20Information=20erweitern?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/DataTables/PartsDataTable.php | 29 +++++++++++++++++
templates/parts/info/_assemblies.html.twig | 31 +++++++++++++++++++
templates/parts/info/show_part_info.html.twig | 27 ++++++++++------
translations/messages.cs.xlf | 6 ++++
translations/messages.da.xlf | 6 ++++
translations/messages.de.xlf | 6 ++++
translations/messages.el.xlf | 6 ++++
translations/messages.en.xlf | 6 ++++
translations/messages.es.xlf | 6 ++++
translations/messages.fr.xlf | 6 ++++
translations/messages.it.xlf | 6 ++++
translations/messages.ja.xlf | 6 ++++
translations/messages.nl.xlf | 6 ++++
translations/messages.pl.xlf | 6 ++++
translations/messages.ru.xlf | 6 ++++
translations/messages.zh.xlf | 6 ++++
16 files changed, 156 insertions(+), 9 deletions(-)
create mode 100644 templates/parts/info/_assemblies.html.twig
diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php
index f0decf271..b98c97629 100644
--- a/src/DataTables/PartsDataTable.php
+++ b/src/DataTables/PartsDataTable.php
@@ -39,6 +39,7 @@
use App\DataTables\Helpers\ColumnSortHelper;
use App\DataTables\Helpers\PartDataTableHelper;
use App\Doctrine\Helpers\FieldHelper;
+use App\Entity\AssemblySystem\Assembly;
use App\Entity\Parts\ManufacturingStatus;
use App\Entity\Parts\Part;
use App\Entity\Parts\PartLot;
@@ -238,6 +239,34 @@ public function configure(DataTable $dataTable, array $options): void
]);
}
+ //Add a assembly column to list where the part is used, when the user has the permission to see the assemblies
+ if ($this->security->isGranted('read', Assembly::class)) {
+ $this->csh->add('assemblies', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.labelp'),
+ 'render' => function ($value, Part $context): string {
+ //Only show the first 5 assembly names
+ $assemblies = $context->getAssemblies();
+ $tmp = "";
+
+ $max = 5;
+
+ for ($i = 0; $i < min($max, count($assemblies)); $i++) {
+ $url = $this->urlGenerator->infoURL($assemblies[$i]);
+ $tmp .= sprintf('%s', $url, htmlspecialchars($assemblies[$i]->getName()));
+ if ($i < count($assemblies) - 1) {
+ $tmp .= ", ";
+ }
+ }
+
+ if (count($assemblies) > $max) {
+ $tmp .= ", + ".(count($assemblies) - $max);
+ }
+
+ return $tmp;
+ }
+ ]);
+ }
+
$this->csh
->add('edit', IconLinkColumn::class, [
'label' => $this->translator->trans('part.table.edit'),
diff --git a/templates/parts/info/_assemblies.html.twig b/templates/parts/info/_assemblies.html.twig
new file mode 100644
index 000000000..d4996c592
--- /dev/null
+++ b/templates/parts/info/_assemblies.html.twig
@@ -0,0 +1,31 @@
+{% import "components/attachments.macro.html.twig" as attachments %}
+{% import "helper.twig" as helper %}
+
+
+
+
+
+
{% trans %}entity.info.name{% endtrans %}
+
{% trans %}description.label{% endtrans %}
+
{% trans %}assembly.bom.quantity{% endtrans %}
+
+
+
+
+ {% for bom_entry in part.assemblyBomEntries %}
+ {# @var bom_entry App\Entity\Assembly\AssemblyBOMEntry #}
+
+
{% if bom_entry.assembly.masterPictureAttachment is not null %}{{ attachments.attachment_icon(bom_entry.assembly.masterPictureAttachment, attachment_manager) }}{% endif %}
+
+
+
+ {% trans %}part.info.add_part_to_assembly{% endtrans %}
+
\ No newline at end of file
diff --git a/templates/parts/info/show_part_info.html.twig b/templates/parts/info/show_part_info.html.twig
index 96b5e2091..cd7b4ce7a 100644
--- a/templates/parts/info/show_part_info.html.twig
+++ b/templates/parts/info/show_part_info.html.twig
@@ -109,15 +109,20 @@
{% trans %}vendor.partinfo.history{% endtrans %}
- {% if part.projectBomEntries is not empty %}
-
\ No newline at end of file
diff --git a/templates/assemblies/info/info.html.twig b/templates/assemblies/info/info.html.twig
index 166535a64..d787ea086 100644
--- a/templates/assemblies/info/info.html.twig
+++ b/templates/assemblies/info/info.html.twig
@@ -108,7 +108,7 @@
{% include "assemblies/info/_builds.html.twig" %}
- {% include "parts/info/_attachments_info.html.twig" with {"part": assembly} %}
+ {% include "assemblies/info/_attachments_info.html.twig" with {"assembly": assembly} %}
{% trans %}assembly.bom.partOrProject{% endtrans %}
+
{% trans %}assembly.bom.partOrAssembly{% endtrans %}
{% trans %}assembly.bom.name{% endtrans %}
{# Remove button #}
@@ -44,18 +44,9 @@
{{ form_row(form.part) }}
{{ form_errors(form.part) }}
-
- {% if form.vars.value is not null and form.vars.value.assembly is not null %}
- {% if is_granted("@projects.read") or has_project(form.vars.value.assembly.bomEntries.toArray) %}
-
{{ form_widget(form.name) }}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index bd4ec699b..ce79aaced 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -9867,7 +9867,7 @@ Element 3
assembly.edit.status
- Stav
+ Stav sestavy
@@ -13408,6 +13408,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
%value% (Součást)
+
+
+ part.table.name.value.for_assembly
+ %value% (Sestava)
+
+ part.table.name.value.for_project
@@ -13444,6 +13450,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Sestavy
+
+
+ assembly.referencedAssembly.labelp
+ Odkazované sestavy
+
+ assembly.edit
@@ -13612,6 +13624,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Sestavit
+
+
+ assembly.build.form.referencedAssembly
+ Sestava "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -13666,6 +13684,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Projekt
+
+
+ assembly.bom.referencedAssembly
+ Sestava
+
+ assembly.bom.name
@@ -13702,10 +13726,10 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Importovat součásti do sestavy
-
+
- assembly.bom.partOrProject
- Součást
+ assembly.bom.partOrAssembly
+ Součást nebo sestava
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index 4cec94054..c68acdd4b 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -9893,7 +9893,7 @@ Element 3
assembly.edit.status
- Status
+ Samlingens status
@@ -12569,6 +12569,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
%value% (Del)
+
+
+ part.table.name.value.for_assembly
+ %value% (Samling)
+
+ part.table.name.value.for_project
@@ -12605,6 +12611,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Samlinger
+
+
+ assembly.referencedAssembly.labelp
+ Refererede samlinger
+
+ assembly.edit
@@ -12773,6 +12785,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Byg
+
+
+ assembly.build.form.referencedAssembly
+ Samling "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12827,6 +12845,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Projekt
+
+
+ assembly.bom.referencedAssembly
+ Sammenstilling
+
+ assembly.bom.name
@@ -12863,10 +12887,10 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Importer dele til samling
-
+
- assembly.bom.partOrProject
- Del
+ assembly.bom.partOrAssembly
+ Del eller samling
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index 3140a1368..bee171d41 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -4746,6 +4746,12 @@ Wenn Sie dies fehlerhafterweise gemacht haben oder ein Computer nicht mehr vertr
%value% (Bauteil)
+
+
+ part.table.name.value.for_assembly
+ %value% (Baugruppe)
+
+ part.table.name.value.for_project
@@ -9881,7 +9887,7 @@ Element 1 -> Element 1.2
assembly.edit.status
- Status
+ Status Baugruppe
@@ -13260,6 +13266,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Baugruppen
+
+
+ assembly.referencedAssembly.labelp
+ Referenzierte Baugruppen
+
+ assembly.edit
@@ -13428,6 +13440,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Bauen
+
+
+ asssembly.build.form.referencedAssembly
+ Baugruppe "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -13482,6 +13500,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Projekt
+
+
+ assembly.bom.referencedAssembly
+ Baugruppe
+
+ assembly.bom.name
@@ -13518,10 +13542,10 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Importiere Parts für Baugruppe
-
+
- assembly.bom.partOrProject
- Bauteil oder Projekt
+ assembly.bom.partOrAssembly
+ Bauteil oder Baugruppe
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index fc03f08be..97b27f53f 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -1541,6 +1541,12 @@
%value% (Μέρος)
+
+
+ part.table.name.value.for_assembly
+ %value% (Συναρμολόγηση)
+
+ part.table.name.value.for_project
@@ -1550,7 +1556,7 @@
assembly.edit.status
- Κατάσταση
+ Κατάσταση συναρμολόγησης
@@ -1613,6 +1619,12 @@
Συναρμολογήσεις
+
+
+ assembly.referencedAssembly.labelp
+ Αναφερόμενες συναρμολογήσεις
+
+ assembly.edit
@@ -1781,6 +1793,12 @@
Κατασκευή
+
+
+ assembly.build.form.referencedAssembly
+ Συναρμολόγηση "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -1835,6 +1853,12 @@
έργο
+
+
+ assembly.bom.referencedAssembly
+ Συναρμολόγηση
+
+ assembly.bom.name
@@ -1871,10 +1895,10 @@
Εισαγωγή εξαρτημάτων συναρμολόγησης
-
+
- assembly.bom.partOrProject
- Εξάρτημα
+ assembly.bom.partOrAssembly
+ Μέρος ή συναρμολόγηση
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 85942ddf5..4f398d6b0 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -4747,6 +4747,12 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
%value% (Part)
+
+
+ part.table.name.value.for_assembly
+ %value% (Assembly)
+
+ part.table.name.value.for_project
@@ -9882,7 +9888,7 @@ Element 1 -> Element 1.2
assembly.edit.status
- Project status
+ Assembly status
@@ -13261,6 +13267,12 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Assemblies
+
+
+ assembly.referencedAssembly.labelp
+ Referenced assemblies
+
+ assembly.edit
@@ -13429,6 +13441,12 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Build
+
+
+ assembly.build.form.referencedAssembly
+ Assembly "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -13483,6 +13501,12 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Project
+
+
+ assembly.bom.referencedAssembly
+ Assembly
+
+ assembly.bom.name
@@ -13519,10 +13543,10 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Import part list for assembly
-
+
- assembly.bom.partOrProject
- Part
+ assembly.bom.partOrAssembly
+ Part or assembly
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index 7ce3fe062..b67198a78 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -4746,6 +4746,12 @@ Subelementos serán desplazados hacia arriba.
%value% (Componente)
+
+
+ part.table.name.value.for_assembly
+ %value% (Ensamblaje)
+
+ part.table.name.value.for_project
@@ -9897,7 +9903,7 @@ Elemento 3
assembly.edit.status
- Estatus
+ Estado del ensamblaje
@@ -12753,6 +12759,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Ensamblajes
+
+
+ assembly.referencedAssembly.labelp
+ Conjuntos referenciados
+
+ assembly.edit
@@ -12921,6 +12933,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Construir
+
+
+ assembly.build.form.referencedAssembly
+ Ensamblaje "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12975,6 +12993,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Proyecto
+
+
+ assembly.bom.referencedAssembly
+ Ensamblaje
+
+ assembly.bom.name
@@ -13011,10 +13035,10 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Importar piezas para ensamblaje
-
+
- assembly.bom.partOrProject
- Pieza
+ assembly.bom.partOrAssembly
+ Parte o conjunto
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 4bb77d8eb..ecfcf5928 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -4709,6 +4709,12 @@ Si vous avez fait cela de manière incorrecte ou si un ordinateur n'est plus fia
%value% (Componente)
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblage)
+
+ part.table.name.value.for_project
@@ -9112,7 +9118,7 @@ exemple de ville
assembly.edit.status
- Statut
+ Statut de l'assemblage
@@ -9175,6 +9181,12 @@ exemple de ville
Assemblages
+
+
+ assembly.referencedAssembly.labelp
+ Assemblages référencés
+
+ assembly.edit
@@ -9343,6 +9355,12 @@ exemple de ville
Construire
+
+
+ assembly.build.form.referencedAssembly
+ Assemblage "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -9397,6 +9415,12 @@ exemple de ville
Projet
+
+
+ assembly.bom.referencedAssembly
+ Assemblage
+
+ assembly.bom.name
@@ -9433,10 +9457,10 @@ exemple de ville
Importer des pièces pour l'assemblage
-
+
- assembly.bom.partOrProject
- Pièce
+ assembly.bom.partOrAssembly
+ Pièce ou assemblage
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index e7628984a..12e20ca2c 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -4748,6 +4748,12 @@ Se è stato fatto in modo errato o se un computer non è più attendibile, puoi
%value% (Componente)
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblaggio)
+
+ part.table.name.value.for_project
@@ -9899,7 +9905,7 @@ Element 3
assembly.edit.status
- Stato
+ Stato dell'assemblaggio
@@ -12755,6 +12761,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Assemblaggi
+
+
+ assembly.referencedAssembly.labelp
+ Assembly referenziati
+
+ assembly.edit
@@ -12923,6 +12935,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Costruire
+
+
+ assembly.build.form.referencedAssembly
+ Gruppo "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12977,6 +12995,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Progetto
+
+
+ assembly.bom.referencedAssembly
+ Assemblaggio
+
+ assembly.bom.name
@@ -13013,10 +13037,10 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Importa componenti per il gruppo
-
+
- assembly.bom.partOrProject
- Componente
+ assembly.bom.partOrAssembly
+ Parte o assieme
diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf
index b61b585f3..b7be7490d 100644
--- a/translations/messages.ja.xlf
+++ b/translations/messages.ja.xlf
@@ -4709,6 +4709,12 @@
%value%(部品)
+
+
+ part.table.name.value.for_assembly
+ %value%(アセンブリ)
+
+ part.table.name.value.for_project
@@ -8849,7 +8855,7 @@ Exampletown
assembly.edit.status
- ステータス
+ アセンブリのステータス
@@ -8912,6 +8918,12 @@ Exampletown
アセンブリ一覧
+
+
+ assembly.referencedAssembly.labelp
+ 参照されたアセンブリ
+
+ assembly.edit
@@ -9080,6 +9092,12 @@ Exampletown
ビルド
+
+
+ assembly.build.form.referencedAssembly
+ アセンブリ「%name%」
+
+ assembly.builds.no_stocked_builds
@@ -9134,6 +9152,12 @@ Exampletown
プロジェクト
+
+
+ assembly.bom.referencedAssembly
+ アセンブリ
+
+ assembly.bom.name
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index c52a4733a..fe17c3aca 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -730,6 +730,12 @@
%value% (Onderdeel)
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblage)
+
+ part.table.name.value.for_project
@@ -739,7 +745,7 @@
assembly.edit.status
- Κατάσταση
+ Montagestatus
@@ -802,6 +808,12 @@
Assemblages
+
+
+ assembly.referencedAssembly.labelp
+ Gerefereerde assemblages
+
+ assembly.edit
@@ -970,6 +982,12 @@
Bouwen
+
+
+ assembly.build.form.referencedAssembly
+ Assemblage "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -1024,6 +1042,12 @@
Project
+
+
+ assembly.bom.referencedAssembly
+ Assemblage
+
+ assembly.bom.name
@@ -1060,10 +1084,10 @@
Importeer onderdelen voor assemblage
-
+
- assembly.bom.partOrProject
- Onderdeel
+ assembly.bom.partOrAssembly
+ Onderdeel of samenstelling
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index fc6eba18d..73b6e4fcc 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -4751,6 +4751,12 @@ Jeśli zrobiłeś to niepoprawnie lub komputer nie jest już godny zaufania, mo
%value%(部品)
+
+
+ part.table.name.value.for_assembly
+ %value% (Złożenie)
+
+ part.table.name.value.for_project
@@ -9902,7 +9908,7 @@ Element 3
assembly.edit.status
- Status
+ Status montażu
@@ -12632,6 +12638,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Zespoły
+
+
+ assembly.referencedAssembly.labelp
+ Odwołane zestawy
+
+ assembly.edit
@@ -12800,6 +12812,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Zbuduj
+
+
+ assembly.build.form.referencedAssembly
+ Zespół "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12854,6 +12872,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Projekt
+
+
+ assembly.bom.referencedAssembly
+ Złożenie
+
+ assembly.bom.name
@@ -12890,10 +12914,10 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Importuj części dla zespołu
-
+
- assembly.bom.partOrProject
- Część
+ assembly.bom.partOrAssembly
+ Część lub zespół
diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf
index 252b857bd..751ff35f1 100644
--- a/translations/messages.ru.xlf
+++ b/translations/messages.ru.xlf
@@ -4757,6 +4757,12 @@
%value% (Часть)
+
+
+ part.table.name.value.for_assembly
+ %value% (Сборка)
+
+ part.table.name.value.for_project
@@ -9906,7 +9912,7 @@
assembly.edit.status
- Статус
+ Статус сборки
@@ -12732,6 +12738,12 @@
Сборки
+
+
+ assembly.referencedAssembly.labelp
+ Ссылочные сборки
+
+ assembly.edit
@@ -12900,6 +12912,12 @@
Собрать
+
+
+ assembly.build.form.referencedAssembly
+ Сборка "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12954,6 +12972,12 @@
Проект
+
+
+ assembly.bom.referencedAssembly
+ Сборка
+
+ assembly.bom.name
@@ -12990,10 +13014,10 @@
Импортировать детали для сборки
-
+
- assembly.bom.partOrProject
- Компонент
+ assembly.bom.partOrAssembly
+ Часть или сборка
diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf
index 9c0b5a76f..396feae3e 100644
--- a/translations/messages.zh.xlf
+++ b/translations/messages.zh.xlf
@@ -4755,6 +4755,12 @@
%value%(部件)
+
+
+ part.table.name.value.for_assembly
+ %value%(装配)
+
+ part.table.name.value.for_project
@@ -9905,7 +9911,7 @@ Element 3
assembly.edit.status
- 状态
+ 装配状态
@@ -12617,6 +12623,12 @@ Element 3
装配列表
+
+
+ assembly.referencedAssembly.labelp
+ 引用的程序集
+
+ assembly.edit
@@ -12785,6 +12797,12 @@ Element 3
构建
+
+
+ assembly.build.form.referencedAssembly
+ 组件“%name%”
+
+ assembly.builds.no_stocked_builds
@@ -12839,6 +12857,12 @@ Element 3
项目
+
+
+ assembly.bom.referencedAssembly
+ 组件
+
+ assembly.bom.name
@@ -12875,10 +12899,10 @@ Element 3
导入组件的零件
-
+
- assembly.bom.partOrProject
- 零件
+ assembly.bom.partOrAssembly
+ 部件或组件
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index 607b8a3b6..f053743f3 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -257,7 +257,7 @@
Je povoleno vybrat pouze jednu součástku nebo sestavu. Upravit prosím svůj výběr!
-
+ project.bom_entry.name_already_in_bomJiž existuje položka BOM s tímto názvem!
@@ -395,6 +395,12 @@
Tato součást již existuje ve skupině!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Tato sestava již existuje jako položka v seznamu materiálů!
+
+ assembly.bom_entry.project_already_in_bom
@@ -413,6 +419,12 @@
Musíte vybrat součást nebo nastavit název pro nesoučást!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Je povoleno vybrat pouze jednu součástku nebo sestavu. Upravit prosím svůj výběr!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index f25712719..239e3572a 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -251,12 +251,6 @@
Du skal vælge en komponent eller angive et navn til en ikke-komponent styklistepost!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
-
- project.bom_entry.name_already_in_bom
@@ -371,6 +365,12 @@
Denne del eksisterer allerede i gruppen!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Denne samling findes allerede som en post!
+
+ assembly.bom_entry.project_already_in_bom
@@ -389,6 +389,12 @@
Du skal vælge en del eller sætte et navn for en ikke-del!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index abd191d9e..86b31e583 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -251,12 +251,6 @@
Sie müssen ein Bauteil bzw. eine Baugruppe auswählen, oder einen Namen für ein nicht-Bauteil BOM-Eintrag setzen!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Es darf nur ein Bauteil oder eine Baugruppe ausgewählt werden. Bitte passen Sie Ihre Auswahl an!
-
- project.bom_entry.name_already_in_bom
@@ -395,6 +389,12 @@
Dieses Bauteil existiert bereits in der Gruppe!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Diese Baugruppe existiert bereits als Eintrag!
+
+ assembly.bom_entry.project_already_in_bom
@@ -413,6 +413,12 @@
Sie müssen ein Bauteil auswählen, oder einen Namen für den Eintrag setzen!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Es darf nur ein Bauteil oder eine Baugruppe ausgewählt werden. Bitte passen Sie Ihre Auswahl an!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index 580c91275..4e4278daf 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -13,12 +13,6 @@
Ο εσωτερικός αριθμός εξαρτήματος πρέπει να είναι μοναδικός. {{ value }} χρησιμοποιείται ήδη!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
-
- validator.bom_importer.invalid_import_type
@@ -37,6 +31,12 @@
Αυτό το εξάρτημα υπάρχει ήδη στην ομάδα!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Αυτή η συναρμολόγηση υπάρχει ήδη ως εγγραφή!
+
+ assembly.bom_entry.project_already_in_bom
@@ -55,6 +55,12 @@
Πρέπει να επιλέξετε ένα εξάρτημα ή να βάλετε ένα όνομα για ένα μη εξάρτημα!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index e20e7ff8c..59cabf552 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -251,12 +251,6 @@
You have to select a part or assembly, or set a name for a non-component Bom entry!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Only one part or assembly may be selected. Please modify your selection!
-
- project.bom_entry.name_already_in_bom
@@ -395,6 +389,12 @@
This part already exists in the list!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ This assembly already exists as an entry!
+
+ assembly.bom_entry.project_already_in_bom
@@ -413,6 +413,12 @@
You must select a part or set a name for the entry!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Only one part or assembly may be selected. Please modify your selection!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index e603bdaf8..aff68a185 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -203,12 +203,6 @@
L'emplacement de stockage a été marqué comme "Composant seul", par conséquent aucun nouveau composant ne peut être ajouté.
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Seule une pièce ou un assemblage peut être sélectionné. Veuillez ajuster votre sélection!
-
- validator.bom_importer.invalid_import_type
@@ -227,6 +221,12 @@
Cette pièce existe déjà dans le groupe!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Cet assemblage existe déjà en tant qu'entrée !
+
+ assembly.bom_entry.project_already_in_bom
@@ -245,6 +245,12 @@
Vous devez sélectionner une pièce ou attribuer un nom pour un non-élément!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Seule une pièce ou un assemblage peut être sélectionné. Veuillez ajuster votre sélection!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index c0af03354..1ee5c06fe 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -251,12 +251,6 @@
Morate odabrati dio za unos u BOM ili postaviti naziv za unos koji nije dio.
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Dozvoljeno je odabrati samo jednu komponentu ili sklop. Molimo prilagodite svoj odabir!
-
- project.bom_entry.name_already_in_bom
@@ -389,6 +383,12 @@
Ovaj dio već postoji u grupi!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Ova se montaža već nalazi kao zapis!
+
+ assembly.bom_entry.project_already_in_bom
@@ -407,6 +407,12 @@
Morate odabrati dio ili unijeti naziv za nedio!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Dozvoljeno je odabrati samo jednu komponentu ili sklop. Molimo prilagodite svoj odabir!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index 88369640f..ac57a2cc4 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -251,12 +251,6 @@
È necessario selezionare un componente o assegnare un nome ad una voce BOM che non indica un componente!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- È consentito selezionare solo una parte o un assieme. Si prega di modificare la selezione!
-
- project.bom_entry.name_already_in_bom
@@ -389,6 +383,12 @@
Questa parte è già presente nel gruppo!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Questo assemblaggio è già presente come voce!
+
+ assembly.bom_entry.project_already_in_bom
@@ -407,6 +407,12 @@
È necessario selezionare una parte o inserire un nome per un non-parte!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ È consentito selezionare solo una parte o un assieme. Si prega di modificare la selezione!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index 070281ccc..a316707ad 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -203,12 +203,6 @@
新しい部品を追加できません。保管場所は「1つの部品のみ」とマークされています。
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- 部品またはアセンブリのみ選択可能です。選択内容を調整してください!
-
- validator.bom_importer.invalid_import_type
@@ -227,6 +221,12 @@
この部品はすでにグループに存在します!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ このアセンブリはすでにエントリとして存在します!
+
+ assembly.bom_entry.project_already_in_bom
@@ -245,6 +245,12 @@
部品を選択するか、非部品の名前を入力する必要があります!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ 部品またはアセンブリのみ選択可能です。選択内容を調整してください!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 60713fa02..95c44ab4d 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -251,12 +251,6 @@
Należy wybrać część dla wpisu BOM części lub ustawić nazwę dla wpisu BOM niebędącego częścią.
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Można wybrać tylko jedną część lub zespół. Proszę dostosować swój wybór!
-
- project.bom_entry.name_already_in_bom
@@ -389,6 +383,12 @@
Ten element już istnieje w grupie!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ To zestawienie jest już dodane jako wpis!
+
+ assembly.bom_entry.project_already_in_bom
@@ -407,6 +407,12 @@
Musisz wybrać element lub przypisać nazwę dla elementu niestandardowego!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Można wybrać tylko jedną część lub zespół. Proszę dostosować swój wybór!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index 32540f8c7..425ede5f1 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -251,12 +251,6 @@
Вам необходимо выбрать компонент или задать имя для BOM, не относящейся к компоненту!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Можно выбрать только деталь или сборку. Пожалуйста, измените ваш выбор!
-
- project.bom_entry.name_already_in_bom
@@ -389,6 +383,12 @@
Эта деталь уже существует в группе!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Этот сборочный узел уже добавлен как запись!
+
+ assembly.bom_entry.project_already_in_bom
@@ -407,6 +407,12 @@
Необходимо выбрать деталь или ввести название для недетали!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Можно выбрать только деталь или сборку. Пожалуйста, измените ваш выбор!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 4a0ec79e8..4a02523bb 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -251,12 +251,6 @@
您必须为 BOM 条目选择部件,或为非部件 BOM 条目设置名称。
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- 只能选择一个零件或组件。请修改您的选择!
-
- project.bom_entry.name_already_in_bom
@@ -377,6 +371,12 @@
此零件已存在于组中!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ 此装配已经作为条目存在!
+
+ assembly.bom_entry.project_already_in_bom
@@ -395,6 +395,12 @@
必须选择零件或为非零件指定名称!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ 只能选择一个零件或组件。请修改您的选择!
+
+ validator.bom_importer.json_csv.quantity.required
From 4deab8ecf3e965f4dc9c9442541431fcf9263397 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 3 Jul 2025 13:43:55 +0200
Subject: [PATCH 17/83] AssemblyBomEntriesDataTable anpassen
---
.../AssemblyBomEntriesDataTable.php | 82 ++++++-------------
1 file changed, 23 insertions(+), 59 deletions(-)
diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php
index b31c72bc0..fed6850f4 100644
--- a/src/DataTables/AssemblyBomEntriesDataTable.php
+++ b/src/DataTables/AssemblyBomEntriesDataTable.php
@@ -22,12 +22,13 @@
*/
namespace App\DataTables;
-use App\DataTables\Column\EntityColumn;
use App\DataTables\Column\LocaleDateTimeColumn;
use App\DataTables\Column\MarkdownColumn;
+use App\DataTables\Helpers\AssemblyDataTableHelper;
use App\DataTables\Helpers\ProjectDataTableHelper;
use App\DataTables\Helpers\ColumnSortHelper;
use App\DataTables\Helpers\PartDataTableHelper;
+use App\Entity\AssemblySystem\Assembly;
use App\Entity\Attachments\Attachment;
use App\Entity\Parts\Part;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
@@ -45,20 +46,20 @@
class AssemblyBomEntriesDataTable implements DataTableTypeInterface
{
public function __construct(
- protected TranslatorInterface $translator,
- protected PartDataTableHelper $partDataTableHelper,
- protected ProjectDataTableHelper $projectDataTableHelper,
- protected EntityURLGenerator $entityURLGenerator,
- protected AmountFormatter $amountFormatter,
- private string $visible_columns,
- private ColumnSortHelper $csh
+ protected TranslatorInterface $translator,
+ protected PartDataTableHelper $partDataTableHelper,
+ protected ProjectDataTableHelper $projectDataTableHelper,
+ protected AssemblyDataTableHelper $assemblyDataTableHelper,
+ protected EntityURLGenerator $entityURLGenerator,
+ protected AmountFormatter $amountFormatter,
+ private string $visible_columns,
+ private ColumnSortHelper $csh
){
}
public function configure(DataTable $dataTable, array $options): void
{
$this->csh
- //->add('select', SelectColumn::class)
->add('picture', TextColumn::class, [
'label' => '',
'className' => 'no-colvis',
@@ -89,7 +90,7 @@ public function configure(DataTable $dataTable, array $options): void
'label' => $this->translator->trans('part.table.name'),
'orderField' => 'NATSORT(part.name)',
'render' => function ($value, AssemblyBOMEntry $context) {
- if(!$context->getPart() instanceof Part && !$context->getProject() instanceof Project) {
+ if(!$context->getPart() instanceof Part && !$context->getReferencedAssembly() instanceof Assembly && !$context->getProject() instanceof Project) {
return htmlspecialchars((string) $context->getName());
}
@@ -97,6 +98,13 @@ public function configure(DataTable $dataTable, array $options): void
$tmp = $this->partDataTableHelper->renderName($context->getPart());
$tmp = $this->translator->trans('part.table.name.value.for_part', ['%value%' => $tmp]);
+ if($context->getName() !== null && $context->getName() !== '') {
+ $tmp .= ' '.htmlspecialchars($context->getName()).'';
+ }
+ } elseif ($context->getReferencedAssembly() !== null) {
+ $tmp = $this->assemblyDataTableHelper->renderName($context->getReferencedAssembly());
+ $tmp = $this->translator->trans('part.table.name.value.for_assembly', ['%value%' => $tmp]);
+
if($context->getName() !== null && $context->getName() !== '') {
$tmp .= ' '.htmlspecialchars($context->getName()).'';
}
@@ -127,59 +135,15 @@ public function configure(DataTable $dataTable, array $options): void
->add('description', MarkdownColumn::class, [
'label' => $this->translator->trans('part.table.description'),
'data' => function (AssemblyBOMEntry $context) {
- if($context->getPart() instanceof Part) {
+ if ($context->getPart() instanceof Part) {
return $context->getPart()->getDescription();
+ } elseif ($context->getReferencedAssembly() instanceof Assembly) {
+ return $context->getReferencedAssembly()->getDescription();
}
//For non-part BOM entries show the comment field
return $context->getComment();
},
])
- ->add('category', EntityColumn::class, [
- 'label' => $this->translator->trans('part.table.category'),
- 'property' => 'part.category',
- 'orderField' => 'NATSORT(category.name)',
- ])
- ->add('footprint', EntityColumn::class, [
- 'property' => 'part.footprint',
- 'label' => $this->translator->trans('part.table.footprint'),
- 'orderField' => 'NATSORT(footprint.name)',
- ])
- ->add('manufacturer', EntityColumn::class, [
- 'property' => 'part.manufacturer',
- 'label' => $this->translator->trans('part.table.manufacturer'),
- 'orderField' => 'NATSORT(manufacturer.name)',
- ])
- ->add('mountnames', TextColumn::class, [
- 'label' => 'assembly.bom.mountnames',
- 'render' => function ($value, AssemblyBOMEntry $context) {
- $html = '';
-
- foreach (explode(',', $context->getMountnames()) as $mountname) {
- $html .= sprintf('%s ', htmlspecialchars($mountname));
- }
- return $html;
- },
- ])
- ->add('instockAmount', TextColumn::class, [
- 'label' => 'assembly.bom.instockAmount',
- 'render' => function ($value, AssemblyBOMEntry $context) {
- if ($context->getPart() !== null) {
- return $this->partDataTableHelper->renderAmount($context->getPart());
- }
-
- return '';
- }
- ])
- ->add('storageLocations', TextColumn::class, [
- 'label' => 'part.table.storeLocations',
- 'render' => function ($value, AssemblyBOMEntry $context) {
- if ($context->getPart() !== null) {
- return $this->partDataTableHelper->renderStorageLocations($context->getPart());
- }
-
- return '';
- }
- ])
->add('addedDate', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.addedDate'),
])
@@ -189,8 +153,7 @@ public function configure(DataTable $dataTable, array $options): void
;
//Apply the user configured order and visibility and add the columns to the table
- $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,
- "TABLE_ASSEMBLIES_DEFAULT_COLUMNS");
+ $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,"TABLE_ASSEMBLIES_BOM_DEFAULT_COLUMNS");
$dataTable->addOrderBy('name');
@@ -214,6 +177,7 @@ private function getQuery(QueryBuilder $builder, array $options): void
->addSelect('part')
->from(AssemblyBOMEntry::class, 'bom_entry')
->leftJoin('bom_entry.part', 'part')
+ ->leftJoin('bom_entry.referencedAssembly', 'referencedAssembly')
->leftJoin('part.category', 'category')
->leftJoin('part.footprint', 'footprint')
->leftJoin('part.manufacturer', 'manufacturer')
From b7cb51d48c08b09672c6db4bd16bd90df32ad8b7 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 3 Jul 2025 13:47:20 +0200
Subject: [PATCH 18/83] =?UTF-8?q?Assembly=20Listen=C3=BCbersicht=20umsetze?=
=?UTF-8?q?n?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
assets/css/app/images.css | 5 +
docs/configuration.md | 3 +-
src/Controller/AssemblyController.php | 74 ++++++
src/DataTables/AssemblyDataTable.php | 249 ++++++++++++++++++
src/DataTables/Filters/AssemblyFilter.php | 68 +++++
.../Filters/AssemblySearchFilter.php | 183 +++++++++++++
.../Helpers/AssemblyDataTableHelper.php | 77 ++++++
.../Helpers/ProjectDataTableHelper.php | 2 +-
src/Form/Filters/AssemblyFilterType.php | 114 ++++++++
.../assemblies/lists/_action_bar.html.twig | 6 +
templates/assemblies/lists/_filter.html.twig | 62 +++++
templates/assemblies/lists/all_list.html.twig | 30 +++
templates/assemblies/lists/data.html.twig | 3 +
translations/messages.cs.xlf | 126 +++++++++
translations/messages.da.xlf | 126 +++++++++
translations/messages.de.xlf | 126 +++++++++
translations/messages.el.xlf | 126 +++++++++
translations/messages.en.xlf | 126 +++++++++
translations/messages.es.xlf | 126 +++++++++
translations/messages.fr.xlf | 126 +++++++++
translations/messages.it.xlf | 126 +++++++++
translations/messages.ja.xlf | 126 +++++++++
translations/messages.nl.xlf | 126 +++++++++
translations/messages.pl.xlf | 126 +++++++++
translations/messages.ru.xlf | 126 +++++++++
translations/messages.zh.xlf | 126 +++++++++
26 files changed, 2511 insertions(+), 3 deletions(-)
create mode 100644 src/DataTables/AssemblyDataTable.php
create mode 100644 src/DataTables/Filters/AssemblyFilter.php
create mode 100644 src/DataTables/Filters/AssemblySearchFilter.php
create mode 100644 src/DataTables/Helpers/AssemblyDataTableHelper.php
create mode 100644 src/Form/Filters/AssemblyFilterType.php
create mode 100644 templates/assemblies/lists/_action_bar.html.twig
create mode 100644 templates/assemblies/lists/_filter.html.twig
create mode 100644 templates/assemblies/lists/all_list.html.twig
create mode 100644 templates/assemblies/lists/data.html.twig
diff --git a/assets/css/app/images.css b/assets/css/app/images.css
index 0212a85b7..132cab99b 100644
--- a/assets/css/app/images.css
+++ b/assets/css/app/images.css
@@ -61,3 +61,8 @@
.object-fit-cover {
object-fit: cover;
}
+
+.assembly-table-image {
+ max-height: 40px;
+ object-fit: contain;
+}
diff --git a/docs/configuration.md b/docs/configuration.md
index 498308b00..242164bf5 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -137,8 +137,7 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `storage_location`, `amount`, `minamount`, `partUnit`, `addedDate`, `lastModified`, `needs_review`, `favorite`, `manufacturing_status`, `manufacturer_product_number`, `mass`, `tags`, `attachments`, `edit`.
-* `TABLE_ASSEMBLIES_DEFAULT_COLUMNS`: The columns in assemblies tables, which are visible by default (when loading table for first
- time).
+* `TABLE_ASSEMBLIES_DEFAULT_COLUMNS`: The columns in assemblies tables, which are visible by default (when loading table for first time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `referencedAssemblies`, `edit`, `addedDate`, `lastModified`.
* `TABLE_ASSEMBLIES_BOM_DEFAULT_COLUMNS`: The columns in assemblies bom tables, which are visible by default (when loading table for first time).
diff --git a/src/Controller/AssemblyController.php b/src/Controller/AssemblyController.php
index 9106f6775..a1ba7fa65 100644
--- a/src/Controller/AssemblyController.php
+++ b/src/Controller/AssemblyController.php
@@ -23,15 +23,22 @@
namespace App\Controller;
use App\DataTables\AssemblyBomEntriesDataTable;
+use App\DataTables\AssemblyDataTable;
+use App\DataTables\ErrorDataTable;
+use App\DataTables\Filters\AssemblyFilter;
use App\Entity\AssemblySystem\Assembly;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
use App\Entity\Parts\Part;
+use App\Exceptions\InvalidRegexException;
use App\Form\AssemblySystem\AssemblyAddPartsType;
use App\Form\AssemblySystem\AssemblyBuildType;
+use App\Form\Filters\AssemblyFilterType;
use App\Helpers\Assemblies\AssemblyBuildRequest;
use App\Services\ImportExportSystem\BOMImporter;
use App\Services\AssemblySystem\AssemblyBuildHelper;
+use App\Services\Trees\NodesListBuilder;
use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\DBAL\Exception\DriverException;
use Doctrine\ORM\EntityManagerInterface;
use League\Csv\SyntaxError;
use Omines\DataTablesBundle\DataTableFactory;
@@ -54,9 +61,76 @@ class AssemblyController extends AbstractController
public function __construct(
private readonly DataTableFactory $dataTableFactory,
private readonly TranslatorInterface $translator,
+ private readonly NodesListBuilder $nodesListBuilder
) {
}
+ #[Route(path: '/list', name: 'assemblies_list')]
+ public function showAll(Request $request): Response
+ {
+ return $this->showListWithFilter($request,'assemblies/lists/all_list.html.twig');
+ }
+
+ /**
+ * Common implementation for the part list pages.
+ * @param Request $request The request to parse
+ * @param string $template The template that should be rendered
+ * @param callable|null $filter_changer A function that is called with the filter object as parameter. This function can be used to customize the filter
+ * @param callable|null $form_changer A function that is called with the form object as parameter. This function can be used to customize the form
+ * @param array $additonal_template_vars Any additional template variables that should be passed to the template
+ * @param array $additional_table_vars Any additional variables that should be passed to the table creation
+ */
+ protected function showListWithFilter(Request $request, string $template, ?callable $filter_changer = null, ?callable $form_changer = null, array $additonal_template_vars = [], array $additional_table_vars = []): Response
+ {
+ $this->denyAccessUnlessGranted('@assemblies.read');
+
+ $formRequest = clone $request;
+ $formRequest->setMethod('GET');
+ $filter = new AssemblyFilter($this->nodesListBuilder);
+ if($filter_changer !== null){
+ $filter_changer($filter);
+ }
+
+ $filterForm = $this->createForm(AssemblyFilterType::class, $filter, ['method' => 'GET']);
+ if($form_changer !== null) {
+ $form_changer($filterForm);
+ }
+
+ $filterForm->handleRequest($formRequest);
+
+ $table = $this->dataTableFactory->createFromType(
+ AssemblyDataTable::class,
+ array_merge(['filter' => $filter], $additional_table_vars),
+ ['lengthMenu' => AssemblyDataTable::LENGTH_MENU]
+ )
+ ->handleRequest($request);
+
+ if ($table->isCallback()) {
+ try {
+ try {
+ return $table->getResponse();
+ } catch (DriverException $driverException) {
+ if ($driverException->getCode() === 1139) {
+ //Convert the driver exception to InvalidRegexException so it has the same handler as for SQLite
+ throw InvalidRegexException::fromDriverException($driverException);
+ } else {
+ throw $driverException;
+ }
+ }
+ } catch (InvalidRegexException $exception) {
+ $errors = $this->translator->trans('assembly.table.invalid_regex').': '.$exception->getReason();
+ $request->request->set('order', []);
+
+ return ErrorDataTable::errorTable($this->dataTableFactory, $request, $errors);
+ }
+ }
+
+ return $this->render($template, array_merge([
+ 'datatable' => $table,
+ 'filterForm' => $filterForm->createView(),
+ ], $additonal_template_vars));
+ }
+
#[Route(path: '/{id}/info', name: 'assembly_info', requirements: ['id' => '\d+'])]
public function info(Assembly $assembly, Request $request, AssemblyBuildHelper $buildHelper): Response
{
diff --git a/src/DataTables/AssemblyDataTable.php b/src/DataTables/AssemblyDataTable.php
new file mode 100644
index 000000000..f3854ebca
--- /dev/null
+++ b/src/DataTables/AssemblyDataTable.php
@@ -0,0 +1,249 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace App\DataTables;
+
+use App\DataTables\Adapters\TwoStepORMAdapter;
+use App\DataTables\Column\IconLinkColumn;
+use App\DataTables\Column\LocaleDateTimeColumn;
+use App\DataTables\Column\MarkdownColumn;
+use App\DataTables\Column\SelectColumn;
+use App\DataTables\Filters\AssemblyFilter;
+use App\DataTables\Filters\AssemblySearchFilter;
+use App\DataTables\Helpers\AssemblyDataTableHelper;
+use App\DataTables\Helpers\ColumnSortHelper;
+use App\Doctrine\Helpers\FieldHelper;
+use App\Entity\AssemblySystem\Assembly;
+use App\Services\EntityURLGenerator;
+use Doctrine\ORM\AbstractQuery;
+use Doctrine\ORM\QueryBuilder;
+use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
+use Omines\DataTablesBundle\Column\TextColumn;
+use Omines\DataTablesBundle\DataTable;
+use Omines\DataTablesBundle\DataTableTypeInterface;
+use Symfony\Bundle\SecurityBundle\Security;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+final class AssemblyDataTable implements DataTableTypeInterface
+{
+ const LENGTH_MENU = [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]];
+
+ public function __construct(
+ private readonly EntityURLGenerator $urlGenerator,
+ private readonly TranslatorInterface $translator,
+ private readonly AssemblyDataTableHelper $assemblyDataTableHelper,
+ private readonly Security $security,
+ private readonly string $visible_columns,
+ private readonly ColumnSortHelper $csh,
+ ) {
+ }
+
+ public function configureOptions(OptionsResolver $optionsResolver): void
+ {
+ $optionsResolver->setDefaults([
+ 'filter' => null,
+ 'search' => null
+ ]);
+
+ $optionsResolver->setAllowedTypes('filter', [AssemblyFilter::class, 'null']);
+ $optionsResolver->setAllowedTypes('search', [AssemblySearchFilter::class, 'null']);
+ }
+
+ public function configure(DataTable $dataTable, array $options): void
+ {
+ $resolver = new OptionsResolver();
+ $this->configureOptions($resolver);
+ $options = $resolver->resolve($options);
+
+ $this->csh
+ ->add('select', SelectColumn::class, visibility_configurable: false)
+ ->add('picture', TextColumn::class, [
+ 'label' => '',
+ 'className' => 'no-colvis',
+ 'render' => fn($value, Assembly $context) => $this->assemblyDataTableHelper->renderPicture($context),
+ ], visibility_configurable: false)
+ ->add('name', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.name'),
+ 'render' => fn($value, Assembly $context) => $this->assemblyDataTableHelper->renderName($context),
+ 'orderField' => 'NATSORT(assembly.name)'
+ ])
+ ->add('id', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.id'),
+ ])
+ ->add('ipn', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.ipn'),
+ 'orderField' => 'NATSORT(assembly.ipn)'
+ ])
+ ->add('description', MarkdownColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.description'),
+ ])
+ ->add('addedDate', LocaleDateTimeColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.addedDate'),
+ ])
+ ->add('lastModified', LocaleDateTimeColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.lastModified'),
+ ]);
+
+ //Add a assembly column to list where the assembly is used as referenced assembly as bom-entry, when the user has the permission to see the assemblies
+ if ($this->security->isGranted('read', Assembly::class)) {
+ $this->csh->add('referencedAssemblies', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.referencedAssembly.labelp'),
+ 'render' => function ($value, Assembly $context): string {
+ $assemblies = $context->getReferencedAssemblies();
+
+ $max = 5;
+ $tmp = "";
+
+ for ($i = 0; $i < min($max, count($assemblies)); $i++) {
+ $url = $this->urlGenerator->infoURL($assemblies[$i]);
+ $tmp .= sprintf('%s', $url, htmlspecialchars($assemblies[$i]->getName()));
+ if ($i < count($assemblies) - 1) {
+ $tmp .= ", ";
+ }
+ }
+
+ if (count($assemblies) > $max) {
+ $tmp .= ", + ".(count($assemblies) - $max);
+ }
+
+ return $tmp;
+ }
+ ]);
+ }
+
+ $this->csh
+ ->add('edit', IconLinkColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.edit'),
+ 'href' => fn($value, Assembly $context) => $this->urlGenerator->editURL($context),
+ 'disabled' => fn($value, Assembly $context) => !$this->security->isGranted('edit', $context),
+ 'title' => $this->translator->trans('assembly.table.edit.title'),
+ ]);
+
+ //Apply the user configured order and visibility and add the columns to the table
+ $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns, "TABLE_ASSEMBLIES_DEFAULT_COLUMNS");
+
+ $dataTable->addOrderBy('name')
+ ->createAdapter(TwoStepORMAdapter::class, [
+ 'filter_query' => $this->getFilterQuery(...),
+ 'detail_query' => $this->getDetailQuery(...),
+ 'entity' => Assembly::class,
+ 'hydrate' => AbstractQuery::HYDRATE_OBJECT,
+ //Use the simple total query, as we just want to get the total number of assemblies without any conditions
+ //For this the normal query would be pretty slow
+ 'simple_total_query' => true,
+ 'criteria' => [
+ function (QueryBuilder $builder) use ($options): void {
+ $this->buildCriteria($builder, $options);
+ },
+ new SearchCriteriaProvider(),
+ ],
+ 'query_modifier' => $this->addJoins(...),
+ ]);
+ }
+
+
+ private function getFilterQuery(QueryBuilder $builder): void
+ {
+ /* In the filter query we only select the IDs. The fetching of the full entities is done in the detail query.
+ * We only need to join the entities here, so we can filter by them.
+ * The filter conditions are added to this QB in the buildCriteria method.
+ *
+ * The amountSum field and the joins are dynamically added by the addJoins method, if the fields are used in the query.
+ * This improves the performance, as we do not need to join all tables, if we do not need them.
+ */
+ $builder
+ ->select('assembly.id')
+ ->from(Assembly::class, 'assembly')
+
+ //The other group by fields, are dynamically added by the addJoins method
+ ->addGroupBy('assembly');
+ }
+
+ private function getDetailQuery(QueryBuilder $builder, array $filter_results): void
+ {
+ $ids = array_map(static fn($row) => $row['id'], $filter_results);
+
+ /*
+ * In this query we take the IDs which were filtered, paginated and sorted in the filter query, and fetch the
+ * full entities.
+ * We can do complex fetch joins, as we do not need to filter or sort here (which would kill the performance).
+ * The only condition should be for the IDs.
+ * It is important that elements are ordered the same way, as the IDs are passed, or ordering will be wrong.
+ *
+ * We do not require the subqueries like amountSum here, as it is not used to render the table (and only for sorting)
+ */
+ $builder
+ ->select('assembly')
+ ->addSelect('master_picture_attachment')
+ ->addSelect('attachments')
+ ->from(Assembly::class, 'assembly')
+ ->leftJoin('assembly.master_picture_attachment', 'master_picture_attachment')
+ ->leftJoin('assembly.attachments', 'attachments')
+ ->where('assembly.id IN (:ids)')
+ ->setParameter('ids', $ids)
+ ->addGroupBy('assembly')
+ ->addGroupBy('master_picture_attachment')
+ ->addGroupBy('attachments');
+
+ //Get the results in the same order as the IDs were passed
+ FieldHelper::addOrderByFieldParam($builder, 'assembly.id', 'ids');
+ }
+
+ /**
+ * This function is called right before the filter query is executed.
+ * We use it to dynamically add joins to the query, if the fields are used in the query.
+ * @param QueryBuilder $builder
+ * @return QueryBuilder
+ */
+ private function addJoins(QueryBuilder $builder): QueryBuilder
+ {
+ //Check if the query contains certain conditions, for which we need to add additional joins
+ //The join fields get prefixed with an underscore, so we can check if they are used in the query easy without confusing them for a assembly subfield
+ $dql = $builder->getDQL();
+
+ if (str_contains($dql, '_master_picture_attachment')) {
+ $builder->leftJoin('assembly.master_picture_attachment', '_master_picture_attachment');
+ $builder->addGroupBy('_master_picture_attachment');
+ }
+ if (str_contains($dql, '_attachments')) {
+ $builder->leftJoin('assembly.attachments', '_attachments');
+ }
+
+ return $builder;
+ }
+
+ private function buildCriteria(QueryBuilder $builder, array $options): void
+ {
+ //Apply the search criterias first
+ if ($options['search'] instanceof AssemblySearchFilter) {
+ $search = $options['search'];
+ $search->apply($builder);
+ }
+
+ //We do the most stuff here in the filter class
+ if ($options['filter'] instanceof AssemblyFilter) {
+ $filter = $options['filter'];
+ $filter->apply($builder);
+ }
+ }
+}
diff --git a/src/DataTables/Filters/AssemblyFilter.php b/src/DataTables/Filters/AssemblyFilter.php
new file mode 100644
index 000000000..d8d07a1ec
--- /dev/null
+++ b/src/DataTables/Filters/AssemblyFilter.php
@@ -0,0 +1,68 @@
+.
+ */
+namespace App\DataTables\Filters;
+
+use App\DataTables\Filters\Constraints\DateTimeConstraint;
+use App\DataTables\Filters\Constraints\EntityConstraint;
+use App\DataTables\Filters\Constraints\IntConstraint;
+use App\DataTables\Filters\Constraints\TextConstraint;
+use App\Entity\Attachments\AttachmentType;
+use App\Services\Trees\NodesListBuilder;
+use Doctrine\ORM\QueryBuilder;
+
+class AssemblyFilter implements FilterInterface
+{
+
+ use CompoundFilterTrait;
+
+ public readonly IntConstraint $dbId;
+ public readonly TextConstraint $ipn;
+ public readonly TextConstraint $name;
+ public readonly TextConstraint $description;
+ public readonly TextConstraint $comment;
+ public readonly DateTimeConstraint $lastModified;
+ public readonly DateTimeConstraint $addedDate;
+
+ public readonly IntConstraint $attachmentsCount;
+ public readonly EntityConstraint $attachmentType;
+ public readonly TextConstraint $attachmentName;
+
+ public function __construct(NodesListBuilder $nodesListBuilder)
+ {
+ $this->name = new TextConstraint('assembly.name');
+ $this->description = new TextConstraint('assembly.description');
+ $this->comment = new TextConstraint('assembly.comment');
+ $this->dbId = new IntConstraint('assembly.id');
+ $this->ipn = new TextConstraint('assembly.ipn');
+ $this->addedDate = new DateTimeConstraint('assembly.addedDate');
+ $this->lastModified = new DateTimeConstraint('assembly.lastModified');
+ $this->attachmentsCount = new IntConstraint('COUNT(_attachments)');
+ $this->attachmentType = new EntityConstraint($nodesListBuilder, AttachmentType::class, '_attachments.attachment_type');
+ $this->attachmentName = new TextConstraint('_attachments.name');
+ }
+
+ public function apply(QueryBuilder $queryBuilder): void
+ {
+ $this->applyAllChildFilters($queryBuilder);
+ }
+}
diff --git a/src/DataTables/Filters/AssemblySearchFilter.php b/src/DataTables/Filters/AssemblySearchFilter.php
new file mode 100644
index 000000000..1627cc612
--- /dev/null
+++ b/src/DataTables/Filters/AssemblySearchFilter.php
@@ -0,0 +1,183 @@
+.
+ */
+namespace App\DataTables\Filters;
+use Doctrine\ORM\QueryBuilder;
+
+class AssemblySearchFilter implements FilterInterface
+{
+
+ /** @var boolean Whether to use regex for searching */
+ protected bool $regex = false;
+
+ /** @var bool Use name field for searching */
+ protected bool $name = true;
+
+ /** @var bool Use description for searching */
+ protected bool $description = true;
+
+ /** @var bool Use comment field for searching */
+ protected bool $comment = true;
+
+ /** @var bool Use ordernr for searching */
+ protected bool $ordernr = true;
+
+ /** @var bool Use Internal part number for searching */
+ protected bool $ipn = true;
+
+ public function __construct(
+ /** @var string The string to query for */
+ protected string $keyword
+ )
+ {
+ }
+
+ protected function getFieldsToSearch(): array
+ {
+ $fields_to_search = [];
+
+ if($this->name) {
+ $fields_to_search[] = 'assembly.name';
+ }
+ if($this->description) {
+ $fields_to_search[] = 'assembly.description';
+ }
+ if ($this->comment) {
+ $fields_to_search[] = 'assembly.comment';
+ }
+ if ($this->ipn) {
+ $fields_to_search[] = 'assembly.ipn';
+ }
+
+ return $fields_to_search;
+ }
+
+ public function apply(QueryBuilder $queryBuilder): void
+ {
+ $fields_to_search = $this->getFieldsToSearch();
+
+ //If we have nothing to search for, do nothing
+ if ($fields_to_search === [] || $this->keyword === '') {
+ return;
+ }
+
+ //Convert the fields to search to a list of expressions
+ $expressions = array_map(function (string $field): string {
+ if ($this->regex) {
+ return sprintf("REGEXP(%s, :search_query) = TRUE", $field);
+ }
+
+ return sprintf("ILIKE(%s, :search_query) = TRUE", $field);
+ }, $fields_to_search);
+
+ //Add Or concatenation of the expressions to our query
+ $queryBuilder->andWhere(
+ $queryBuilder->expr()->orX(...$expressions)
+ );
+
+ //For regex, we pass the query as is, for like we add % to the start and end as wildcards
+ if ($this->regex) {
+ $queryBuilder->setParameter('search_query', $this->keyword);
+ } else {
+ $queryBuilder->setParameter('search_query', '%' . $this->keyword . '%');
+ }
+ }
+
+ public function getKeyword(): string
+ {
+ return $this->keyword;
+ }
+
+ public function setKeyword(string $keyword): AssemblySearchFilter
+ {
+ $this->keyword = $keyword;
+ return $this;
+ }
+
+ public function isRegex(): bool
+ {
+ return $this->regex;
+ }
+
+ public function setRegex(bool $regex): AssemblySearchFilter
+ {
+ $this->regex = $regex;
+ return $this;
+ }
+
+ public function isName(): bool
+ {
+ return $this->name;
+ }
+
+ public function setName(bool $name): AssemblySearchFilter
+ {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function isCategory(): bool
+ {
+ return $this->category;
+ }
+
+ public function setCategory(bool $category): AssemblySearchFilter
+ {
+ $this->category = $category;
+ return $this;
+ }
+
+ public function isDescription(): bool
+ {
+ return $this->description;
+ }
+
+ public function setDescription(bool $description): AssemblySearchFilter
+ {
+ $this->description = $description;
+ return $this;
+ }
+
+ public function isIPN(): bool
+ {
+ return $this->ipn;
+ }
+
+ public function setIPN(bool $ipn): AssemblySearchFilter
+ {
+ $this->ipn = $ipn;
+ return $this;
+ }
+
+ public function isComment(): bool
+ {
+ return $this->comment;
+ }
+
+ public function setComment(bool $comment): AssemblySearchFilter
+ {
+ $this->comment = $comment;
+ return $this;
+ }
+
+
+}
diff --git a/src/DataTables/Helpers/AssemblyDataTableHelper.php b/src/DataTables/Helpers/AssemblyDataTableHelper.php
new file mode 100644
index 000000000..dda563ea4
--- /dev/null
+++ b/src/DataTables/Helpers/AssemblyDataTableHelper.php
@@ -0,0 +1,77 @@
+.
+ */
+
+namespace App\DataTables\Helpers;
+
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\Attachments\Attachment;
+use App\Services\Attachments\AssemblyPreviewGenerator;
+use App\Services\Attachments\AttachmentURLGenerator;
+use App\Services\EntityURLGenerator;
+
+/**
+ * A helper service which contains common code to render columns for assembly related tables
+ */
+class AssemblyDataTableHelper
+{
+ public function __construct(
+ private readonly EntityURLGenerator $entityURLGenerator,
+ private readonly AssemblyPreviewGenerator $previewGenerator,
+ private readonly AttachmentURLGenerator $attachmentURLGenerator
+ ) {
+ }
+
+ public function renderName(Assembly $context): string
+ {
+ $icon = '';
+
+ return sprintf(
+ '%s%s',
+ $this->entityURLGenerator->infoURL($context),
+ $icon,
+ htmlspecialchars($context->getName())
+ );
+ }
+
+ public function renderPicture(Assembly $context): string
+ {
+ $preview_attachment = $this->previewGenerator->getTablePreviewAttachment($context);
+ if (!$preview_attachment instanceof Attachment) {
+ return '';
+ }
+
+ $title = htmlspecialchars($preview_attachment->getName());
+ if ($preview_attachment->getFilename()) {
+ $title .= ' ('.htmlspecialchars($preview_attachment->getFilename()).')';
+ }
+
+ return sprintf(
+ '',
+ 'Assembly image',
+ $this->attachmentURLGenerator->getThumbnailURL($preview_attachment),
+ $this->attachmentURLGenerator->getThumbnailURL($preview_attachment, 'thumbnail_md'),
+ 'hoverpic assembly-table-image',
+ $title
+ );
+ }
+}
diff --git a/src/DataTables/Helpers/ProjectDataTableHelper.php b/src/DataTables/Helpers/ProjectDataTableHelper.php
index 0118d5d56..baa0e24e1 100644
--- a/src/DataTables/Helpers/ProjectDataTableHelper.php
+++ b/src/DataTables/Helpers/ProjectDataTableHelper.php
@@ -27,7 +27,7 @@
use App\Services\EntityURLGenerator;
/**
- * A helper service which contains common code to render columns for assembly related tables
+ * A helper service which contains common code to render columns for project related tables
*/
class ProjectDataTableHelper
{
diff --git a/src/Form/Filters/AssemblyFilterType.php b/src/Form/Filters/AssemblyFilterType.php
new file mode 100644
index 000000000..acfbb1a8e
--- /dev/null
+++ b/src/Form/Filters/AssemblyFilterType.php
@@ -0,0 +1,114 @@
+.
+ */
+namespace App\Form\Filters;
+
+use App\DataTables\Filters\AssemblyFilter;
+use App\Entity\Attachments\AttachmentType;
+use App\Form\Filters\Constraints\DateTimeConstraintType;
+use App\Form\Filters\Constraints\NumberConstraintType;
+use App\Form\Filters\Constraints\StructuralEntityConstraintType;
+use App\Form\Filters\Constraints\TextConstraintType;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\ResetType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class AssemblyFilterType extends AbstractType
+{
+ public function configureOptions(OptionsResolver $resolver): void
+ {
+ $resolver->setDefaults([
+ 'compound' => true,
+ 'data_class' => AssemblyFilter::class,
+ 'csrf_protection' => false,
+ ]);
+ }
+
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ /*
+ * Common tab
+ */
+
+ $builder->add('name', TextConstraintType::class, [
+ 'label' => 'assembly.filter.name',
+ ]);
+
+ $builder->add('description', TextConstraintType::class, [
+ 'label' => 'assembly.filter.description',
+ ]);
+
+ $builder->add('comment', TextConstraintType::class, [
+ 'label' => 'assembly.filter.comment'
+ ]);
+
+ /*
+ * Advanced tab
+ */
+
+ $builder->add('dbId', NumberConstraintType::class, [
+ 'label' => 'assembly.filter.dbId',
+ 'min' => 1,
+ 'step' => 1,
+ ]);
+
+ $builder->add('ipn', TextConstraintType::class, [
+ 'label' => 'assembly.filter.ipn',
+ ]);
+
+ $builder->add('lastModified', DateTimeConstraintType::class, [
+ 'label' => 'lastModified'
+ ]);
+
+ $builder->add('addedDate', DateTimeConstraintType::class, [
+ 'label' => 'createdAt'
+ ]);
+
+ /**
+ * Attachments count
+ */
+ $builder->add('attachmentsCount', NumberConstraintType::class, [
+ 'label' => 'assembly.filter.attachments_count',
+ 'step' => 1,
+ 'min' => 0,
+ ]);
+
+ $builder->add('attachmentType', StructuralEntityConstraintType::class, [
+ 'label' => 'attachment.attachment_type',
+ 'entity_class' => AttachmentType::class
+ ]);
+
+ $builder->add('attachmentName', TextConstraintType::class, [
+ 'label' => 'assembly.filter.attachmentName',
+ ]);
+
+ $builder->add('submit', SubmitType::class, [
+ 'label' => 'filter.submit',
+ ]);
+
+ $builder->add('discard', ResetType::class, [
+ 'label' => 'filter.discard',
+ ]);
+ }
+}
diff --git a/templates/assemblies/lists/_action_bar.html.twig b/templates/assemblies/lists/_action_bar.html.twig
new file mode 100644
index 000000000..37289812a
--- /dev/null
+++ b/templates/assemblies/lists/_action_bar.html.twig
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/templates/assemblies/lists/_filter.html.twig b/templates/assemblies/lists/_filter.html.twig
new file mode 100644
index 000000000..11be7bc24
--- /dev/null
+++ b/templates/assemblies/lists/_filter.html.twig
@@ -0,0 +1,62 @@
+
+
+ {% trans %}filter.title{% endtrans %}
+
+
+
+
+
+ {% trans %}assembly.edit.tab.common{% endtrans %}
+
+
+ {% trans %}assembly.edit.tab.advanced{% endtrans %}
+
+
+ {% trans %}assembly.edit.tab.attachments{% endtrans %}
+
+
+ {# Retain the query parameters of the search form if it is existing #}
+ {% if searchFilter is defined %}
+ {% for property, value in searchFilter|to_array %}
+
+ {% endfor %}
+
+ {% endif %}
+
+ {{ form_end(filterForm) }}
+
+
+
\ No newline at end of file
diff --git a/templates/assemblies/lists/all_list.html.twig b/templates/assemblies/lists/all_list.html.twig
new file mode 100644
index 000000000..70d75ad40
--- /dev/null
+++ b/templates/assemblies/lists/all_list.html.twig
@@ -0,0 +1,30 @@
+{% extends "base.html.twig" %}
+
+{% block title %}
+ {% trans %}assembly_list.all.title{% endtrans %}
+{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+ {% trans %}assembly_list.all.title{% endtrans %}
+
+
+
+
+
+
+
+
+
+ {% include "assemblies/lists/_filter.html.twig" %}
+
+
+ {% include "assemblies/lists/_action_bar.html.twig" with {'url_options': {}} %}
+ {% include "assemblies/lists/data.html.twig" %}
+
+{% endblock %}
diff --git a/templates/assemblies/lists/data.html.twig b/templates/assemblies/lists/data.html.twig
new file mode 100644
index 000000000..69e13e4f5
--- /dev/null
+++ b/templates/assemblies/lists/data.html.twig
@@ -0,0 +1,3 @@
+{% import "components/datatables.macro.html.twig" as datatables %}
+
+{{ datatables.partsDatatableWithForm(datatable) }}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index ce79aaced..a1ede652a 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -14655,5 +14655,131 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Minimální šířka náhledu (px)
+
+
+ assembly_list.all.title
+ Všechny sestavy
+
+
+
+
+ assembly.edit.tab.common
+ Obecné
+
+
+
+
+ assembly.edit.tab.advanced
+ Pokročilé možnosti
+
+
+
+
+ assembly.edit.tab.attachments
+ Přílohy
+
+
+
+
+ assembly.filter.dbId
+ ID databáze
+
+
+
+
+ assembly.filter.ipn
+ Interní číslo dílu (IPN)
+
+
+
+
+ assembly.filter.name
+ Název
+
+
+
+
+ assembly.filter.description
+ Popis
+
+
+
+
+ assembly.filter.comment
+ Poznámky
+
+
+
+
+ assembly.filter.attachments_count
+ Počet příloh
+
+
+
+
+ assembly.filter.attachmentName
+ Název přílohy
+
+
+
+
+ assemblies.create.btn
+ Vytvořit novou sestavu
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Název
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Popis
+
+
+
+
+ assembly.table.addedDate
+ Přidáno
+
+
+
+
+ assembly.table.lastModified
+ Naposledy upraveno
+
+
+
+
+ assembly.table.edit
+ Upravit
+
+
+
+
+ assembly.table.edit.title
+ Upravit sestavu
+
+
+
+
+ assembly.table.invalid_regex
+ Neplatný regulární výraz (regex)
+
+
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index c68acdd4b..5901e9f5a 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -13336,5 +13336,131 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
+
+
+ assembly_list.all.title
+ Alle samlinger
+
+
+
+
+ assembly.edit.tab.common
+ Generelt
+
+
+
+
+ assembly.edit.tab.advanced
+ Avancerede indstillinger
+
+
+
+
+ assembly.edit.tab.attachments
+ Vedhæftede filer
+
+
+
+
+ assembly.filter.dbId
+ Database-ID
+
+
+
+
+ assembly.filter.ipn
+ Internt delnummer (IPN)
+
+
+
+
+ assembly.filter.name
+ Navn
+
+
+
+
+ assembly.filter.description
+ Beskrivelse
+
+
+
+
+ assembly.filter.comment
+ Kommentarer
+
+
+
+
+ assembly.filter.attachments_count
+ Antal vedhæftninger
+
+
+
+
+ assembly.filter.attachmentName
+ Vedhæftningens navn
+
+
+
+
+ assemblies.create.btn
+ Opret ny samling
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Navn
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Beskrivelse
+
+
+
+
+ assembly.table.addedDate
+ Tilføjet
+
+
+
+
+ assembly.table.lastModified
+ Sidst ændret
+
+
+
+
+ assembly.table.edit
+ Rediger
+
+
+
+
+ assembly.table.edit.title
+ Rediger samling
+
+
+
+
+ assembly.table.invalid_regex
+ Ugyldigt regulært udtryk (regex)
+
+
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index bee171d41..a7ece41a9 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -14621,5 +14621,131 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Min. Vorschaubilde-Breite (px)
+
+
+ assembly_list.all.title
+ Alle Baugruppen
+
+
+
+
+ assembly.edit.tab.common
+ Allgemein
+
+
+
+
+ assembly.edit.tab.advanced
+ Erweiterte Optionen
+
+
+
+
+ assembly.edit.tab.attachments
+ Dateianhänge
+
+
+
+
+ assembly.filter.dbId
+ Datenbank ID
+
+
+
+
+ assembly.filter.ipn
+ Internal Part Number (IPN)
+
+
+
+
+ assembly.filter.name
+ Name
+
+
+
+
+ assembly.filter.description
+ Beschreibung
+
+
+
+
+ assembly.filter.comment
+ Notizen
+
+
+
+
+ assembly.filter.attachments_count
+ Anzahl der Anhänge
+
+
+
+
+ assembly.filter.attachmentName
+ Name des Anhangs
+
+
+
+
+ assemblies.create.btn
+ Neue Baugruppe anlegen
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Name
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Beschreibung
+
+
+
+
+ assembly.table.addedDate
+ Hinzugefügt
+
+
+
+
+ assembly.table.lastModified
+ Zuletzt bearbeitet
+
+
+
+
+ assembly.table.edit
+ Ändern
+
+
+
+
+ assembly.table.edit.title
+ Baugruppe ändern
+
+
+
+
+ assembly.table.invalid_regex
+ Ungültiger regulärer Ausdruck (regex)
+
+
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index 97b27f53f..fd5114539 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -2344,5 +2344,131 @@
+
+
+ assembly_list.all.title
+ Όλες οι συναρμολογήσεις
+
+
+
+
+ assembly.edit.tab.common
+ Γενικά
+
+
+
+
+ assembly.edit.tab.advanced
+ Προηγμένες επιλογές
+
+
+
+
+ assembly.edit.tab.attachments
+ Συνημμένα
+
+
+
+
+ assembly.filter.dbId
+ Αναγνωριστικό βάσης δεδομένων
+
+
+
+
+ assembly.filter.ipn
+ Εσωτερικός αριθμός εξαρτήματος (IPN)
+
+
+
+
+ assembly.filter.name
+ Όνομα
+
+
+
+
+ assembly.filter.description
+ Περιγραφή
+
+
+
+
+ assembly.filter.comment
+ Σχόλια
+
+
+
+
+ assembly.filter.attachments_count
+ Αριθμός συνημμένων
+
+
+
+
+ assembly.filter.attachmentName
+ Όνομα συνημμένου
+
+
+
+
+ assemblies.create.btn
+ Δημιουργία νέας συναρμολόγησης
+
+
+
+
+ assembly.table.id
+ Αναγνωριστικό
+
+
+
+
+ assembly.table.name
+ Όνομα
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Περιγραφή
+
+
+
+
+ assembly.table.addedDate
+ Προστέθηκε
+
+
+
+
+ assembly.table.lastModified
+ Τελευταία επεξεργασία
+
+
+
+
+ assembly.table.edit
+ Επεξεργασία
+
+
+
+
+ assembly.table.edit.title
+ Επεξεργασία συναρμολόγησης
+
+
+
+
+ assembly.table.invalid_regex
+ Μη έγκυρη κανονική έκφραση (regex)
+
+
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 4f398d6b0..c4f7c60f9 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -14622,5 +14622,131 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Preview image min width (px)
+
+
+ assembly_list.all.title
+ All assemblies
+
+
+
+
+ assembly.edit.tab.common
+ General
+
+
+
+
+ assembly.edit.tab.advanced
+ Advanced options
+
+
+
+
+ assembly.edit.tab.attachments
+ Attachments
+
+
+
+
+ assembly.filter.dbId
+ Database ID
+
+
+
+
+ assembly.filter.ipn
+ Internal Part Number (IPN)
+
+
+
+
+ assembly.filter.name
+ Name
+
+
+
+
+ assembly.filter.description
+ Description
+
+
+
+
+ assembly.filter.comment
+ Comments
+
+
+
+
+ assembly.filter.attachments_count
+ Number of attachments
+
+
+
+
+ assembly.filter.attachmentName
+ Attachment name
+
+
+
+
+ assemblies.create.btn
+ Create new assembly
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Name
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Description
+
+
+
+
+ assembly.table.addedDate
+ Added
+
+
+
+
+ assembly.table.lastModified
+ Last modified
+
+
+
+
+ assembly.table.edit
+ Edit
+
+
+
+
+ assembly.table.edit.title
+ Edit assembly
+
+
+
+
+ assembly.table.invalid_regex
+ Invalid regular expression (regex)
+
+
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index b67198a78..461e7a7b1 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -13508,5 +13508,131 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Este componente contiene más de un stock. Cambie la ubicación manualmente para seleccionar el stock deseado.
+
+
+ assembly_list.all.title
+ Todas las ensamblajes
+
+
+
+
+ assembly.edit.tab.common
+ General
+
+
+
+
+ assembly.edit.tab.advanced
+ Opciones avanzadas
+
+
+
+
+ assembly.edit.tab.attachments
+ Archivos adjuntos
+
+
+
+
+ assembly.filter.dbId
+ ID de la base de datos
+
+
+
+
+ assembly.filter.ipn
+ Número interno de pieza (IPN)
+
+
+
+
+ assembly.filter.name
+ Nombre
+
+
+
+
+ assembly.filter.description
+ Descripción
+
+
+
+
+ assembly.filter.comment
+ Comentarios
+
+
+
+
+ assembly.filter.attachments_count
+ Cantidad de adjuntos
+
+
+
+
+ assembly.filter.attachmentName
+ Nombre del adjunto
+
+
+
+
+ assemblies.create.btn
+ Crear una nueva ensamblaje
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Nombre
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Descripción
+
+
+
+
+ assembly.table.addedDate
+ Añadido
+
+
+
+
+ assembly.table.lastModified
+ Última modificación
+
+
+
+
+ assembly.table.edit
+ Editar
+
+
+
+
+ assembly.table.edit.title
+ Editar ensamblaje
+
+
+
+
+ assembly.table.invalid_regex
+ Expresión regular no válida (regex)
+
+
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index ecfcf5928..fe470e449 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -9918,5 +9918,131 @@ exemple de ville
+
+
+ assembly_list.all.title
+ Toutes les assemblages
+
+
+
+
+ assembly.edit.tab.common
+ Général
+
+
+
+
+ assembly.edit.tab.advanced
+ Options avancées
+
+
+
+
+ assembly.edit.tab.attachments
+ Pièces jointes
+
+
+
+
+ assembly.filter.dbId
+ ID de la base de données
+
+
+
+
+ assembly.filter.ipn
+ Numéro de pièce interne (IPN)
+
+
+
+
+ assembly.filter.name
+ Nom
+
+
+
+
+ assembly.filter.description
+ Description
+
+
+
+
+ assembly.filter.comment
+ Commentaires
+
+
+
+
+ assembly.filter.attachments_count
+ Nombre de pièces jointes
+
+
+
+
+ assembly.filter.attachmentName
+ Nom de la pièce jointe
+
+
+
+
+ assemblies.create.btn
+ Créer un nouvel assemblage
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Nom
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Description
+
+
+
+
+ assembly.table.addedDate
+ Ajouté
+
+
+
+
+ assembly.table.lastModified
+ Dernière modification
+
+
+
+
+ assembly.table.edit
+ Modifier
+
+
+
+
+ assembly.table.edit.title
+ Modifier l'assemblage
+
+
+
+
+ assembly.table.invalid_regex
+ Expression régulière invalide (regex)
+
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index 12e20ca2c..c727eef82 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -13510,5 +13510,131 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Questo componente contiene più di uno stock. Cambia manualmente la posizione per selezionare quale stock scegliere.
+
+
+ assembly_list.all.title
+ Tutti gli assiemi
+
+
+
+
+ assembly.edit.tab.common
+ Generale
+
+
+
+
+ assembly.edit.tab.advanced
+ Opzioni avanzate
+
+
+
+
+ assembly.edit.tab.attachments
+ Allegati
+
+
+
+
+ assembly.filter.dbId
+ ID del database
+
+
+
+
+ assembly.filter.ipn
+ Numero interno di parte (IPN)
+
+
+
+
+ assembly.filter.name
+ Nome
+
+
+
+
+ assembly.filter.description
+ Descrizione
+
+
+
+
+ assembly.filter.comment
+ Commenti
+
+
+
+
+ assembly.filter.attachments_count
+ Numero di allegati
+
+
+
+
+ assembly.filter.attachmentName
+ Nome dell'allegato
+
+
+
+
+ assemblies.create.btn
+ Crea un nuovo assieme
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Nome
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Descrizione
+
+
+
+
+ assembly.table.addedDate
+ Aggiunto
+
+
+
+
+ assembly.table.lastModified
+ Ultima modifica
+
+
+
+
+ assembly.table.edit
+ Modifica
+
+
+
+
+ assembly.table.edit.title
+ Modifica l'assieme
+
+
+
+
+ assembly.table.invalid_regex
+ Espressione regolare non valida (regex)
+
+
diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf
index b7be7490d..157b1cf26 100644
--- a/translations/messages.ja.xlf
+++ b/translations/messages.ja.xlf
@@ -9631,5 +9631,131 @@ Exampletown
+
+
+ assembly_list.all.title
+ すべてのアセンブリ
+
+
+
+
+ assembly.edit.tab.common
+ 一般
+
+
+
+
+ assembly.edit.tab.advanced
+ 詳細オプション
+
+
+
+
+ assembly.edit.tab.attachments
+ 添付ファイル
+
+
+
+
+ assembly.filter.dbId
+ データベースID
+
+
+
+
+ assembly.filter.ipn
+ 内部部品番号(IPN)
+
+
+
+
+ assembly.filter.name
+ 名前
+
+
+
+
+ assembly.filter.description
+ 説明
+
+
+
+
+ assembly.filter.comment
+ コメント
+
+
+
+
+ assembly.filter.attachments_count
+ 添付ファイルの数
+
+
+
+
+ assembly.filter.attachmentName
+ 添付ファイル名
+
+
+
+
+ assemblies.create.btn
+ 新しいアセンブリを作成
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ 名前
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ 説明
+
+
+
+
+ assembly.table.addedDate
+ 追加日
+
+
+
+
+ assembly.table.lastModified
+ 最終変更
+
+
+
+
+ assembly.table.edit
+ 編集
+
+
+
+
+ assembly.table.edit.title
+ アセンブリを編集
+
+
+
+
+ assembly.table.invalid_regex
+ 無効な正規表現(regex)
+
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index fe17c3aca..44a48dcb3 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -1569,5 +1569,131 @@
+
+
+ assembly_list.all.title
+ Alle assemblages
+
+
+
+
+ assembly.edit.tab.common
+ Algemeen
+
+
+
+
+ assembly.edit.tab.advanced
+ Geavanceerde opties
+
+
+
+
+ assembly.edit.tab.attachments
+ Bijlagen
+
+
+
+
+ assembly.filter.dbId
+ Database-ID
+
+
+
+
+ assembly.filter.ipn
+ Intern partnummer (IPN)
+
+
+
+
+ assembly.filter.name
+ Naam
+
+
+
+
+ assembly.filter.description
+ Beschrijving
+
+
+
+
+ assembly.filter.comment
+ Opmerkingen
+
+
+
+
+ assembly.filter.attachments_count
+ Aantal bijlagen
+
+
+
+
+ assembly.filter.attachmentName
+ Naam van de bijlage
+
+
+
+
+ assemblies.create.btn
+ Nieuwe assemblage aanmaken
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Naam
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Beschrijving
+
+
+
+
+ assembly.table.addedDate
+ Toegevoegd
+
+
+
+
+ assembly.table.lastModified
+ Laatst gewijzigd
+
+
+
+
+ assembly.table.edit
+ Bewerken
+
+
+
+
+ assembly.table.edit.title
+ Assemblage bewerken
+
+
+
+
+ assembly.table.invalid_regex
+ Ongeldige reguliere expressie (regex)
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index 73b6e4fcc..171c585d6 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -13363,5 +13363,131 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
+
+
+ assembly_list.all.title
+ Wszystkie zespoły
+
+
+
+
+ assembly.edit.tab.common
+ Ogólne
+
+
+
+
+ assembly.edit.tab.advanced
+ Zaawansowane
+
+
+
+
+ assembly.edit.tab.attachments
+ Załączniki
+
+
+
+
+ assembly.filter.dbId
+ ID bazy danych
+
+
+
+
+ assembly.filter.ipn
+ Wewnętrzny numer części (IPN)
+
+
+
+
+ assembly.filter.name
+ Nazwa
+
+
+
+
+ assembly.filter.description
+ Opis
+
+
+
+
+ assembly.filter.comment
+ Komentarze
+
+
+
+
+ assembly.filter.attachments_count
+ Liczba załączników
+
+
+
+
+ assembly.filter.attachmentName
+ Nazwa załącznika
+
+
+
+
+ assemblies.create.btn
+ Utwórz nowy zespół
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Nazwa
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Opis
+
+
+
+
+ assembly.table.addedDate
+ Dodano
+
+
+
+
+ assembly.table.lastModified
+ Ostatnia modyfikacja
+
+
+
+
+ assembly.table.edit
+ Edytuj
+
+
+
+
+ assembly.table.edit.title
+ Edytuj zespół
+
+
+
+
+ assembly.table.invalid_regex
+ Nieprawidłowe wyrażenie regularne (regex)
+
+
diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf
index 751ff35f1..7bd0f3bc4 100644
--- a/translations/messages.ru.xlf
+++ b/translations/messages.ru.xlf
@@ -13463,5 +13463,131 @@
+
+
+ assembly_list.all.title
+ Все сборки
+
+
+
+
+ assembly.edit.tab.common
+ Общие
+
+
+
+
+ assembly.edit.tab.advanced
+ Дополнительные параметры
+
+
+
+
+ assembly.edit.tab.attachments
+ Вложения
+
+
+
+
+ assembly.filter.dbId
+ ID базы данных
+
+
+
+
+ assembly.filter.ipn
+ Внутренний номер детали (IPN)
+
+
+
+
+ assembly.filter.name
+ Название
+
+
+
+
+ assembly.filter.description
+ Описание
+
+
+
+
+ assembly.filter.comment
+ Комментарии
+
+
+
+
+ assembly.filter.attachments_count
+ Количество вложений
+
+
+
+
+ assembly.filter.attachmentName
+ Имя вложения
+
+
+
+
+ assemblies.create.btn
+ Создать новую сборку
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Название
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Описание
+
+
+
+
+ assembly.table.addedDate
+ Добавлено
+
+
+
+
+ assembly.table.lastModified
+ Последнее изменение
+
+
+
+
+ assembly.table.edit
+ Редактировать
+
+
+
+
+ assembly.table.edit.title
+ Редактировать сборку
+
+
+
+
+ assembly.table.invalid_regex
+ Неверное регулярное выражение (regex)
+
+
diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf
index 396feae3e..9e8d8aa1f 100644
--- a/translations/messages.zh.xlf
+++ b/translations/messages.zh.xlf
@@ -13348,5 +13348,131 @@ Element 3
+
+
+ assembly_list.all.title
+ 所有组件
+
+
+
+
+ assembly.edit.tab.common
+ 通用
+
+
+
+
+ assembly.edit.tab.advanced
+ 高级选项
+
+
+
+
+ assembly.edit.tab.attachments
+ 附件
+
+
+
+
+ assembly.filter.dbId
+ 数据库ID
+
+
+
+
+ assembly.filter.ipn
+ 内部零件编号(IPN)
+
+
+
+
+ assembly.filter.name
+ 名称
+
+
+
+
+ assembly.filter.description
+ 描述
+
+
+
+
+ assembly.filter.comment
+ 评论
+
+
+
+
+ assembly.filter.attachments_count
+ 附件数量
+
+
+
+
+ assembly.filter.attachmentName
+ 附件名称
+
+
+
+
+ assemblies.create.btn
+ 创建新组件
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ 名称
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ 描述
+
+
+
+
+ assembly.table.addedDate
+ 添加日期
+
+
+
+
+ assembly.table.lastModified
+ 最后修改
+
+
+
+
+ assembly.table.edit
+ 编辑
+
+
+
+
+ assembly.table.edit.title
+ 编辑组件
+
+
+
+
+ assembly.table.invalid_regex
+ 无效的正则表达式(regex)
+
+
From 6dd91521a0d6b1bfd4cf82074b36b5ae801bc840 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 3 Jul 2025 13:50:33 +0200
Subject: [PATCH 19/83] =?UTF-8?q?Assembly=20Konstanten=20in=20.env=20einf?=
=?UTF-8?q?=C3=BCgen=20bzw.=20anpassen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/.env b/.env
index 201633989..c530f312c 100644
--- a/.env
+++ b/.env
@@ -35,6 +35,9 @@ DATABASE_EMULATE_NATURAL_SORT=0
# This must end with a slash!
DEFAULT_URI="https://partdb.changeme.invalid/"
+# Use an %%ipn%% placeholder in the name of a assembly. Placeholder is replaced with the ipn input while saving.
+CREATE_ASSEMBLY_USE_IPN_PLACEHOLDER_IN_NAME=0
+
###################################################################################
# Email settings
###################################################################################
@@ -66,8 +69,9 @@ ERROR_PAGE_SHOW_HELP=1
# Configure which columns will be visible by default in the specific table (and in which order).
# This is a comma separated list of column names. See documentation for available values.
-TABLE_ASSEMBLIES_DEFAULT_COLUMNS=quantity,manufacturer,name,description,category
-
+TABLE_PARTS_DEFAULT_COLUMNS=name,description,category,footprint,manufacturer,storage_location,amount
+TABLE_ASSEMBLIES_DEFAULT_COLUMNS=id,ipn,name,description,referencedAssemblies,edit
+TABLE_ASSEMBLIES_BOM_DEFAULT_COLUMNS=quantity,id,ipn,name,description
###################################################################################
# SAML Single sign on-settings
From 657f9c935647183df4903ebedff75a224b6ef930 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 3 Jul 2025 14:47:19 +0200
Subject: [PATCH 20/83] Assembly getReferencedAssemblies korrigieren
---
src/Entity/AssemblySystem/Assembly.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php
index 5991b9e1d..9593dbb53 100644
--- a/src/Entity/AssemblySystem/Assembly.php
+++ b/src/Entity/AssemblySystem/Assembly.php
@@ -400,7 +400,7 @@ public function getReferencedAssemblies(): array
$assemblies = [];
foreach($this->bom_entries as $entry) {
- if ($entry->getAssembly() !== null) {
+ if ($entry->getReferencedAssembly() !== null) {
$assemblies[] = $entry->getReferencedAssembly();
}
}
From 6f8f745f41ec181e6b7b054758d37b243de43268 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 7 Jul 2025 10:08:19 +0200
Subject: [PATCH 21/83] =?UTF-8?q?F=C3=BCge=20Unterst=C3=BCtzung=20f=C3=BCr?=
=?UTF-8?q?=20Datenquellen-Synonyme=20hinzu.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ermöglicht benutzerdefinierte Synonyme für Datenquellen basierend auf Locale. Synonyme werden in verschiedenen Bereichen wie Bäumen, Übersetzungen und Vorlagen genutzt, um anpassbare Namen anzuzeigen.
---
config/parameters.yaml | 14 ++++++
config/services.yaml | 21 +++++++++
src/Controller/AssemblyController.php | 1 +
src/Services/Trees/ToolsTreeBuilder.php | 43 +++++++++++++++----
src/Services/Trees/TreeViewGenerator.php | 36 +++++++++++++---
src/Twig/DataSourceNameExtension.php | 42 ++++++++++++++++++
templates/admin/assembly_admin.html.twig | 4 +-
templates/admin/category_admin.html.twig | 4 +-
templates/admin/footprint_admin.html.twig | 4 +-
templates/admin/manufacturer_admin.html.twig | 4 +-
templates/admin/project_admin.html.twig | 4 +-
templates/admin/storelocation_admin.html.twig | 4 +-
templates/admin/supplier_admin.html.twig | 4 +-
templates/components/tree_macros.html.twig | 24 ++++++-----
templates/form/permission_layout.html.twig | 23 +++++++++-
translations/messages.cs.xlf | 6 +++
translations/messages.da.xlf | 6 +++
translations/messages.de.xlf | 6 +++
translations/messages.el.xlf | 6 +++
translations/messages.en.xlf | 6 +++
translations/messages.es.xlf | 6 +++
translations/messages.fr.xlf | 6 +++
translations/messages.it.xlf | 6 +++
translations/messages.ja.xlf | 6 +++
translations/messages.nl.xlf | 6 +++
translations/messages.pl.xlf | 6 +++
translations/messages.ru.xlf | 6 +++
translations/messages.zh.xlf | 6 +++
28 files changed, 274 insertions(+), 36 deletions(-)
create mode 100644 src/Twig/DataSourceNameExtension.php
diff --git a/config/parameters.yaml b/config/parameters.yaml
index c6ef90e03..9a590ec87 100644
--- a/config/parameters.yaml
+++ b/config/parameters.yaml
@@ -16,6 +16,20 @@ parameters:
partdb.create_assembly_use_ipn_placeholder_in_name: '%env(bool:CREATE_ASSEMBLY_USE_IPN_PLACEHOLDER_IN_NAME)%' # Use an %%ipn%% placeholder in the name of an assembly. Placeholder is replaced with the ipn input while saving.
+ partdb.data_sources.synonyms: # Define your own synonyms for the given data sources
+ # Possible datasources: category, storagelocation, footprint, manufacturer, supplier, project, assembly
+ # Possible locales like the ones in 'partdb.locale_menu': en, de, it, fr, ru, ja, cs, da, zh, pl
+ #category:
+ #de: 'Bauteil Kategorien'
+ #en: 'Part categories'
+ #project:
+ #de: 'Geräte'
+ #en: 'Devices'
+ #assembly:
+ #de: 'Zusammengestellte Baugruppe'
+ #en: 'Combined assembly'
+
+
######################################################################################################################
# Users and Privacy
######################################################################################################################
diff --git a/config/services.yaml b/config/services.yaml
index f787a5be3..3a13a7136 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -198,6 +198,27 @@ services:
$fontDirectory: '%kernel.project_dir%/var/dompdf/fonts/'
$tmpDirectory: '%kernel.project_dir%/var/dompdf/tmp/'
+ ####################################################################################################################
+ # Trees
+ ####################################################################################################################
+ App\Services\Trees\TreeViewGenerator:
+ arguments:
+ $rootNodeExpandedByDefault: '%partdb.sidebar.root_expanded%'
+ $rootNodeEnabled: '%partdb.sidebar.root_node_enable%'
+ $dataSourceSynonyms: '%partdb.data_sources.synonyms%'
+ App\Services\Trees\ToolsTreeBuilder:
+ arguments:
+ $dataSourceSynonyms: '%partdb.data_sources.synonyms%'
+
+ ####################################################################################################################
+ # Twig Extensions
+ ####################################################################################################################
+
+ App\Twig\DataSourceNameExtension:
+ arguments:
+ $dataSourceSynonyms: '%partdb.data_sources.synonyms%'
+ tags: [ 'twig.extension' ]
+
####################################################################################################################
# Part info provider system
####################################################################################################################
diff --git a/src/Controller/AssemblyController.php b/src/Controller/AssemblyController.php
index a1ba7fa65..94e129643 100644
--- a/src/Controller/AssemblyController.php
+++ b/src/Controller/AssemblyController.php
@@ -29,6 +29,7 @@
use App\Entity\AssemblySystem\Assembly;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
use App\Entity\Parts\Part;
+use App\Entity\UserSystem\User;
use App\Exceptions\InvalidRegexException;
use App\Form\AssemblySystem\AssemblyAddPartsType;
use App\Form\AssemblySystem\AssemblyBuildType;
diff --git a/src/Services/Trees/ToolsTreeBuilder.php b/src/Services/Trees/ToolsTreeBuilder.php
index 5f08b8183..a2c86b7e8 100644
--- a/src/Services/Trees/ToolsTreeBuilder.php
+++ b/src/Services/Trees/ToolsTreeBuilder.php
@@ -50,8 +50,15 @@
*/
class ToolsTreeBuilder
{
- public function __construct(protected TranslatorInterface $translator, protected UrlGeneratorInterface $urlGenerator, protected TagAwareCacheInterface $cache, protected UserCacheKeyGenerator $keyGenerator, protected Security $security)
- {
+ public function __construct(
+ protected TranslatorInterface $translator,
+ protected UrlGeneratorInterface $urlGenerator,
+ protected TagAwareCacheInterface $cache,
+ protected UserCacheKeyGenerator $keyGenerator,
+ protected Security $security,
+ protected ?array $dataSourceSynonyms = [],
+ ) {
+ $this->dataSourceSynonyms = $dataSourceSynonyms ?? [];
}
/**
@@ -161,43 +168,43 @@ protected function getEditNodes(): array
}
if ($this->security->isGranted('read', new Category())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.categories'),
+ $this->getTranslatedDataSourceOrSynonym('category', 'tree.tools.edit.categories', $this->translator->getLocale()),
$this->urlGenerator->generate('category_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-tags');
}
if ($this->security->isGranted('read', new Project())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.projects'),
+ $this->getTranslatedDataSourceOrSynonym('project', 'tree.tools.edit.projects', $this->translator->getLocale()),
$this->urlGenerator->generate('project_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-archive');
}
if ($this->security->isGranted('read', new Assembly())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.assemblies'),
+ $this->getTranslatedDataSourceOrSynonym('assembly', 'tree.tools.edit.assemblies', $this->translator->getLocale()),
$this->urlGenerator->generate('assembly_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-list');
}
if ($this->security->isGranted('read', new Supplier())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.suppliers'),
+ $this->getTranslatedDataSourceOrSynonym('supplier', 'tree.tools.edit.suppliers', $this->translator->getLocale()),
$this->urlGenerator->generate('supplier_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-truck');
}
if ($this->security->isGranted('read', new Manufacturer())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.manufacturer'),
+ $this->getTranslatedDataSourceOrSynonym('manufacturer', 'tree.tools.edit.manufacturer', $this->translator->getLocale()),
$this->urlGenerator->generate('manufacturer_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-industry');
}
if ($this->security->isGranted('read', new StorageLocation())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.storelocation'),
+ $this->getTranslatedDataSourceOrSynonym('storagelocation', 'tree.tools.edit.storelocation', $this->translator->getLocale()),
$this->urlGenerator->generate('store_location_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-cube');
}
if ($this->security->isGranted('read', new Footprint())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.footprint'),
+ $this->getTranslatedDataSourceOrSynonym('footprint', 'tree.tools.edit.footprint', $this->translator->getLocale()),
$this->urlGenerator->generate('footprint_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-microchip');
}
@@ -305,4 +312,22 @@ protected function getSystemNodes(): array
return $nodes;
}
+
+ protected function getTranslatedDataSourceOrSynonym(string $dataSource, string $translationKey, string $locale): string
+ {
+ $currentTranslation = $this->translator->trans($translationKey);
+
+ // Call alternatives from DataSourcesynonyms (if available)
+ if (!empty($this->dataSourceSynonyms[$dataSource][$locale])) {
+ $alternativeTranslation = $this->dataSourceSynonyms[$dataSource][$locale];
+
+ // Use alternative translation when it deviates from the standard translation
+ if ($alternativeTranslation !== $currentTranslation) {
+ return $alternativeTranslation;
+ }
+ }
+
+ // Otherwise return the standard translation
+ return $currentTranslation;
+ }
}
diff --git a/src/Services/Trees/TreeViewGenerator.php b/src/Services/Trees/TreeViewGenerator.php
index 3a0979028..d5358bfa2 100644
--- a/src/Services/Trees/TreeViewGenerator.php
+++ b/src/Services/Trees/TreeViewGenerator.php
@@ -68,9 +68,11 @@ public function __construct(
protected TranslatorInterface $translator,
private readonly UrlGeneratorInterface $router,
private readonly SidebarSettings $sidebarSettings,
+ protected ?array $dataSourceSynonyms = [],
) {
$this->rootNodeEnabled = $this->sidebarSettings->rootNodeEnabled;
$this->rootNodeExpandedByDefault = $this->sidebarSettings->rootNodeExpanded;
+ $this->dataSourceSynonyms = $dataSourceSynonyms ?? [];
}
/**
@@ -226,14 +228,16 @@ protected function entityClassToRootNodeHref(string $class): ?string
protected function entityClassToRootNodeString(string $class): string
{
+ $locale = $this->translator->getLocale();
+
return match ($class) {
- Category::class => $this->translator->trans('category.labelp'),
- StorageLocation::class => $this->translator->trans('storelocation.labelp'),
- Footprint::class => $this->translator->trans('footprint.labelp'),
- Manufacturer::class => $this->translator->trans('manufacturer.labelp'),
- Supplier::class => $this->translator->trans('supplier.labelp'),
- Project::class => $this->translator->trans('project.labelp'),
- Assembly::class => $this->translator->trans('assembly.labelp'),
+ Category::class => $this->getTranslatedOrSynonym('category', $locale),
+ StorageLocation::class => $this->getTranslatedOrSynonym('storelocation', $locale),
+ Footprint::class => $this->getTranslatedOrSynonym('footprint', $locale),
+ Manufacturer::class => $this->getTranslatedOrSynonym('manufacturer', $locale),
+ Supplier::class => $this->getTranslatedOrSynonym('supplier', $locale),
+ Project::class => $this->getTranslatedOrSynonym('project', $locale),
+ Assembly::class => $this->getTranslatedOrSynonym('assembly', $locale),
default => $this->translator->trans('tree.root_node.text'),
};
}
@@ -290,4 +294,22 @@ public function getGenericTree(string $class, ?AbstractStructuralDBElement $pare
return $repo->getGenericNodeTree($parent); //@phpstan-ignore-line
});
}
+
+ protected function getTranslatedOrSynonym(string $key, string $locale): string
+ {
+ $currentTranslation = $this->translator->trans($key . '.labelp');
+
+ // Call alternatives from DataSourcesynonyms (if available)
+ if (!empty($this->dataSourceSynonyms[$key][$locale])) {
+ $alternativeTranslation = $this->dataSourceSynonyms[$key][$locale];
+
+ // Use alternative translation when it deviates from the standard translation
+ if ($alternativeTranslation !== $currentTranslation) {
+ return $alternativeTranslation;
+ }
+ }
+
+ // Otherwise return the standard translation
+ return $currentTranslation;
+ }
}
diff --git a/src/Twig/DataSourceNameExtension.php b/src/Twig/DataSourceNameExtension.php
new file mode 100644
index 000000000..1c02243f7
--- /dev/null
+++ b/src/Twig/DataSourceNameExtension.php
@@ -0,0 +1,42 @@
+translator = $translator;
+ $this->dataSourceSynonyms = $dataSourceSynonyms ?? [];
+ }
+
+ public function getFunctions(): array
+ {
+ return [
+ new TwigFunction('get_data_source_name', [$this, 'getDataSourceName']),
+ ];
+ }
+
+ /**
+ * Based on the locale and data source names, gives the right synonym value back or the default translator value.
+ */
+ public function getDataSourceName(string $dataSourceName, string $defaultKey): string
+ {
+ $locale = $this->translator->getLocale();
+
+ // Use alternative dataSource synonym (if available)
+ if (isset($this->dataSourceSynonyms[$dataSourceName][$locale])) {
+ return $this->dataSourceSynonyms[$dataSourceName][$locale];
+ }
+
+ // Otherwise return the standard translation
+ return $this->translator->trans($defaultKey);
+ }
+}
\ No newline at end of file
diff --git a/templates/admin/assembly_admin.html.twig b/templates/admin/assembly_admin.html.twig
index e6a90dc09..def4eeb2e 100644
--- a/templates/admin/assembly_admin.html.twig
+++ b/templates/admin/assembly_admin.html.twig
@@ -3,7 +3,9 @@
{# @var entity App\Entity\AssemblySystem\Assembly #}
{% block card_title %}
- {% trans %}assembly.caption{% endtrans %}
+ {% set dataSourceName = get_data_source_name('assembly', 'assembly.caption') %}
+ {% set translatedSource = 'assembly.caption'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block edit_title %}
diff --git a/templates/admin/category_admin.html.twig b/templates/admin/category_admin.html.twig
index 5811640b9..f1fe7663a 100644
--- a/templates/admin/category_admin.html.twig
+++ b/templates/admin/category_admin.html.twig
@@ -1,7 +1,9 @@
{% extends "admin/base_admin.html.twig" %}
{% block card_title %}
- {% trans %}category.labelp{% endtrans %}
+ {% set dataSourceName = get_data_source_name('category', 'category.labelp') %}
+ {% set translatedSource = 'category.labelp'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block additional_pills %}
diff --git a/templates/admin/footprint_admin.html.twig b/templates/admin/footprint_admin.html.twig
index a2c3e4afd..a6acbe84e 100644
--- a/templates/admin/footprint_admin.html.twig
+++ b/templates/admin/footprint_admin.html.twig
@@ -1,7 +1,9 @@
{% extends "admin/base_admin.html.twig" %}
{% block card_title %}
- {% trans %}footprint.labelp{% endtrans %}
+ {% set dataSourceName = get_data_source_name('footprint', 'footprint.labelp') %}
+ {% set translatedSource = 'footprint.labelp'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block master_picture_block %}
diff --git a/templates/admin/manufacturer_admin.html.twig b/templates/admin/manufacturer_admin.html.twig
index 5db892c04..3ce9a124c 100644
--- a/templates/admin/manufacturer_admin.html.twig
+++ b/templates/admin/manufacturer_admin.html.twig
@@ -1,7 +1,9 @@
{% extends "admin/base_company_admin.html.twig" %}
{% block card_title %}
- {% trans %}manufacturer.caption{% endtrans %}
+ {% set dataSourceName = get_data_source_name('manufacturer', 'manufacturer.caption') %}
+ {% set translatedSource = 'manufacturer.caption'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block edit_title %}
diff --git a/templates/admin/project_admin.html.twig b/templates/admin/project_admin.html.twig
index dcf8c64cf..401be7cf7 100644
--- a/templates/admin/project_admin.html.twig
+++ b/templates/admin/project_admin.html.twig
@@ -3,7 +3,9 @@
{# @var entity App\Entity\ProjectSystem\Project #}
{% block card_title %}
- {% trans %}project.caption{% endtrans %}
+ {% set dataSourceName = get_data_source_name('project', 'project.caption') %}
+ {% set translatedSource = 'project.caption'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block edit_title %}
diff --git a/templates/admin/storelocation_admin.html.twig b/templates/admin/storelocation_admin.html.twig
index c93339dc1..1e60eeea2 100644
--- a/templates/admin/storelocation_admin.html.twig
+++ b/templates/admin/storelocation_admin.html.twig
@@ -2,7 +2,9 @@
{% import "label_system/dropdown_macro.html.twig" as dropdown %}
{% block card_title %}
- {% trans %}storelocation.labelp{% endtrans %}
+ {% set dataSourceName = get_data_source_name('storagelocation', 'storelocation.labelp') %}
+ {% set translatedSource = 'storelocation.labelp'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block additional_controls %}
diff --git a/templates/admin/supplier_admin.html.twig b/templates/admin/supplier_admin.html.twig
index ce38a5ca4..b5cf7b236 100644
--- a/templates/admin/supplier_admin.html.twig
+++ b/templates/admin/supplier_admin.html.twig
@@ -1,7 +1,9 @@
{% extends "admin/base_company_admin.html.twig" %}
{% block card_title %}
- {% trans %}supplier.caption{% endtrans %}
+ {% set dataSourceName = get_data_source_name('supplier', 'supplier.caption') %}
+ {% set translatedSource = 'supplier.caption'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block additional_panes %}
diff --git a/templates/components/tree_macros.html.twig b/templates/components/tree_macros.html.twig
index 2e55147a1..210a00633 100644
--- a/templates/components/tree_macros.html.twig
+++ b/templates/components/tree_macros.html.twig
@@ -1,14 +1,16 @@
{% macro sidebar_dropdown() %}
+ {% set currentLocale = app.request.locale %}
+
{# Format is [mode, route, label, show_condition] #}
{% set data_sources = [
- ['categories', path('tree_category_root'), 'category.labelp', is_granted('@categories.read') and is_granted('@parts.read')],
- ['locations', path('tree_location_root'), 'storelocation.labelp', is_granted('@storelocations.read') and is_granted('@parts.read')],
- ['footprints', path('tree_footprint_root'), 'footprint.labelp', is_granted('@footprints.read') and is_granted('@parts.read')],
- ['manufacturers', path('tree_manufacturer_root'), 'manufacturer.labelp', is_granted('@manufacturers.read') and is_granted('@parts.read')],
- ['suppliers', path('tree_supplier_root'), 'supplier.labelp', is_granted('@suppliers.read') and is_granted('@parts.read')],
- ['projects', path('tree_device_root'), 'project.labelp', is_granted('@projects.read')],
- ['assembly', path('tree_assembly_root'), 'assembly.labelp', is_granted('@assemblies.read')],
- ['tools', path('tree_tools'), 'tools.label', true],
+ ['categories', path('tree_category_root'), 'category.labelp', is_granted('@categories.read') and is_granted('@parts.read'), 'category'],
+ ['locations', path('tree_location_root'), 'storelocation.labelp', is_granted('@storelocations.read') and is_granted('@parts.read'), 'storagelocation'],
+ ['footprints', path('tree_footprint_root'), 'footprint.labelp', is_granted('@footprints.read') and is_granted('@parts.read'), 'footprint'],
+ ['manufacturers', path('tree_manufacturer_root'), 'manufacturer.labelp', is_granted('@manufacturers.read') and is_granted('@parts.read'), 'manufacturer'],
+ ['suppliers', path('tree_supplier_root'), 'supplier.labelp', is_granted('@suppliers.read') and is_granted('@parts.read'), 'supplier'],
+ ['projects', path('tree_device_root'), 'project.labelp', is_granted('@projects.read'), 'project'],
+ ['assembly', path('tree_assembly_root'), 'assembly.labelp', is_granted('@assemblies.read'), 'assembly'],
+ ['tools', path('tree_tools'), 'tools.label', true, 'tool'],
] %}
{% trans %}actions{% endtrans %}
@@ -19,9 +21,9 @@
{% for source in data_sources %}
{% if source[3] %} {# show_condition #}
-
{{ source[2] | trans }}
+ >{{ get_data_source_name(source[4], source[2]) }}
{% endif %}
{% endfor %}
{% endmacro %}
@@ -62,4 +64,4 @@
-{% endmacro %}
\ No newline at end of file
+{% endmacro %}
diff --git a/templates/form/permission_layout.html.twig b/templates/form/permission_layout.html.twig
index 166147b4c..896a2defa 100644
--- a/templates/form/permission_layout.html.twig
+++ b/templates/form/permission_layout.html.twig
@@ -6,12 +6,31 @@
{% else %}
- {{ form.vars.label | trans }}
+ def{{ form.vars.label | trans }}
{% endif %}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index a1ede652a..c838f07b8 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -14781,5 +14781,11 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Neplatný regulární výraz (regex)
+
+
+ datasource.synonym
+ %name% (Váš synonymum: %synonym%)
+
+
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index 5901e9f5a..07f6c1b37 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -13462,5 +13462,11 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Ugyldigt regulært udtryk (regex)
+
+
+ datasource.synonym
+ %name% (Dit synonym: %synonym%)
+
+
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index a7ece41a9..7e2c84385 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -14747,5 +14747,11 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Ungültiger regulärer Ausdruck (regex)
+
+
+ datasource.synonym
+ %name% (Ihr Synonym: %synonym%)
+
+
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index fd5114539..07143e5b7 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -2470,5 +2470,11 @@
Μη έγκυρη κανονική έκφραση (regex)
+
+
+ datasource.synonym
+ %name% (Το συνώνυμό σας: %synonym%)
+
+
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index c4f7c60f9..df4c2aed7 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -14748,5 +14748,11 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Invalid regular expression (regex)
+
+
+ datasource.synonym
+ %name% (Your synonym: %synonym%)
+
+
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index 461e7a7b1..1dfdf1dd6 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -13634,5 +13634,11 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Expresión regular no válida (regex)
+
+
+ datasource.synonym
+ %name% (Tu sinónimo: %synonym%)
+
+
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index fe470e449..5c055aaef 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -10044,5 +10044,11 @@ exemple de ville
Expression régulière invalide (regex)
+
+
+ datasource.synonym
+ %name% (Votre synonyme : %synonym%)
+
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index c727eef82..b018468bb 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -13636,5 +13636,11 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Espressione regolare non valida (regex)
+
+
+ datasource.synonym
+ %name% (Il tuo sinonimo: %synonym%)
+
+
diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf
index 157b1cf26..4d1c82edf 100644
--- a/translations/messages.ja.xlf
+++ b/translations/messages.ja.xlf
@@ -9757,5 +9757,11 @@ Exampletown
無効な正規表現(regex)
+
+
+ datasource.synonym
+ %name% (あなたの同義語: %synonym%)
+
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index 44a48dcb3..822191818 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -1695,5 +1695,11 @@
Ongeldige reguliere expressie (regex)
+
+
+ datasource.synonym
+ %name% (Uw synoniem: %synonym%)
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index 171c585d6..6a7e5d591 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -13489,5 +13489,11 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Nieprawidłowe wyrażenie regularne (regex)
+
+
+ datasource.synonym
+ %name% (Twój synonim: %synonym%)
+
+
diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf
index 7bd0f3bc4..2add6347a 100644
--- a/translations/messages.ru.xlf
+++ b/translations/messages.ru.xlf
@@ -13589,5 +13589,11 @@
Неверное регулярное выражение (regex)
+
+
+ datasource.synonym
+ %name% (Ваш синоним: %synonym%)
+
+
diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf
index 9e8d8aa1f..cd6b34b2c 100644
--- a/translations/messages.zh.xlf
+++ b/translations/messages.zh.xlf
@@ -13474,5 +13474,11 @@ Element 3
无效的正则表达式(regex)
+
+
+ datasource.synonym
+ %name% (您的同义词: %synonym%)
+
+
From d26585b14213d8589ab6903a5cffcb05d3db3f03 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 8 Jul 2025 09:05:53 +0200
Subject: [PATCH 22/83] =?UTF-8?q?F=C3=BCge=20Validierung=20f=C3=BCr=20zykl?=
=?UTF-8?q?ische=20Baugruppenreferenzen=20hinzu?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Eine neue Validierung wurde implementiert, um zyklische Referenzen in Baugruppen zu erkennen. Entsprechende Fehlertexte wurden in allen unterstützten Sprachen hinzugefügt. Zudem wurde der Validator in die Entität AssemblyBOMEntry integriert.
---
config/services.yaml | 3 +
src/Entity/AssemblySystem/Assembly.php | 2 +
.../AssemblySystem/AssemblyBOMEntry.php | 2 +
.../AssemblySystem/AssemblyCycle.php | 39 +++++
.../AssemblySystem/AssemblyCycleValidator.php | 139 ++++++++++++++++++
translations/validators.cs.xlf | 6 +
translations/validators.da.xlf | 6 +
translations/validators.de.xlf | 6 +
translations/validators.el.xlf | 6 +
translations/validators.en.xlf | 6 +
translations/validators.fr.xlf | 6 +
translations/validators.hr.xlf | 6 +
translations/validators.it.xlf | 6 +
translations/validators.ja.xlf | 6 +
translations/validators.pl.xlf | 6 +
translations/validators.ru.xlf | 6 +
translations/validators.zh.xlf | 6 +
17 files changed, 257 insertions(+)
create mode 100644 src/Validator/Constraints/AssemblySystem/AssemblyCycle.php
create mode 100644 src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
diff --git a/config/services.yaml b/config/services.yaml
index 3a13a7136..7f0b5897f 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -168,6 +168,9 @@ services:
arguments:
$useAssemblyIpnPlaceholder: '%partdb.create_assembly_use_ipn_placeholder_in_name%'
+ App\Validator\Constraints\AssemblySystem\AssemblyCycleValidator:
+ tags: [ 'validator.constraint_validator' ]
+
####################################################################################################################
# Table settings
####################################################################################################################
diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php
index 9593dbb53..5ce060d8e 100644
--- a/src/Entity/AssemblySystem/Assembly.php
+++ b/src/Entity/AssemblySystem/Assembly.php
@@ -23,6 +23,7 @@
namespace App\Entity\AssemblySystem;
use App\Repository\AssemblyRepository;
+use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
use Doctrine\Common\Collections\Criteria;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Metadata\ApiFilter;
@@ -113,6 +114,7 @@ class Assembly extends AbstractStructuralDBElement
#[Groups(['extended', 'full', 'import'])]
#[ORM\OneToMany(targetEntity: AssemblyBOMEntry::class, mappedBy: 'assembly', cascade: ['persist', 'remove'], orphanRemoval: true)]
#[UniqueObjectCollection(message: 'assembly.bom_entry.part_already_in_bom', fields: ['part'])]
+ #[AssemblyCycle]
#[UniqueReferencedAssembly]
#[UniqueObjectCollection(message: 'assembly.bom_entry.project_already_in_bom', fields: ['project'])]
#[UniqueObjectCollection(message: 'assembly.bom_entry.name_already_in_bom', fields: ['name'])]
diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
index 820fc2f5c..6a3e82d3c 100644
--- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php
+++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
@@ -38,6 +38,7 @@
use App\Entity\Contracts\TimeStampableInterface;
use App\Entity\ProjectSystem\Project;
use App\Repository\DBElementRepository;
+use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
use App\Validator\UniqueValidatableInterface;
use Doctrine\DBAL\Types\Types;
use App\Entity\Base\AbstractDBElement;
@@ -140,6 +141,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
'(this.getPart() === null or this.getReferencedAssembly() === null) and (this.getName() === null or (this.getName() != null and this.getName() != ""))',
message: 'validator.assembly.bom_entry.only_part_or_assembly_allowed'
)]
+ #[AssemblyCycle]
#[ORM\ManyToOne(targetEntity: Assembly::class)]
#[ORM\JoinColumn(name: 'id_referenced_assembly', nullable: true, onDelete: 'SET NULL')]
#[Groups(['bom_entry:read', 'bom_entry:write', ])]
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycle.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycle.php
new file mode 100644
index 000000000..9d79b879c
--- /dev/null
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycle.php
@@ -0,0 +1,39 @@
+.
+ */
+namespace App\Validator\Constraints\AssemblySystem;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * This constraint checks that there is no cycle in bom configuration of the assembly
+ */
+#[\Attribute(\Attribute::TARGET_PROPERTY)]
+class AssemblyCycle extends Constraint
+{
+ public string $message = 'assembly.bom_entry.assembly_cycle';
+
+ public function validatedBy(): string
+ {
+ return AssemblyCycleValidator::class;
+ }
+}
\ No newline at end of file
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
new file mode 100644
index 000000000..3483f94a1
--- /dev/null
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
@@ -0,0 +1,139 @@
+.
+ */
+namespace App\Validator\Constraints\AssemblySystem;
+
+use App\Entity\AssemblySystem\Assembly;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\Validator\Violation\ConstraintViolationBuilder;
+use ReflectionClass;
+
+/**
+ * Validator class to check for cycles in assemblies based on BOM entries.
+ *
+ * This validator ensures that the structure of assemblies does not contain circular dependencies
+ * by validating each entry in the Bill of Materials (BOM) of the given assembly. Additionally,
+ * it can handle form-submitted BOM entries to include these in the validation process.
+ */
+class AssemblyCycleValidator extends ConstraintValidator
+{
+ public function validate($value, Constraint $constraint): void
+ {
+ if (!$constraint instanceof AssemblyCycle) {
+ throw new UnexpectedTypeException($constraint, AssemblyCycle::class);
+ }
+
+ if (!$value instanceof Assembly) {
+ return;
+ }
+
+ $bomEntries = $value->getBomEntries()->toArray();
+
+ // Consider additional entries from the form
+ if ($this->context->getRoot()->has('bom_entries')) {
+ $formBomEntries = $this->context->getRoot()->get('bom_entries')->getData();
+ if ($formBomEntries) {
+ $given = is_array($formBomEntries) ? $formBomEntries : iterator_to_array($formBomEntries);
+ foreach ($given as $givenIdx => $entry) {
+ if (in_array($entry, $bomEntries, true)) {
+ continue;
+ } else {
+ $bomEntries[$givenIdx] = $entry;
+ }
+ }
+ }
+ }
+
+ $visitedAssemblies = [];
+ foreach ($bomEntries as $bomEntry) {
+ if ($this->hasCycle($bomEntry->getReferencedAssembly(), $value, $visitedAssemblies)) {
+ $this->addViolation($value, $constraint);
+ }
+ }
+ }
+
+ private function hasCycle(?Assembly $currentAssembly, Assembly $originalAssembly, array &$visitedAssemblies): bool
+ {
+ if ($currentAssembly === null) {
+ return false;
+ }
+
+ if (in_array($currentAssembly, $visitedAssemblies, true)) {
+ return true;
+ }
+
+ $visitedAssemblies[] = $currentAssembly;
+
+ foreach ($currentAssembly->getBomEntries() as $bomEntry) {
+ if ($this->hasCycle($bomEntry->getReferencedAssembly(), $originalAssembly, $visitedAssemblies)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds a violation to the current context if it hasn’t already been added.
+ *
+ * This method checks whether a violation with the same property path as the current violation
+ * already exists in the context. If such a violation is found, the current violation is not added again.
+ * The process involves reflection to access private or protected properties of violation objects.
+ *
+ * @param mixed $value The value that triggered the violation.
+ * @param Constraint $constraint The constraint containing the validation details.
+ *
+ */
+ private function addViolation($value, Constraint $constraint): void
+ {
+ /** @var ConstraintViolationBuilder $buildViolation */
+ $buildViolation = $this->context->buildViolation($constraint->message)
+ ->setParameter('%name%', $value->getName());
+
+ $alreadyAdded = false;
+
+ try {
+ $reflectionClass = new ReflectionClass($buildViolation);
+ $property = $reflectionClass->getProperty('propertyPath');
+ $propertyPath = $property->getValue($buildViolation);
+
+ $availableViolations = $this->context->getViolations();
+
+ foreach ($availableViolations as $tmpViolation) {
+ $tmpReflectionClass = new ReflectionClass($tmpViolation);
+ $tmpProperty = $tmpReflectionClass->getProperty('propertyPath');
+ $tmpPropertyPath = $tmpProperty->getValue($tmpViolation);
+
+ if ($tmpPropertyPath === $propertyPath) {
+ $alreadyAdded = true;
+ }
+ }
+ } catch (\ReflectionException) {
+ }
+
+ if (!$alreadyAdded) {
+ $buildViolation->addViolation();
+ }
+ }
+}
\ No newline at end of file
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index f053743f3..b99fe349d 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -401,6 +401,12 @@
Tato sestava již existuje jako položka v seznamu materiálů!
+
+
+ assembly.bom_entry.assembly_cycle
+ Byl zjištěn cyklus: Sestava "%name%" nepřímo odkazuje sama na sebe.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index 239e3572a..24fa330af 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -371,6 +371,12 @@
Denne samling findes allerede som en post!
+
+
+ assembly.bom_entry.assembly_cycle
+ En cyklus blev opdaget: Samlingen "%name%" refererer indirekte til sig selv.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index 86b31e583..fa84354b9 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -395,6 +395,12 @@
Diese Baugruppe existiert bereits als Eintrag!
+
+
+ assembly.bom_entry.assembly_cycle
+ Ein Zyklus wurde entdeckt: Die Baugruppe "%name%" referenziert sich indirekt selbst.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index 4e4278daf..bc9b0947e 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -37,6 +37,12 @@
Αυτή η συναρμολόγηση υπάρχει ήδη ως εγγραφή!
+
+
+ assembly.bom_entry.assembly_cycle
+ Εντοπίστηκε κύκλος: Η συναρμολόγηση "%name%" αναφέρεται έμμεσα στον εαυτό της.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index 59cabf552..7d9beb4ec 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -395,6 +395,12 @@
This assembly already exists as an entry!
+
+
+ assembly.bom_entry.assembly_cycle
+ A cycle was detected: the assembly "%name%" indirectly references itself.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index aff68a185..1c9c53029 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -227,6 +227,12 @@
Cet assemblage existe déjà en tant qu'entrée !
+
+
+ assembly.bom_entry.assembly_cycle
+ Un cycle a été détecté : L'assemblage "%name%" se réfère indirectement à lui-même.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index 1ee5c06fe..89d470e7e 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -389,6 +389,12 @@
Ova se montaža već nalazi kao zapis!
+
+
+ assembly.bom_entry.assembly_cycle
+ Otkriven je ciklus: Sklop "%name%" neizravno referencira samog sebe.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index ac57a2cc4..e9b528bb7 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -389,6 +389,12 @@
Questo assemblaggio è già presente come voce!
+
+
+ assembly.bom_entry.assembly_cycle
+ È stato rilevato un ciclo: L'assemblaggio "%name%" fa riferimento indirettamente a sé stesso.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index a316707ad..80ec65ff2 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -227,6 +227,12 @@
このアセンブリはすでにエントリとして存在します!
+
+
+ assembly.bom_entry.assembly_cycle
+ 循環が検出されました: アセンブリ「%name%」が間接的に自身を参照しています。
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 95c44ab4d..5df01cd6a 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -389,6 +389,12 @@
To zestawienie jest już dodane jako wpis!
+
+
+ assembly.bom_entry.assembly_cycle
+ 循環が検出されました: アセンブリ「%name%」が間接的に自身を参照しています。
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index 425ede5f1..8bf08ab3c 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -389,6 +389,12 @@
Этот сборочный узел уже добавлен как запись!
+
+
+ assembly.bom_entry.assembly_cycle
+ Обнаружен цикл: Сборка «%name%» косвенно ссылается на саму себя.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 4a02523bb..87c507c19 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -377,6 +377,12 @@
此装配已经作为条目存在!
+
+
+ assembly.bom_entry.assembly_cycle
+ 检测到循环:装配体“%name%”间接引用了其自身。
+
+ assembly.bom_entry.project_already_in_bom
From 360f4f07a770e631433a910d121ac0ea4332e35e Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 17 Jul 2025 10:54:44 +0200
Subject: [PATCH 23/83] Anpassungen aus Analyse vornehmen
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Name Validierung bei Assembly Angabe in Stücklisten anpassen. permission_layout.html hinsichtlich Synonym-Ausgabe Datenquelle anpassen. Anpassung aus Analyse.
---
assets/js/lib/datatables.js | 8 ++++++--
migrations/Version20250304154507.php | 2 +-
src/DataTables/AssemblyBomEntriesDataTable.php | 2 ++
src/Entity/AssemblySystem/AssemblyBOMEntry.php | 6 +++---
templates/form/permission_layout.html.twig | 15 ++++++++++-----
5 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/assets/js/lib/datatables.js b/assets/js/lib/datatables.js
index 67bab02db..7c82439cc 100644
--- a/assets/js/lib/datatables.js
+++ b/assets/js/lib/datatables.js
@@ -13,11 +13,16 @@
* Initializes the datatable dynamically.
*/
$.fn.initDataTables = function(config, options) {
-
//Update default used url, so it reflects the current location (useful on single side apps)
//CHANGED jbtronics: Preserve the get parameters (needed so we can pass additional params to query)
$.fn.initDataTables.defaults.url = window.location.origin + window.location.pathname + window.location.search;
+ $.fn.dataTable.ext.errMode = function(settings, helpPage, message) {
+ if (message.includes('ColReorder')) {
+ console.warn('ColReorder does not fit the number of columns', message);
+ }
+ };
+
var root = this,
config = $.extend({}, $.fn.initDataTables.defaults, config),
state = ''
@@ -105,7 +110,6 @@
}
}
-
root.html(data.template);
dt = $('table', root).DataTable(dtOpts);
if (config.state !== 'none') {
diff --git a/migrations/Version20250304154507.php b/migrations/Version20250304154507.php
index 4f7fed2f4..8a406b27d 100644
--- a/migrations/Version20250304154507.php
+++ b/migrations/Version20250304154507.php
@@ -18,7 +18,7 @@ public function getDescription(): string
public function mySQLUp(Schema $schema): void
{
$this->addSql(<<<'SQL'
- ALTER TABLE parts ADD built_assembly_id INT DEFAULT NULL
+ ALTER TABLE parts ADD built_assembly_id INT DEFAULT NULL AFTER build_project_id
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE parts ADD CONSTRAINT FK_6940A7FECC660B3C FOREIGN KEY (built_assembly_id) REFERENCES assemblies (id)
diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php
index fed6850f4..b2c3e118d 100644
--- a/src/DataTables/AssemblyBomEntriesDataTable.php
+++ b/src/DataTables/AssemblyBomEntriesDataTable.php
@@ -127,6 +127,8 @@ public function configure(DataTable $dataTable, array $options): void
'render' => function ($value, AssemblyBOMEntry $context) {
if($context->getPart() instanceof Part) {
return $context->getPart()->getIpn();
+ } elseif($context->getReferencedAssembly() instanceof Assembly) {
+ return $context->getReferencedAssembly()->getIpn();
}
return '';
diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
index 6a3e82d3c..8a4cdbc24 100644
--- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php
+++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
@@ -106,7 +106,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
/**
* @var string|null An optional name describing this BOM entry (useful for non-part entries)
*/
- #[Assert\Expression('this.getPart() !== null or this.getName() !== null', message: 'validator.assembly.bom_entry.name_or_part_needed')]
+ #[Assert\Expression('this.getPart() !== null or this.getReferencedAssembly() !== null or this.getName() !== null', message: 'validator.assembly.bom_entry.name_or_part_needed')]
#[ORM\Column(type: Types::STRING, nullable: true)]
#[Groups(['bom_entry:read', 'bom_entry:write', 'import', 'simple', 'extended', 'full'])]
protected ?string $name = null;
@@ -206,7 +206,7 @@ public function setMountnames(string $mountnames): AssemblyBOMEntry
*/
public function getName(): ?string
{
- return $this->name;
+ return trim($this->name ?? '') === '' ? null : $this->name;
}
/**
@@ -214,7 +214,7 @@ public function getName(): ?string
*/
public function setName(?string $name): AssemblyBOMEntry
{
- $this->name = $name;
+ $this->name = trim($name ?? '') === '' ? null : $name;
return $this;
}
diff --git a/templates/form/permission_layout.html.twig b/templates/form/permission_layout.html.twig
index 896a2defa..dcceae335 100644
--- a/templates/form/permission_layout.html.twig
+++ b/templates/form/permission_layout.html.twig
@@ -7,15 +7,15 @@
From 40778c4e0519e99c328d7e45204f185b74185471 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Fri, 18 Jul 2025 10:36:12 +0200
Subject: [PATCH 24/83] =?UTF-8?q?St=C3=BCcklisten=20beim=20L=C3=B6schen:?=
=?UTF-8?q?=20Markieren=20von=20referenzierten=20Baugruppen=20als=20Hinwei?=
=?UTF-8?q?s=20vornehmen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../AdminPages/BaseAdminController.php | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php
index 039751ea6..bae817de6 100644
--- a/src/Controller/AdminPages/BaseAdminController.php
+++ b/src/Controller/AdminPages/BaseAdminController.php
@@ -24,6 +24,7 @@
use App\DataTables\LogDataTable;
use App\Entity\AssemblySystem\Assembly;
+use App\Entity\AssemblySystem\AssemblyBOMEntry;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Attachments\AttachmentUpload;
@@ -469,6 +470,10 @@ protected function _delete(Request $request, AbstractNamedDBElement $entity, Str
return $this->redirectToRoute($this->route_base.'_edit', ['id' => $entity->getID()]);
}
} else {
+ if ($entity instanceof Assembly) {
+ $this->markReferencedBomEntry($entity);
+ }
+
if ($entity instanceof AbstractStructuralDBElement) {
$parent = $entity->getParent();
@@ -516,4 +521,16 @@ protected function _exportEntity(AbstractNamedDBElement $entity, EntityExporter
return $exporter->exportEntityFromRequest($entity, $request);
}
+
+ private function markReferencedBomEntry(Assembly $referencedAssembly): void
+ {
+ $bomEntries = $this->entityManager->getRepository(AssemblyBOMEntry::class)->findBy(['referencedAssembly' => $referencedAssembly]);
+
+ foreach ($bomEntries as $entry) {
+ $entry->setReferencedAssembly(null);
+ $entry->setName($referencedAssembly->getName(). ' DELETED');
+
+ $this->entityManager->persist($entry);
+ }
+ }
}
From db9c7663104f9bcd9f0e5c00ef5672db867b93c1 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 21 Jul 2025 10:04:54 +0200
Subject: [PATCH 25/83] Migration: Spaltenname korrigieren
---
migrations/Version20250304154507.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/migrations/Version20250304154507.php b/migrations/Version20250304154507.php
index 8a406b27d..bb25b8022 100644
--- a/migrations/Version20250304154507.php
+++ b/migrations/Version20250304154507.php
@@ -18,7 +18,7 @@ public function getDescription(): string
public function mySQLUp(Schema $schema): void
{
$this->addSql(<<<'SQL'
- ALTER TABLE parts ADD built_assembly_id INT DEFAULT NULL AFTER build_project_id
+ ALTER TABLE parts ADD built_assembly_id INT DEFAULT NULL AFTER built_project_id
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE parts ADD CONSTRAINT FK_6940A7FECC660B3C FOREIGN KEY (built_assembly_id) REFERENCES assemblies (id)
From 64c9773b3366897cb6abf94efd10cb8ee8f98cbb Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 22 Jul 2025 10:30:22 +0200
Subject: [PATCH 26/83] BOMImporter: Verbesserung des CSV-Parsing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Das Parsing wurde angepasst, um sowohl Komma- als auch Semikolon-getrennte CSV-Dateien zu unterstützen. Zudem werden Spaltennamen in Kleinbuchstaben konvertiert und zusätzliche Fallback-Logik für bestimmte Felder hinzugefügt.
---
.../ImportExportSystem/BOMImporter.php | 31 ++++++++++++++++---
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php
index e345e595c..a504ab879 100644
--- a/src/Services/ImportExportSystem/BOMImporter.php
+++ b/src/Services/ImportExportSystem/BOMImporter.php
@@ -433,14 +433,27 @@ private function parseJson(string $data, string $objectType = ProjectBOMEntry::c
function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class): ImporterResult
{
$result = new ImporterResult();
- $rows = explode("\n", trim($csvData));
- $headers = str_getcsv(array_shift($rows), ';');
+ $rows = explode("\r\n", trim($csvData));
+ $headers = str_getcsv(array_shift($rows), ',');
+
+ if (count($headers) === 1 && isset($headers[0])) {
+ //If only one column was recognized, try fallback with semicolon as a separator
+ $headers = str_getcsv($headers[0], ';');
+ }
foreach ($rows as $key => $row) {
$entry = [];
- $values = str_getcsv($row, ';');
+ $values = str_getcsv($row, ',');
+
+ if (count($values) === 1 || count($values) !== count($headers)) {
+ //If only one column was recognized, try fallback with semicolon as a separator
+ $values = str_getcsv($row, ';');
+ }
foreach ($headers as $index => $column) {
+ //Change the column names in small letters
+ $column = strtolower($column);
+
//Convert column name into hierarchy
$path = explode('_', $column);
$temp = &$entry;
@@ -493,6 +506,11 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
));
}
+ if (isset($entry['id']) && is_numeric($entry['id'])) {
+ //Use id column as a fallback for the expected part_id column
+ $entry['part']['id'] = (int) $entry['id'];
+ }
+
if (isset($entry['part'])) {
$this->processPart($entry, $result, $key, $objectType, self::IMPORT_TYPE_CSV);
} else {
@@ -775,7 +793,12 @@ private function processPart(array $entry, ImporterResult $result, int $key, str
$bomEntry->setQuantity((float) $entry['quantity']);
if (isset($entry['name'])) {
- $bomEntry->setName(trim($entry['name']) === '' ? null : trim ($entry['name']));
+ $givenName = trim($entry['name']) === '' ? null : trim ($entry['name']);
+
+ if ($givenName !== null && $bomEntry->getPart() !== null && $bomEntry->getPart()->getName() !== $givenName) {
+ //Apply different names for parts list entry
+ $bomEntry->setName(trim($entry['name']) === '' ? null : trim ($entry['name']));
+ }
} else {
$bomEntry->setName(null);
}
From 15ad64c93b4632be3da6512827bac265b1c8a4a2 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 22 Jul 2025 12:20:26 +0200
Subject: [PATCH 27/83] Reihenfolge der Tabs in Baugruppenansicht korrigiert
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Die Tabs "Details" und "Stückliste" wurden in der Baugruppenansicht vertauscht, um der Nutzererwartung besser zu entsprechen. Zudem wurde die Methode zur rekursiven Ermittlung referenzierter Baugruppen überarbeitet und in der Datentabelle integriert.
---
src/DataTables/AssemblyDataTable.php | 5 ++--
src/Entity/AssemblySystem/Assembly.php | 29 +++++++++++++++++++-----
templates/assemblies/info/info.html.twig | 24 ++++++++++----------
3 files changed, 37 insertions(+), 21 deletions(-)
diff --git a/src/DataTables/AssemblyDataTable.php b/src/DataTables/AssemblyDataTable.php
index f3854ebca..745a62b62 100644
--- a/src/DataTables/AssemblyDataTable.php
+++ b/src/DataTables/AssemblyDataTable.php
@@ -109,14 +109,13 @@ public function configure(DataTable $dataTable, array $options): void
$this->csh->add('referencedAssemblies', TextColumn::class, [
'label' => $this->translator->trans('assembly.referencedAssembly.labelp'),
'render' => function ($value, Assembly $context): string {
- $assemblies = $context->getReferencedAssemblies();
+ $assemblies = $context->getAllReferencedAssembliesRecursive($context);
$max = 5;
$tmp = "";
for ($i = 0; $i < min($max, count($assemblies)); $i++) {
- $url = $this->urlGenerator->infoURL($assemblies[$i]);
- $tmp .= sprintf('%s', $url, htmlspecialchars($assemblies[$i]->getName()));
+ $tmp .= $this->assemblyDataTableHelper->renderName($assemblies[$i]);
if ($i < count($assemblies) - 1) {
$tmp .= ", ";
}
diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php
index 5ce060d8e..cb6e94def 100644
--- a/src/Entity/AssemblySystem/Assembly.php
+++ b/src/Entity/AssemblySystem/Assembly.php
@@ -393,20 +393,37 @@ public function validate(ExecutionContextInterface $context, $payload): void
}
/**
- * Get all referenced assemblies which uses this assembly.
+ * Get all assemblies and sub-assemblies recursive that are referenced in the assembly bom entries.
*
- * @return Assembly[] all referenced assemblies which uses this assembly as a one-dimensional array of assembly objects
+ * @param Assembly $assembly Assembly, which is to be processed recursively.
+ * @param array $processedAssemblies (optional) a list of the already edited assemblies to avoid circulatory references.
+ * @return Assembly[] A flat list of all recursively found assemblies.
*/
- public function getReferencedAssemblies(): array
+ public function getAllReferencedAssembliesRecursive(Assembly $assembly, array &$processedAssemblies = []): array
{
$assemblies = [];
- foreach($this->bom_entries as $entry) {
- if ($entry->getReferencedAssembly() !== null) {
- $assemblies[] = $entry->getReferencedAssembly();
+ // Avoid circular references
+ if (in_array($assembly, $processedAssemblies, true)) {
+ return $assemblies;
+ }
+
+ // Add the current assembly to the processed
+ $processedAssemblies[] = $assembly;
+
+ // Iterate by the bom entries of the current assembly
+ foreach ($assembly->getBomEntries() as $bomEntry) {
+ if ($bomEntry->getReferencedAssembly() !== null) {
+ $referencedAssembly = $bomEntry->getReferencedAssembly();
+
+ $assemblies[] = $referencedAssembly;
+
+ // Continue recursively to process sub-assemblies
+ $assemblies = array_merge($assemblies, $this->getAllReferencedAssembliesRecursive($referencedAssembly, $processedAssemblies));
}
}
return $assemblies;
}
+
}
diff --git a/templates/assemblies/info/info.html.twig b/templates/assemblies/info/info.html.twig
index d787ea086..098173861 100644
--- a/templates/assemblies/info/info.html.twig
+++ b/templates/assemblies/info/info.html.twig
@@ -64,18 +64,18 @@
{% block card_content %}
- {% include "assemblies/info/_part.html.twig" %}
-
{% include "assemblies/info/_info.html.twig" %}
+
+ {% include "assemblies/info/_part.html.twig" %}
+
{% include "assemblies/info/_builds.html.twig" %}
From 08a33338bdcb3e67a97d63fef83079444442d890 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 22 Jul 2025 15:52:57 +0200
Subject: [PATCH 28/83] BOMImporter und AssemblyCycleValidator: Verbesserte
Import-Logik
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Die Importmethoden wurden vereinheitlicht, um Projekte und Baugruppen gleichermaßen zu unterstützen. Zudem wurde die Validierung optimiert und die CSV-, JSON- und KiCAD-Parsing-Methoden angepasst, um kontextbasierte BOM-Einträge effizienter zu erstellen.
---
.../ImportExportSystem/BOMImporter.php | 180 ++++++++++++------
.../AssemblySystem/AssemblyCycleValidator.php | 3 +-
2 files changed, 124 insertions(+), 59 deletions(-)
diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php
index a504ab879..6a3528117 100644
--- a/src/Services/ImportExportSystem/BOMImporter.php
+++ b/src/Services/ImportExportSystem/BOMImporter.php
@@ -100,7 +100,7 @@ protected function configureOptions(OptionsResolver $resolver): OptionsResolver
*/
public function importFileIntoProject(UploadedFile $file, Project $project, array $options): ImporterResult
{
- $importerResult = $this->fileToImporterResult($file, $options);
+ $importerResult = $this->fileToImporterResult($project, $file, $options);
if ($importerResult->getViolations()->count() === 0) {
//Assign the bom_entries to the project
@@ -113,12 +113,21 @@ public function importFileIntoProject(UploadedFile $file, Project $project, arra
}
/**
- * Converts the given file into an ImporterResult with an array of BOM entries using the given options and save them into the given assembly.
- * The changes are not saved into the database yet.
+ * Imports a file into an Assembly object and processes its contents.
+ *
+ * This method converts the provided file into an ImporterResult object that contains BOM entries and potential
+ * validation violations. If no violations are found, the BOM entries extracted from the file are added to the
+ * provided Assembly object.
+ *
+ * @param UploadedFile $file The file to be imported and processed.
+ * @param Assembly $assembly The target Assembly object to which the BOM entries are added.
+ * @param array $options Options or configurations related to the import process.
+ *
+ * @return ImporterResult An object containing the result of the import process, including BOM entries and any violations.
*/
public function importFileIntoAssembly(UploadedFile $file, Assembly $assembly, array $options): ImporterResult
{
- $importerResult = $this->fileToImporterResult($file, $options, AssemblyBOMEntry::class);
+ $importerResult = $this->fileToImporterResult($assembly, $file, $options);
if ($importerResult->getViolations()->count() === 0) {
//Assign the bom_entries to the assembly
@@ -131,18 +140,37 @@ public function importFileIntoAssembly(UploadedFile $file, Assembly $assembly, a
}
/**
- * Converts the given file into an array of BOM entries using the given options.
- * @return ProjectBOMEntry[]|AssemblyBOMEntry[]
+ * Converts the content of a file into an array of BOM (Bill of Materials) entries.
+ *
+ * This method processes the content of the provided file and delegates the conversion
+ * to a helper method that generates BOM entries based on the provided import object and options.
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entries (either a Project or Assembly).
+ * @param File $file The file whose content will be converted into BOM entries.
+ * @param array $options Additional options or configurations to be applied during the conversion process.
+ *
+ * @return array An array of BOM entries created from the file content.
*/
- public function fileToBOMEntries(File $file, array $options, string $objectType = ProjectBOMEntry::class): array
+ public function fileToBOMEntries(Project|Assembly $importObject, File $file, array $options): array
{
- return $this->stringToBOMEntries($file->getContent(), $options, $objectType);
+ return $this->stringToBOMEntries($importObject, $file->getContent(), $options);
}
+
/**
- * Converts the given file into an ImporterResult with an array of BOM entries using the given options.
+ * Handles the conversion of an uploaded file into an ImporterResult for a given project or assembly.
+ *
+ * This method processes the uploaded file by validating its file extension based on the provided import type
+ * options and then proceeds to convert the file content into an ImporterResult. If the file extension is
+ * invalid or unsupported, the result will contain a corresponding violation.
+ *
+ * @param Project|Assembly $importObject The context of the import operation (either a Project or Assembly).
+ * @param UploadedFile $file The uploaded file to be processed.
+ * @param array $options An array of options, expected to include an 'type' key to determine valid file types.
+ *
+ * @return ImporterResult An object containing the results of the import process, including any detected violations.
*/
- public function fileToImporterResult(UploadedFile $file, array $options, string $objectType = ProjectBOMEntry::class): ImporterResult
+ public function fileToImporterResult(Project|Assembly $importObject, UploadedFile $file, array $options): ImporterResult
{
$result = new ImporterResult();
@@ -172,7 +200,7 @@ public function fileToImporterResult(UploadedFile $file, array $options, string
$fileExtension,
[
'%extension%' => $fileExtension,
- '%importType%' => $this->translator->trans($objectType === ProjectBOMEntry::class ? 'project.bom_import.type.'.$options['type'] : 'assembly.bom_import.type.'.$options['type']),
+ '%importType%' => $this->translator->trans($importObject instanceof Project ? 'project.bom_import.type.'.$options['type'] : 'assembly.bom_import.type.'.$options['type']),
'%allowedExtensions%' => implode(', ', $validExtensions),
]
));
@@ -180,7 +208,7 @@ public function fileToImporterResult(UploadedFile $file, array $options, string
return $result;
}
- return $this->stringToImporterResult($file->getContent(), $options, $objectType);
+ return $this->stringToImporterResult($importObject, $file->getContent(), $options);
}
/**
@@ -202,11 +230,14 @@ public function validateBOMData(string $data, array $options): array
/**
* Import string data into an array of BOM entries, which are not yet assigned to a project.
- * @param string $data The data to import
- * @param array $options An array of options
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $data The data to import
+ * @param array $options An array of options
+ *
* @return ProjectBOMEntry[]|AssemblyBOMEntry[] An array of imported entries
*/
- public function stringToBOMEntries(string $data, array $options, string $objectType = ProjectBOMEntry::class): array
+ public function stringToBOMEntries(Project|Assembly $importObject, string $data, array $options): array
{
$resolver = new OptionsResolver();
$resolver = $this->configureOptions($resolver);
@@ -221,11 +252,14 @@ public function stringToBOMEntries(string $data, array $options, string $objectT
/**
* Import string data into an array of BOM entries, which are not yet assigned to a project.
- * @param string $data The data to import
- * @param array $options An array of options
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $data The data to import
+ * @param array $options An array of options
+ *
* @return ImporterResult An result of imported entries or a violation list
*/
- public function stringToImporterResult(string $data, array $options, string $objectType = ProjectBOMEntry::class): ImporterResult
+ public function stringToImporterResult(Project|Assembly $importObject, string $data, array $options): ImporterResult
{
$resolver = new OptionsResolver();
$resolver = $this->configureOptions($resolver);
@@ -238,14 +272,28 @@ public function stringToImporterResult(string $data, array $options, string $obj
));
return match ($options['type']) {
- self::IMPORT_TYPE_KICAD_PCB => $this->parseKiCADPCB($data, $objectType),
- self::IMPORT_TYPE_JSON => $this->parseJson($data, $objectType),
- self::IMPORT_TYPE_CSV => $this->parseCsv($data, $objectType),
+ self::IMPORT_TYPE_KICAD_PCB => $this->parseKiCADPCB($importObject, $data, $options),
+ self::IMPORT_TYPE_JSON => $this->parseJson($importObject, $data),
+ self::IMPORT_TYPE_CSV => $this->parseCsv($importObject, $data),
default => $defaultImporterResult,
};
}
- private function parseKiCADPCB(string $data, string $objectType = ProjectBOMEntry::class): ImporterResult
+ /**
+ * Parses a KiCAD PCB file and imports its BOM (Bill of Materials) entries into the given Project or Assembly context.
+ *
+ * This method processes a semicolon-delimited CSV data string, normalizes column names,
+ * validates the required fields, and creates BOM entries for each record in the data.
+ * The BOM entries are added to the provided Project or Assembly, depending on the context.
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $data The semicolon- or comma-delimited CSV data to be parsed.
+ *
+ * @return ImporterResult The result of the import process, containing the created BOM entries.
+ *
+ * @throws UnexpectedValueException If required fields are missing in the provided data.
+ */
+ private function parseKiCADPCB(Project|Assembly $importObject, string $data): ImporterResult
{
$result = new ImporterResult();
@@ -271,8 +319,8 @@ private function parseKiCADPCB(string $data, string $objectType = ProjectBOMEntr
throw new \UnexpectedValueException('Quantity missing at line ' . ($offset + 1) . '!');
}
- $bom_entry = $objectType === ProjectBOMEntry::class ? new ProjectBOMEntry() : new AssemblyBOMEntry();
- if ($objectType === ProjectBOMEntry::class) {
+ $bom_entry = $importObject instanceof Project ? new ProjectBOMEntry() : new AssemblyBOMEntry();
+ if ($bom_entry instanceof ProjectBOMEntry) {
$bom_entry->setName($entry['Designation'] . ' (' . $entry['Package'] . ')');
} else {
$bom_entry->setName($entry['Designation']);
@@ -370,15 +418,15 @@ private function validateKiCADSchematicData(string $data, array $options): array
* - Checking for empty or invalid descriptions.
* - Ensuring manufacturers, if specified, have valid `name` or `id` values.
*
- * @param string $data JSON encoded string containing BOM entries data.
- * @param string $objectType The type of entries expected during import (e.g., `ProjectBOMEntry` or `AssemblyBOMEntry`).
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $data JSON encoded string containing BOM entries data.
*
* @return ImporterResult The result containing parsed data and any violations encountered during the parsing process.
*/
- private function parseJson(string $data, string $objectType = ProjectBOMEntry::class): ImporterResult
+ private function parseJson(Project|Assembly $importObject, string $data): ImporterResult
{
$result = new ImporterResult();
- $this->jsonRoot = 'JSON Import for '.$objectType === ProjectBOMEntry::class ? 'Project' : 'Assembly';
+ $this->jsonRoot = 'JSON Import for '.($importObject instanceof Project ? 'Project' : 'Assembly');
$data = json_decode($data, true);
@@ -407,9 +455,9 @@ private function parseJson(string $data, string $objectType = ProjectBOMEntry::c
}
if (isset($entry['part'])) {
- $this->processPart($entry, $result, $key, $objectType,self::IMPORT_TYPE_JSON);
+ $this->processPart($importObject, $entry, $result, $key, self::IMPORT_TYPE_JSON);
} else {
- $bomEntry = $this->getOrCreateBomEntry($objectType, $entry['name'] ?? null);
+ $bomEntry = $this->getOrCreateBomEntry($importObject, $entry['name'] ?? null);
$bomEntry->setQuantity((float) $entry['quantity']);
$result->addBomEntry($bomEntry);
@@ -425,16 +473,16 @@ private function parseJson(string $data, string $objectType = ProjectBOMEntry::c
* performing validations and converting data based on the provided headers.
* Handles potential violations and manages the creation of BOM entries based on the given type.
*
- * @param string $csvData The raw CSV data to parse, with rows separated by newlines.
- * @param string $objectType The class type to instantiate for BOM entries, defaults to ProjectBOMEntry.
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $csvData The raw CSV data to parse, with rows separated by newlines.
*
* @return ImporterResult Returns an ImporterResult instance containing BOM entries and any validation violations encountered.
*/
- function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class): ImporterResult
+ function parseCsv(Project|Assembly $importObject, string $csvData): ImporterResult
{
$result = new ImporterResult();
$rows = explode("\r\n", trim($csvData));
- $headers = str_getcsv(array_shift($rows), ',');
+ $headers = str_getcsv(array_shift($rows));
if (count($headers) === 1 && isset($headers[0])) {
//If only one column was recognized, try fallback with semicolon as a separator
@@ -443,7 +491,7 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
foreach ($rows as $key => $row) {
$entry = [];
- $values = str_getcsv($row, ',');
+ $values = str_getcsv($row);
if (count($values) === 1 || count($values) !== count($headers)) {
//If only one column was recognized, try fallback with semicolon as a separator
@@ -471,7 +519,7 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
//Check whether the value is numerical
if (is_numeric($values[$index])) {
//Convert to integer or float
- $temp = (strpos($values[$index], '.') !== false)
+ $temp = (str_contains($values[$index], '.'))
? floatval($values[$index])
: intval($values[$index]);
} else {
@@ -512,9 +560,9 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
}
if (isset($entry['part'])) {
- $this->processPart($entry, $result, $key, $objectType, self::IMPORT_TYPE_CSV);
+ $this->processPart($importObject, $entry, $result, $key, self::IMPORT_TYPE_CSV);
} else {
- $bomEntry = $this->getOrCreateBomEntry($objectType, $entry['name'] ?? null);
+ $bomEntry = $this->getOrCreateBomEntry($importObject, $entry['name'] ?? null);
$bomEntry->setQuantity((float) $entry['quantity'] ?? 0);
$result->addBomEntry($bomEntry);
@@ -531,15 +579,15 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
* to identify corresponding objects in the database. The result is recorded, and violations are
* logged if issues or discrepancies exist in the validation or database matching process.
*
- * @param array $entry The array representation of the part entry.
- * @param ImporterResult $result The result object used for recording validation violations.
- * @param int $key The index of the entry in the data array.
- * @param string $objectType The type of object being processed.
- * @param string $importType The type of import being performed.
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param array $entry The array representation of the part entry.
+ * @param ImporterResult $result The result object used for recording validation violations.
+ * @param int $key The index of the entry in the data array.
+ * @param string $importType The type of import being performed.
*
* @return void
*/
- private function processPart(array $entry, ImporterResult $result, int $key, string $objectType, string $importType): void
+ private function processPart(Project|Assembly $importObject, array $entry, ImporterResult $result, int $key, string $importType): void
{
$prefix = $importType === self::IMPORT_TYPE_JSON ? 'entry' : 'row';
@@ -764,12 +812,12 @@ private function processPart(array $entry, ImporterResult $result, int $key, str
$part->setCategory($category);
}
- if ($objectType === AssemblyBOMEntry::class) {
- $bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['part' => $part]);
+ if ($importObject instanceof Assembly) {
+ $bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['assembly' => $importObject, 'part' => $part]);
if ($bomEntry === null) {
if (isset($entry['name']) && $entry['name'] !== '') {
- $bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['name' => $entry['name']]);
+ $bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['assembly' => $importObject, 'name' => $entry['name']]);
}
if ($bomEntry === null) {
@@ -777,11 +825,11 @@ private function processPart(array $entry, ImporterResult $result, int $key, str
}
}
} else {
- $bomEntry = $this->projectBOMEntryRepository->findOneBy(['part' => $part]);
+ $bomEntry = $this->projectBOMEntryRepository->findOneBy(['project' => $importObject, 'part' => $part]);
if ($bomEntry === null) {
if (isset($entry['name']) && $entry['name'] !== '') {
- $bomEntry = $this->projectBOMEntryRepository->findOneBy(['name' => $entry['name']]);
+ $bomEntry = $this->projectBOMEntryRepository->findOneBy(['project' => $importObject, 'name' => $entry['name']]);
}
if ($bomEntry === null) {
@@ -828,22 +876,38 @@ private function removeEmptyProperties(array $data): array
return $data;
}
- private function getOrCreateBomEntry(string $objectType, ?string $name)
+ /**
+ * Retrieves an existing BOM (Bill of Materials) entry by name or creates a new one if not found.
+ *
+ * Depending on whether the provided import object is a Project or Assembly, this method attempts to locate
+ * a corresponding BOM entry in the appropriate repository. If no entry is located, a new BOM entry object
+ * is instantiated according to the type of the import object.
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string|null $name The name of the BOM entry to search for or assign to a new entry.
+ *
+ * @return ProjectBOMEntry|AssemblyBOMEntry An existing or newly created BOM entry.
+ */
+ private function getOrCreateBomEntry(Project|Assembly $importObject, ?string $name): ProjectBOMEntry|AssemblyBOMEntry
{
$bomEntry = null;
//Check whether there is a name
if (!empty($name)) {
- if ($objectType === ProjectBOMEntry::class) {
+ if ($importObject instanceof Project) {
$bomEntry = $this->projectBOMEntryRepository->findOneBy(['name' => $name]);
- } elseif ($objectType === AssemblyBOMEntry::class) {
+ } else {
$bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['name' => $name]);
}
}
- //If no bom enttry was found, a new object create
+ //If no bom entry was found, a new object create
if ($bomEntry === null) {
- $bomEntry = new $objectType();
+ if ($importObject instanceof Project) {
+ $bomEntry = new ProjectBOMEntry();
+ } else {
+ $bomEntry = new AssemblyBOMEntry();
+ }
}
$bomEntry->setName($name);
@@ -1374,10 +1438,10 @@ public function detectFields(string $data, ?string $delimiter = null): array
* The violation includes a message, property path, invalid value, and other contextual information.
* Translations for the violation message can be applied through the translator service.
*
- * @param string $message The translation key for the validation message.
- * @param string $propertyPath The property path where the violation occurred.
- * @param mixed|null $invalidValue The value that caused the violation (optional).
- * @param array $parameters Additional parameters for message placeholders (default is an empty array).
+ * @param string $message The translation key for the validation message.
+ * @param string $propertyPath The property path where the violation occurred.
+ * @param mixed|null $invalidValue The value that caused the violation (optional).
+ * @param array $parameters Additional parameters for message placeholders (default is an empty array).
*
* @return ConstraintViolation The created constraint violation object.
*/
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
index 3483f94a1..73df284dd 100644
--- a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
@@ -23,6 +23,7 @@
namespace App\Validator\Constraints\AssemblySystem;
use App\Entity\AssemblySystem\Assembly;
+use Symfony\Component\Form\Form;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
@@ -51,7 +52,7 @@ public function validate($value, Constraint $constraint): void
$bomEntries = $value->getBomEntries()->toArray();
// Consider additional entries from the form
- if ($this->context->getRoot()->has('bom_entries')) {
+ if ($this->context->getRoot() instanceof Form && $this->context->getRoot()->has('bom_entries')) {
$formBomEntries = $this->context->getRoot()->get('bom_entries')->getData();
if ($formBomEntries) {
$given = is_array($formBomEntries) ? $formBomEntries : iterator_to_array($formBomEntries);
From 771c6c573b70f42da41890a346c7c50ee7afc568 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 24 Jul 2025 09:11:28 +0200
Subject: [PATCH 29/83] =?UTF-8?q?BOMValidator:=20Validierung=20f=C3=BCr=20?=
=?UTF-8?q?rekursive=20Baugruppen-Eintragspr=C3=BCfung=20erg=C3=A4nzt?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Es wurde eine neue Validierung hinzugefügt, um sicherzustellen, dass keine Baugruppe in ihrer eigenen Hierarchie als Unterbaugruppe referenziert wird. Diese Logik wurde in die entsprechenden Dateien integriert und unterstützt Mehrsprachigkeit durch neue Übersetzungen.
---
src/Entity/AssemblySystem/Assembly.php | 6 +-
.../AssemblySystem/AssemblyBOMEntry.php | 2 +
.../AssemblySystem/AssemblyCycleValidator.php | 67 +++++---
.../AssemblyInvalidBomEntry.php | 21 +++
.../AssemblyInvalidBomEntryValidator.php | 155 ++++++++++++++++++
translations/validators.cs.xlf | 6 +
translations/validators.da.xlf | 6 +
translations/validators.de.xlf | 6 +
translations/validators.el.xlf | 6 +
translations/validators.en.xlf | 6 +
translations/validators.fr.xlf | 6 +
translations/validators.hr.xlf | 6 +
translations/validators.it.xlf | 6 +
translations/validators.ja.xlf | 6 +
translations/validators.pl.xlf | 6 +
translations/validators.ru.xlf | 6 +
translations/validators.zh.xlf | 6 +
17 files changed, 302 insertions(+), 21 deletions(-)
create mode 100644 src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntry.php
create mode 100644 src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntryValidator.php
diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php
index cb6e94def..c65ca71fe 100644
--- a/src/Entity/AssemblySystem/Assembly.php
+++ b/src/Entity/AssemblySystem/Assembly.php
@@ -24,6 +24,7 @@
use App\Repository\AssemblyRepository;
use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
+use App\Validator\Constraints\AssemblySystem\AssemblyInvalidBomEntry;
use Doctrine\Common\Collections\Criteria;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Metadata\ApiFilter;
@@ -111,11 +112,12 @@ class Assembly extends AbstractStructuralDBElement
* @var Collection
*/
#[Assert\Valid]
+ #[AssemblyCycle]
+ #[AssemblyInvalidBomEntry]
+ #[UniqueReferencedAssembly]
#[Groups(['extended', 'full', 'import'])]
#[ORM\OneToMany(targetEntity: AssemblyBOMEntry::class, mappedBy: 'assembly', cascade: ['persist', 'remove'], orphanRemoval: true)]
#[UniqueObjectCollection(message: 'assembly.bom_entry.part_already_in_bom', fields: ['part'])]
- #[AssemblyCycle]
- #[UniqueReferencedAssembly]
#[UniqueObjectCollection(message: 'assembly.bom_entry.project_already_in_bom', fields: ['project'])]
#[UniqueObjectCollection(message: 'assembly.bom_entry.name_already_in_bom', fields: ['name'])]
protected Collection $bom_entries;
diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
index 8a4cdbc24..7d54fe684 100644
--- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php
+++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
@@ -39,6 +39,7 @@
use App\Entity\ProjectSystem\Project;
use App\Repository\DBElementRepository;
use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
+use App\Validator\Constraints\AssemblySystem\AssemblyInvalidBomEntry;
use App\Validator\UniqueValidatableInterface;
use Doctrine\DBAL\Types\Types;
use App\Entity\Base\AbstractDBElement;
@@ -142,6 +143,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
message: 'validator.assembly.bom_entry.only_part_or_assembly_allowed'
)]
#[AssemblyCycle]
+ #[AssemblyInvalidBomEntry]
#[ORM\ManyToOne(targetEntity: Assembly::class)]
#[ORM\JoinColumn(name: 'id_referenced_assembly', nullable: true, onDelete: 'SET NULL')]
#[Groups(['bom_entry:read', 'bom_entry:write', ])]
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
index 73df284dd..f12f19a73 100644
--- a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
@@ -49,49 +49,78 @@ public function validate($value, Constraint $constraint): void
return;
}
- $bomEntries = $value->getBomEntries()->toArray();
+ $availableViolations = $this->context->getViolations();
+ if (count($availableViolations) > 0) {
+ //already violations given, currently no more needed to check
+
+ return;
+ }
+
+ $bomEntries = [];
- // Consider additional entries from the form
if ($this->context->getRoot() instanceof Form && $this->context->getRoot()->has('bom_entries')) {
- $formBomEntries = $this->context->getRoot()->get('bom_entries')->getData();
- if ($formBomEntries) {
- $given = is_array($formBomEntries) ? $formBomEntries : iterator_to_array($formBomEntries);
- foreach ($given as $givenIdx => $entry) {
- if (in_array($entry, $bomEntries, true)) {
- continue;
- } else {
- $bomEntries[$givenIdx] = $entry;
- }
- }
+ $bomEntries = $this->context->getRoot()->get('bom_entries')->getData();
+ $bomEntries = is_array($bomEntries) ? $bomEntries : iterator_to_array($bomEntries);
+ } elseif ($this->context->getRoot() instanceof Assembly) {
+ $bomEntries = $value->getBomEntries()->toArray();
+ }
+
+ $relevantEntries = [];
+
+ foreach ($bomEntries as $bomEntry) {
+ if ($bomEntry->getReferencedAssembly() !== null) {
+ $relevantEntries[$bomEntry->getId()] = $bomEntry;
}
}
$visitedAssemblies = [];
- foreach ($bomEntries as $bomEntry) {
+ foreach ($relevantEntries as $bomEntry) {
if ($this->hasCycle($bomEntry->getReferencedAssembly(), $value, $visitedAssemblies)) {
$this->addViolation($value, $constraint);
}
}
}
- private function hasCycle(?Assembly $currentAssembly, Assembly $originalAssembly, array &$visitedAssemblies): bool
+ /**
+ * Determines if there is a cyclic dependency in the assembly hierarchy.
+ *
+ * This method checks if a cycle exists in the hierarchy of referenced assemblies starting
+ * from a given assembly. It traverses through the Bill of Materials (BOM) entries of each
+ * assembly recursively and keeps track of visited assemblies to detect cycles.
+ *
+ * @param Assembly|null $currentAssembly The current assembly being checked for cycles.
+ * @param Assembly $originalAssembly The original assembly from where the cycle detection started.
+ * @param Assembly[] $visitedAssemblies A list of assemblies that have been visited during the current traversal.
+ *
+ * @return bool True if a cycle is detected, false otherwise.
+ */
+ private function hasCycle(?Assembly $currentAssembly, Assembly $originalAssembly, array $visitedAssemblies = []): bool
{
+ //No referenced assembly → no cycle
if ($currentAssembly === null) {
return false;
}
- if (in_array($currentAssembly, $visitedAssemblies, true)) {
+ //If the assembly has already been visited, there is a cycle
+ if (in_array($currentAssembly->getId(), array_map(fn($a) => $a->getId(), $visitedAssemblies), true)) {
return true;
}
+ //Add the current assembly to the visited
$visitedAssemblies[] = $currentAssembly;
+ //Go through the bom entries of the current assembly
foreach ($currentAssembly->getBomEntries() as $bomEntry) {
- if ($this->hasCycle($bomEntry->getReferencedAssembly(), $originalAssembly, $visitedAssemblies)) {
+ $referencedAssembly = $bomEntry->getReferencedAssembly();
+
+ if ($referencedAssembly !== null && $this->hasCycle($referencedAssembly, $originalAssembly, $visitedAssemblies)) {
return true;
}
}
+ //Remove the current assembly from the list of visit (recursion completed)
+ array_pop($visitedAssemblies);
+
return false;
}
@@ -102,11 +131,11 @@ private function hasCycle(?Assembly $currentAssembly, Assembly $originalAssembly
* already exists in the context. If such a violation is found, the current violation is not added again.
* The process involves reflection to access private or protected properties of violation objects.
*
- * @param mixed $value The value that triggered the violation.
- * @param Constraint $constraint The constraint containing the validation details.
+ * @param mixed $value The value that triggered the violation.
+ * @param Constraint $constraint The constraint containing the validation details.
*
*/
- private function addViolation($value, Constraint $constraint): void
+ private function addViolation(mixed $value, Constraint $constraint): void
{
/** @var ConstraintViolationBuilder $buildViolation */
$buildViolation = $this->context->buildViolation($constraint->message)
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntry.php b/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntry.php
new file mode 100644
index 000000000..73234c86e
--- /dev/null
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntry.php
@@ -0,0 +1,21 @@
+context->getViolations();
+ if (count($availableViolations) > 0) {
+ //already violations given, currently no more needed to check
+
+ return;
+ }
+
+ $bomEntries = [];
+
+ if ($this->context->getRoot() instanceof Form && $this->context->getRoot()->has('bom_entries')) {
+ $bomEntries = $this->context->getRoot()->get('bom_entries')->getData();
+ $bomEntries = is_array($bomEntries) ? $bomEntries : iterator_to_array($bomEntries);
+ } elseif ($this->context->getRoot() instanceof Assembly) {
+ $bomEntries = $value->getBomEntries()->toArray();
+ }
+
+ $relevantEntries = [];
+
+ foreach ($bomEntries as $bomEntry) {
+ if ($bomEntry->getReferencedAssembly() !== null) {
+ $relevantEntries[$bomEntry->getId()] = $bomEntry;
+ }
+ }
+
+ foreach ($relevantEntries as $bomEntry) {
+ $referencedAssembly = $bomEntry->getReferencedAssembly();
+
+ if ($bomEntry->getAssembly()->getParent()?->getId() === $referencedAssembly->getParent()?->getId()) {
+ //Save on the same assembly level
+ continue;
+ } elseif ($this->isInvalidBomEntry($referencedAssembly, $bomEntry->getAssembly())) {
+ $this->addViolation($value, $constraint);
+ }
+ }
+ }
+
+ /**
+ * Determines whether a Bill of Materials (BOM) entry is invalid based on the relationship
+ * between the current assembly and the parent assembly.
+ *
+ * @param Assembly|null $currentAssembly The current assembly being analyzed. Null indicates no assembly is referenced.
+ * @param Assembly $parentAssembly The parent assembly to check against the current assembly.
+ *
+ * @return bool Returns
+ */
+ private function isInvalidBomEntry(?Assembly $currentAssembly, Assembly $parentAssembly): bool
+ {
+ //No assembly referenced -> no problems
+ if ($currentAssembly === null) {
+ return false;
+ }
+
+ //Check: is the current assembly a descendant of the parent assembly?
+ if ($currentAssembly->isChildOf($parentAssembly)) {
+ return true;
+ }
+
+ //Recursive check: Analyze the current assembly list
+ foreach ($currentAssembly->getBomEntries() as $bomEntry) {
+ $referencedAssembly = $bomEntry->getReferencedAssembly();
+
+ if ($this->isInvalidBomEntry($referencedAssembly, $parentAssembly)) {
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+ private function isOnSameLevel(Assembly $assembly1, Assembly $assembly2): bool
+ {
+ $parent1 = $assembly1->getParent();
+ $parent2 = $assembly2->getParent();
+
+ if ($parent1 === null || $parent2 === null) {
+ return false;
+ }
+
+ // Beide Assemblies teilen denselben Parent
+ return $parent1 !== null && $parent2 !== null && $parent1->getId() === $parent2->getId();
+ }
+
+ /**
+ * Adds a violation to the current context if it hasn’t already been added.
+ *
+ * This method checks whether a violation with the same property path as the current violation
+ * already exists in the context. If such a violation is found, the current violation is not added again.
+ * The process involves reflection to access private or protected properties of violation objects.
+ *
+ * @param mixed $value The value that triggered the violation.
+ * @param Constraint $constraint The constraint containing the validation details.
+ *
+ */
+ private function addViolation($value, Constraint $constraint): void
+ {
+ /** @var ConstraintViolationBuilder $buildViolation */
+ $buildViolation = $this->context->buildViolation($constraint->message)
+ ->setParameter('%name%', $value->getName());
+
+ $alreadyAdded = false;
+
+ try {
+ $reflectionClass = new ReflectionClass($buildViolation);
+ $property = $reflectionClass->getProperty('propertyPath');
+ $propertyPath = $property->getValue($buildViolation);
+
+ $availableViolations = $this->context->getViolations();
+
+ foreach ($availableViolations as $tmpViolation) {
+ $tmpReflectionClass = new ReflectionClass($tmpViolation);
+ $tmpProperty = $tmpReflectionClass->getProperty('propertyPath');
+ $tmpPropertyPath = $tmpProperty->getValue($tmpViolation);
+
+ if ($tmpPropertyPath === $propertyPath) {
+ $alreadyAdded = true;
+ }
+ }
+ } catch (\ReflectionException) {
+ }
+
+ if (!$alreadyAdded) {
+ $buildViolation->addViolation();
+ }
+ }
+}
\ No newline at end of file
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index b99fe349d..838f47450 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -407,6 +407,12 @@
Byl zjištěn cyklus: Sestava "%name%" nepřímo odkazuje sama na sebe.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Sestava nesmí ve svém seznamu materiálů (BOM) odkazovat na podskupinu, která je součástí její vlastní hierarchie.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index 24fa330af..f30dd2116 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -377,6 +377,12 @@
En cyklus blev opdaget: Samlingen "%name%" refererer indirekte til sig selv.
+
+
+ assembly.bom_entry.invalid_child_entry
+ En samling må ikke referere til en undergruppe fra sin egen hierarki i BOM-listerne.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index fa84354b9..645d72ed1 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -401,6 +401,12 @@
Ein Zyklus wurde entdeckt: Die Baugruppe "%name%" referenziert sich indirekt selbst.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Eine Baugruppe darf keine Unterbaugruppe aus seiner eigenen Hierarchie in den BOM-Einträgen referenzieren.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index bc9b0947e..9464f2886 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -43,6 +43,12 @@
Εντοπίστηκε κύκλος: Η συναρμολόγηση "%name%" αναφέρεται έμμεσα στον εαυτό της.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Μία συναρμολόγηση δεν πρέπει να αναφέρεται σε μία υποσυναρμολόγηση από την ίδια την ιεραρχία της στη λίστα BOM.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index 7d9beb4ec..53ad4cde6 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -401,6 +401,12 @@
A cycle was detected: the assembly "%name%" indirectly references itself.
+
+
+ assembly.bom_entry.invalid_child_entry
+ An assembly must not reference a subassembly from its own hierarchy in the BOM entries.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index 1c9c53029..440468295 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -233,6 +233,12 @@
Un cycle a été détecté : L'assemblage "%name%" se réfère indirectement à lui-même.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Un assemblage ne doit pas référencer un sous-assemblage de sa propre hiérarchie dans les entrées de la nomenclature (BOM).
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index 89d470e7e..485cb0e2f 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -395,6 +395,12 @@
Otkriven je ciklus: Sklop "%name%" neizravno referencira samog sebe.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Sklop ne smije referencirati podsklop iz vlastite hijerarhije u unosima BOM-a.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index e9b528bb7..74d3969f7 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -395,6 +395,12 @@
È stato rilevato un ciclo: L'assemblaggio "%name%" fa riferimento indirettamente a sé stesso.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Un assemblaggio non deve fare riferimento a un sottoassemblaggio nella propria gerarchia nelle voci della distinta base (BOM).
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index 80ec65ff2..f9f8a54f8 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -233,6 +233,12 @@
循環が検出されました: アセンブリ「%name%」が間接的に自身を参照しています。
+
+
+ assembly.bom_entry.invalid_child_entry
+ アセンブリは、BOMエントリで自身の階層内のサブアセンブリを参照してはいけません。
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 5df01cd6a..9916178ca 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -395,6 +395,12 @@
循環が検出されました: アセンブリ「%name%」が間接的に自身を参照しています。
+
+
+ assembly.bom_entry.invalid_child_entry
+ Zespół nie może odwoływać się do podzespołu w swojej własnej hierarchii w wpisach BOM.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index 8bf08ab3c..b8029e47f 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -395,6 +395,12 @@
Обнаружен цикл: Сборка «%name%» косвенно ссылается на саму себя.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Сборка не должна ссылаться на подсборку внутри своей собственной иерархии в записях спецификации (BOM).
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 87c507c19..6e4fc0568 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -383,6 +383,12 @@
检测到循环:装配体“%name%”间接引用了其自身。
+
+
+ assembly.bom_entry.invalid_child_entry
+ Сборка не должна ссылаться на подсборку внутри своей собственной иерархии в записях спецификации (BOM).
+
+ assembly.bom_entry.project_already_in_bom
From eb6e5905ee7d4fbf960df0064b3a68a57a4e3326 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 24 Jul 2025 10:31:19 +0200
Subject: [PATCH 30/83] Tabs und BOMImporter: Verbesserte Anzeige und
Validierung
Die Standardanzeige des Tabs "Details" wurde korrigiert. Im BOMImporter wurden nichtnumerische Spalten kategorisch ausgeschlossen und eine Validation-message angepasst.
---
src/Services/ImportExportSystem/BOMImporter.php | 4 ++--
templates/assemblies/info/info.html.twig | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php
index 6a3528117..034bebaaa 100644
--- a/src/Services/ImportExportSystem/BOMImporter.php
+++ b/src/Services/ImportExportSystem/BOMImporter.php
@@ -517,7 +517,7 @@ function parseCsv(Project|Assembly $importObject, string $csvData): ImporterResu
//If there is no value, skip
if (isset($values[$index]) && $values[$index] !== '') {
//Check whether the value is numerical
- if (is_numeric($values[$index])) {
+ if (is_numeric($values[$index]) && !in_array($column, ['name','description','manufacturer','designator'])) {
//Convert to integer or float
$temp = (str_contains($values[$index], '.'))
? floatval($values[$index])
@@ -548,7 +548,7 @@ function parseCsv(Project|Assembly $importObject, string $csvData): ImporterResu
if (isset($entry['name']) && !is_string($entry['name'])) {
$result->addViolation($this->buildJsonViolation(
- 'validator.bom_importer.csv.parameter.string.notEmpty',
+ 'validator.bom_importer.json_csv.parameter.string.notEmpty',
"row[$key].name",
$entry['name']
));
diff --git a/templates/assemblies/info/info.html.twig b/templates/assemblies/info/info.html.twig
index 098173861..5a419e364 100644
--- a/templates/assemblies/info/info.html.twig
+++ b/templates/assemblies/info/info.html.twig
@@ -98,10 +98,10 @@
-
+
{% include "assemblies/info/_info.html.twig" %}
-
+
{% include "assemblies/info/_part.html.twig" %}
From c08c2f0b43d4056741654bad85604a7f446c0f65 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 28 Jul 2025 10:33:30 +0200
Subject: [PATCH 31/83] =?UTF-8?q?BOMImporter=20und=20AssemblyBomEntriesDat?=
=?UTF-8?q?aTable:=20Mountnames=20hinzugef=C3=BCgt?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Die Verarbeitung der Designators im BOMImporter wurde ergänzt, um Mountnames zu setzen. Zudem wurden neue Spalten wie Kategorie, Footprint, Hersteller und Mountnames in der AssemblyBomEntriesDataTable hinzugefügt. Dies verbessert die Darstellung und Handhabung von Bauteildaten in der Stücklisten-Ansicht.
---
.../AssemblyBomEntriesDataTable.php | 49 +++++++++++++++++++
.../ImportExportSystem/BOMImporter.php | 9 ++++
2 files changed, 58 insertions(+)
diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php
index b2c3e118d..e506dccd2 100644
--- a/src/DataTables/AssemblyBomEntriesDataTable.php
+++ b/src/DataTables/AssemblyBomEntriesDataTable.php
@@ -22,6 +22,7 @@
*/
namespace App\DataTables;
+use App\DataTables\Column\EntityColumn;
use App\DataTables\Column\LocaleDateTimeColumn;
use App\DataTables\Column\MarkdownColumn;
use App\DataTables\Helpers\AssemblyDataTableHelper;
@@ -146,6 +147,54 @@ public function configure(DataTable $dataTable, array $options): void
return $context->getComment();
},
])
+ ->add('category', EntityColumn::class, [
+ 'label' => $this->translator->trans('part.table.category'),
+ 'property' => 'part.category',
+ 'orderField' => 'NATSORT(category.name)',
+ ])
+ ->add('footprint', EntityColumn::class, [
+ 'property' => 'part.footprint',
+ 'label' => $this->translator->trans('part.table.footprint'),
+ 'orderField' => 'NATSORT(footprint.name)',
+ ])
+ ->add('manufacturer', EntityColumn::class, [
+ 'property' => 'part.manufacturer',
+ 'label' => $this->translator->trans('part.table.manufacturer'),
+ 'orderField' => 'NATSORT(manufacturer.name)',
+ ])
+ ->add('mountnames', TextColumn::class, [
+ 'label' => 'assembly.bom.mountnames',
+ 'render' => function ($value, AssemblyBOMEntry $context) {
+ $html = '';
+
+ foreach (explode(',', $context->getMountnames()) as $mountname) {
+ $html .= sprintf('%s ', htmlspecialchars($mountname));
+ }
+ return $html;
+ },
+ ])
+ ->add('instockAmount', TextColumn::class, [
+ 'label' => 'assembly.bom.instockAmount',
+ 'visible' => false,
+ 'render' => function ($value, AssemblyBOMEntry $context) {
+ if ($context->getPart() !== null) {
+ return $this->partDataTableHelper->renderAmount($context->getPart());
+ }
+
+ return '';
+ }
+ ])
+ ->add('storageLocations', TextColumn::class, [
+ 'label' => 'part.table.storeLocations',
+ 'visible' => false,
+ 'render' => function ($value, AssemblyBOMEntry $context) {
+ if ($context->getPart() !== null) {
+ return $this->partDataTableHelper->renderStorageLocations($context->getPart());
+ }
+
+ return '';
+ }
+ ])
->add('addedDate', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.addedDate'),
])
diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php
index 034bebaaa..1a57e1f90 100644
--- a/src/Services/ImportExportSystem/BOMImporter.php
+++ b/src/Services/ImportExportSystem/BOMImporter.php
@@ -563,6 +563,11 @@ function parseCsv(Project|Assembly $importObject, string $csvData): ImporterResu
$this->processPart($importObject, $entry, $result, $key, self::IMPORT_TYPE_CSV);
} else {
$bomEntry = $this->getOrCreateBomEntry($importObject, $entry['name'] ?? null);
+
+ if (isset($entry['designator'])) {
+ $bomEntry->setMountnames(trim($entry['designator']) === '' ? '' : trim($entry['designator']));
+ }
+
$bomEntry->setQuantity((float) $entry['quantity'] ?? 0);
$result->addBomEntry($bomEntry);
@@ -851,6 +856,10 @@ private function processPart(Project|Assembly $importObject, array $entry, Impor
$bomEntry->setName(null);
}
+ if (isset($entry['designator'])) {
+ $bomEntry->setMountnames(trim($entry['designator']) === '' ? '' : trim($entry['designator']));
+ }
+
$bomEntry->setPart($part);
$result->addBomEntry($bomEntry);
From 1c45054967d30f950afb0e39f619e8ca50ae6c1c Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 8 Sep 2025 13:32:34 +0200
Subject: [PATCH 32/83] =?UTF-8?q?F=C3=BCge=20Option=20f=C3=BCr=20lesbares?=
=?UTF-8?q?=20CSV=20beim=20Export=20hinzu=20(APS-3)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../elements/toggle_visibility_controller.js | 52 ++++
.../AssemblySystem/AssemblyBOMEntry.php | 6 +-
.../ImportExportSystem/EntityExporter.php | 291 +++++++++++++++++-
templates/admin/_export_form.html.twig | 19 +-
translations/messages.cs.xlf | 6 +
translations/messages.da.xlf | 6 +
translations/messages.de.xlf | 6 +
translations/messages.el.xlf | 6 +
translations/messages.en.xlf | 6 +
translations/messages.es.xlf | 6 +
translations/messages.fr.xlf | 6 +
translations/messages.it.xlf | 6 +
translations/messages.ja.xlf | 6 +
translations/messages.nl.xlf | 6 +
translations/messages.pl.xlf | 6 +
translations/messages.ru.xlf | 6 +
translations/messages.zh.xlf | 6 +
17 files changed, 432 insertions(+), 14 deletions(-)
create mode 100644 assets/controllers/elements/toggle_visibility_controller.js
diff --git a/assets/controllers/elements/toggle_visibility_controller.js b/assets/controllers/elements/toggle_visibility_controller.js
new file mode 100644
index 000000000..4600dfb29
--- /dev/null
+++ b/assets/controllers/elements/toggle_visibility_controller.js
@@ -0,0 +1,52 @@
+import { Controller } from "@hotwired/stimulus";
+
+export default class extends Controller {
+
+ static values = {
+ classes: Array
+ };
+
+ connect() {
+ this.readableCheckbox = this.element.querySelector("#readable");
+
+ if (!this.readableCheckbox) {
+ return;
+ }
+
+ // Apply the initial visibility state based on the checkbox being checked or not
+ this.toggleContainers(this.readableCheckbox.checked);
+
+ // Add a change event listener to the 'readable' checkbox
+ this.readableCheckbox.addEventListener("change", (event) => {
+ // Toggle container visibility when the checkbox value changes
+ this.toggleContainers(event.target.checked);
+ });
+ }
+
+ /**
+ * Toggles the visibility of containers based on the checkbox state.
+ * Hides specified containers if the checkbox is checked and shows them otherwise.
+ *
+ * @param {boolean} isChecked - The current state of the checkbox:
+ * true if checked (hide elements), false if unchecked (show them).
+ */
+ toggleContainers(isChecked) {
+ if (!Array.isArray(this.classesValue) || this.classesValue.length === 0) {
+ return;
+ }
+
+ this.classesValue.forEach((cssClass) => {
+ const elements = document.querySelectorAll(`.${cssClass}`);
+
+ if (!elements.length) {
+ return;
+ }
+
+ // Update the visibility for each selected element
+ elements.forEach((element) => {
+ // If the checkbox is checked, hide the container; otherwise, show it
+ element.style.display = isChecked ? "none" : "";
+ });
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
index 7d54fe684..9bca209d0 100644
--- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php
+++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
@@ -124,7 +124,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
*/
#[ORM\ManyToOne(targetEntity: Assembly::class, inversedBy: 'bom_entries')]
#[ORM\JoinColumn(name: 'id_assembly', nullable: true)]
- #[Groups(['bom_entry:read', 'bom_entry:write', ])]
+ #[Groups(['bom_entry:read', 'bom_entry:write'])]
protected ?Assembly $assembly = null;
/**
@@ -146,7 +146,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
#[AssemblyInvalidBomEntry]
#[ORM\ManyToOne(targetEntity: Assembly::class)]
#[ORM\JoinColumn(name: 'id_referenced_assembly', nullable: true, onDelete: 'SET NULL')]
- #[Groups(['bom_entry:read', 'bom_entry:write', ])]
+ #[Groups(['bom_entry:read', 'bom_entry:write'])]
protected ?Assembly $referencedAssembly = null;
/**
@@ -158,7 +158,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
)]
#[ORM\ManyToOne(targetEntity: Project::class)]
#[ORM\JoinColumn(name: 'id_project', nullable: true)]
- #[Groups(['bom_entry:read', 'bom_entry:write', ])]
+ #[Groups(['bom_entry:read', 'bom_entry:write'])]
protected ?Project $project = null;
/**
diff --git a/src/Services/ImportExportSystem/EntityExporter.php b/src/Services/ImportExportSystem/EntityExporter.php
index 271642dad..1adbcdcbb 100644
--- a/src/Services/ImportExportSystem/EntityExporter.php
+++ b/src/Services/ImportExportSystem/EntityExporter.php
@@ -22,8 +22,19 @@
namespace App\Services\ImportExportSystem;
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\Attachments\AttachmentType;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement;
+use App\Entity\LabelSystem\LabelProfile;
+use App\Entity\Parts\Category;
+use App\Entity\Parts\Footprint;
+use App\Entity\Parts\Manufacturer;
+use App\Entity\Parts\MeasurementUnit;
+use App\Entity\Parts\StorageLocation;
+use App\Entity\Parts\Supplier;
+use App\Entity\PriceInformations\Currency;
+use App\Entity\ProjectSystem\Project;
use App\Helpers\FilenameSanatizer;
use App\Serializer\APIPlatform\SkippableItemNormalizer;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -62,6 +73,9 @@ protected function configureOptions(OptionsResolver $resolver): void
$resolver->setDefault('include_children', false);
$resolver->setAllowedTypes('include_children', 'bool');
+
+ $resolver->setDefault('readable', false);
+ $resolver->setAllowedTypes('readable', 'bool');
}
/**
@@ -144,15 +158,50 @@ public function exportEntityFromRequest(AbstractNamedDBElement|array $entities,
$entities = [$entities];
}
- //Do the serialization with the given options
- $serialized_data = $this->exportEntities($entities, $options);
+ if ($request->get('readable', false)) {
+ // Map entity classes to export functions
+ $entityExportMap = [
+ AttachmentType::class => fn($entities) => $this->exportReadable($entities, AttachmentType::class),
+ Category::class => fn($entities) => $this->exportReadable($entities, Category::class),
+ Project::class => fn($entities) => $this->exportReadable($entities, Project::class),
+ Assembly::class => fn($entities) => $this->exportReadable($entities, Assembly::class),
+ Supplier::class => fn($entities) => $this->exportReadable($entities, Supplier::class),
+ Manufacturer::class => fn($entities) => $this->exportReadable($entities, Manufacturer::class),
+ StorageLocation::class => fn($entities) => $this->exportReadable($entities, StorageLocation::class),
+ Footprint::class => fn($entities) => $this->exportReadable($entities, Footprint::class),
+ Currency::class => fn($entities) => $this->exportReadable($entities, Currency::class),
+ MeasurementUnit::class => fn($entities) => $this->exportReadable($entities, MeasurementUnit::class),
+ LabelProfile::class => fn($entities) => $this->exportReadable($entities, LabelProfile::class, false),
+ ];
+
+ // Determine the type of the entity
+ $type = null;
+ foreach ($entities as $entity) {
+ $entityClass = get_class($entity);
+ if (isset($entityExportMap[$entityClass])) {
+ $type = $entityClass;
+ break;
+ }
+ }
+
+ // Generate the response
+ $response = isset($entityExportMap[$type])
+ ? new Response($entityExportMap[$type]($entities))
+ : new Response('');
+
+ $options['format'] = 'csv';
+ $options['level'] = 'readable';
+ } else {
+ //Do the serialization with the given options
+ $serialized_data = $this->exportEntities($entities, $options);
- $response = new Response($serialized_data);
+ $response = new Response($serialized_data);
- //Resolve the format
- $optionsResolver = new OptionsResolver();
- $this->configureOptions($optionsResolver);
- $options = $optionsResolver->resolve($options);
+ //Resolve the format
+ $optionsResolver = new OptionsResolver();
+ $this->configureOptions($optionsResolver);
+ $options = $optionsResolver->resolve($options);
+ }
//Determine the content type for the response
@@ -203,4 +252,232 @@ public function exportEntityFromRequest(AbstractNamedDBElement|array $entities,
return $response;
}
+
+ /**
+ * Exports data for multiple entity types in a readable CSV format.
+ *
+ * @param array $entities The entities to export.
+ * @param string $type The type of entities ('category', 'project', 'assembly', 'attachmentType', 'supplier').
+ * @return string The generated CSV content as a string.
+ */
+ public function exportReadable(array $entities, string $type, bool $isHierarchical = true): string
+ {
+ //Define headers and entity-specific processing logic
+ $defaultProcessEntity = fn($entity, $depth) => [
+ 'Id' => $entity->getId(),
+ 'ParentId' => $entity->getParent()?->getId() ?? '',
+ 'NameHierarchical' => str_repeat('--', $depth) . ' ' . $entity->getName(),
+ 'Name' => $entity->getName(),
+ 'FullName' => $this->getFullName($entity),
+ ];
+
+ $config = [
+ AttachmentType::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Category::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Project::class => [
+ 'header' => [
+ 'Id', 'ParentId', 'Type', 'ProjectNameHierarchical', 'ProjectName', 'ProjectFullName',
+ 'BomQuantity', 'BomPartId', 'BomPartIpn', 'BomPartName', 'BomName', 'BomPartDescription', 'BomMountNames'
+ ],
+ 'processEntity' => fn($entity, $depth) => [
+ 'ProjectId' => $entity->getId(),
+ 'ParentProjectId' => $entity->getParent()?->getId() ?? '',
+ 'Type' => 'project',
+ 'ProjectNameHierarchical' => str_repeat('--', $depth) . ' ' . $entity->getName(),
+ 'ProjectName' => $entity->getName(),
+ 'ProjectFullName' => $this->getFullName($entity),
+ 'BomQuantity' => '-',
+ 'BomPartId' => '-',
+ 'BomPartIpn' => '-',
+ 'BomPartName' => '-',
+ 'BomName' => '-',
+ 'BomPartDescription' => '-',
+ 'BomMountNames' => '-',
+ ],
+ 'processBomEntries' => fn($entity, $depth) => array_map(fn($bomEntry) => [
+ 'Id' => $entity->getId(),
+ 'ParentId' => '',
+ 'Type' => 'project_bom_entry',
+ 'ProjectNameHierarchical' => str_repeat('--', $depth) . '> ' . $entity->getName(),
+ 'ProjectName' => $entity->getName(),
+ 'ProjectFullName' => $this->getFullName($entity),
+ 'BomQuantity' => $bomEntry->getQuantity() ?? '',
+ 'BomPartId' => $bomEntry->getPart()?->getId() ?? '',
+ 'BomPartIpn' => $bomEntry->getPart()?->getIpn() ?? '',
+ 'BomPartName' => $bomEntry->getPart()?->getName() ?? '',
+ 'BomName' => $bomEntry->getName() ?? '',
+ 'BomPartDescription' => $bomEntry->getPart()?->getDescription() ?? '',
+ 'BomMountNames' => $bomEntry->getMountNames(),
+ ], $entity->getBomEntries()->toArray()),
+ ],
+ Assembly::class => [
+ 'header' => [
+ 'Id', 'ParentId', 'Type', 'AssemblyIpn', 'AssemblyNameHierarchical', 'AssemblyName',
+ 'AssemblyFullName', 'BomQuantity', 'BomPartId', 'BomPartIpn', 'BomPartName', 'BomName', 'BomPartDescription',
+ 'BomMountNames', 'BomReferencedAssemblyId', 'BomReferencedAssemblyIpn', 'BomReferencedAssemblyFullName'
+ ],
+ 'processEntity' => fn($entity, $depth) => [
+ 'Id' => $entity->getId(),
+ 'ParentId' => $entity->getParent()?->getId() ?? '',
+ 'Type' => 'assembly',
+ 'AssemblyIpn' => $entity->getIpn(),
+ 'AssemblyNameHierarchical' => str_repeat('--', $depth) . ' ' . $entity->getName(),
+ 'AssemblyName' => $entity->getName(),
+ 'AssemblyFullName' => $this->getFullName($entity),
+ 'BomQuantity' => '-',
+ 'BomPartId' => '-',
+ 'BomPartIpn' => '-',
+ 'BomPartName' => '-',
+ 'BomName' => '-',
+ 'BomPartDescription' => '-',
+ 'BomMountNames' => '-',
+ 'BomReferencedAssemblyId' => '-',
+ 'BomReferencedAssemblyIpn' => '-',
+ 'BomReferencedAssemblyFullName' => '-',
+ ],
+ 'processBomEntries' => fn($entity, $depth) => array_map(fn($bomEntry) => [
+ 'Id' => $entity->getId(),
+ 'ParentId' => '',
+ 'Type' => 'assembly_bom_entry',
+ 'AssemblyIpn' => $entity->getIpn(),
+ 'AssemblyNameHierarchical' => str_repeat('--', $depth) . '> ' . $entity->getName(),
+ 'AssemblyName' => $entity->getName(),
+ 'AssemblyFullName' => $this->getFullName($entity),
+ 'BomQuantity' => $bomEntry->getQuantity() ?? '',
+ 'BomPartId' => $bomEntry->getPart()?->getId() ?? '',
+ 'BomPartIpn' => $bomEntry->getPart()?->getIpn() ?? '',
+ 'BomPartName' => $bomEntry->getPart()?->getName() ?? '',
+ 'BomName' => $bomEntry->getName() ?? '',
+ 'BomPartDescription' => $bomEntry->getPart()?->getDescription() ?? '',
+ 'BomMountNames' => $bomEntry->getMountNames(),
+ 'BomReferencedAssemblyId' => $bomEntry->getReferencedAssembly()?->getId() ?? '',
+ 'BomReferencedAssemblyIpn' => $bomEntry->getReferencedAssembly()?->getIpn() ?? '',
+ 'BomReferencedAssemblyFullName' => $this->getFullName($bomEntry->getReferencedAssembly() ?? null),
+ ], $entity->getBomEntries()->toArray()),
+ ],
+ Supplier::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Manufacturer::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ StorageLocation::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Footprint::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Currency::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ MeasurementUnit::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ LabelProfile::class => [
+ 'header' => ['Id', 'SupportedElement', 'Name'],
+ 'processEntity' => fn(LabelProfile $entity, $depth) => [
+ 'Id' => $entity->getId(),
+ 'SupportedElement' => $entity->getOptions()->getSupportedElement()->name,
+ 'Name' => $entity->getName(),
+ ],
+ ],
+ ];
+
+ //Get configuration for the entity type
+ $entityConfig = $config[$type] ?? null;
+
+ if (!$entityConfig) {
+ return '';
+ }
+
+ //Initialize CSV data with the header
+ $csvData = [];
+ $csvData[] = $entityConfig['header'];
+
+ $relevantEntities = $entities;
+
+ if ($isHierarchical) {
+ //Filter root entities (those without parents)
+ $relevantEntities = array_filter($entities, fn($entity) => $entity->getParent() === null);
+
+ if (count($relevantEntities) === 0 && count($entities) > 0) {
+ //If no root entities are found, then we need to add all entities
+
+ $relevantEntities = $entities;
+ }
+ }
+
+ //Sort root entities alphabetically by `name`
+ usort($relevantEntities, fn($a, $b) => strnatcasecmp($a->getName(), $b->getName()));
+
+ //Recursive function to process an entity and its children
+ $processEntity = function ($entity, &$csvData, $depth = 0) use (&$processEntity, $entityConfig, $isHierarchical) {
+ //Add main entity data to CSV
+ $csvData[] = $entityConfig['processEntity']($entity, $depth);
+
+ //Process BOM entries if applicable
+ if (isset($entityConfig['processBomEntries'])) {
+ $bomRows = $entityConfig['processBomEntries']($entity, $depth);
+ foreach ($bomRows as $bomRow) {
+ $csvData[] = $bomRow;
+ }
+ }
+
+ if ($isHierarchical) {
+ //Retrieve children, sort alphabetically, then process them
+ $children = $entity->getChildren()->toArray();
+ usort($children, fn($a, $b) => strnatcasecmp($a->getName(), $b->getName()));
+ foreach ($children as $childEntity) {
+ $processEntity($childEntity, $csvData, $depth + 1);
+ }
+ }
+ };
+
+ //Start processing with root entities
+ foreach ($relevantEntities as $rootEntity) {
+ $processEntity($rootEntity, $csvData);
+ }
+
+ //Generate CSV string
+ $output = '';
+ foreach ($csvData as $line) {
+ $output .= implode(';', $line) . "\n"; // Use a semicolon as the delimiter
+ }
+
+ return $output;
+ }
+
+ /**
+ * Constructs the full hierarchical name of an object by traversing
+ * through its parent objects and concatenating their names using
+ * a specified separator.
+ *
+ * @param AttachmentType|Category|Project|Assembly|Supplier|Manufacturer|StorageLocation|Footprint|Currency|MeasurementUnit|LabelProfile|null $object The object whose full name is to be constructed. If null, the result will be an empty string.
+ * @param string $separator The string used to separate the names of the objects in the full hierarchy.
+ *
+ * @return string The full hierarchical name constructed by concatenating the names of the object and its parents.
+ */
+ private function getFullName(AttachmentType|Category|Project|Assembly|Supplier|Manufacturer|StorageLocation|Footprint|Currency|MeasurementUnit|LabelProfile|null $object, string $separator = '->'): string
+ {
+ $fullNameParts = [];
+
+ while ($object !== null) {
+ array_unshift($fullNameParts, $object->getName());
+ $object = $object->getParent();
+ }
+
+ return implode($separator, $fullNameParts);
+ }
}
diff --git a/templates/admin/_export_form.html.twig b/templates/admin/_export_form.html.twig
index 07b00d43c..527518640 100644
--- a/templates/admin/_export_form.html.twig
+++ b/templates/admin/_export_form.html.twig
@@ -1,6 +1,6 @@
-
{% set lots = build_request.partLotsForBOMEntry(bom_entry) %}
+ {% set assemblyBomEntriesWithoutPart = build_request.assemblyBomEntriesWithoutPart(bom_entry) %}
+ {% set assemblyBomEntriesWithPartNoStock = build_request.assemblyBomEntriesWithPartNoStock(bom_entry) %}
{% if lots is not null %}
+ {% set previousLabel = null %}
+
{% for lot in lots %}
{# @var lot \App\Entity\Parts\PartLot #}
+
+ {% set label = '' %}
+ {% if form["lot_"~lot.id].vars.label is defined and form["lot_"~lot.id].vars.label is not empty %}
+ {% set label = form["lot_"~lot.id].vars.label %}
+ {% endif %}
+
+ {% if label != '' and (previousLabel is null or label != previousLabel) %}
+
{% endfor %}
{% endif %}
+ {% if assemblyBomEntriesWithoutPart is not null %}
+ {% for bomEntryWithoutPart in assemblyBomEntriesWithoutPart %}
+
+
+
+
+ / {% trans %}project.builds.no_stock{% endtrans %}
+
+
+ {% endfor %}
+ {% endif %}
+ {% if assemblyBomEntriesWithPartNoStock is not null %}
+ {% for bomEntryWithPartNoStock in assemblyBomEntriesWithPartNoStock %}
+
+
+
+
+
+ / {% trans %}project.builds.no_stock{% endtrans %}
+
+
+
+ {% endfor %}
+ {% endif %}
{% endfor %}
diff --git a/tests/Entity/Attachments/AttachmentTest.php b/tests/Entity/Attachments/AttachmentTest.php
index 00a68d7d4..699648eb7 100644
--- a/tests/Entity/Attachments/AttachmentTest.php
+++ b/tests/Entity/Attachments/AttachmentTest.php
@@ -24,6 +24,8 @@
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Depends;
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\Attachments\AssemblyAttachment;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Attachments\AttachmentTypeAttachment;
@@ -81,6 +83,7 @@ public static function subClassesDataProvider(): \Iterator
yield [CategoryAttachment::class, Category::class];
yield [CurrencyAttachment::class, Currency::class];
yield [ProjectAttachment::class, Project::class];
+ yield [AssemblyAttachment::class, Assembly::class];
yield [FootprintAttachment::class, Footprint::class];
yield [GroupAttachment::class, Group::class];
yield [ManufacturerAttachment::class, Manufacturer::class];
diff --git a/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php b/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php
new file mode 100644
index 000000000..210e33018
--- /dev/null
+++ b/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php
@@ -0,0 +1,177 @@
+.
+ */
+namespace App\Tests\Helpers\Assemblies;
+
+use App\Entity\Parts\MeasurementUnit;
+use App\Entity\Parts\Part;
+use App\Entity\Parts\PartLot;
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\AssemblySystem\AssemblyBOMEntry;
+use App\Helpers\Assemblies\AssemblyBuildRequest;
+use PHPUnit\Framework\TestCase;
+
+class AssemblyBuildRequestTest extends TestCase
+{
+
+ /** @var MeasurementUnit $float_unit */
+ private MeasurementUnit $float_unit;
+
+ /** @var Assembly */
+ private Assembly $assembly1;
+ /** @var AssemblyBOMEntry */
+ private AssemblyBOMEntry $bom_entry1a;
+ /** @var AssemblyBOMEntry */
+ private AssemblyBOMEntry $bom_entry1b;
+ /** @var AssemblyBOMEntry */
+ private AssemblyBOMEntry $bom_entry1c;
+
+ private PartLot $lot1a;
+ private PartLot $lot1b;
+ private PartLot $lot2;
+
+ /** @var Part */
+ private Part $part1;
+ /** @var Part */
+ private Part $part2;
+
+
+ public function setUp(): void
+ {
+ $this->float_unit = new MeasurementUnit();
+ $this->float_unit->setName('float');
+ $this->float_unit->setUnit('f');
+ $this->float_unit->setIsInteger(false);
+ $this->float_unit->setUseSIPrefix(true);
+
+ //Setup some example parts and part lots
+ $this->part1 = new Part();
+ $this->part1->setName('Part 1');
+ $this->lot1a = new class extends PartLot {
+ public function getID(): ?int
+ {
+ return 1;
+ }
+ };
+ $this->part1->addPartLot($this->lot1a);
+ $this->lot1a->setAmount(10);
+ $this->lot1a->setDescription('Lot 1a');
+
+ $this->lot1b = new class extends PartLot {
+ public function getID(): ?int
+ {
+ return 2;
+ }
+ };
+ $this->part1->addPartLot($this->lot1b);
+ $this->lot1b->setAmount(20);
+ $this->lot1b->setDescription('Lot 1b');
+
+ $this->part2 = new Part();
+
+ $this->part2->setName('Part 2');
+ $this->part2->setPartUnit($this->float_unit);
+ $this->lot2 = new PartLot();
+ $this->part2->addPartLot($this->lot2);
+ $this->lot2->setAmount(2.5);
+ $this->lot2->setDescription('Lot 2');
+
+ $this->bom_entry1a = new AssemblyBOMEntry();
+ $this->bom_entry1a->setPart($this->part1);
+ $this->bom_entry1a->setQuantity(2);
+
+ $this->bom_entry1b = new AssemblyBOMEntry();
+ $this->bom_entry1b->setPart($this->part2);
+ $this->bom_entry1b->setQuantity(1.5);
+
+ $this->bom_entry1c = new AssemblyBOMEntry();
+ $this->bom_entry1c->setName('Non-part BOM entry');
+ $this->bom_entry1c->setQuantity(4);
+
+
+ $this->assembly1 = new Assembly();
+ $this->assembly1->setName('Assembly 1');
+ $this->assembly1->addBomEntry($this->bom_entry1a);
+ $this->assembly1->addBomEntry($this->bom_entry1b);
+ $this->assembly1->addBomEntry($this->bom_entry1c);
+ }
+
+ public function testInitialization(): void
+ {
+ //The values should be already prefilled correctly
+ $request = new AssemblyBuildRequest($this->assembly1, 10);
+ //We need totally 20: Take 10 from the first (maximum 10) and 10 from the second (maximum 20)
+ $this->assertEqualsWithDelta(10.0, $request->getLotWithdrawAmount($this->lot1a), PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(10.0, $request->getLotWithdrawAmount($this->lot1b), PHP_FLOAT_EPSILON);
+
+ //If the needed amount is higher than the maximum, we should get the maximum
+ $this->assertEqualsWithDelta(2.5, $request->getLotWithdrawAmount($this->lot2), PHP_FLOAT_EPSILON);
+ }
+
+ public function testGetNumberOfBuilds(): void
+ {
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+ $this->assertSame(5, $build_request->getNumberOfBuilds());
+ }
+
+ public function testGetAssembly(): void
+ {
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+ $this->assertEquals($this->assembly1, $build_request->getAssembly());
+ }
+
+ public function testGetNeededAmountForBOMEntry(): void
+ {
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+ $this->assertEqualsWithDelta(10.0, $build_request->getNeededAmountForBOMEntry($this->bom_entry1a), PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(7.5, $build_request->getNeededAmountForBOMEntry($this->bom_entry1b), PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(20.0, $build_request->getNeededAmountForBOMEntry($this->bom_entry1c), PHP_FLOAT_EPSILON);
+ }
+
+ public function testGetSetLotWithdrawAmount(): void
+ {
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+
+ //We can set the amount for a lot either via the lot object or via the ID
+ $build_request->setLotWithdrawAmount($this->lot1a, 2);
+ $build_request->setLotWithdrawAmount($this->lot1b->getID(), 3);
+
+ //And it should be possible to get the amount via the lot object or via the ID
+ $this->assertEqualsWithDelta(2.0, $build_request->getLotWithdrawAmount($this->lot1a->getID()), PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(3.0, $build_request->getLotWithdrawAmount($this->lot1b), PHP_FLOAT_EPSILON);
+ }
+
+ public function testGetWithdrawAmountSum(): void
+ {
+ //The sum of all withdraw amounts for an BOM entry (over all lots of the associated part) should be correct
+ $build_request = new AssemblyBuildRequest($this->assembly1, 5);
+
+ $build_request->setLotWithdrawAmount($this->lot1a, 2);
+ $build_request->setLotWithdrawAmount($this->lot1b, 3);
+
+ $this->assertEqualsWithDelta(5.0, $build_request->getWithdrawAmountSum($this->bom_entry1a), PHP_FLOAT_EPSILON);
+ $build_request->setLotWithdrawAmount($this->lot2, 1.5);
+ $this->assertEqualsWithDelta(1.5, $build_request->getWithdrawAmountSum($this->bom_entry1b), PHP_FLOAT_EPSILON);
+ }
+
+
+}
diff --git a/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php b/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php
new file mode 100644
index 000000000..c513ed8de
--- /dev/null
+++ b/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php
@@ -0,0 +1,117 @@
+.
+ */
+namespace App\Tests\Services\AssemblySystem;
+
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\AssemblySystem\AssemblyBOMEntry;
+use App\Entity\Parts\Part;
+use App\Entity\Parts\PartLot;
+use App\Services\AssemblySystem\AssemblyBuildHelper;
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+class AssemblyBuildHelperTest extends WebTestCase
+{
+ /** @var AssemblyBuildHelper */
+ protected $service;
+
+ protected function setUp(): void
+ {
+ self::bootKernel();
+ $this->service = self::getContainer()->get(AssemblyBuildHelper::class);
+ }
+
+ public function testGetMaximumBuildableCountForBOMEntryNonPartBomEntry(): void
+ {
+ $bom_entry = new AssemblyBOMEntry();
+ $bom_entry->setPart(null);
+ $bom_entry->setQuantity(10);
+ $bom_entry->setName('Test');
+
+ $this->expectException(\InvalidArgumentException::class);
+ $this->service->getMaximumBuildableCountForBOMEntry($bom_entry);
+ }
+
+ public function testGetMaximumBuildableCountForBOMEntry(): void
+ {
+ $assembly_bom_entry = new AssemblyBOMEntry();
+ $assembly_bom_entry->setQuantity(10);
+
+ $part = new Part();
+ $lot1 = new PartLot();
+ $lot1->setAmount(120);
+ $lot2 = new PartLot();
+ $lot2->setAmount(5);
+ $part->addPartLot($lot1);
+ $part->addPartLot($lot2);
+
+ $assembly_bom_entry->setPart($part);
+
+ //We have 125 parts in stock, so we can build 12 times the assembly (125 / 10 = 12.5)
+ $this->assertSame(12, $this->service->getMaximumBuildableCountForBOMEntry($assembly_bom_entry));
+
+
+ $lot1->setAmount(0);
+ //We have 5 parts in stock, so we can build 0 times the assembly (5 / 10 = 0.5)
+ $this->assertSame(0, $this->service->getMaximumBuildableCountForBOMEntry($assembly_bom_entry));
+ }
+
+ public function testGetMaximumBuildableCount(): void
+ {
+ $assembly = new Assembly();
+
+ $assembly_bom_entry1 = new AssemblyBOMEntry();
+ $assembly_bom_entry1->setQuantity(10);
+ $part = new Part();
+ $lot1 = new PartLot();
+ $lot1->setAmount(120);
+ $lot2 = new PartLot();
+ $lot2->setAmount(5);
+ $part->addPartLot($lot1);
+ $part->addPartLot($lot2);
+ $assembly_bom_entry1->setPart($part);
+ $assembly->addBomEntry($assembly_bom_entry1);
+
+ $assembly_bom_entry2 = new AssemblyBOMEntry();
+ $assembly_bom_entry2->setQuantity(5);
+ $part2 = new Part();
+ $lot3 = new PartLot();
+ $lot3->setAmount(10);
+ $part2->addPartLot($lot3);
+ $assembly_bom_entry2->setPart($part2);
+ $assembly->addBomEntry($assembly_bom_entry2);
+
+ $assembly->addBomEntry((new AssemblyBOMEntry())->setName('Non part entry')->setQuantity(1));
+
+ //Restricted by the few parts in stock of part2
+ $this->assertSame(2, $this->service->getMaximumBuildableCount($assembly));
+
+ $lot3->setAmount(1000);
+ //Now the build count is restricted by the few parts in stock of part1
+ $this->assertSame(12, $this->service->getMaximumBuildableCount($assembly));
+
+ $lot3->setAmount(0);
+ //Now the build count must be 0, as we have no parts in stock
+ $this->assertSame(0, $this->service->getMaximumBuildableCount($assembly));
+
+ }
+}
diff --git a/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php b/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php
new file mode 100644
index 000000000..b8aa0ddc3
--- /dev/null
+++ b/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php
@@ -0,0 +1,52 @@
+.
+ */
+namespace App\Tests\Services\AssemblySystem;
+
+use App\Entity\AssemblySystem\Assembly;
+use App\Services\AssemblySystem\AssemblyBuildPartHelper;
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+class AssemblyBuildPartHelperTest extends WebTestCase
+{
+ /** @var AssemblyBuildPartHelper */
+ protected $service;
+
+ protected function setUp(): void
+ {
+ self::bootKernel();
+ $this->service = self::getContainer()->get(AssemblyBuildPartHelper::class);
+ }
+
+ public function testGetPartInitialization(): void
+ {
+ $assembly = new Assembly();
+ $assembly->setName('Assembly 1');
+ $assembly->setDescription('Description 1');
+
+ $part = $this->service->getPartInitialization($assembly);
+ $this->assertSame('Assembly 1', $part->getName());
+ $this->assertSame('Description 1', $part->getDescription());
+ $this->assertSame($assembly, $part->getBuiltAssembly());
+ $this->assertSame($part, $assembly->getBuildPart());
+ }
+}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index 1f234450e..8b1f2a620 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -4741,6 +4741,18 @@ Pokud jste to provedli nesprávně nebo pokud počítač již není důvěryhodn
Název
+
+
+ project.bom.assembly
+ Sestava
+
+
+
+
+ project.bom.partOrAssembly
+ Výběr
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9786,6 +9798,18 @@ Element 3
Díl
+
+
+ project.bom.assembly
+ Baugruppe
+
+
+
+
+ project.bom.partOrAssembly
+ Auswahl
+
+ project.bom.add_entry
@@ -9864,6 +9888,42 @@ Element 3
Archivováno
+
+
+ assembly.edit.status
+ Stav
+
+
+
+
+ assembly.status.draft
+ Návrh
+
+
+
+
+ assembly.status.planning
+ Plánování
+
+
+
+
+ assembly.status.in_production
+ Ve výrobě
+
+
+
+
+ assembly.status.finished
+ Dokončeno
+
+
+
+
+ assembly.status.archived
+ Archivováno
+
+ part.new_build_part.error.build_part_already_exists
@@ -10140,6 +10200,12 @@ Element 3
k dispozici
+
+
+ project.builds.no_stock
+ není uveden žádný sklad
+
+ project.builds.needed
@@ -10212,6 +10278,12 @@ Element 3
Cílový inventář
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% požadováno)
+
+ project.builds.number_of_builds
@@ -13479,5 +13551,633 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Minimální šířka náhledu (px)
+
+
+ part.table.name.value.for_part
+ %value% (Součást)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Sestava)
+
+
+
+
+ assembly.label
+ Sestava
+
+
+
+
+ assembly.caption
+ Sestava
+
+
+
+
+ perm.assemblies
+ Sestavy
+
+
+
+
+ assembly_bom_entry.label
+ Součásti
+
+
+
+
+ assembly.labelp
+ Sestavy
+
+
+
+
+ assembly.edit
+ Upravit sestavu
+
+
+
+
+ assembly.new
+ Nová sestava
+
+
+
+
+ assembly.edit.associated_build_part
+ Přidružená součást
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Přidat součást
+
+
+
+
+ assembly.edit.associated_build.hint
+ Tato součást představuje vyrobené instance sestavy. Zadejte, pokud jsou vyrobené instance potřeba. Pokud ne, počet součástí bude použit až při sestavení daného projektu.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importovat součásti
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Sestavy
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% součástí úspěšně importováno do sestavy.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Chyba ověření! Zkontrolujte svůj importovaný soubor!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Soubor nelze importovat. Zkontrolujte, zda jste vybrali správný typ souboru. Chybová zpráva: %message%
+
+
+
+
+ assembly.bom.quantity
+ Množství
+
+
+
+
+ assembly.bom.mountnames
+ Názvy osazení
+
+
+
+
+ assembly.bom.instockAmount
+ Stav na skladě
+
+
+
+
+ assembly.info.title
+ Info o sestavě
+
+
+
+
+ assembly.info.info.label
+ Informace
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Podskupina
+
+
+
+
+ assembly.info.builds.label
+ Sestavení
+
+
+
+
+ assembly.info.bom_add_parts
+ Přidat součásti
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Měli byste zkontrolovat, zda opravdu chcete sestavu postavit s tímto stavem!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Sestavení není možné: Nedostatek součástí
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Není dostatek součástí na skladě pro postavení tohoto projektu %number_of_builds% krát. Následující součásti nejsou skladem v dostatečném množství.
+
+
+
+
+ assembly.builds.build_possible
+ Sestavení je možné
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% kusů této sestavy.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Počet sestavení
+
+
+
+
+ assembly.build.btn_build
+ Sestavit
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Počet skladovaných vyrobených instancí
+
+
+
+
+ assembly.info.bom_entries_count
+ Součásti
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Podskupiny
+
+
+
+
+ assembly.builds.stocked
+ skladem
+
+
+
+
+ assembly.builds.needed
+ potřebné
+
+
+
+
+ assembly.add_parts_to_assembly
+ Přidat součásti do sestavy
+
+
+
+
+ assembly.bom.name
+ Název
+
+
+
+
+ assembly.bom.comment
+ Poznámky
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Není dostatek součástí na skladě pro sestavení této sestavy %number_of_builds% krát. Následující součásti nejsou skladem:
+
+
+
+
+ assembly.build.help
+ Vyberte, ze kterých zásob se mají brát potřebné součásti pro sestavení (a v jakém množství). Zaškrtněte políčko u každého dílu, pokud jste jej odebrali, nebo použijte horní políčko k výběru všech naráz.
+
+
+
+
+ assembly.build.required_qty
+ Požadované množství
+
+
+
+
+ assembly.import_bom
+ Importovat součásti do sestavy
+
+
+
+
+ assembly.bom.part
+ Součást
+
+
+
+
+ assembly.bom.add_entry
+ Přidat položku
+
+
+
+
+ assembly.bom.price
+ Cena
+
+
+
+
+ assembly.build.dont_check_quantity
+ Neověřovat množství
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Pokud je tato volba vybrána, budou vybraná množství odstraněna ze skladu bez ohledu na to, zda je méně nebo více součástí, než je skutečně potřeba pro sestavení sestavy.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Přidat vyrobené instance do součásti sestavy
+
+
+
+
+ assembly.bom_import.type
+ Typ
+
+
+
+
+ assembly.bom_import.type.json
+ JSON pro sestavu
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Smazat existující položky před importem
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Pokud je tato možnost vybrána, budou všechny již existující součásti sestavy smazány a nahrazeny importovanými daty součástí.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Šablona importu JSON pro sestavu
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Šablona importu CSV (KiCAD Pcbnew BOM) pro sestavu
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Název součásti v sestavě
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Unikátní číslo produktu u výrobce
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unikátní IPN součásti
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unikátní název součásti
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unikátní jméno výrobce
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Unikátní název kategorie
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Pole
+
Podmínka
+
Datový typ
+
Popis
+
+
+
+
+
quantity
+
Povinné
+
Číslo s plovoucí desetinnou čárkou (Float)
+
Musí být uvedeno a obsahovat hodnotu s plovoucí desetinnou čárkou (Float) větší než 0,0.
+
+
+
name
+
Volitelné
+
Řetězec (String)
+
Pokud je přítomen, musí být neprázdný řetězec.
+
+
+
part
+
Volitelné
+
Objekt/Array
+
+ Pokud je uvedeno, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID součástky v Part-DB.
+
+
+
part.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není zadáno part.mpnr nebo part.ipn.
+
+
+
part.mpnr
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není zadáno part.name nebo part.ipn.
+
+
+
part.ipn
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není zadáno part.name nebo part.mpnr.
+
+
+
part.description
+
Volitelné
+
Řetězec nebo null
+
Pokud je přítomen, musí být neprázdný řetězec nebo null.
+
+
+
part.manufacturer
+
Volitelné
+
Objekt/Array
+
+ Pokud je přítomen, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID výrobce.
+
+
+
manufacturer.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno manufacturer.id.
+
+
+
part.category
+
Volitelné
+
Objekt/Array
+
+ Pokud je přítomen, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID kategorie součástky.
+
+
+
category.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno category.id.
Volný údaj. Jedinečné identifikační číslo pro každou součástku.
+
+
+
Designator
+
Volitelný
+
Řetězec (String)
+
Volný údaj. Jedinečný referenční označovač součástky na desce plošných spojů, např. „R1“ pro rezistor 1. Používá se pro název osazení součástky v rámci skupiny součástek.
+
+
+
Package
+
Volitelný
+
Řetězec (String)
+
Volný údaj. Pouzdro nebo tvar součástky, např. „0805“ pro SMD rezistory.
+
+
+
Množství
+
Povinný
+
Celé číslo (Integer)
+
Počet identických součástek, které jsou potřeba k vytvoření jedné instance sestavy.
+
+
+
Určení
+
Povinný
+
Řetězec (String)
+
Popis nebo funkce součástky, např. hodnota rezistoru „10kΩ“ nebo hodnota kondenzátoru „100nF“. Používá se pro název položky v BOM.
+
+
+
Dodavatel a ref
+
Volitelný
+
Řetězec (String)
+
Volný údaj. Může obsahovat např. specifické údaje distributora.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (součást)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (sestava)
+
+
+
+
+ projects.build.form.part
+ Součást "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Sestava "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (potřebné množství: %quantity%)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ není skladem
+
+
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index d72589864..f231163a1 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -4748,6 +4748,18 @@ Bemærk også, at uden to-faktor-godkendelse er din konto ikke længere så godt
Navn
+
+
+ project.bom.assembly
+ Montering
+
+
+
+
+ project.bom.partOrAssembly
+ Valg
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9812,6 +9824,18 @@ Element 3
Komponent
+
+
+ project.bom.assembly
+ Baugruppe
+
+
+
+
+ project.bom.partOrAssembly
+ Auswahl
+
+ project.bom.add_entry
@@ -9890,6 +9914,42 @@ Element 3
Arkiveret
+
+
+ assembly.edit.status
+ Status
+
+
+
+
+ assembly.status.draft
+ Kladde
+
+
+
+
+ assembly.status.planning
+ Under planlægning
+
+
+
+
+ assembly.status.in_production
+ I produktion
+
+
+
+
+ assembly.status.finished
+ Ophørt
+
+
+
+
+ assembly.status.archived
+ Arkiveret
+
+ part.new_build_part.error.build_part_already_exists
@@ -10166,6 +10226,12 @@ Element 3
På lager
+
+
+ project.builds.no_stock
+ intet lager angivet
+
+ project.builds.needed
@@ -10238,6 +10304,12 @@ Element 3
Mål mængde
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% påkrævet)
+
+ project.builds.number_of_builds
@@ -12196,5 +12268,633 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Du forsøgte at fjerne/tilføje en mængde sat til nul! Der blev ikke foretaget nogen handling.
+
+
+ part.table.name.value.for_part
+ %value% (Del)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Samlingsenhed)
+
+
+
+
+ assembly.label
+ Samling
+
+
+
+
+ assembly.caption
+ Samling
+
+
+
+
+ perm.assemblies
+ Samlinger
+
+
+
+
+ assembly_bom_entry.label
+ Komponenter
+
+
+
+
+ assembly.labelp
+ Samlinger
+
+
+
+
+ assembly.edit
+ Rediger samling
+
+
+
+
+ assembly.new
+ Ny samling
+
+
+
+
+ assembly.edit.associated_build_part
+ Tilknyttet komponent
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Tilføj komponent
+
+
+
+
+ assembly.edit.associated_build.hint
+ Denne komponent repræsenterer de fremstillede instanser af samlingen. Angiv, hvis fremstillede instanser er påkrævet. Hvis ikke, vil antallet af komponenter først blive anvendt ved opbygning af det pågældende projekt.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importér komponenter
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Samlinger
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% komponent(er) blev importeret til samlingen med succes.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Valideringsfejl! Kontroller venligst den importerede fil!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Filen kunne ikke importeres. Kontrollér, at du har valgt den korrekte filtype. Fejlmeddelelse: %message%
+
+
+
+
+ assembly.bom.quantity
+ Mængde
+
+
+
+
+ assembly.bom.mountnames
+ Monteringsnavne
+
+
+
+
+ assembly.bom.instockAmount
+ Antal på lager
+
+
+
+
+ assembly.info.title
+ Samleinfo
+
+
+
+
+ assembly.info.info.label
+ Info
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Undergruppe
+
+
+
+
+ assembly.info.builds.label
+ Byggeri
+
+
+
+
+ assembly.info.bom_add_parts
+ Tilføj dele
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Du bør kontrollere, om du virkelig ønsker at bygge samlingen med denne status!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Opbygning ikke mulig: Ikke nok komponenter til rådighed
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Der er ikke nok dele på lager til at bygge dette projekt %number_of_builds% gange. Følgende dele mangler på lager:
+
+
+
+
+ assembly.builds.build_possible
+ Byggeri muligt
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% eksemplarer af denne samling.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Antal opbygninger
+
+
+
+
+ assembly.build.btn_build
+ Byg
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Antal lagrede byggede enheder
+
+
+
+
+ assembly.info.bom_entries_count
+ Komponenter
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Undergrupper
+
+
+
+
+ assembly.builds.stocked
+ på lager
+
+
+
+
+ assembly.builds.needed
+ nødvendig
+
+
+
+
+ assembly.add_parts_to_assembly
+ Tilføj dele til samlingen
+
+
+
+
+ assembly.bom.name
+ Navn
+
+
+
+
+ assembly.bom.comment
+ Notater
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Der er ikke nok dele på lager til at bygge denne samling %number_of_builds% gange. Følgende dele mangler på lager:
+
+
+
+
+ assembly.build.help
+ Vælg, hvilke lagre de nødvendige dele til bygningen skal tages fra (og i hvilken mængde). Marker afkrydsningsfeltet for hver delpost, når du har fjernet delene, eller brug det øverste afkrydsningsfelt for at markere alle på én gang.
+
+
+
+
+ assembly.build.required_qty
+ Krævet antal
+
+
+
+
+ assembly.import_bom
+ Importer dele til samling
+
+
+
+
+ assembly.bom.part
+ Del
+
+
+
+
+ assembly.bom.add_entry
+ Tilføj post
+
+
+
+
+ assembly.bom.price
+ Pris
+
+
+
+
+ assembly.build.dont_check_quantity
+ Tjek ikke mængder
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Hvis denne mulighed vælges, fjernes de valgte mængder fra lageret, uanset om der er mere eller mindre end nødvendigt for at bygge samlingen.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Tilføj byggede enheder til assemblies del
+
+
+
+
+ assembly.bom_import.type
+ Type
+
+
+
+
+ assembly.bom_import.type.json
+ JSON for en samling
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Slet eksisterende poster før import
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Hvis dette valg er markeret, slettes alle eksisterende komponentposter i samlingen og erstattes med de importerede.
+
+
+
+
+ assembly.import_bom.template.header.json
+ JSON-importskabelon til en samling
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Importskabelon CSV (KiCAD Pcbnew BOM) til en samling
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Delens navn i samlingen
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Unik produktnummer hos producenten
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unik IPN for delen
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unikt komponentnavn
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unikt producenter navn
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Kategoriens unikke navn
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Felt
+
Betingelse
+
Datatype
+
Beskrivelse
+
+
+
+
+
quantity
+
Påkrævet
+
Flydende tal (Float)
+
Skal være til stede og indeholde en flydende værdi (Float), der er større end 0,0.
+
+
+
name
+
Valgfri
+
String
+
Hvis til stede, skal det være en ikke-tom streng.
+
+
+
part
+
Valgfri
+
Objekt/Array
+
+ Hvis angivet, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Valgfri
+
Heltal (Integer)
+
Heltal (Integer) > 0. Matcher Part-DB's interne numeriske ID for komponenten.
+
+
+
part.name
+
Valgfri
+
String
+
Ikke-tom streng, hvis part.mpnr eller part.ipn ikke er givet.
+
+
+
part.mpnr
+
Valgfri
+
String
+
Ikke-tom streng, hvis part.name eller part.ipn ikke er givet.
+
+
+
part.ipn
+
Valgfri
+
String
+
Ikke-tom streng, hvis part.name eller part.mpnr ikke er givet.
+
+
+
part.description
+
Valgfri
+
String eller null
+
Hvis til stede, skal det være en ikke-tom streng eller null.
+
+
+
part.manufacturer
+
Valgfri
+
Objekt/Array
+
+ Hvis til stede, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+
Fri oplysning. Et unikt identifikationsnummer for hver komponent.
+
+
+
Designator
+
Valgfri
+
Streng
+
Fri oplysning. En unik referencebetegnelse for komponenten på printkortet, f.eks. "R1" for modstand 1. Bruges til navngivning af monteringssæt i komponentgruppen.
+
+
+
Package
+
Valgfri
+
Streng
+
Fri oplysning. Komponentenheden eller -formatet, f.eks. "0805" for SMD-modstande.
+
+
+
Antal
+
Påkrævet
+
Heltal (Integer)
+
Antallet af identiske komponenter, der kræves for at oprette en enkelt instans af samling.
+
+
+
Betegnelse
+
Påkrævet
+
Streng
+
Beskrivelse eller funktion for komponenten, f.eks. modstandsværdi "10kΩ" eller kondensatorværdi "100nF". Bruges til navnet i BOM-posten.
+
+
+
Leverandør og ref
+
Valgfri
+
Streng
+
Fri oplysning. Kan indeholde f.eks. distributørspecifik værdi.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (del)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (samling)
+
+
+
+
+ projects.build.form.part
+ Del "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Samling "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% nødvendig)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ ikke på lager
+
+
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index 9fb3f6ef6..c32bf46a7 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -4740,6 +4740,18 @@ Wenn Sie dies fehlerhafterweise gemacht haben oder ein Computer nicht mehr vertr
Name
+
+
+ part.table.name.value.for_part
+ %value% (Bauteil)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Baugruppe)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9788,6 +9800,18 @@ Element 1 -> Element 1.2
Bauteil
+
+
+ project.bom.assembly
+ Baugruppe
+
+
+
+
+ project.bom.partOrAssembly
+ Auswahl
+
+ project.bom.add_entry
@@ -9866,6 +9890,42 @@ Element 1 -> Element 1.2
Archiviert
+
+
+ assembly.edit.status
+ Status
+
+
+
+
+ assembly.status.draft
+ Entwurf
+
+
+
+
+ assembly.status.planning
+ In Planung
+
+
+
+
+ assembly.status.in_production
+ In Produktion
+
+
+
+
+ assembly.status.finished
+ Abgeschlossen
+
+
+
+
+ assembly.status.archived
+ Archiviert
+
+ part.new_build_part.error.build_part_already_exists
@@ -10142,6 +10202,12 @@ Element 1 -> Element 1.2
vorhanden
+
+
+ project.builds.no_stock
+ kein Lager angegeben
+
+ project.builds.needed
@@ -10214,6 +10280,12 @@ Element 1 -> Element 1.2
Ziel-Bestand
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% benötigt)
+
+ project.builds.number_of_builds
@@ -12851,6 +12923,622 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Externe Version anzeigen
+
+
+ assembly.label
+ Baugruppe
+
+
+
+
+ assembly.caption
+ Baugruppe
+
+
+
+
+ perm.assemblies
+ Baugruppen
+
+
+
+
+ assembly_bom_entry.label
+ Bauteile
+
+
+
+
+ assembly.labelp
+ Baugruppen
+
+
+
+
+ assembly.edit
+ Bearbeite Baugruppe
+
+
+
+
+ assembly.new
+ Neue Baugruppe
+
+
+
+
+ assembly.edit.associated_build_part
+ Verknüpftes Bauteil
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Bauteil hinzufügen
+
+
+
+
+ assembly.edit.associated_build.hint
+ Dieses Bauteil repräsentiert die gebauten Instanzen der Baugruppe. Anzugeben, sofern gebaute Instanzen benötigt werden. Wenn nein, werden die Stückzahlen bzgl. der Baugruppe erst beim Build des jeweiligen Projektes herangezogen.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Bauteile importieren
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Baugruppen
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% Part Einträge erfolgreich in Baugruppe importiert.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Validierungsfehler! Bitte überprüfen Sie die importierte Datei!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Datei konnte nicht importiert werden. Überprüfen Sie, dass Sie den richtigen Dateityp gewählt haben. Fehlermeldung: %message%
+
+
+
+
+ assembly.bom.quantity
+ Menge
+
+
+
+
+ assembly.bom.mountnames
+ Bestückungsnamen
+
+
+
+
+ assembly.bom.instockAmount
+ Bestand im Lager
+
+
+
+
+ assembly.info.title
+ Baugruppen-Info
+
+
+
+
+ assembly.info.info.label
+ Info
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Untergruppe
+
+
+
+
+ assembly.info.builds.label
+ Bau
+
+
+
+
+ assembly.info.bom_add_parts
+ Bauteile hinzufügen
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Sie sollten überprüfen, ob sie die Baugruppe mit diesem Status wirklich bauen wollen!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Bau nicht möglich: Nicht genügend Bauteile vorhanden
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Es sind nicht genügend Bauteile auf Lager, um dieses Projekt %number_of_builds% mal zu bauen. Von folgenden Bauteilen ist nicht genügend auf Lager.
+
+
+
+
+ assembly.builds.build_possible
+ Bau möglich
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% Exemplare dieser Baugruppe zu bauen.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Zu bauende Anzahl
+
+
+
+
+ assembly.build.btn_build
+ Bauen
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Anzahl gelagerter gebauter Instanzen
+
+
+
+
+ assembly.info.bom_entries_count
+ Bauteile
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Untergruppen
+
+
+
+
+ assembly.builds.stocked
+ vorhanden
+
+
+
+
+ assembly.builds.needed
+ benötigt
+
+
+
+
+ assembly.add_parts_to_assembly
+ Bauteile zur Baugruppe hinzufügen
+
+
+
+
+ assembly.bom.name
+ Name
+
+
+
+
+ assembly.bom.comment
+ Notizen
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Es sind nicht genügend Bauteile auf Lager, um diese Baugruppe %number_of_builds% mal zu bauen. Von folgenden Bauteilen ist nicht genügend auf Lager:
+
+
+
+
+ assembly.build.help
+ Wählen Sie aus, aus welchen Beständen die zum Bau notwendigen Bauteile genommen werden sollen (und in welcher Anzahl). Setzen Sie den Haken für jeden Part Eintrag, wenn sie die Bauteile entnommen haben, oder nutzen Sie die oberste Checkbox, um alle Haken auf einmal zu setzen.
+
+
+
+
+ assembly.build.required_qty
+ Benötigte Anzahl
+
+
+
+
+ assembly.import_bom
+ Importiere Parts für Baugruppe
+
+
+
+
+ assembly.bom.part
+ Bauteil
+
+
+
+
+ assembly.bom.add_entry
+ Eintrag hinzufügen
+
+
+
+
+ assembly.bom.price
+ Preis
+
+
+
+
+ assembly.build.dont_check_quantity
+ Mengen nicht überprüfen
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Wenn diese Option gewählt wird, werden die gewählten Mengen aus dem Lager entfernt, egal ob mehr oder weniger Bauteile sind, als für den Bau der Baugruppe eigentlich benötigt werden.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Gebaute Instanzen zum Bauteil der Baugruppe hinzufügen
+
+
+
+
+ assembly.bom_import.type
+ Typ
+
+
+
+
+ assembly.bom_import.type.json
+ JSON für eine Baugruppe
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Lösche existierende Bauteil-Einträge vor dem Import
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Wenn diese Option ausgewählt ist, werden alle bereits in der Baugruppe existierenden Bauteile gelöscht und mit den importierten Bauteildaten überschrieben.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Import-Vorlage JSON für eine Baugruppe
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Import-Vorlage CSV (KiCAD Pcbnew BOM) für eine Baugruppe
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Name des Bauteils in der Baugruppe
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Eindeutige Produktnummer innerhalb des Herstellers
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Eideutige IPN des Bauteils
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Eindeutiger Name des Bauteils
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Eindeutiger Name des Herstellers
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Eindeutiger Name der Kategorie
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
quantity
+
Pflichtfeld
+
Gleitkommazahl (Float)
+
Muss gegeben sein und enthält einen Gleitkommawert (Float), der größer als 0.0 ist.
+
+
+
name
+
Optional
+
String
+
Falls vorhanden, muss es ein nicht-leerer String sein.
+
+
+
part
+
Optional
+
Objekt/Array
+
+ Falls angegeben, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
+
+
+
part.name
+
Optional
+
String
+
Nicht-leerer String, falls keine part.mpnr- bzw. part.ipn-Angabe gegeben ist.
+
+
+
part.mpnr
+
Optional
+
String
+
Nicht-leerer String, falls keine part.name- bzw. part-ipn-Angabe gegeben ist.
+
+
+
part.ipn
+
Optional
+
String
+
Nicht-leerer String, falls keine part.name- bzw. part.mpnr-Angabe gegeben ist.
+
+
+
part.description
+
Optional
+
String oder null
+
Falls vorhanden, muss es ein nicht-leerer String sein oder null.
+
+
+
part.manufacturer
+
Optional
+
Objekt/Array
+
+ Falls vorhanden, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID des Herstellers.
+
+
+
manufacturer.name
+
Optional
+
String
+
Nicht-leerer String, falls keine manufacturer.id-Angabe gegeben ist.
+
+
+
part.category
+
Optional
+
Objekt/Array
+
+ Falls vorhanden, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID der Kategorie des Bauteils.
+
+
+
category.name
+
Optional
+
String
+
Nicht-leerer String, falls keine category.id-Angabe gegeben ist.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Erwartete Spalten:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Hinweis: Es findet keine Zuordnung zu konkreten Bauteilen aus der Kategorie-Verwaltung statt.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
Id
+
Optional
+
Ganzzahl (Integer)
+
Offene Angabe. Eine eindeutige Identifikationsnummer für jedes Bauteil.
+
+
+
Designator
+
Optional
+
String
+
Offene Angabe. Ein eindeutiger Referenzbezeichner des Bauteils auf der Leiterplatte, z.B. „R1“ für Widerstand 1. Wird für den Bestückungsnamen des Bauteil-Eintrags innerhalb der Bauteilgruppe verwendet.
+
+
+
Package
+
Optional
+
String
+
Offene Angabe. Das Gehäuse oder die Bauform des Bauteils, z.B. „0805“ für SMD-Widerstände.
+
+
+
Quantity
+
Pflichtfeld
+
Ganzzahl (Integer)
+
Anzahl der identischen Bauteile, die benötigt werden, um eine Instanz der Baugruppe zu erstellen.
+
+
+
Designation
+
Pflichtfeld
+
String
+
Beschreibung oder Funktion des Bauteils, z.B. Widerstandswert „10kΩ“ oder Kondensatorwert „100nF“. Wird für den Namen des BOM-Eintrags verwendet.
+
+
+
Supplier and ref
+
Optional
+
String
+
Offene Angabe. Kann z.B. Distributor spezifischen Wert enthalten.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Bauteil)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Baugruppe)
+
+
+
+
+ projects.build.form.part
+ Bauteil "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Baugruppe "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% benötigt)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ nicht auf Lager
+
+ part.table.actions.error
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index cc17d9be4..8fdb801b7 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -1535,5 +1535,693 @@
Επεξεργασία
+
+
+ part.table.name.value.for_part
+ %value% (Μέρος)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Συναρμολόγηση)
+
+
+
+
+ project.bom.assembly
+ Συναρμολόγηση
+
+
+
+
+ project.bom.partOrAssembly
+ Επιλογή
+
+
+
+
+ assembly.edit.status
+ Κατάσταση
+
+
+
+
+ assembly.status.draft
+ Προσχέδιο
+
+
+
+
+ assembly.status.planning
+ Υπό σχεδιασμό
+
+
+
+
+ assembly.status.in_production
+ Σε παραγωγή
+
+
+
+
+ assembly.status.finished
+ Ολοκληρώθηκε
+
+
+
+
+ assembly.status.archived
+ Αρχειοθετήθηκε
+
+
+
+
+ project.builds.no_stock
+ δεν έχει καθοριστεί απόθεμα
+
+
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% απαιτείται)
+
+
+
+
+ assembly.label
+ Σύνολο
+
+
+
+
+ assembly.caption
+ Σύνολο
+
+
+
+
+ perm.assemblies
+ Συναρμολογήσεις
+
+
+
+
+ assembly_bom_entry.label
+ Μέρη
+
+
+
+
+ assembly.labelp
+ Συναρμολογήσεις
+
+
+
+
+ assembly.edit
+ Επεξεργασία συνόλου
+
+
+
+
+ assembly.new
+ Νέο σύνολο
+
+
+
+
+ assembly.edit.associated_build_part
+ Σχετικό μέρος
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Προσθήκη μέρους
+
+
+
+
+ assembly.edit.associated_build.hint
+ Αυτό το μέρος αντιπροσωπεύει τις κατασκευασμένες εκδόσεις του συνόλου. Καταχωρίστε το εάν απαιτούνται κατασκευασμένες εκδόσεις. Εάν όχι, οι ποσότητες θα χρησιμοποιηθούν μόνο κατά την κατασκευή του εκάστοτε έργου.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Εισαγωγή μερών
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Συναρμολογήσεις
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% εγγραφές εξαρτημάτων εισήχθησαν με επιτυχία στο σύνολο.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Σφάλμα επικύρωσης! Ελέγξτε το εισαγόμενο αρχείο!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Το αρχείο δεν μπόρεσε να εισαχθεί. Ελέγξτε ότι έχετε επιλέξει τον σωστό τύπο αρχείου. Μήνυμα σφάλματος: %message%
+
+
+
+
+ assembly.bom.quantity
+ Ποσότητα
+
+
+
+
+ assembly.bom.mountnames
+ Ονόματα συναρμολόγησης
+
+
+
+
+ assembly.bom.instockAmount
+ Ποσότητα σε απόθεμα
+
+
+
+
+ assembly.info.title
+ Πληροφορίες συναρμολόγησης
+
+
+
+
+ assembly.info.info.label
+ Πληροφορίες
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Υποομάδες
+
+
+
+
+ assembly.info.builds.label
+ Κατασκευές
+
+
+
+
+ assembly.info.bom_add_parts
+ Προσθήκη εξαρτημάτων
+
+
+
+
+ assembly.builds.check_assembly_status
+ «%assembly_status%». Ελέγξτε εάν θέλετε πραγματικά να κατασκευάσετε τη συναρμολόγηση με αυτήν την κατάσταση!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Η κατασκευή δεν είναι δυνατή: Δεν υπάρχουν αρκετά διαθέσιμα εξαρτήματα
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Δεν υπάρχουν αρκετά εξαρτήματα σε απόθεμα για να κατασκευαστεί αυτό το έργο %number_of_builds% φορές. Λείπουν τα ακόλουθα εξαρτήματα:
+
+
+
+
+ assembly.builds.build_possible
+ Κατασκευή δυνατή
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% μονάδες αυτής της συναρμολόγησης.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Αριθμός κατασκευών
+
+
+
+
+ assembly.build.btn_build
+ Κατασκευή
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Αποθηκευμένα κατασκευασμένα κομμάτια
+
+
+
+
+ assembly.info.bom_entries_count
+ Εξαρτήματα
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Υποομάδες
+
+
+
+
+ assembly.builds.stocked
+ σε απόθεμα
+
+
+
+
+ assembly.builds.needed
+ απαιτούμενο
+
+
+
+
+ assembly.add_parts_to_assembly
+ Προσθήκη εξαρτημάτων στη συναρμολόγηση
+
+
+
+
+ assembly.bom.name
+ Όνομα
+
+
+
+
+ assembly.bom.comment
+ Σχόλια
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Δεν υπάρχουν αρκετά εξαρτήματα σε απόθεμα για να κατασκευαστεί αυτή η συναρμολόγηση %number_of_builds% φορές. Λείπουν τα ακόλουθα εξαρτήματα:
+
+
+
+
+ assembly.build.help
+ Επιλέξτε από ποια αποθέματα θα αφαιρεθούν τα αναγκαία για την κατασκευή εξαρτήματα (και σε ποια ποσότητα). Σημειώστε το πλαίσιο επιλογής για κάθε εξάρτημα όταν αφαιρέσετε τα εξαρτήματα ή χρησιμοποιήστε το ανώτερο πλαίσιο επιλογής για να τα ελέγξετε όλα ταυτόχρονα.
+
+
+
+
+ assembly.build.required_qty
+ Απαιτούμενη ποσότητα
+
+
+
+
+ assembly.import_bom
+ Εισαγωγή εξαρτημάτων συναρμολόγησης
+
+
+
+
+ assembly.bom.part
+ Εξάρτημα
+
+
+
+
+ assembly.bom.add_entry
+ Προσθήκη καταχώρησης
+
+
+
+
+ assembly.bom.price
+ Τιμή
+
+
+
+
+ assembly.build.dont_check_quantity
+ Μην ελέγχετε την ποσότητα
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Εάν επιλεγεί αυτή η επιλογή, οι επιλεγμένες ποσότητες θα αφαιρεθούν από το απόθεμα ανεξάρτητα από το αν είναι περισσότερο ή λιγότερο από το απαιτούμενο για την κατασκευή της συναρμολόγησης.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Προσθήκη κατασκευασμένων κομματιών στο τμήμα συναρμολόγησης
+
+
+
+
+ assembly.bom_import.type
+ Τύπος
+
+
+
+
+ assembly.bom_import.type.json
+ JSON για συναρμολόγηση
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Διαγραφή υπαρχόντων εξαρτημάτων πριν από την εισαγωγή
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Εάν επιλεγεί αυτή η επιλογή, όλα τα ήδη υπάρχοντα εξαρτήματα στη συναρμολόγηση θα διαγραφούν και θα αντικατασταθούν με τα δεδομένα εξαρτημάτων που εισάγονται.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Πρότυπο εισαγωγής JSON για συναρμολόγηση
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Πρότυπο εισαγωγής CSV (KiCAD Pcbnew BOM) για συναρμολόγηση
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Όνομα του εξαρτήματος στη συναρμολόγηση
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Μοναδικός αριθμός προϊόντος από τον κατασκευαστή
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Μοναδικός IPN του εξαρτήματος
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Μοναδικό όνομα εξαρτήματος
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Μοναδικό όνομα κατασκευαστή
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Μοναδικό όνομα κατηγορίας
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Πεδίο
+
Προϋπόθεση
+
Τύπος Δεδομένων
+
Περιγραφή
+
+
+
+
+
quantity
+
Υποχρεωτικό πεδίο
+
Αριθμός κινητής υποδιαστολής (Float)
+
Πρέπει να παρέχεται και να περιέχει τιμή κινητής υποδιαστολής (Float) μεγαλύτερη από 0.0.
+
+
+
name
+
Προαιρετικό
+
Κείμενο (String)
+
Εάν υπάρχει, πρέπει να είναι μη κενό κείμενο.
+
+
+
part
+
Προαιρετικό
+
Αντικείμενο/Πίνακας
+
+ Εάν παρέχεται, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) του εξαρτήματος στη βάση δεδομένων.
+
+
+
part.name
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.mpnr ή part.ipn.
+
+
+
part.mpnr
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.name ή part.ipn.
+
+
+
part.ipn
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.name ή part.mpnr.
+
+
+
part.description
+
Προαιρετικό
+
Κείμενο ή null
+
Εάν υπάρχει, πρέπει να είναι μη κενό κείμενο, ή null.
+
+
+
part.manufacturer
+
Προαιρετικό
+
Αντικείμενο/Πίνακας
+
+ Εάν υπάρχει, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) του κατασκευαστή.
+
+
+
manufacturer.name
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχεται η ένδειξη manufacturer.id.
+
+
+
part.category
+
Προαιρετικό
+
Αντικείμενο/Πίνακας
+
+ Εάν υπάρχει, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) της κατηγορίας του εξαρτήματος.
+
+
+
category.name
+
Προαιρετικό
+
Κείμενο (String)
+
Μη κενό κείμενο, εάν δεν παρέχεται η ένδειξη category.id.
Ελεύθερη καταχώρηση. Μοναδικός αριθμός ταυτοποίησης για κάθε εξάρτημα.
+
+
+
Σχεδιαστής
+
Προαιρετικό
+
Συμβολοσειρά (String)
+
Ελεύθερη καταχώρηση. Μοναδικός αναγνωριστικός δείκτης του εξαρτήματος στην πλακέτα κυκλώματος, π.χ. "R1" για την αντίσταση 1. Χρησιμοποιείται για το όνομα του εξαρτήματος στο πλαίσιο της ομάδας εξαρτημάτων.
+
+
+
Συσκευασία
+
Προαιρετικό
+
Συμβολοσειρά (String)
+
Ελεύθερη καταχώρηση. Ο τύπος ή η μορφή του εξαρτήματος, π.χ. "0805" για αντιστάσεις SMD.
+
+
+
Ποσότητα
+
Υποχρεωτικό
+
Ακέραιος αριθμός (Integer)
+
Ο αριθμός των πανομοιότυπων εξαρτημάτων που απαιτούνται για τη δημιουργία μίας μονάδας του συνόλου.
+
+
+
Ορισμός
+
Υποχρεωτικό
+
Συμβολοσειρά (String)
+
Περιγραφή ή λειτουργία του εξαρτήματος, π.χ. αντίσταση "10kΩ" ή χωρητικότητα "100nF". Χρησιμοποιείται για το όνομα της εγγραφής στο BOM.
+
+
+
Προμηθευτής και παραπομπή
+
Προαιρετικό
+
Συμβολοσειρά (String)
+
Ελεύθερη καταχώρηση. Μπορεί να περιλαμβάνει, π.χ., ειδική τιμή από διανομέα.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Εξάρτημα)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Συναρμολόγηση)
+
+
+
+
+ projects.build.form.part
+ Εξάρτημα "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Συναρμολόγηση "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% απαιτείται)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ δεν υπάρχει στο απόθεμα
+
+
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index be1e63488..d267c89ac 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -4741,6 +4741,18 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
Name
+
+
+ part.table.name.value.for_part
+ %value% (Part)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Assembly)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9789,6 +9801,18 @@ Element 1 -> Element 1.2
Part
+
+
+ project.bom.assembly
+ Assembly
+
+
+
+
+ project.bom.partOrAssembly
+ Selection
+
+ project.bom.add_entry
@@ -9867,6 +9891,42 @@ Element 1 -> Element 1.2
Archived
+
+
+ assembly.edit.status
+ Project status
+
+
+
+
+ assembly.status.draft
+ Draft
+
+
+
+
+ assembly.status.planning
+ Planning
+
+
+
+
+ assembly.status.in_production
+ In production
+
+
+
+
+ assembly.status.finished
+ Finished
+
+
+
+
+ assembly.status.archived
+ Archived
+
+ part.new_build_part.error.build_part_already_exists
@@ -10143,6 +10203,12 @@ Element 1 -> Element 1.2
stocked
+
+
+ project.builds.no_stock
+ no stock specified
+
+ project.builds.needed
@@ -10215,6 +10281,12 @@ Element 1 -> Element 1.2
Target lot
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% needed)
+
+ project.builds.number_of_builds
@@ -12852,6 +12924,622 @@ Please note, that you can not impersonate a disabled user. If you try you will g
View external version
+
+
+ assembly.label
+ Assembly
+
+
+
+
+ assembly.caption
+ Assembly
+
+
+
+
+ assembly_bom_entry.label
+ Parts
+
+
+
+
+ perm.assemblies
+ Assemblies
+
+
+
+
+ assembly.labelp
+ Assemblies
+
+
+
+
+ assembly.edit
+ Edit assembly
+
+
+
+
+ assembly.new
+ New assembly
+
+
+
+
+ assembly.edit.associated_build_part
+ Associated builds part
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Add builds part
+
+
+
+
+ assembly.edit.associated_build.hint
+ This part represents the builds of this assembly. To indicate if built instances are required. If not, the number of pieces regarding the assembly are only used for the build of the respective project.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Import BOM
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Assemblies
+
+
+
+
+ assembly.bom_import.flash.success
+ Imported %count% parts in assembly successfully.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Validation error! Please check your data!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ File could not be imported. Please check that you have selected the right file type. Error message: %message%
+
+
+
+
+ assembly.bom.quantity
+ Quantity
+
+
+
+
+ assembly.bom.mountnames
+ Mount names
+
+
+
+
+ assembly.bom.instockAmount
+ Stocked amount
+
+
+
+
+ assembly.info.title
+ Assembly info
+
+
+
+
+ assembly.info.info.label
+ Info
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Sub-assemblies
+
+
+
+
+ assembly.info.builds.label
+ Build
+
+
+
+
+ assembly.info.bom_add_parts
+ Add part entries
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". You should check if you really want to build the assembly with this status!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Build not possible: Parts not stocked
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ You do not have enough parts stocked to build this assembly %number_of_builds% times. The following parts have missing instock:
+
+
+
+
+ assembly.builds.build_possible
+ Build possible
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% builds of this assembly.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Build amount
+
+
+
+
+ assembly.build.btn_build
+ Build
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Number of stocked builds
+
+
+
+
+ assembly.info.bom_entries_count
+ Part entries
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Sub-assemblies
+
+
+
+
+ assembly.builds.stocked
+ stocked
+
+
+
+
+ assembly.builds.needed
+ needed
+
+
+
+
+ assembly.add_parts_to_assembly
+ Add parts to assembly
+
+
+
+
+ assembly.bom.name
+ Name
+
+
+
+
+ assembly.bom.comment
+ Notes
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ You do not have enough parts stocked to build this assembly %number_of_builds% times. The following parts have missing instock:
+
+
+
+
+ assembly.build.help
+ Choose from which part lots the stock to build this assembly should be taken (and in which amount). Check the checkbox for each part, when you are finished withdrawing the parts, or use the top checkbox to check all boxes at once.
+
+
+
+
+ assembly.build.required_qty
+ Required quantity
+
+
+
+
+ assembly.import_bom
+ Import BOM for project
+
+
+
+
+ assembly.bom.part
+ Part
+
+
+
+
+ assembly.bom.add_entry
+ Add entry
+
+
+
+
+ assembly.bom.price
+ Price
+
+
+
+
+ assembly.build.dont_check_quantity
+ Do not check quantities
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ If this option is selected, the given withdraw quantities are used as given, no matter if more or less parts are actually required to build this assembly.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Add builds to assembly builds part
+
+
+
+
+ assembly.bom_import.type
+ Type
+
+
+
+
+ assembly.bom_import.type.json
+ JSON for one assembly
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Clear existing part entries before importing
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Selecting this option will remove all existing part entries in the assembly and overwrite them with the imported part data!
+
+
+
+
+ assembly.import_bom.template.header.json
+ Import template JSON format for one assembly
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Import template CSV format (KiCAD Pcbnew BOM) for one assembly
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Name of the part in the assembly
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Unique product number within the manufacturer
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unique IPN of the part
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unique name of the part
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unique name of the manufacturer
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Unique name of the category
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Field
+
Condition
+
Data type
+
Description
+
+
+
+
+
quantity
+
Required
+
Floating point (Float)
+
Must be provided and contains a floating-point value (Float) greater than 0.0.
+
+
+
name
+
Optional
+
String
+
If present, it must be a non-empty string.
+
+
+
part
+
Optional
+
Object/Array
+
+ If provided, it must be an object/array and at least one of the fields must be filled:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Optional
+
Integer
+
Integer > 0. Matches the Part-DB internal numeric ID of the component.
+
+
+
part.name
+
Optional
+
String
+
Non-empty string if no part.mpnr or part.ipn is provided.
+
+
+
part.mpnr
+
Optional
+
String
+
Non-empty string if no part.name or part.ipn is provided.
+
+
+
part.ipn
+
Optional
+
String
+
Non-empty string if no part.name or part.mpnr is provided.
+
+
+
part.description
+
Optional
+
String or null
+
If present, it must be a non-empty string or null.
+
+
+
part.manufacturer
+
Optional
+
Object/Array
+
+ If present, it must be an object/array and at least one of the fields must be filled:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optional
+
Integer
+
Integer > 0. Matches the internal numeric ID of the manufacturer.
+
+
+
manufacturer.name
+
Optional
+
String
+
Non-empty string if no manufacturer.id is provided.
+
+
+
part.category
+
Optional
+
Object/Array
+
+ If present, it must be an object/array and at least one of the fields must be filled:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Optional
+
Integer
+
Integer > 0. Matches the internal numeric ID of the component's category.
+
+
+
category.name
+
Optional
+
String
+
Non-empty string if no category.id is provided.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Expected Columns:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Note: No mapping is performed with specific components from category management.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Field
+
Condition
+
Data Type
+
Description
+
+
+
+
+
Id
+
Optional
+
Integer
+
Free-form field. A unique identification number for each component.
+
+
+
Designator
+
Optional
+
String
+
Free-form field. A unique reference designator of the component on the PCB, e.g., “R1” for resistor 1. Used for naming the placement in the component group.
+
+
+
Package
+
Optional
+
String
+
Free-form field. The casing or form factor of the component, e.g., “0805” for SMD resistors.
+
+
+
Quantity
+
Required
+
Integer
+
The number of identical components required to create a single instance of an assembly.
+
+
+
Designation
+
Required
+
String
+
The description or function of the component, e.g., resistor value “10kΩ” or capacitor value “100nF.” Used for the name in the BOM entry.
+
+
+
Supplier and ref
+
Optional
+
String
+
Free-form field. May include, for example, specific distributor information.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Part)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Assembly)
+
+
+
+
+ projects.build.form.part
+ Part "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Assembly "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% needed)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ not in stock
+
+ part.table.actions.error
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index fce38e52f..f961630c5 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -4740,6 +4740,18 @@ Subelementos serán desplazados hacia arriba.
Nombre
+
+
+ part.table.name.value.for_part
+ %value% (Componente)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Ensamblaje)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9804,6 +9816,18 @@ Elemento 3
Componente
+
+
+ project.bom.assembly
+ Baugruppe
+
+
+
+
+ project.bom.partOrAssembly
+ Auswahl
+
+ project.bom.add_entry
@@ -9882,6 +9906,42 @@ Elemento 3
Archivado
+
+
+ assembly.edit.status
+ Estatus
+
+
+
+
+ assembly.status.draft
+ Esbozo
+
+
+
+
+ assembly.status.planning
+ En planificación
+
+
+
+
+ assembly.status.in_production
+ En producción
+
+
+
+
+ assembly.status.finished
+ Completado
+
+
+
+
+ assembly.status.archived
+ Archivado
+
+ part.new_build_part.error.build_part_already_exists
@@ -10158,6 +10218,12 @@ Elemento 3
Almacenado
+
+
+ project.builds.no_stock
+ no se ha especificado stock
+
+ project.builds.needed
@@ -10230,6 +10296,12 @@ Elemento 3
Lote objetivo
+
+
+ project.build.builds_part_lot_label
+ %name% (se requiere %quantity%)
+
+ project.builds.number_of_builds
@@ -12368,5 +12440,621 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Este componente contiene más de un stock. Cambie la ubicación manualmente para seleccionar el stock deseado.
+
+
+ assembly.label
+ Ensamblaje
+
+
+
+
+ assembly.caption
+ Ensamblaje
+
+
+
+
+ perm.assemblies
+ Ensamblajes
+
+
+
+
+ assembly_bom_entry.label
+ Componentes
+
+
+
+
+ assembly.labelp
+ Ensamblajes
+
+
+
+
+ assembly.edit
+ Editar ensamblaje
+
+
+
+
+ assembly.new
+ Nuevo ensamblaje
+
+
+
+
+ assembly.edit.associated_build_part
+ Componente asociado
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Añadir componente
+
+
+
+
+ assembly.edit.associated_build.hint
+ Este componente representa las instancias fabricadas del ensamblaje. Indique si se necesitan instancias fabricadas. De lo contrario, las cantidades del componente solo se utilizarán cuando se construya el proyecto correspondiente.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importar componentes
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Ensamblajes
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% componente(s) se importaron correctamente al ensamblaje.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ ¡Error de validación! ¡Revisa el archivo importado!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ No se pudo importar el archivo. Asegúrate de haber seleccionado el tipo de archivo correcto. Mensaje de error: %message%
+
+
+
+
+ assembly.bom.quantity
+ Cantidad
+
+
+
+
+ assembly.bom.mountnames
+ Nombres de montaje
+
+
+
+
+ assembly.bom.instockAmount
+ Cantidad en stock
+
+
+
+
+ assembly.info.title
+ Información del ensamblaje
+
+
+
+
+ assembly.info.info.label
+ Información
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Subconjuntos
+
+
+
+
+ assembly.info.builds.label
+ Construcciones
+
+
+
+
+ assembly.info.bom_add_parts
+ Añadir piezas
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". ¡Por favor, verifica si realmente deseas construir el ensamblaje con este estado!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Construcción no posible: No hay suficientes componentes disponibles
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ No hay suficientes piezas en stock para construir este proyecto %number_of_builds% veces. Faltan las siguientes piezas:
+
+
+
+
+ assembly.builds.build_possible
+ Construcción posible
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% unidades de este ensamblaje.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Número de construcciones
+
+
+
+
+ assembly.build.btn_build
+ Construir
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Unidades construidas almacenadas
+
+
+
+
+ assembly.info.bom_entries_count
+ Componentes
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Subconjuntos
+
+
+
+
+ assembly.builds.stocked
+ en stock
+
+
+
+
+ assembly.builds.needed
+ necesario
+
+
+
+
+ assembly.add_parts_to_assembly
+ Añadir piezas al ensamblaje
+
+
+
+
+ assembly.bom.name
+ Nombre
+
+
+
+
+ assembly.bom.comment
+ Comentarios
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ No hay suficientes piezas en stock para construir este ensamblaje %number_of_builds% veces. Faltan las siguientes piezas:
+
+
+
+
+ assembly.build.help
+ Seleccione de qué almacenes se tomarán las piezas necesarias para la construcción (y en qué cantidad). Marque la casilla de cada entrada una vez que haya quitado las piezas, o use la casilla superior para marcarlas todas a la vez.
+
+
+
+
+ assembly.build.required_qty
+ Cantidad requerida
+
+
+
+
+ assembly.import_bom
+ Importar piezas para ensamblaje
+
+
+
+
+ assembly.bom.part
+ Pieza
+
+
+
+
+ assembly.bom.add_entry
+ Añadir entrada
+
+
+
+
+ assembly.bom.price
+ Precio
+
+
+
+
+ assembly.build.dont_check_quantity
+ No verificar cantidades
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Si se selecciona esta opción, las cantidades seleccionadas se quitarán del inventario independientemente de si hay más o menos de lo necesario para construir el ensamblaje.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Añadir unidades construidas a la parte del ensamblaje
+
+
+
+
+ assembly.bom_import.type
+ Tipo
+
+
+
+
+ assembly.bom_import.type.json
+ JSON para un ensamblaje
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Eliminar entradas de componentes existentes antes de la importación
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Si esta opción está seleccionada, se eliminarán todos los componentes existentes en el ensamblaje y serán reemplazados por los datos de los componentes importados.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Plantilla de importación JSON para un ensamblaje
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Plantilla de importación CSV (KiCAD Pcbnew BOM) para un ensamblaje
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Nombre del componente en el ensamblaje
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Número de parte único dentro del fabricante
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ IPN único del componente
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Nombre único del componente
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Nombre único del fabricante
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Nombre único de la categoría
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Campo
+
Condición
+
Tipo de dato
+
Descripción
+
+
+
+
+
quantity
+
Obligatorio
+
Número decimal (Float)
+
Debe estar presente y contener un valor decimal (Float) mayor que 0.0.
+
+
+
name
+
Opcional
+
Cadena de texto (String)
+
Si está presente, debe ser una cadena de texto no vacía.
+
+
+
part
+
Opcional
+
Objeto/Array
+
+ Si se proporciona, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno del componente en la base de datos.
+
+
+
part.name
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona part.mpnr o part.ipn.
+
+
+
part.mpnr
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona part.name o part.ipn.
+
+
+
part.ipn
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona part.name o part.mpnr.
+
+
+
part.description
+
Opcional
+
Cadena de texto (String) o null
+
Si está presente, debe ser una cadena de texto no vacía o null.
+
+
+
part.manufacturer
+
Opcional
+
Objeto/Array
+
+ Si está presente, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno del fabricante.
+
+
+
manufacturer.name
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona manufacturer.id.
+
+
+
part.category
+
Opcional
+
Objeto/Array
+
+ Si está presente, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno de la categoría del componente.
+
+
+
category.name
+
Opcional
+
Cadena de texto (String)
+
Cadena de texto no vacía, si no se proporciona category.id.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Columnas esperadas:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Nota: No se realiza una asociación con componentes específicos de la gestión de categorías.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Campo
+
Condición
+
Tipo de Datos
+
Descripción
+
+
+
+
+
Id
+
Opcional
+
Entero
+
Campo libre. Un número de identificación único para cada componente.
+
+
+
Designador
+
Opcional
+
Cadena de texto
+
Campo libre. Un designador de referencia único para el componente en la PCB, p. ej., "R1" para la resistencia 1. Se utiliza para nombrar la colocación en el grupo de componentes.
+
+
+
Package
+
Opcional
+
Cadena de texto
+
Campo libre. El formato o tipo de encapsulado del componente, p. ej., "0805" para resistencias SMD.
+
+
+
Cantidad
+
Obligatorio
+
Entero
+
El número de componentes idénticos necesarios para crear una instancia única de un ensamblaje.
+
+
+
Designación
+
Obligatorio
+
Cadena de texto
+
La descripción o función del componente, p. ej., el valor de la resistencia "10kΩ" o el valor del condensador "100nF". Se utiliza para el nombre en la entrada del BOM.
+
+
+
Proveedor y referencia
+
Opcional
+
Cadena de texto
+
Campo libre. Puede incluir, por ejemplo, información específica del distribuidor.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Componente)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Ensamblaje)
+
+
+
+
+ projects.build.form.part
+ Componente "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Ensamblaje "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% necesario)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ sin stock
+
+
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 292dbafaa..59b63a989 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -4703,6 +4703,18 @@ Si vous avez fait cela de manière incorrecte ou si un ordinateur n'est plus fia
Nom
+
+
+ part.table.name.value.for_part
+ %value% (Componente)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblaggio)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9097,5 +9109,681 @@ exemple de ville
Si vous avez des questions à propos de Part-DB , rendez vous sur <a href="%href%" class="link-external" target="_blank">Github</a>
+
+
+ project.bom.assembly
+ Assemblage
+
+
+
+
+ project.bom.partOrAssembly
+ Sélection
+
+
+
+
+ assembly.edit.status
+ Statut
+
+
+
+
+ assembly.status.draft
+ Brouillon
+
+
+
+
+ assembly.status.planning
+ En planification
+
+
+
+
+ assembly.status.in_production
+ En production
+
+
+
+
+ assembly.status.finished
+ Terminé
+
+
+
+
+ assembly.status.archived
+ Archivé
+
+
+
+
+ project.builds.no_stock
+ aucun stock indiqué
+
+
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% requis)
+
+
+
+
+ assembly.label
+ Assemblage
+
+
+
+
+ assembly.caption
+ Assemblage
+
+
+
+
+ perm.assemblies
+ Assemblages
+
+
+
+
+ assembly_bom_entry.label
+ Composants
+
+
+
+
+ assembly.labelp
+ Assemblages
+
+
+
+
+ assembly.edit
+ Modifier l'assemblage
+
+
+
+
+ assembly.new
+ Nouvel assemblage
+
+
+
+
+ assembly.edit.associated_build_part
+ Composant associé
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Ajouter un composant
+
+
+
+
+ assembly.edit.associated_build.hint
+ Ce composant représente les instances fabriquées de l'assemblage. Indiquez si des instances fabriquées sont nécessaires. Sinon, les quantités des composants ne seront appliquées que lors de la construction du projet correspondant.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importer des composants
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Assemblages
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% composant(s) ont été importé(s) avec succès dans l'assemblage.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Erreur de validation ! Veuillez vérifier le fichier importé !
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Le fichier n'a pas pu être importé. Veuillez vérifier que vous avez sélectionné le bon type de fichier. Message d'erreur : %message%
+
+
+
+
+ assembly.bom.quantity
+ Quantité
+
+
+
+
+ assembly.bom.mountnames
+ Noms de montage
+
+
+
+
+ assembly.bom.instockAmount
+ Quantité en stock
+
+
+
+
+ assembly.info.title
+ Informations sur l'assemblage
+
+
+
+
+ assembly.info.info.label
+ Informations
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Sous-ensembles
+
+
+
+
+ assembly.info.builds.label
+ Constructions
+
+
+
+
+ assembly.info.bom_add_parts
+ Ajouter des pièces
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Vérifiez bien si vous souhaitez construire l'assemblage avec ce statut !]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Construction impossible : pièces insuffisantes disponibles
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Il n'y a pas suffisamment de pièces en stock pour construire ce projet %number_of_builds% fois. Les pièces suivantes manquent en stock :
+
+
+
+
+ assembly.builds.build_possible
+ Construction possible
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% unités de cet assemblage.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Nombre d'assemblages à construire
+
+
+
+
+ assembly.build.btn_build
+ Construire
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Nombre d'instances construites en stock
+
+
+
+
+ assembly.info.bom_entries_count
+ Composants
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Sous-ensembles
+
+
+
+
+ assembly.builds.stocked
+ en stock
+
+
+
+
+ assembly.builds.needed
+ nécessaire
+
+
+
+
+ assembly.add_parts_to_assembly
+ Ajouter des pièces à l'assemblage
+
+
+
+
+ assembly.bom.name
+ Nom
+
+
+
+
+ assembly.bom.comment
+ Commentaires
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Il n'y a pas suffisamment de pièces en stock pour construire cet assemblage %number_of_builds% fois. Les pièces suivantes manquent en stock :
+
+
+
+
+ assembly.build.help
+ Sélectionnez les stocks à partir desquels les pièces nécessaires à la construction seront prises (et en quelle quantité). Vérifiez chaque pièce en les retirant, ou utilisez la case supérieure pour les sélectionner toutes à la fois.
+
+
+
+
+ assembly.build.required_qty
+ Quantité requise
+
+
+
+
+ assembly.import_bom
+ Importer des pièces pour l'assemblage
+
+
+
+
+ assembly.bom.part
+ Pièce
+
+
+
+
+ assembly.bom.add_entry
+ Ajouter une ligne
+
+
+
+
+ assembly.bom.price
+ Prix
+
+
+
+
+ assembly.build.dont_check_quantity
+ Ne pas vérifier les quantités
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Si cette option est activée, les quantités sélectionnées seront retirées du stock, quelle que soit leur suffisance pour l’assemblage.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Ajouter les unités construites à la pièce assemblée
+
+
+
+
+ assembly.bom_import.type
+ Type
+
+
+
+
+ assembly.bom_import.type.json
+ JSON pour un assemblage
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Supprimer les entrées de pièces existantes avant l’importation
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Si cette option est cochée, toutes les pièces existantes dans l’assemblage seront supprimées et remplacées par les données importées.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Modèle d’importation JSON pour un assemblage
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Modèle d’importation CSV (KiCAD Pcbnew BOM) pour un assemblage
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Nom de la pièce dans l’assemblage
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Numéro unique de la pièce chez le fabricant
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Numéro IPN unique de la pièce
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Nom unique de la pièce
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Nom unique du fabricant
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Nom unique de la catégorie
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Champ
+
Condition
+
Type de données
+
Description
+
+
+
+
+
quantity
+
Obligatoire
+
Nombre décimal (Float)
+
Doit être présent et contenir une valeur décimale (Float) supérieure à 0,0.
+
+
+
name
+
Optionnel
+
Chaîne (String)
+
Si présent, doit être une chaîne non vide.
+
+
+
part
+
Optionnel
+
Objet/Tableau
+
+ Si fourni, doit être un objet/un tableau et au moins un des champs doit être rempli :
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Optionnel
+
Entier (Integer)
+
Entier (Integer) > 0. Correspond à l'ID numérique interne dans Part-DB du composant.
+
+
+
part.name
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si part.mpnr ou part.ipn ne sont pas fournis.
+
+
+
part.mpnr
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si part.name ou part.ipn ne sont pas fournis.
+
+
+
part.ipn
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si part.name ou part.mpnr ne sont pas fournis.
+
+
+
part.description
+
Optionnel
+
Chaîne ou null
+
Si présent, doit être une chaîne non vide ou null.
+
+
+
part.manufacturer
+
Optionnel
+
Objet/Tableau
+
+ Si présent, doit être un objet/un tableau et au moins un des champs doit être rempli :
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optionnel
+
Entier (Integer)
+
Entier (Integer) > 0. Correspond à l'ID numérique interne du fabricant.
+
+
+
manufacturer.name
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si manufacturer.id n'est pas fourni.
+
+
+
part.category
+
Optionnel
+
Objet/Tableau
+
+ Si présent, doit être un objet/un tableau et au moins un des champs doit être rempli :
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Optionnel
+
Entier (Integer)
+
Entier (Integer) > 0. Correspond à l'ID numérique interne de la catégorie du composant.
+
+
+
category.name
+
Optionnel
+
Chaîne (String)
+
Chaîne non vide si category.id n'est pas fourni.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Colonnes attendues :
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Remarque : Aucun mappage n'est effectué avec des composants spécifiques issus de la gestion des catégories.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Champ
+
Condition
+
Type de Données
+
Description
+
+
+
+
+
Id
+
Optionnel
+
Entier
+
Champ libre. Un numéro d'identification unique pour chaque composant.
+
+
+
Designeur
+
Optionnel
+
Chaîne
+
Champ libre. Une référence de désignation unique du composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé pour nommer la position au sein du groupe de composants.
+
+
+
Boîtier
+
Optionnel
+
Chaîne
+
Champ libre. Le type ou format d'encapsulation du composant, par exemple, "0805" pour des résistances CMS.
+
+
+
Quantité
+
Obligatoire
+
Entier
+
Le nombre de composants identiques nécessaires pour créer une instance unique d'un ensemble.
+
+
+
Désignation
+
Obligatoire
+
Chaîne
+
La description ou la fonction du composant, par exemple, la valeur de résistance "10kΩ" ou la valeur de condensateur "100nF". Utilisé comme nom dans l'entrée de la nomenclature (BOM).
+
+
+
Fournisseur et réf
+
Optionnel
+
Chaîne
+
Champ libre. Peut inclure, par exemple, des informations spécifiques au distributeur.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (pièce)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (assemblage)
+
+
+
+
+ projects.build.form.part
+ Pièce "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Assemblage "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% nécessaires)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ Non disponible en stock
+
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index 828304eba..0ea57d9f1 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -4742,6 +4742,18 @@ Se è stato fatto in modo errato o se un computer non è più attendibile, puoi
Nome
+
+
+ part.table.name.value.for_part
+ %value% (Componente)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblaggio)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9806,6 +9818,18 @@ Element 3
Componente
+
+
+ project.bom.assembly
+ Assemblaggio
+
+
+
+
+ project.bom.partOrAssembly
+ Selezione
+
+ project.bom.add_entry
@@ -9884,6 +9908,42 @@ Element 3
Archiviato
+
+
+ assembly.edit.status
+ Stato
+
+
+
+
+ assembly.status.draft
+ Bozza
+
+
+
+
+ assembly.status.planning
+ In pianificazione
+
+
+
+
+ assembly.status.in_production
+ In produzione
+
+
+
+
+ assembly.status.finished
+ Completato
+
+
+
+
+ assembly.status.archived
+ Archiviato
+
+ part.new_build_part.error.build_part_already_exists
@@ -10160,6 +10220,12 @@ Element 3
a magazzino
+
+
+ project.builds.no_stock
+ nessuna scorta specificata
+
+ project.builds.needed
@@ -10232,6 +10298,12 @@ Element 3
Lotto target
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% richiesti)
+
+ project.builds.number_of_builds
@@ -12346,6 +12418,622 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Visualizza la versione esterna
+
+
+ assembly.label
+ Assemblaggio
+
+
+
+
+ assembly.caption
+ Assemblaggio
+
+
+
+
+ perm.assemblies
+ Assemblaggi
+
+
+
+
+ assembly_bom_entry.label
+ Componenti
+
+
+
+
+ assembly.labelp
+ Assemblaggi
+
+
+
+
+ assembly.edit
+ Modifica assemblaggio
+
+
+
+
+ assembly.new
+ Nuovo assemblaggio
+
+
+
+
+ assembly.edit.associated_build_part
+ Componente associato
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Aggiungi componente
+
+
+
+
+ assembly.edit.associated_build.hint
+ Questo componente rappresenta le istanze fabbricate dell'assemblaggio. Specificare se sono necessarie istanze fabbricate. In caso contrario, le quantità di componenti verranno utilizzate solo durante la costruzione del progetto corrispondente.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importa componenti
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Assemblaggi
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% componente(i) importato(i) correttamente nell'assemblaggio.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Errore di convalida! Controlla il file importato!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Impossibile importare il file. Assicurati di aver selezionato il tipo di file corretto. Messaggio di errore: %message%
+
+
+
+
+ assembly.bom.quantity
+ Quantità
+
+
+
+
+ assembly.bom.mountnames
+ Nomi di montaggio
+
+
+
+
+ assembly.bom.instockAmount
+ Quantità in magazzino
+
+
+
+
+ assembly.info.title
+ Informazioni sul gruppo
+
+
+
+
+ assembly.info.info.label
+ Info
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Sotto-gruppi
+
+
+
+
+ assembly.info.builds.label
+ Costruzioni
+
+
+
+
+ assembly.info.bom_add_parts
+ Aggiungi componenti
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Controlla se vuoi davvero costruire il gruppo con questo stato!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Costruzione impossibile: componenti insufficienti disponibili
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Non ci sono abbastanza componenti in magazzino per costruire questo progetto %number_of_builds% volte. Mancano i seguenti componenti:
+
+
+
+
+ assembly.builds.build_possible
+ Costruzione possibile
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% unità di questo gruppo.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Numero di gruppi da costruire
+
+
+
+
+ assembly.build.btn_build
+ Costruire
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Numero di istanze costruite in magazzino
+
+
+
+
+ assembly.info.bom_entries_count
+ Componenti
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Sotto-gruppi
+
+
+
+
+ assembly.builds.stocked
+ disponibile
+
+
+
+
+ assembly.builds.needed
+ necessari
+
+
+
+
+ assembly.add_parts_to_assembly
+ Aggiungi componenti al gruppo
+
+
+
+
+ assembly.bom.name
+ Nome
+
+
+
+
+ assembly.bom.comment
+ Commenti
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Non ci sono abbastanza componenti in magazzino per costruire questo gruppo %number_of_builds% volte. Mancano i seguenti componenti:
+
+
+
+
+ assembly.build.help
+ Seleziona i magazzini da cui prelevare i componenti necessari per la costruzione (e in che quantità). Spunta ciascun componente una volta prelevato, oppure utilizza la casella superiore per selezionare tutto in una volta.
+
+
+
+
+ assembly.build.required_qty
+ Quantità necessaria
+
+
+
+
+ assembly.import_bom
+ Importa componenti per il gruppo
+
+
+
+
+ assembly.bom.part
+ Componente
+
+
+
+
+ assembly.bom.add_entry
+ Aggiungi voce
+
+
+
+
+ assembly.bom.price
+ Prezzo
+
+
+
+
+ assembly.build.dont_check_quantity
+ Non controllare le quantità
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Se abilitata, le quantità selezionate verranno rimosse dal magazzino indipendentemente dalla loro sufficienza per il gruppo.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Aggiungi istanze costruite al gruppo componenti
+
+
+
+
+ assembly.bom_import.type
+ Tipo
+
+
+
+
+ assembly.bom_import.type.json
+ JSON per un gruppo
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Elimina i componenti esistenti prima di importare
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Se abilitata, tutti i componenti esistenti verranno rimossi e sostituiti dai dati importati.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Template di importazione JSON per un gruppo
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Template di importazione CSV (KiCAD Pcbnew BOM) per un gruppo
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Nome del componente nel gruppo
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Numero univoco del componente del produttore
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ IPN univoco del componente
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Nome univoco del componente
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Nome univoco del produttore
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Nome univoco della categoria
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Campo
+
Condizione
+
Tipo di dato
+
Descrizione
+
+
+
+
+
quantity
+
Obbligatorio
+
Numero decimale (Float)
+
Deve essere presente e contenere un valore decimale (Float) maggiore di 0,0.
+
+
+
name
+
Opzionale
+
Stringa (String)
+
Se presente, deve essere una stringa non vuota.
+
+
+
part
+
Opzionale
+
Oggetto/Array
+
+ Se fornito, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno di Part-DB per il componente.
+
+
+
part.name
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se part.mpnr o part.ipn non sono forniti.
+
+
+
part.mpnr
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se part.name o part.ipn non sono forniti.
+
+
+
part.ipn
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se part.name o part.mpnr non sono forniti.
+
+
+
part.description
+
Opzionale
+
Stringa o null
+
Se presente, deve essere una stringa non vuota o null.
+
+
+
part.manufacturer
+
Opzionale
+
Oggetto/Array
+
+ Se presente, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno del produttore.
+
+
+
manufacturer.name
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se manufacturer.id non è fornito.
+
+
+
part.category
+
Opzionale
+
Oggetto/Array
+
+ Se presente, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno della categoria del componente.
+
+
+
category.name
+
Opzionale
+
Stringa (String)
+
Stringa non vuota se category.id non è fornito.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Colonne previste:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Nota: Non viene eseguita alcuna mappatura con componenti specifici dalla gestione delle categorie.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Campo
+
Condizione
+
Tipo di Dati
+
Descrizione
+
+
+
+
+
Id
+
Opzionale
+
Intero
+
Campo libero. Un numero identificativo unico per ogni componente.
+
+
+
Designatore
+
Opzionale
+
Stringa
+
Campo libero. Un designatore di riferimento unico per il componente sul PCB, ad esempio, "R1" per il resistore 1. Utilizzato per nominare la posizione nel gruppo di componenti.
+
+
+
Package
+
Opzionale
+
Stringa
+
Campo libero. Il tipo o formato del contenitore del componente, ad esempio, "0805" per le resistenze SMD.
+
+
+
Quantità
+
Obbligatorio
+
Intero
+
Il numero di componenti identici necessari per creare una singola unità di assemblaggio.
+
+
+
Designazione
+
Obbligatorio
+
Stringa
+
La descrizione o la funzione del componente, ad esempio, il valore della resistenza "10kΩ" o il valore del condensatore "100nF". Utilizzato per il nome nell'entrata della lista dei materiali (BOM).
+
+
+
Fornitore e riferimento
+
Opzionale
+
Stringa
+
Campo libero. Può includere, ad esempio, informazioni specifiche del distributore.
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name%(部品)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name%(アセンブリ)
+
+
+
+
+ projects.build.form.part
+ 部品「%name%」
+
+
+
+
+ projects.build.form.assembly
+ アセンブリ「%name%」
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (必要数量: %quantity%)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ 在庫なし
+
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index 760533d7c..b7392b4d7 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -724,5 +724,729 @@
Weet u zeker dat u wilt doorgaan?
+
+
+ part.table.name.value.for_part
+ %value% (Onderdeel)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value% (Samenstelling)
+
+
+
+
+ project.bom.assembly
+ Assemblage
+
+
+
+
+ project.bom.partOrAssembly
+ Selectie
+
+
+
+
+ assembly.edit.status
+ Κατάσταση
+
+
+
+
+ assembly.status.draft
+ Προσχέδιο
+
+
+
+
+ assembly.status.planning
+ Υπό σχεδιασμό
+
+
+
+
+ assembly.status.in_production
+ Σε παραγωγή
+
+
+
+
+ assembly.status.finished
+ Ολοκληρώθηκε
+
+
+
+
+ assembly.status.archived
+ Αρχειοθετήθηκε
+
+
+
+
+ project.builds.no_stock
+ geen voorraad opgegeven
+
+
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% vereist)
+
+
+
+
+ assembly.label
+ Assemblage
+
+
+
+
+ assembly.caption
+ Assemblage
+
+
+
+
+ perm.assemblies
+ Assemblages
+
+
+
+
+ assembly_bom_entry.label
+ Componenten
+
+
+
+
+ assembly.labelp
+ Assemblages
+
+
+
+
+ assembly.edit
+ Assemblage bewerken
+
+
+
+
+ assembly.new
+ Nieuwe assemblage
+
+
+
+
+ assembly.edit.associated_build_part
+ Geassocieerd onderdeel
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Onderdeel toevoegen
+
+
+
+
+ assembly.edit.associated_build.hint
+ Dit onderdeel vertegenwoordigt de vervaardigde exemplaren van de assemblage. Geef aan of vervaardigde exemplaren nodig zijn. Zo niet, dan worden de aantallen onderdelen alleen gebruikt bij het bouwen van het bijbehorende project.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Componenten importeren
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Assemblages
+
+
+
+
+ assembly.bom_import.flash.success
+ %count% component(en) zijn succesvol geïmporteerd in de assemblage.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Validatiefout! Controleer het geïmporteerde bestand!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Het bestand kon niet worden geïmporteerd. Controleer of je het correcte bestandstype hebt geselecteerd. Foutmelding: %message%
+
+
+
+
+ assembly.bom.quantity
+ Aantal
+
+
+
+
+ assembly.bom.mountnames
+ Montagenamen
+
+
+
+
+ assembly.bom.instockAmount
+ Beschikbaar in voorraad
+
+
+
+
+ assembly.info.title
+ Assemblage-informatie
+
+
+
+
+ assembly.info.info.label
+ Informatie
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Subassemblages
+
+
+
+
+ assembly.info.builds.label
+ Bouw
+
+
+
+
+ assembly.info.bom_add_parts
+ Onderdelen toevoegen
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Bevestig dat je hiermee wilt doorgaan!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Bouwen is niet mogelijk: niet voldoende onderdelen beschikbaar
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Er zijn niet voldoende onderdelen in voorraad om %number_of_builds% keer te bouwen. De volgende onderdelen ontbreken:
+
+
+
+
+ assembly.builds.build_possible
+ Bouwen mogelijk
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% assemblages te bouwen.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Aantal te bouwen assemblages
+
+
+
+
+ assembly.build.btn_build
+ Bouwen
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Aantal geassembleerde onderdelen op voorraad
+
+
+
+
+ assembly.info.bom_entries_count
+ Onderdelen
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Subgroepen
+
+
+
+
+ assembly.builds.stocked
+ Op voorraad
+
+
+
+
+ assembly.builds.needed
+ Nodig
+
+
+
+
+ assembly.add_parts_to_assembly
+ Onderdelen toevoegen aan assemblage
+
+
+
+
+ assembly.bom.name
+ Naam
+
+
+
+
+ assembly.bom.comment
+ Notities
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Er zijn niet genoeg onderdelen op voorraad om deze assemblage %number_of_builds% keer te bouwen. Van de volgende onderdelen is er niet genoeg op voorraad:
+
+
+
+
+ assembly.build.help
+ Selecteer uit welke voorraden de benodigde onderdelen voor de bouw gehaald moeten worden (en in welke hoeveelheid). Vink elk onderdeel afzonderlijk aan als het is verwijderd, of gebruik de bovenste selectievak om alle selectievakjes in één keer aan te vinken.
+
+
+
+
+ assembly.build.required_qty
+ Benodigde hoeveelheid
+
+
+
+
+ assembly.import_bom
+ Importeer onderdelen voor assemblage
+
+
+
+
+ assembly.bom.part
+ Onderdeel
+
+
+
+
+ assembly.bom.add_entry
+ Voer item in
+
+
+
+
+ assembly.bom.price
+ Prijs
+
+
+
+
+ assembly.build.dont_check_quantity
+ Hoeveelheden niet controleren
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Als deze optie is geselecteerd, worden de geselecteerde hoeveelheden uit de voorraad verwijderd, ongeacht of er meer of minder onderdelen zijn dan nodig is voor de assemblage.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Gemaakte instanties toevoegen aan onderdeel van assemblage
+
+
+
+
+ assembly.build.required_qty
+ Benodigd aantal
+
+
+
+
+ assembly.build.yes_button
+ Ja
+
+
+
+
+ assembly.build.no_button
+ Nee
+
+
+
+
+ assembly.confirmation.required
+
+
+
+
+
+ assembly.build.success
+ De assemblage is succesvol gebouwd!
+
+
+
+
+ assembly.build.cancelled
+ De assemblage is geannuleerd.
+
+
+
+
+ assembly.bom_import.type
+ Type
+
+
+
+
+ assembly.bom_import.type.json
+ JSON voor assemblage
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Bestaande BOM wissen vóór importeren
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Wanneer dit is ingeschakeld, worden alle bestaande BOM-items verwijderd en vervangen door de geïmporteerde gegevens.
+
+
+
+
+ assembly.import_bom.template.header.json
+ JSON-sjabloon voor assemblage
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ CSV-sjabloon voor assemblage (KiCAD Pcbnew BOM)
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Naam van onderdeel in de assemblage
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Onderdeelnummer van de fabrikant
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unieke IPN van het onderdeel
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unieke naam van het onderdeel
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unieke naam van de fabrikant
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Unieke naam van de categorie
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Veld
+
Voorwaarde
+
Gegevenstype
+
Beschrijving
+
+
+
+
+
quantity
+
Verplicht veld
+
Kommagetal (Float)
+
Moet opgegeven zijn en bevat een kommagetal (Float) dat groter is dan 0,0.
+
+
+
name
+
Optioneel
+
String
+
Indien aanwezig, moet het een niet-lege string zijn.
+
+
+
part
+
Optioneel
+
Object/Array
+
+ Indien opgegeven, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Optioneel
+
Geheel getal (Integer)
+
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van het onderdeel in de Part-DB.
+
+
+
part.name
+
Optioneel
+
String
+
Niet-lege string, indien geen part.mpnr- of part.ipn-vermelding is gegeven.
+
+
+
part.mpnr
+
Optioneel
+
String
+
Niet-lege string, indien geen part.name- of part.ipn-vermelding is gegeven.
+
+
+
part.ipn
+
Optioneel
+
String
+
Niet-lege string, indien geen part.name- of part.mpnr-vermelding is gegeven.
+
+
+
part.description
+
Optioneel
+
String of null
+
Indien aanwezig, moet het een niet-lege string zijn of null.
+
+
+
part.manufacturer
+
Optioneel
+
Object/Array
+
+ Indien aanwezig, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optioneel
+
Geheel getal (Integer)
+
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van de fabrikant.
+
+
+
manufacturer.name
+
Optioneel
+
String
+
Niet-lege string, indien geen manufacturer.id-vermelding is gegeven.
+
+
+
part.category
+
Optioneel
+
Object/Array
+
+ Indien aanwezig, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Optioneel
+
Geheel getal (Integer)
+
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van de categorie van het onderdeel.
+
+
+
category.name
+
Optioneel
+
String
+
Niet-lege string, indien geen category.id-vermelding is gegeven.
+
+
+
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
+ Verwachte kolommen:
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Opmerking: Er wordt geen mapping uitgevoerd met specifieke componenten uit de categoriebeheer.
+ ]]>
+
+
+
+
+
+ assembly.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Veld
+
Voorwaarde
+
Gegevenstype
+
Beschrijving
+
+
+
+
+
Id
+
Optioneel
+
Integer
+
Vrij veld. Een unieke identificatienummer voor elk onderdeel.
+
+
+
Ontwerper
+
Optioneel
+
Tekst
+
Vrij veld. Een unieke referentie-ontwerper voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Gebruikt voor de naamgeving van de plaatsing in de componentgroep.
+
+
+
Omhulsel
+
Optioneel
+
Tekst
+
Vrij veld. Het type of de vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden.
+
+
+
Aantal
+
Verplicht
+
Integer
+
Het aantal identieke onderdelen dat nodig is om een enkele instantie van een assemblage te maken.
+
+
+
Aanduiding
+
Verplicht
+
Tekst
+
De beschrijving of functie van het onderdeel, bijvoorbeeld de weerstandswaarde "10kΩ" of de condensatorwaarde "100nF". Wordt gebruikt als naam in de BOM-invoer.
+
+
+
Leverancier en referentie
+
Optioneel
+
Tekst
+
Vrij veld. Kan bijvoorbeeld informatie bevatten die specifiek is voor de distributeur.
+
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name% (Onderdeel)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name% (Assemblage)
+
+
+
+
+ projects.build.form.part
+ Onderdelen "%name%"
+
+
+
+
+ projects.build.form.assembly
+ Assemblage "%name%"
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name% (%quantity% benodigd)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ niet op voorraad
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index b769e2737..7290e5fe1 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -4745,6 +4745,18 @@ Jeśli zrobiłeś to niepoprawnie lub komputer nie jest już godny zaufania, mo
Nazwa
+
+
+ part.table.name.value.for_part
+ %value%(部品)
+
+
+
+
+ part.table.name.value.for_assembly
+ %value%(アセンブリ)
+
+ Part-DB1\src\DataTables\PartsDataTable.php:178
@@ -9809,6 +9821,18 @@ Element 3
Komponent
+
+
+ project.bom.assembly
+ Zespół
+
+
+
+
+ project.bom.partOrAssembly
+ Wybór
+
+ project.bom.add_entry
@@ -9887,6 +9911,42 @@ Element 3
Zarchiwizowany
+
+
+ assembly.edit.status
+ Status
+
+
+
+
+ assembly.status.draft
+ Wersja robocza
+
+
+
+
+ assembly.status.planning
+ W planowaniu
+
+
+
+
+ assembly.status.in_production
+ W produkcji
+
+
+
+
+ assembly.status.finished
+ Zakończony
+
+
+
+
+ assembly.status.archived
+ Zarchiwizowany
+
+ part.new_build_part.error.build_part_already_exists
@@ -10163,6 +10223,12 @@ Element 3
dostępny
+
+
+ project.builds.no_stock
+ brak podanego stanu magazynowego
+
+ project.builds.needed
@@ -10235,6 +10301,12 @@ Element 3
Partia docelowa
+
+
+ project.build.builds_part_lot_label
+ %name% (%quantity% wymagane)
+
+ project.builds.number_of_builds
@@ -12223,5 +12295,621 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Wygenerowany kod
+
+
+ assembly.label
+ Zespół
+
+
+
+
+ assembly.caption
+ Zespół
+
+
+
+
+ perm.assemblies
+ Zespoły
+
+
+
+
+ assembly_bom_entry.label
+ Komponenty
+
+
+
+
+ assembly.labelp
+ Zespoły
+
+
+
+
+ assembly.edit
+ Edytuj zespół
+
+
+
+
+ assembly.new
+ Nowy zespół
+
+
+
+
+ assembly.edit.associated_build_part
+ Powiązany komponent
+
+
+
+
+ assembly.edit.associated_build_part.add
+ Dodaj komponent
+
+
+
+
+ assembly.edit.associated_build.hint
+ Ten komponent reprezentuje wyprodukowane instancje zespołu. Określ, czy są potrzebne wyprodukowane instancje. W przeciwnym razie ilości komponentów zostaną zastosowane tylko podczas budowy odpowiedniego projektu.
+
+
+
+
+ assembly.edit.bom.import_bom
+ Importuj komponenty
+
+
+
+
+ log.database_updated.failed
+ __log.database_updated.failed
+
+
+
+
+ log.database_updated.old_version
+ __log.database_updated.old_version
+
+
+
+
+ log.database_updated.new_version
+ __log.database_updated.new_version
+
+
+
+
+ tree.tools.edit.assemblies
+ Zespoły
+
+
+
+
+ assembly.bom_import.flash.success
+ Pomyślnie zaimportowano %count% komponent(ów) do zespołu.
+
+
+
+
+ assembly.bom_import.flash.invalid_entries
+ Błąd walidacji! Sprawdź zaimportowany plik!
+
+
+
+
+ assembly.bom_import.flash.invalid_file
+ Nie udało się zaimportować pliku. Sprawdź, czy wybrano poprawny typ pliku. Komunikat błędu: %message%
+
+
+
+
+ assembly.bom.quantity
+ Ilość
+
+
+
+
+ assembly.bom.mountnames
+ Nazwy montażu
+
+
+
+
+ assembly.bom.instockAmount
+ Ilość na magazynie
+
+
+
+
+ assembly.info.title
+ Informacje o zespole
+
+
+
+
+ assembly.info.info.label
+ Informacje
+
+
+
+
+ assembly.info.sub_assemblies.label
+ Podzespoły
+
+
+
+
+ assembly.info.builds.label
+ Budowa
+
+
+
+
+ assembly.info.bom_add_parts
+ Dodaj części
+
+
+
+
+ assembly.builds.check_assembly_status
+ "%assembly_status%". Upewnij się, że chcesz zbudować zespół w tym statusie!]]>
+
+
+
+
+ assembly.builds.build_not_possible
+ Budowa niemożliwa: niewystarczająca ilość części
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock
+ Brakuje wystarczającej ilości części na magazynie, aby zbudować ten projekt %number_of_builds% razy. Brakujące części to:
+
+
+
+
+ assembly.builds.build_possible
+ Budowa możliwa
+
+
+
+
+ assembly.builds.number_of_builds_possible
+ %max_builds% egzemplarzy tego zespołu.]]>
+
+
+
+
+ assembly.builds.number_of_builds
+ Liczba budowanych egzemplarzy
+
+
+
+
+ assembly.build.btn_build
+ Zbuduj
+
+
+
+
+ assembly.builds.no_stocked_builds
+ Liczba zbudowanych i zmagazynowanych egzemplarzy
+
+
+
+
+ assembly.info.bom_entries_count
+ Elementy
+
+
+
+
+ assembly.info.sub_assemblies_count
+ Podzespoły
+
+
+
+
+ assembly.builds.stocked
+ na magazynie
+
+
+
+
+ assembly.builds.needed
+ potrzebne
+
+
+
+
+ assembly.add_parts_to_assembly
+ Dodaj części do zespołu
+
+
+
+
+ assembly.bom.name
+ Nazwa
+
+
+
+
+ assembly.bom.comment
+ Uwagi
+
+
+
+
+ assembly.builds.following_bom_entries_miss_instock_n
+ Brakuje wystarczającej ilości części na magazynie, aby zbudować ten zespół %number_of_builds% razy. Brakujące części to:
+
+
+
+
+ assembly.build.help
+ Wybierz, z których magazynów mają być pobrane części potrzebne do budowy (i w jakiej ilości). Zaznacz każdą pozycję, jeśli części zostały pobrane, lub użyj głównego pola wyboru, aby zaznaczyć wszystkie na raz.
+
+
+
+
+ assembly.build.required_qty
+ Wymagana ilość
+
+
+
+
+ assembly.import_bom
+ Importuj części dla zespołu
+
+
+
+
+ assembly.bom.part
+ Część
+
+
+
+
+ assembly.bom.add_entry
+ Dodaj pozycję
+
+
+
+
+ assembly.bom.price
+ Cena
+
+
+
+
+ assembly.build.dont_check_quantity
+ Nie sprawdzaj ilości
+
+
+
+
+ assembly.build.dont_check_quantity.help
+ Jeśli opcja jest wybrana, zadeklarowana ilość zostanie odjęta z magazynu, niezależnie od tego, czy jest wystarczająca do budowy zespołu.
+
+
+
+
+ assembly.build.add_builds_to_builds_part
+ Dodaj zbudowane egzemplarze jako część zespołu
+
+
+
+
+ assembly.bom_import.type
+ Typ
+
+
+
+
+ assembly.bom_import.type.json
+ JSON dla zespołu
+
+
+
+
+ assembly.bom_import.type.kicad_pcbnew
+ CSV (KiCAD Pcbnew)
+
+
+
+
+ assembly.bom_import.clear_existing_bom
+ Usuń istniejące dane przed importem
+
+
+
+
+ assembly.bom_import.clear_existing_bom.help
+ Jeśli wybrano, wszystkie istniejące wpisy części zostaną usunięte i zastąpione danymi z importu.
+
+
+
+
+ assembly.import_bom.template.header.json
+ Szablon importu JSON dla zespołu
+
+
+
+
+ assembly.import_bom.template.header.kicad_pcbnew
+ Szablon importu CSV (KiCAD Pcbnew BOM) dla zespołu
+
+
+
+
+ assembly.bom_import.template.entry.name
+ Nazwa części w zespole
+
+
+
+
+ assembly.bom_import.template.entry.part.mpnr
+ Unikalny numer katalogowy producenta
+
+
+
+
+ assembly.bom_import.template.entry.part.ipn
+ Unikalny IPN części
+
+
+
+
+ assembly.bom_import.template.entry.part.name
+ Unikalna nazwa części
+
+
+
+
+ assembly.bom_import.template.entry.part.manufacturer.name
+ Unikalna nazwa producenta
+
+
+
+
+ assembly.bom_import.template.entry.part.category.name
+ Unikalna nazwa kategorii
+
+
+
+
+ assembly.bom_import.template.json.table
+
+
+
+
+
Pole
+
Warunek
+
Typ danych
+
Opis
+
+
+
+
+
quantity
+
Wymagane
+
Typ zmiennoprzecinkowy (Float)
+
Musi być obecne i zawierać wartość zmiennoprzecinkową (Float) większą niż 0,0.
+
+
+
name
+
Opcjonalne
+
Ciąg znaków (String)
+
Jeśli obecne, musi być niepustym ciągiem znaków.
+
+
+
part
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli podane, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+
+
part.id
+
part.name
+
+
+
+
+
part.id
+
Opcjonalne
+
Liczba całkowita (Integer)
+
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu numerowi ID komponentu w Part-DB.
+
+
+
part.name
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli part.mpnr ani part.ipn nie są podane.
+
+
+
part.mpnr
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli part.name ani part.ipn nie są podane.
+
+
+
part.ipn
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli part.name ani part.mpnr nie są podane.
+
+
+
part.description
+
Opcjonalne
+
Ciąg znaków lub null
+
Jeśli obecne, musi być niepustym ciągiem znaków lub null.
+
+
+
part.manufacturer
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli obecne, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opcjonalne
+
Liczba całkowita (Integer)
+
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu identyfikatorowi numerowemu producenta.
+
+
+
manufacturer.name
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli manufacturer.id nie jest podane.
+
+
+
part.category
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli obecne, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+
+
category.id
+
category.name
+
+
+
+
+
category.id
+
Opcjonalne
+
Liczba całkowita (Integer)
+
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu numerowi ID kategorii komponentu.
+
+
+
category.name
+
Opcjonalne
+
Ciąg znaków (String)
+
Niepusty ciąg znaków, jeśli category.id nie jest podane.
Произвольное поле. Уникальный идентификационный номер для каждого компонента.
+
+
+
Дизигнатор
+
Опционально
+
Строка
+
Произвольное поле. Уникальный референсный обозначитель компонента на печатной плате, например, "R1" для резистора 1. Используется для именования позиции в группе компонентов.
+
+
+
Корпус
+
Опционально
+
Строка
+
Произвольное поле. Тип или форм-фактор корпуса компонента, например, "0805" для SMD-резисторов.
+
+
+
Количество
+
Обязательно
+
Целое число
+
Количество одинаковых компонентов, необходимое для создания одной единицы сборки.
+
+
+
Обозначение
+
Обязательно
+
Строка
+
Описание или функция компонента, например, номинал резистора "10kΩ" или номинал конденсатора "100nF". Используется в качестве имени в позиции списка материалов (BOM).
+
+
+
Поставщик и ссылка
+
Опционально
+
Строка
+
Произвольное поле. Может содержать, например, информацию, специфичную для дистрибьютора.
+
+
+ ]]>
+
+
+
+
+
+ typeahead.parts.part.name
+ %name%(零件)
+
+
+
+
+ typeahead.parts.assembly.name
+ %name%(组件)
+
+
+
+
+ projects.build.form.part
+ 零件“%name%”
+
+
+
+
+ projects.build.form.assembly
+ 组件“%name%”
+
+
+
+
+ projects.build.form.assembly.bom.entry
+ %name%(需数量:%quantity%)
+
+
+
+
+ projects.build.form.assembly.bom.entry.no.stock
+ 库存不足
+
+
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index c298266af..06354533e 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -245,6 +245,12 @@
Musíte vybrat díl pro položku BOM dílu nebo nastavit název pro položku BOM bez dílu.
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Je povoleno vybrat pouze jednu součástku nebo sestavu. Upravit prosím svůj výběr!
+
+ project.bom_entry.name_already_in_bom
@@ -365,5 +371,23 @@
Neplatný kód. Zkontrolujte, zda je vaše ověřovací aplikace správně nastavena a zda je čas správně nastaven jak na serveru, tak na ověřovacím zařízení.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Tato součást již existuje ve skupině!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Již existuje součást s tímto názvem!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Musíte vybrat součást nebo nastavit název pro nesoučást!
+
+
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index 21149f0e7..9a9dea4cd 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -245,6 +245,12 @@
Du skal vælge en komponent eller angive et navn til en ikke-komponent styklistepost!
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
+
+ project.bom_entry.name_already_in_bom
@@ -341,5 +347,23 @@
Denne leverandørstregkodeværdi er allerede brugt til en anden beholdning. Stregkoden skal være unik!
+
+
+ assembly.bom_entry.part_already_in_bom
+ Denne del eksisterer allerede i gruppen!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Der findes allerede en del med dette navn!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Du skal vælge en del eller sætte et navn for en ikke-del!
+
+
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index 9c123fd85..6fde3419a 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -242,7 +242,13 @@
validator.project.bom_entry.name_or_part_needed
- Sie müssen ein Bauteil auswählen, oder einen Namen für ein nicht-Bauteil BOM-Eintrag setzen!
+ Sie müssen ein Bauteil bzw. eine Baugruppe auswählen, oder einen Namen für ein nicht-Bauteil BOM-Eintrag setzen!
+
+
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Es darf nur ein Bauteil oder eine Baugruppe ausgewählt werden. Bitte passen Sie Ihre Auswahl an!
@@ -365,5 +371,23 @@
Ungültiger Code. Überprüfen Sie, dass die Authenticator App korrekt eingerichtet ist und dass der Server und das Gerät beide die korrekte Uhrzeit eingestellt haben.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Dieses Bauteil existiert bereits in der Gruppe!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Es gibt bereits einen Bauteil mit diesem Namen!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Sie müssen ein Bauteil auswählen, oder einen Namen für ein nicht-Bauteil setzen!
+
+
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index 9ef5b3de4..ee27863c0 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -7,5 +7,29 @@
Ο εσωτερικός αριθμός εξαρτήματος πρέπει να είναι μοναδικός. {{ value }} χρησιμοποιείται ήδη!
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
+
+
+
+
+ assembly.bom_entry.part_already_in_bom
+ Αυτό το εξάρτημα υπάρχει ήδη στην ομάδα!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Υπάρχει ήδη ένα εξάρτημα με αυτό το όνομα!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Πρέπει να επιλέξετε ένα εξάρτημα ή να βάλετε ένα όνομα για ένα μη εξάρτημα!
+
+
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index 6ad144607..86525b6a8 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -242,7 +242,13 @@
validator.project.bom_entry.name_or_part_needed
- You have to choose a part for a part BOM entry or set a name for a non-part BOM entry.
+ You have to select a part or assembly, or set a name for a non-component Bom entry!
+
+
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Only one part or assembly may be selected. Please modify your selection!
@@ -365,5 +371,23 @@
Invalid code. Check that your authenticator app is set up correctly and that both the server and authentication device has the time set correctly.
+
+
+ assembly.bom_entry.part_already_in_bom
+ __assembly.bom_entry.part_already_in_bom
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ __assembly.bom_entry.name_already_in_bom
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ __validator.assembly.bom_entry.name_or_part_needed
+
+
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index e86ab9ccc..e9bf32597 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -203,5 +203,29 @@
L'emplacement de stockage a été marqué comme "Composant seul", par conséquent aucun nouveau composant ne peut être ajouté.
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Seule une pièce ou un assemblage peut être sélectionné. Veuillez ajuster votre sélection!
+
+
+
+
+ assembly.bom_entry.part_already_in_bom
+ Cette pièce existe déjà dans le groupe!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Il existe déjà une pièce avec ce nom!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Vous devez sélectionner une pièce ou attribuer un nom pour un non-élément !
+
+
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index 29e32a16c..9c9c3960c 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -245,6 +245,12 @@
Morate odabrati dio za unos u BOM ili postaviti naziv za unos koji nije dio.
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Dozvoljeno je odabrati samo jednu komponentu ili sklop. Molimo prilagodite svoj odabir!
+
+ project.bom_entry.name_already_in_bom
@@ -359,5 +365,23 @@
Neispravan kod. Provjerite je li vaša aplikacija za autentifikaciju ispravno postavljena i jesu li poslužitelj i uređaj za autentifikaciju ispravno postavili vrijeme.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Ovaj dio već postoji u grupi!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Već postoji dio s tim nazivom!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Morate odabrati dio ili unijeti naziv za nedio!
+
+
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index 7043f4f34..2f747bc5c 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -245,6 +245,12 @@
È necessario selezionare un componente o assegnare un nome ad una voce BOM che non indica un componente!
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ È consentito selezionare solo una parte o un assieme. Si prega di modificare la selezione!
+
+ project.bom_entry.name_already_in_bom
@@ -359,5 +365,23 @@
Codice non valido. Controlla che la tua app di autenticazione sia impostata correttamente e che sia il server che il dispositivo di autenticazione abbiano l'ora impostata correttamente.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Questa parte è già presente nel gruppo!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Esiste già una parte con questo nome!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ È necessario selezionare una parte o inserire un nome per un non-parte!
+
+
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index 01cc3f77b..0156ffefc 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -203,5 +203,29 @@
新しい部品を追加できません。保管場所は「1つの部品のみ」とマークされています。
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ 部品またはアセンブリのみ選択可能です。選択内容を調整してください!
+
+
+
+
+ assembly.bom_entry.part_already_in_bom
+ この部品はすでにグループに存在します!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ この名前の部品はすでに存在します!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ 部品を選択するか、非部品の名前を入力する必要があります!
+
+
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 6c9977983..2cc4aef43 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -245,6 +245,12 @@
Należy wybrać część dla wpisu BOM części lub ustawić nazwę dla wpisu BOM niebędącego częścią.
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Można wybrać tylko jedną część lub zespół. Proszę dostosować swój wybór!
+
+ project.bom_entry.name_already_in_bom
@@ -359,5 +365,23 @@
Nieprawidłowy kod. Sprawdź, czy aplikacja uwierzytelniająca jest poprawnie skonfigurowana i czy zarówno serwer, jak i urządzenie uwierzytelniające mają poprawnie ustawiony czas.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Ten element już istnieje w grupie!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Element o tej nazwie już istnieje!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Musisz wybrać element lub przypisać nazwę dla elementu niestandardowego!
+
+
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index 0f97c4781..4049b453e 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -245,6 +245,12 @@
Вам необходимо выбрать компонент или задать имя для BOM, не относящейся к компоненту!
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ Можно выбрать только деталь или сборку. Пожалуйста, измените ваш выбор!
+
+ project.bom_entry.name_already_in_bom
@@ -359,5 +365,23 @@
Неверный код. Проверьте, что приложение аутентификации настроено правильно и что на сервере и устройстве аутентификации установлено правильное время.
+
+
+ assembly.bom_entry.part_already_in_bom
+ Эта деталь уже существует в группе!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ Деталь с таким названием уже существует!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ Необходимо выбрать деталь или ввести название для недетали!
+
+
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 08c9f014e..3eab5c4e3 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -245,6 +245,12 @@
您必须为 BOM 条目选择部件,或为非部件 BOM 条目设置名称。
+
+
+ validator.project.bom_entry.only_part_or_assembly_allowed
+ 只能选择一个零件或组件。请修改您的选择!
+
+ project.bom_entry.name_already_in_bom
@@ -347,5 +353,23 @@
由于技术限制,在32位系统中无法选择2038年1月19日之后的日期!
+
+
+ assembly.bom_entry.part_already_in_bom
+ 此零件已存在于组中!
+
+
+
+
+ assembly.bom_entry.name_already_in_bom
+ 具有此名称的零件已存在!
+
+
+
+
+ validator.assembly.bom_entry.name_or_part_needed
+ 必须选择零件或为非零件指定名称!
+
+
From f6663276fc27c6e64f5298f9a16824f56969d303 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 20 Mar 2025 09:55:48 +0100
Subject: [PATCH 35/83] =?UTF-8?q?Default-Sortierung=20f=C3=BCr=20Assemblie?=
=?UTF-8?q?s=20per=20YAML-Konfiguration=20einf=C3=BChren?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env | 9 ++++++
config/parameters.yaml | 4 +++
config/services.yaml | 3 ++
.../AssemblyBomEntriesDataTable.php | 28 +++++++++++--------
4 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/.env b/.env
index 982d4bbd0..cfa3bb053 100644
--- a/.env
+++ b/.env
@@ -60,6 +60,15 @@ ERROR_PAGE_ADMIN_EMAIL=''
# If this is set to true, solutions to common problems are shown on error pages. Disable this, if you do not want your users to see them...
ERROR_PAGE_SHOW_HELP=1
+##################################################################################
+# Part table settings
+##################################################################################
+
+# Configure which columns will be visible by default in the specific table (and in which order).
+# This is a comma separated list of column names. See documentation for available values.
+TABLE_PARTS_DEFAULT_COLUMNS=name,description,category,footprint,manufacturer,storage_location,amount
+TABLE_ASSEMBLIES_DEFAULT_COLUMNS=quantity,manufacturer,name,description,category
+
###################################################################################
# SAML Single sign on-settings
diff --git a/config/parameters.yaml b/config/parameters.yaml
index 154fbd8a5..a993d2d5e 100644
--- a/config/parameters.yaml
+++ b/config/parameters.yaml
@@ -43,6 +43,10 @@ parameters:
######################################################################################################################
partdb.saml.enabled: '%env(bool:SAML_ENABLED)%' # If this is set to true, SAML authentication is enabled
+ ######################################################################################################################
+ # Table settings
+ ######################################################################################################################
+ partdb.table.assemblies.default_columns: '%env(trim:string:TABLE_ASSEMBLIES_DEFAULT_COLUMNS)%' # The default columns in assembly tables and their order
######################################################################################################################
# Miscellaneous
diff --git a/config/services.yaml b/config/services.yaml
index 17611ceab..be293d389 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -167,6 +167,9 @@ services:
####################################################################################################################
# Table settings
####################################################################################################################
+ App\DataTables\AssemblyBomEntriesDataTable:
+ arguments:
+ $visible_columns: '%partdb.table.assemblies.default_columns%'
App\DataTables\Helpers\ColumnSortHelper:
shared: false # Service has a state so not share it between different tables
diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php
index 7149ed5f5..a953179a9 100644
--- a/src/DataTables/AssemblyBomEntriesDataTable.php
+++ b/src/DataTables/AssemblyBomEntriesDataTable.php
@@ -25,6 +25,7 @@
use App\DataTables\Column\EntityColumn;
use App\DataTables\Column\LocaleDateTimeColumn;
use App\DataTables\Column\MarkdownColumn;
+use App\DataTables\Helpers\ColumnSortHelper;
use App\DataTables\Helpers\PartDataTableHelper;
use App\Entity\Attachments\Attachment;
use App\Entity\Parts\Part;
@@ -41,14 +42,19 @@
class AssemblyBomEntriesDataTable implements DataTableTypeInterface
{
- public function __construct(protected TranslatorInterface $translator, protected PartDataTableHelper $partDataTableHelper, protected EntityURLGenerator $entityURLGenerator, protected AmountFormatter $amountFormatter)
- {
+ public function __construct(
+ protected TranslatorInterface $translator,
+ protected PartDataTableHelper $partDataTableHelper,
+ protected EntityURLGenerator $entityURLGenerator,
+ protected AmountFormatter $amountFormatter,
+ private string $visible_columns,
+ private ColumnSortHelper $csh
+ ){
}
-
public function configure(DataTable $dataTable, array $options): void
{
- $dataTable
+ $this->csh
//->add('select', SelectColumn::class)
->add('picture', TextColumn::class, [
'label' => '',
@@ -62,7 +68,6 @@ public function configure(DataTable $dataTable, array $options): void
])
->add('id', TextColumn::class, [
'label' => $this->translator->trans('part.table.id'),
- 'visible' => false,
])
->add('quantity', TextColumn::class, [
'label' => $this->translator->trans('assembly.bom.quantity'),
@@ -97,11 +102,12 @@ public function configure(DataTable $dataTable, array $options): void
->add('ipn', TextColumn::class, [
'label' => $this->translator->trans('part.table.ipn'),
'orderField' => 'NATSORT(part.ipn)',
- 'visible' => false,
'render' => function ($value, AssemblyBOMEntry $context) {
if($context->getPart() instanceof Part) {
return $context->getPart()->getIpn();
}
+
+ return '';
}
])
->add('description', MarkdownColumn::class, [
@@ -142,7 +148,6 @@ public function configure(DataTable $dataTable, array $options): void
])
->add('instockAmount', TextColumn::class, [
'label' => 'assembly.bom.instockAmount',
- 'visible' => false,
'render' => function ($value, AssemblyBOMEntry $context) {
if ($context->getPart() !== null) {
return $this->partDataTableHelper->renderAmount($context->getPart());
@@ -153,7 +158,6 @@ public function configure(DataTable $dataTable, array $options): void
])
->add('storageLocations', TextColumn::class, [
'label' => 'part.table.storeLocations',
- 'visible' => false,
'render' => function ($value, AssemblyBOMEntry $context) {
if ($context->getPart() !== null) {
return $this->partDataTableHelper->renderStorageLocations($context->getPart());
@@ -164,15 +168,17 @@ public function configure(DataTable $dataTable, array $options): void
])
->add('addedDate', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.addedDate'),
- 'visible' => false,
])
->add('lastModified', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.lastModified'),
- 'visible' => false,
])
;
- $dataTable->addOrderBy('name', DataTable::SORT_ASCENDING);
+ //Apply the user configured order and visibility and add the columns to the table
+ $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,
+ "TABLE_ASSEMBLIES_DEFAULT_COLUMNS");
+
+ $dataTable->addOrderBy('name');
$dataTable->createAdapter(ORMAdapter::class, [
'entity' => Attachment::class,
From 59a2669a05ba6a89d8e7832beaa4b550551dab6a Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 20 Mar 2025 10:02:30 +0100
Subject: [PATCH 36/83] =?UTF-8?q?configuration.md:=20Info=20f=C3=BCr=20Def?=
=?UTF-8?q?ault-Sortierung=20zu=20Assemblies=20einf=C3=BCgen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/configuration.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/docs/configuration.md b/docs/configuration.md
index d4b217816..efa3efd34 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -137,6 +137,10 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `storage_location`, `amount`, `minamount`, `partUnit`, `addedDate`, `lastModified`, `needs_review`, `favorite`, `manufacturing_status`, `manufacturer_product_number`, `mass`, `tags`, `attachments`, `edit`.
+* `TABLE_ASSEMBLIES_DEFAULT_COLUMNS`: The columns in assemblies tables, which are visible by default (when loading table for first
+ time).
+ Also specify the default order of the columns. This is a comma separated list of column names. Available columns
+ are: `name`, `id`, `quantity`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `mountnames`, `instockAmount`, `storageLocations`, `addedDate`, `lastModified`.
### History/Eventlog-related settings
From bc0df762d96c934835c1f9591a761d292b61e036 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Wed, 2 Apr 2025 12:24:14 +0200
Subject: [PATCH 37/83] Anpassungen aus Benutzersicht, um den Fokus auf die
reine Baugruppen-Konfiguration zu legen
---
.../AdminPages/BaseAdminController.php | 2 +
src/Form/Type/AssemblySelectType.php | 1 -
templates/admin/assembly_admin.html.twig | 4 +-
templates/admin/base_admin.html.twig | 2 +-
templates/assemblies/info/_bom.html.twig | 22 ----
.../assemblies/info/_info_card.html.twig | 15 ---
templates/assemblies/info/_part.html.twig | 5 +
.../assemblies/info/_subassemblies.html.twig | 28 -----
templates/assemblies/info/info.html.twig | 100 ++++++++++--------
.../form/collection_types_layout.html.twig | 1 +
10 files changed, 66 insertions(+), 114 deletions(-)
delete mode 100644 templates/assemblies/info/_bom.html.twig
create mode 100644 templates/assemblies/info/_part.html.twig
delete mode 100644 templates/assemblies/info/_subassemblies.html.twig
diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php
index edc5917ac..8c8d7520d 100644
--- a/src/Controller/AdminPages/BaseAdminController.php
+++ b/src/Controller/AdminPages/BaseAdminController.php
@@ -232,6 +232,7 @@ protected function _edit(AbstractNamedDBElement $entity, Request $request, Entit
'timeTravel' => $timeTravel_timestamp,
'repo' => $repo,
'partsContainingElement' => $repo instanceof PartsContainingRepositoryInterface,
+ 'showParameters' => !($this instanceof AssemblyAdminController),
]);
}
@@ -382,6 +383,7 @@ protected function _new(Request $request, EntityManagerInterface $em, EntityImpo
'import_form' => $import_form,
'mass_creation_form' => $mass_creation_form,
'route_base' => $this->route_base,
+ 'showParameters' => !($this instanceof AssemblyAdminController),
]);
}
diff --git a/src/Form/Type/AssemblySelectType.php b/src/Form/Type/AssemblySelectType.php
index ee6cf7c2a..10e858f26 100644
--- a/src/Form/Type/AssemblySelectType.php
+++ b/src/Form/Type/AssemblySelectType.php
@@ -71,7 +71,6 @@ public function configureOptions(OptionsResolver $resolver): void
$resolver->setDefaults([
'class' => Assembly::class,
'choice_label' => 'name',
- 'placeholder' => 'None',
'compound' => true,
'error_bubbling' => false,
]);
diff --git a/templates/admin/assembly_admin.html.twig b/templates/admin/assembly_admin.html.twig
index d8b3ab257..57dde7d15 100644
--- a/templates/admin/assembly_admin.html.twig
+++ b/templates/admin/assembly_admin.html.twig
@@ -15,7 +15,7 @@
{% endblock %}
{% block additional_pills %}
-
{% endblock %}
\ No newline at end of file
diff --git a/templates/form/collection_types_layout.html.twig b/templates/form/collection_types_layout.html.twig
index def235000..0175aeaf6 100644
--- a/templates/form/collection_types_layout.html.twig
+++ b/templates/form/collection_types_layout.html.twig
@@ -44,6 +44,7 @@
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index 8b1f2a620..52edddb41 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -14086,56 +14086,56 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Pole
-
Podmínka
-
Datový typ
-
Popis
-
+
+
Pole
+
Podmínka
+
Datový typ
+
Popis
+
Id
-
Volitelný
-
Celé číslo (Integer)
-
Volný údaj. Jedinečné identifikační číslo pro každou součástku.
+
Volitelné
+
Celé číslo
+
Volné pole. Unikátní identifikační číslo pro každou součástku.
Designator
-
Volitelný
-
Řetězec (String)
-
Volný údaj. Jedinečný referenční označovač součástky na desce plošných spojů, např. „R1“ pro rezistor 1. Používá se pro název osazení součástky v rámci skupiny součástek.
+
Volitelné
+
Řetězec
+
Volné pole. Unikátní referenční označení součástky na PCB, např. „R1“ pro rezistor 1. Používá se pro název umístění v rámci součástkové skupiny.
Package
-
Volitelný
-
Řetězec (String)
-
Volný údaj. Pouzdro nebo tvar součástky, např. „0805“ pro SMD rezistory.
+
Volitelné
+
Řetězec
+
Volné pole. Pouzdro nebo formát součástky, např. „0805“ pro SMD rezistory. Není použito pro záznam součástky v rámci sestavy.
-
Množství
-
Povinný
-
Celé číslo (Integer)
-
Počet identických součástek, které jsou potřeba k vytvoření jedné instance sestavy.
+
Quantity
+
Povinné pole
+
Celé číslo
+
Počet identických součástek potřebných k vytvoření jedné instance sestavy. Použito jako počet záznamu součástky v rámci sestavy.
-
Určení
-
Povinný
-
Řetězec (String)
-
Popis nebo funkce součástky, např. hodnota rezistoru „10kΩ“ nebo hodnota kondenzátoru „100nF“. Používá se pro název položky v BOM.
+
Designation
+
Povinné pole
+
Řetězec
+
Popis nebo funkce součástky, např. hodnota rezistoru „10kΩ“ nebo hodnota kondenzátoru „100nF“. Použito jako název záznamu součástky v rámci sestavy.
-
Dodavatel a ref
-
Volitelný
-
Řetězec (String)
-
Volný údaj. Může obsahovat např. specifické údaje distributora.
+
Supplier and ref
+
Volitelné
+
Řetězec
+
Volné pole. Může obsahovat např. specifické informace o distributorovi. Používá se jako poznámka k záznamu součástky v rámci sestavy.
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index f231163a1..2461f8c77 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -12803,56 +12803,56 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Felt
-
Betingelse
-
Datatype
-
Beskrivelse
-
+
+
Felt
+
Betingelse
+
Datatype
+
Beskrivelse
+
Id
-
Valgfri
-
Heltal (Integer)
-
Fri oplysning. Et unikt identifikationsnummer for hver komponent.
+
Valgfrit
+
Heltal
+
Fri tekst. Et unikt identifikationsnummer for hver komponent.
Designator
-
Valgfri
+
Valgfrit
Streng
-
Fri oplysning. En unik referencebetegnelse for komponenten på printkortet, f.eks. "R1" for modstand 1. Bruges til navngivning af monteringssæt i komponentgruppen.
+
Fri tekst. En unik referencebetegnelse for komponenten på PCB'en, f.eks. “R1” for modstand 1. Bruges som navnet på placeringen i komponentgruppen.
Package
-
Valgfri
+
Valgfrit
Streng
-
Fri oplysning. Komponentenheden eller -formatet, f.eks. "0805" for SMD-modstande.
+
Fri tekst. Komponentens kabinet eller formfaktor, f.eks. “0805” for SMD-modstande. Ikke inkluderet som komponentoplysning i samlingen.
-
Antal
+
Quantity
Påkrævet
-
Heltal (Integer)
-
Antallet af identiske komponenter, der kræves for at oprette en enkelt instans af samling.
+
Heltal
+
Antallet af identiske komponenter, der kræves for at oprette en enkelt forekomst af samlingen. Bruges som antal af komponentoplysning i samlingen.
-
Betegnelse
+
Designation
Påkrævet
Streng
-
Beskrivelse eller funktion for komponenten, f.eks. modstandsværdi "10kΩ" eller kondensatorværdi "100nF". Bruges til navnet i BOM-posten.
+
Beskrivelse eller funktion af komponenten, f.eks. modstandsværdi “10kΩ” eller kondensatorværdi “100nF”. Bruges som navnet på komponentoplysningen i samlingen.
-
Leverandør og ref
-
Valgfri
+
Supplier and ref
+
Valgfrit
Streng
-
Fri oplysning. Kan indeholde f.eks. distributørspecifik værdi.
+
Fri tekst. Kan indeholde, for eksempel, specifikke oplysninger fra en distributør. Bruges som en note til komponentoplysningen i samlingen.
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index c32bf46a7..bc0cac33f 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -13446,19 +13446,19 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Feld
-
Bedingung
-
Datentyp
-
Beschreibung
-
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
@@ -13471,31 +13471,31 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Designator
Optional
String
-
Offene Angabe. Ein eindeutiger Referenzbezeichner des Bauteils auf der Leiterplatte, z.B. „R1“ für Widerstand 1. Wird für den Bestückungsnamen des Bauteil-Eintrags innerhalb der Bauteilgruppe verwendet.
+
Offene Angabe. Ein eindeutiger Referenzbezeichner des Bauteils auf der Leiterplatte, z.B. „R1“ für Widerstand 1. Wird in den Bestückungsnamen des Bauteil-Eintrags in der Baugruppe übernommen.
Package
Optional
String
-
Offene Angabe. Das Gehäuse oder die Bauform des Bauteils, z.B. „0805“ für SMD-Widerstände.
+
Offene Angabe. Das Gehäuse oder die Bauform des Bauteils, z.B. „0805“ für SMD-Widerstände. Wird für ein Bauteil-Eintrag innerhalb der Baugruppe nicht übernommen.
Quantity
Pflichtfeld
Ganzzahl (Integer)
-
Anzahl der identischen Bauteile, die benötigt werden, um eine Instanz der Baugruppe zu erstellen.
+
Anzahl der identischen Bauteile, die benötigt werden, um eine Instanz der Baugruppe zu erstellen. Wird als Anzahl des Bauteil-Eintrags innerhalb der Baugruppe übernommen.
Designation
Pflichtfeld
String
-
Beschreibung oder Funktion des Bauteils, z.B. Widerstandswert „10kΩ“ oder Kondensatorwert „100nF“. Wird für den Namen des BOM-Eintrags verwendet.
+
Beschreibung oder Funktion des Bauteils, z.B. Widerstandswert „10kΩ“ oder Kondensatorwert „100nF“. Wird in den Namen des Bauteil-Eintrags innerhalb der Baugruppe übernommen.
Supplier and ref
Optional
String
-
Offene Angabe. Kann z.B. Distributor spezifischen Wert enthalten.
+
Offene Angabe. Kann z.B. Distributor spezifischen Wert enthalten. Wird als Notiz zum Bauteil-Eintrag innerhalb der Baugruppe übernommen.
Ελεύθερη καταχώρηση. Μοναδικός αριθμός ταυτοποίησης για κάθε εξάρτημα.
+
Ακέραιος
+
Πεδίο ελεύθερης μορφής. Ένας μοναδικός αριθμός ταυτοποίησης για κάθε εξάρτημα.
-
Σχεδιαστής
+
Designator
Προαιρετικό
-
Συμβολοσειρά (String)
-
Ελεύθερη καταχώρηση. Μοναδικός αναγνωριστικός δείκτης του εξαρτήματος στην πλακέτα κυκλώματος, π.χ. "R1" για την αντίσταση 1. Χρησιμοποιείται για το όνομα του εξαρτήματος στο πλαίσιο της ομάδας εξαρτημάτων.
+
Συμβολοσειρά
+
Πεδίο ελεύθερης μορφής. Ένας μοναδικός αναγνωριστικός δείκτης για το εξάρτημα στην πλακέτα PCB, π.χ. "R1" για τον αντιστάτη 1. Χρησιμοποιείται για την ονομασία της θέσης στην ομάδα εξαρτημάτων.
-
Συσκευασία
+
Package
Προαιρετικό
-
Συμβολοσειρά (String)
-
Ελεύθερη καταχώρηση. Ο τύπος ή η μορφή του εξαρτήματος, π.χ. "0805" για αντιστάσεις SMD.
+
Συμβολοσειρά
+
Πεδίο ελεύθερης μορφής. Η θήκη ή ο μορφολογικός τύπος του εξαρτήματος, π.χ. "0805" για τους SMD αντιστάτες. Δεν περιλαμβάνεται στις πληροφορίες εξαρτήματος της συναρμολόγησης.
-
Ποσότητα
-
Υποχρεωτικό
-
Ακέραιος αριθμός (Integer)
-
Ο αριθμός των πανομοιότυπων εξαρτημάτων που απαιτούνται για τη δημιουργία μίας μονάδας του συνόλου.
+
Quantity
+
Απαιτείται
+
Ακέραιος
+
Ο αριθμός πανομοιότυπων εξαρτημάτων που απαιτούνται για τη δημιουργία μιας μοναδικής παρουσίας της συναρμολόγησης. Χρησιμοποιείται ως ποσότητα στις πληροφορίες εξαρτήματος της συναρμολόγησης.
-
Ορισμός
-
Υποχρεωτικό
-
Συμβολοσειρά (String)
-
Περιγραφή ή λειτουργία του εξαρτήματος, π.χ. αντίσταση "10kΩ" ή χωρητικότητα "100nF". Χρησιμοποιείται για το όνομα της εγγραφής στο BOM.
+
Designation
+
Απαιτείται
+
Συμβολοσειρά
+
Η περιγραφή ή η λειτουργία του εξαρτήματος, π.χ. τιμή αντιστάτη "10kΩ" ή τιμή πυκνωτή "100nF". Χρησιμοποιείται ως το όνομα στις πληροφορίες εξαρτήματος της συναρμολόγησης.
-
Προμηθευτής και παραπομπή
+
Supplier and ref
Προαιρετικό
-
Συμβολοσειρά (String)
-
Ελεύθερη καταχώρηση. Μπορεί να περιλαμβάνει, π.χ., ειδική τιμή από διανομέα.
+
Συμβολοσειρά
+
Πεδίο ελεύθερης μορφής. Μπορεί να περιλαμβάνει, για παράδειγμα, συγκεκριμένες πληροφορίες για τον προμηθευτή. Χρησιμοποιείται ως σημείωση για τις πληροφορίες εξαρτήματος της συναρμολόγησης.
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index d267c89ac..8ac704001 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -13447,56 +13447,56 @@ Please note, that you can not impersonate a disabled user. If you try you will g
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Field
-
Condition
-
Data Type
-
Description
-
+
+
Field
+
Condition
+
Data Type
+
Description
+
Id
Optional
Integer
-
Free-form field. A unique identification number for each component.
+
Free-form field. A unique identification number for each part.
Designator
Optional
String
-
Free-form field. A unique reference designator of the component on the PCB, e.g., “R1” for resistor 1. Used for naming the placement in the component group.
+
Free-form field. A unique reference designator of the part on the PCB, e.g., “R1” for resistor 1. Used for the placement name of the part entry in the assembly.
Package
Optional
String
-
Free-form field. The casing or form factor of the component, e.g., “0805” for SMD resistors.
+
Free-form field. The case or form factor of the part, e.g., “0805” for SMD resistors. Not adopted for a part entry within the assembly.
Quantity
-
Required
+
Required field
Integer
-
The number of identical components required to create a single instance of an assembly.
+
The number of identical parts needed to create an instance of the assembly. Adopted as the quantity of the part entry within the assembly.
Designation
-
Required
+
Required field
String
-
The description or function of the component, e.g., resistor value “10kΩ” or capacitor value “100nF.” Used for the name in the BOM entry.
+
Description or function of the part, e.g., resistor value “10kΩ” or capacitor value “100nF.” Adopted into the name of the part entry within the assembly.
Supplier and ref
Optional
String
-
Free-form field. May include, for example, specific distributor information.
+
Free-form field. May, for example, contain distributor-specific information. Adopted as a note for the part entry within the assembly.
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index f961630c5..7315f3760 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -12963,7 +12963,7 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
-
+ assembly.bom_import.template.kicad_pcbnew.table
@@ -12982,37 +12982,37 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Id
Opcional
Entero
-
Campo libre. Un número de identificación único para cada componente.
+
Campo libre. Un número único de identificación para cada componente.
-
Designador
+
Designator
Opcional
-
Cadena de texto
-
Campo libre. Un designador de referencia único para el componente en la PCB, p. ej., "R1" para la resistencia 1. Se utiliza para nombrar la colocación en el grupo de componentes.
+
Cadena
+
Campo libre. Un designador de referencia único para el componente en la PCB, por ejemplo, "R1" para la resistencia 1. Se utiliza como el nombre de ubicación en la entrada de componentes dentro del ensamblaje.
Package
Opcional
-
Cadena de texto
-
Campo libre. El formato o tipo de encapsulado del componente, p. ej., "0805" para resistencias SMD.
+
Cadena
+
Campo libre. El encapsulado o formato del componente, por ejemplo, "0805" para resistencias SMD. No se incluye en la entrada del componente dentro del ensamblaje.
-
Cantidad
-
Obligatorio
+
Quantity
+
Requerido
Entero
-
El número de componentes idénticos necesarios para crear una instancia única de un ensamblaje.
+
El número de componentes idénticos necesarios para crear una instancia del ensamblaje. Se usa como la cantidad en la entrada de componentes dentro del ensamblaje.
-
Designación
-
Obligatorio
-
Cadena de texto
-
La descripción o función del componente, p. ej., el valor de la resistencia "10kΩ" o el valor del condensador "100nF". Se utiliza para el nombre en la entrada del BOM.
+
Designation
+
Requerido
+
Cadena
+
Descripción o función del componente, por ejemplo, valor de resistencia "10kΩ" o valor de condensador "100nF". Se usa como el nombre de la entrada del componente dentro del ensamblaje.
-
Proveedor y referencia
+
Supplier and ref
Opcional
-
Cadena de texto
-
Campo libre. Puede incluir, por ejemplo, información específica del distribuidor.
+
Cadena
+
Campo libre. Puede contener, por ejemplo, información específica del distribuidor. Se usa como una nota en la entrada del componente dentro del ensamblaje.
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 59b63a989..320121909 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -6959,7 +6959,7 @@ Si vous avez fait cela de manière incorrecte ou si un ordinateur n'est plus fia
company.edit.address.placeholder
- Ex. 99 exemple de rue
+ Ex. 99 exemple de rue
exemple de ville
@@ -9692,19 +9692,19 @@ exemple de ville
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Champ
-
Condition
-
Type de Données
-
Description
-
+
+
Champ
+
Condition
+
Type de Données
+
Description
+
@@ -9714,34 +9714,34 @@ exemple de ville
Champ libre. Un numéro d'identification unique pour chaque composant.
-
Designeur
+
Designator
Optionnel
Chaîne
-
Champ libre. Une référence de désignation unique du composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé pour nommer la position au sein du groupe de composants.
+
Champ libre. Une désignation de référence unique pour le composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé comme le nom de l'emplacement de l'entrée composant dans l'assemblage.
-
Boîtier
+
Package
Optionnel
Chaîne
-
Champ libre. Le type ou format d'encapsulation du composant, par exemple, "0805" pour des résistances CMS.
+
Champ libre. Le boîtier ou le format du composant, par exemple, "0805" pour les résistances CMS. Non inclus dans l'entrée composant pour l'assemblage.
-
Quantité
+
Quantity
Obligatoire
Entier
-
Le nombre de composants identiques nécessaires pour créer une instance unique d'un ensemble.
+
Le nombre de composants identiques nécessaires pour créer une instance de l'assemblage. Utilisé comme la quantité dans l'entrée composant de l'assemblage.
-
Désignation
+
Designation
Obligatoire
Chaîne
-
La description ou la fonction du composant, par exemple, la valeur de résistance "10kΩ" ou la valeur de condensateur "100nF". Utilisé comme nom dans l'entrée de la nomenclature (BOM).
+
La description ou la fonction du composant, par exemple, valeur de résistance "10kΩ" ou valeur de condensateur "100nF". Utilisé comme le nom dans l'entrée composant pour l'assemblage.
-
Fournisseur et réf
+
Supplier and ref
Optionnel
Chaîne
-
Champ libre. Peut inclure, par exemple, des informations spécifiques au distributeur.
+
Champ libre. Peut contenir par exemple des informations spécifiques sur le fournisseur. Utilisé comme une note dans l'entrée composant pour l'assemblage.
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index 0ea57d9f1..f6e3c9446 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -12941,56 +12941,56 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Campo
-
Condizione
-
Tipo di Dati
-
Descrizione
-
+
+
Campo
+
Condizione
+
Tipo di Dati
+
Descrizione
+
Id
Opzionale
Intero
-
Campo libero. Un numero identificativo unico per ogni componente.
+
Campo libero. Un numero identificativo univoco per ogni componente.
-
Designatore
+
Designator
Opzionale
Stringa
-
Campo libero. Un designatore di riferimento unico per il componente sul PCB, ad esempio, "R1" per il resistore 1. Utilizzato per nominare la posizione nel gruppo di componenti.
+
Campo libero. Un riferimento univoco al componente su PCB, ad esempio "R1" per il resistore 1. Utilizzato come nome della posizione nella voce componenti all'interno dell'assemblaggio.
Package
Opzionale
Stringa
-
Campo libero. Il tipo o formato del contenitore del componente, ad esempio, "0805" per le resistenze SMD.
+
Campo libero. L'involucro o il fattore di forma del componente, ad esempio "0805" per i resistori SMD. Non incluso nelle informazioni del componente nell'assemblaggio.
-
Quantità
+
Quantity
Obbligatorio
Intero
-
Il numero di componenti identici necessari per creare una singola unità di assemblaggio.
+
Il numero di componenti identici richiesti per creare un'istanza dell'assemblaggio. Utilizzato come quantità nella voce componenti dell'assemblaggio.
-
Designazione
+
Designation
Obbligatorio
Stringa
-
La descrizione o la funzione del componente, ad esempio, il valore della resistenza "10kΩ" o il valore del condensatore "100nF". Utilizzato per il nome nell'entrata della lista dei materiali (BOM).
+
Descrizione o funzione del componente, ad esempio valore resistore "10kΩ" o valore condensatore "100nF". Utilizzato come nome nella voce componenti dell'assemblaggio.
-
Fornitore e riferimento
+
Supplier and ref
Opzionale
Stringa
-
Campo libero. Può includere, ad esempio, informazioni specifiche del distributore.
+
Campo libero. Può contenere, ad esempio, informazioni specifiche del fornitore. Utilizzato come nota nelle informazioni del componente nell'assemblaggio.
Vrij veld. Een unieke identificatienummer voor elk onderdeel.
-
Ontwerper
+
Designator
Optioneel
-
Tekst
-
Vrij veld. Een unieke referentie-ontwerper voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Gebruikt voor de naamgeving van de plaatsing in de componentgroep.
+
String
+
Vrij veld. Een unieke referentienaam voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Wordt gebruikt als positioneringsnaam in de onderdelenlijst van de assemblage.
-
Omhulsel
+
Package
Optioneel
-
Tekst
-
Vrij veld. Het type of de vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden.
+
String
+
Vrij veld. De behuizing of vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden. Wordt niet opgenomen in de onderdelenlijst binnen de assemblage.
-
Aantal
-
Verplicht
+
Quantity
+
Vereist
Integer
-
Het aantal identieke onderdelen dat nodig is om een enkele instantie van een assemblage te maken.
+
Het aantal identieke onderdelen dat nodig is om een assemblage-instantie te creëren. Wordt gebruikt als hoeveelheid in de onderdelenlijst binnen de assemblage.
-
Aanduiding
-
Verplicht
-
Tekst
-
De beschrijving of functie van het onderdeel, bijvoorbeeld de weerstandswaarde "10kΩ" of de condensatorwaarde "100nF". Wordt gebruikt als naam in de BOM-invoer.
+
Designation
+
Vereist
+
String
+
De beschrijving of functie van het onderdeel, zoals weerstandwaarde "10kΩ" of condensatorwaarde "100nF". Wordt gebruikt als de naam in de onderdelenlijst binnen de assemblage.
-
Leverancier en referentie
+
Supplier and ref
Optioneel
-
Tekst
-
Vrij veld. Kan bijvoorbeeld informatie bevatten die specifiek is voor de distributeur.
+
String
+
Vrij veld. Kan bijvoorbeeld specifieke informatie over leveranciers bevatten. Wordt gebruikt als notitie in de onderdelenlijst binnen de assemblage.
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index 7290e5fe1..d1a095072 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -12818,19 +12818,19 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
-
+ assembly.bom_import.template.kicad_pcbnew.table
-
-
Pole
-
Warunek
-
Typ Danych
-
Opis
-
+
+
Pole
+
Warunek
+
Typ Danych
+
Opis
+
@@ -12840,34 +12840,34 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Pole dowolne. Unikalny numer identyfikacyjny dla każdego komponentu.
-
Designer
+
Designator
Opcjonalne
-
Łańcuch znaków
-
Pole dowolne. Unikalny oznacznik referencyjny komponentu na PCB, np. "R1" dla rezystora 1. Używany do nazewnictwa położenia w grupie komponentów.
+
Tekst
+
Pole dowolne. Jednoznaczny znacznik referencyjny komponentu na PCB, np. "R1" dla rezystora 1. Używane jako nazwa pozycji w pozycji komponentu w montażu.
-
Obudowa
+
Package
Opcjonalne
-
Łańcuch znaków
-
Pole dowolne. Typ lub forma obudowy komponentu, np. "0805" dla rezystorów SMD.
+
Tekst
+
Pole dowolne. Obudowa lub forma komponentu, np. "0805" dla rezystorów SMD. Niewykorzystywane w pozycji komponentu w montażu.
-
Ilość
+
Quantity
Wymagane
Liczba całkowita
-
Liczba identycznych komponentów potrzebnych do stworzenia jednej instancji złożenia.
+
Liczba identycznych komponentów potrzebna do utworzenia jednej instancji montażu. Używane jako ilość w pozycji komponentu w montażu.
-
Oznaczenie
+
Designation
Wymagane
-
Łańcuch znaków
-
Opis lub funkcja komponentu, np. wartość rezystora "10kΩ" lub wartość kondensatora "100nF". Używane jako nazwa w pozycji na liście materiałowej (BOM).
+
Tekst
+
Opis lub funkcja komponentu, np. wartość rezystora "10kΩ" lub wartość kondensatora "100nF". Używane jako nazwa w pozycji komponentu w montażu.
-
Dostawca i referencja
+
Supplier and ref
Opcjonalne
-
Łańcuch znaków
-
Pole dowolne. Może zawierać, np. informacje specyficzne dla dystrybutora.
+
Tekst
+
Pole dowolne. Może zawierać np. specyficzne informacje o dostawcy. Używane jako notatka w pozycji komponentu w montażu.
Произвольное поле. Уникальный идентификационный номер для каждого компонента.
+
Целое
+
Свободное поле. Уникальный идентификационный номер для каждого компонента.
-
Дизигнатор
-
Опционально
+
Package
+
Designator
Строка
-
Произвольное поле. Уникальный референсный обозначитель компонента на печатной плате, например, "R1" для резистора 1. Используется для именования позиции в группе компонентов.
+
Свободное поле. Уникальная ссылочная метка компонента на печатной плате, например, "R1" для резистора 1. Используется как наименование позиции в компоненте сборки.
-
Корпус
+
Package
Опционально
Строка
-
Произвольное поле. Тип или форм-фактор корпуса компонента, например, "0805" для SMD-резисторов.
+
Свободное поле. Тип корпуса или форм-фактор компонента, например, "0805" для SMD-резисторов. Не включается в информацию о компоненте сборки.
-
Количество
+
Quantity
Обязательно
-
Целое число
-
Количество одинаковых компонентов, необходимое для создания одной единицы сборки.
+
Целое
+
Количество одинаковых компонентов, необходимых для создания одной версии сборки. Используется как количество в информации о компоненте сборки.
-
Обозначение
+
Designation
Обязательно
Строка
-
Описание или функция компонента, например, номинал резистора "10kΩ" или номинал конденсатора "100nF". Используется в качестве имени в позиции списка материалов (BOM).
+
Описание или функция компонента, например, значение резистора "10kΩ" или значение конденсатора "100nF". Используется как наименование в информации о компоненте сборки.
-
Поставщик и ссылка
+
Supplier and ref
Опционально
Строка
-
Произвольное поле. Может содержать, например, информацию, специфичную для дистрибьютора.
+
Свободное поле. Может содержать, например, информацию о конкретных поставщиках. Используется как примечание в информации о компоненте сборки.
- {{ form_widget(form.assembly) }}
- {{ form_errors(form.assembly) }}
+
+ {% if form.vars.value is not null and form.vars.value.project is not null %}
+ {% set hasAssembly = false %}
+ {% if is_granted("@assemblies.read") or has_assembly(form.vars.value.project.bomEntries.toArray) %}
+
Id;Designator;Package;Quantity;Designation;Supplier and ref
+
+
+
Id
+
Designator
+
Package
+
Quantity
+
Designation
+
Supplier and ref
+
Note
+
Footprint
+
Value
+
Footprint
+
+
{{ 'assembly.bom_import.template.kicad_pcbnew.exptected_columns.note'|trans|raw }}
{{ 'assembly.bom_import.template.kicad_pcbnew.table'|trans|raw }}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index 52edddb41..c1d1b5177 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -13881,6 +13881,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
JSON pro sestavu
+
+
+ assembly.bom_import.type.csv
+ CSV pro sestavu
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -13905,6 +13911,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Šablona importu JSON pro sestavu
+
+
+ assembly.import_bom.template.header.csv
+ Importní šablona CSV pro sestavu
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -13964,24 +13976,26 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
quantity
-
Povinné
+
Povinné pole
Číslo s plovoucí desetinnou čárkou (Float)
-
Musí být uvedeno a obsahovat hodnotu s plovoucí desetinnou čárkou (Float) větší než 0,0.
+
Musí být vyplněno a obsahovat číselnou hodnotu (Float) větší než 0.0.
name
Volitelné
-
Řetězec (String)
-
Pokud je přítomen, musí být neprázdný řetězec.
+
Řetězec
+
Pokud je uvedeno, musí být neprázdný text. Název položky ve skupině.
part
Volitelné
Objekt/Array
- Pokud je uvedeno, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+ Pokud má být přiřazena součástka, musí být objektem/arrayem a alespoň jedno z následujících polí musí být vyplněno:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -13990,38 +14004,38 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
part.id
Volitelné
Celé číslo (Integer)
-
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID součástky v Part-DB.
+
Celé číslo > 0. Odpovídá internímu číselnému ID součástky v databázi.
-
part.name
+
part.mpnr
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není zadáno part.mpnr nebo part.ipn.
+
Řetězec
+
Neprázdný text, pokud není vyplněno part.id, part.ipn ani part.name.
-
part.mpnr
+
part.ipn
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není zadáno part.name nebo part.ipn.
+
Řetězec
+
Neprázdný text, pokud není vyplněno part.id, part.mpnr ani part.name.
-
part.ipn
+
part.name
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není zadáno part.name nebo part.mpnr.
+
Řetězec
+
Neprázdný text, pokud není vyplněno part.id, part.mpnr ani part.ipn.
part.description
Volitelné
Řetězec nebo null
-
Pokud je přítomen, musí být neprázdný řetězec nebo null.
+
Pokud je uvedeno, musí být neprázdný řetězec nebo null. Přepíše stávající hodnotu v součástce.
part.manufacturer
Volitelné
Objekt/Array
- Pokud je přítomen, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+ Pokud má být výrobce součástky upraven nebo má být součástka jednoznačně identifikována pomocí hodnoty part.mpnr, musí být objektem/arrayem a alespoň jedno z následujících polí musí být vyplněno:
manufacturer.id
manufacturer.name
@@ -14032,20 +14046,20 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
manufacturer.id
Volitelné
Celé číslo (Integer)
-
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID výrobce.
+
Celé číslo > 0. Odpovídá internímu číselnému ID výrobce.
manufacturer.name
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není uvedeno manufacturer.id.
+
Řetězec
+
Neprázdný text, pokud není uveden manufacturer.id.
part.category
Volitelné
Objekt/Array
- Pokud je přítomen, musí to být objekt/array a minimálně jedno pole musí být vyplněno:
+ Pokud má být kategorie součástky upravena, musí být objektem/arrayem a alespoň jedno z následujících polí musí být vyplněno:
category.id
category.name
@@ -14056,13 +14070,138 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
category.id
Volitelné
Celé číslo (Integer)
-
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID kategorie součástky.
+
Celé číslo > 0. Odpovídá internímu číselnému ID kategorie součástky.
category.name
Volitelné
-
Řetězec (String)
-
Neprázdný řetězec, pokud není uvedeno category.id.
Musí být vyplněno a obsahovat číselnou hodnotu (Float) větší než 0.0.
+
+
+
name
+
Volitelné
+
Řetězec
+
Název položky ve skupině.
+
+
+
Sloupce začínající part_
+
+ Pokud má být přiřazena součástka, jeden z následujících sloupců musí být uveden a vyplněn:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo > 0. Odpovídá internímu číselnému ID součástky v databázi.
+
+
+
part_mpnr
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_ipn nebo part_name.
+
+
+
part_ipn
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_mpnr nebo part_name.
+
+
+
part_name
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_mpnr nebo part_ipn.
+
+
+
part_description
+
Volitelné
+
Řetězec
+
Bude přeneseno do součástky a přepíše aktuální hodnotu, pokud je uveden neprázdný text.
+
+
+
Sloupce začínající part_manufacturer_
+
+ Pokud má být výrobce upraven nebo součástka jednoznačně identifikována pomocí part_mpnr, jeden z následujících sloupců musí být uveden a vyplněn:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo > 0. Odpovídá internímu číselnému ID výrobce.
+
+
+
part_manufacturer_name
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud není vyplněn sloupec part_manufacturer_id.
+
+
+
Sloupce začínající part.category_
+
+ Pokud má být kategorie upravena, jeden z následujících sloupců musí být uveden a vyplněn:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo > 0. Odpovídá internímu číselnému ID kategorie součástky.
+
+
+
part_category_name
+
Volitelné
+
Řetězec
+
Musí být uvedeno, pokud není vyplněn sloupec part_category_id.
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index 2461f8c77..4322fd9f8 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -12598,6 +12598,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
JSON for en samling
+
+
+ assembly.bom_import.type.csv
+ CSV til en samling
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -12622,6 +12628,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
JSON-importskabelon til en samling
+
+
+ assembly.import_bom.template.header.csv
+ Importskabelon CSV til en samling
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -12681,64 +12693,66 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
quantity
-
Påkrævet
-
Flydende tal (Float)
-
Skal være til stede og indeholde en flydende værdi (Float), der er større end 0,0.
+
Påkrævet felt
+
Flydende punkt-tal (Float)
+
Skal være udfyldt og indeholde en flydende værdi (Float), der er større end 0.0.
name
-
Valgfri
-
String
-
Hvis til stede, skal det være en ikke-tom streng.
+
Valgfrit
+
Streng
+
Hvis det er angivet, skal det være en ikke-tom streng. Navn på posten inden for samlingen.
part
-
Valgfri
+
Valgfrit
Objekt/Array
- Hvis angivet, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+ Hvis en del skal tildeles, skal det være et objekt/array, og mindst et af følgende felter skal være udfyldt:
part.id
+
part.mpnr
+
part.ipn
part.name
part.id
-
Valgfri
+
Valgfrit
Heltal (Integer)
-
Heltal (Integer) > 0. Matcher Part-DB's interne numeriske ID for komponenten.
-
-
-
part.name
-
Valgfri
-
String
-
Ikke-tom streng, hvis part.mpnr eller part.ipn ikke er givet.
+
Heltal > 0. Tilsvarer den interne nummer-ID for delen i database.
part.mpnr
-
Valgfri
-
String
-
Ikke-tom streng, hvis part.name eller part.ipn ikke er givet.
+
Valgfrit
+
Streng
+
Ikke-tom streng, hvis ingen part.id-, part.ipn- eller part.name-værdi er angivet.
part.ipn
-
Valgfri
-
String
-
Ikke-tom streng, hvis part.name eller part.mpnr ikke er givet.
+
Valgfrit
+
Streng
+
Ikke-tom streng, hvis ingen part.id-, part.mpnr- eller part.name-værdi er angivet.
+
+
+
part.name
+
Valgfrit
+
Streng
+
Ikke-tom streng, hvis ingen part.id-, part.mpnr- eller part.ipn-værdi er angivet.
part.description
-
Valgfri
-
String eller null
-
Hvis til stede, skal det være en ikke-tom streng eller null.
+
Valgfrit
+
Streng eller null
+
Hvis angivet, skal det være en ikke-tom streng eller null. Værdien bliver overskrevet i delen.
part.manufacturer
-
Valgfri
+
Valgfrit
Objekt/Array
- Hvis til stede, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+ Hvis producenten af en del skal ændres eller entydigt søges ved hjælp af part.mpnr-værdien, skal det være et objekt/array og mindst et af følgende felter skal være udfyldt:
manufacturer.id
manufacturer.name
@@ -12747,22 +12761,22 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Heltal > 0. Tilsvarer den interne nummer-ID for producenten.
manufacturer.name
-
Valgfri
-
String
-
Ikke-tom streng, hvis manufacturer.id ikke er givet.
+
Valgfrit
+
Streng
+
Ikke-tom streng, hvis ingen manufacturer.id er angivet.
part.category
-
Valgfri
+
Valgfrit
Objekt/Array
- Hvis til stede, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+ Hvis en delens kategori skal ændres, skal det være et objekt/array, og mindst et af følgende felter skal være udfyldt:
category.id
category.name
@@ -12771,15 +12785,140 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Skal være udfyldt og indeholde en flydende værdi (Float), der er større end 0.0.
+
+
+
name
+
Valgfrit
+
Streng
+
Navnet på posten inden for samlingen.
+
+
+
Kolonner, der starter med part_
+
+ Hvis en del skal tildeles, skal en af følgende kolonner være angivet og udfyldt:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Valgfrit
+
Heltal (Integer)
+
Heltal > 0. Tilsvarer den interne nummer-ID for delen i databasen.
+
+
+
part_mpnr
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen af kolonnerne part_id, part_ipn, eller part_name er udfyldt.
+
+
+
part_ipn
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen af kolonnerne part_id, part_mpnr eller part_name er udfyldt.
+
+
+
part_name
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen af kolonnerne part_id, part_mpnr eller part_ipn er udfyldt.
+
+
+
part_description
+
Valgfrit
+
Streng
+
Vil blive overført og overskrive værdien for delen, hvis en ikke-tom streng er angivet.
+
+
+
Kolonner, der starter med part_manufacturer_
+
+ Hvis producenten for en del skal ændres eller søges entydigt ved hjælp af part_mpnr, skal en af følgende kolonner være angivet og udfyldt:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Valgfrit
+
Heltal (Integer)
+
Heltal > 0. Tilsvarer den interne nummer-ID for producenten.
+
+
+
part_manufacturer_name
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen part_manufacturer_id er udfyldt.
+
+
+
Kolonner, der starter med part.category_
+
+ Hvis en dels kategori skal ændres, skal en af følgende kolonner være angivet og udfyldt:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Valgfrit
+
Heltal (Integer)
+
Heltal > 0. Tilsvarer den interne nummer-ID for delens kategori.
+
+
+
part_category_name
+
Valgfrit
+
Streng
+
Skal angives, hvis ingen part_category_id er udfyldt.
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index bc0cac33f..8377facc9 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -12986,7 +12986,7 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
assembly.edit.bom.import_bom
- Bauteile importieren
+ Importiere Bauteil-Liste
@@ -13241,6 +13241,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
JSON für eine Baugruppe
+
+
+ assembly.bom_import.type.csv
+ CSV für eine Baugruppe
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -13265,6 +13271,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Import-Vorlage JSON für eine Baugruppe
+
+
+ assembly.import_bom.template.header.csv
+ Import-Vorlage CSV für eine Baugruppe
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -13332,16 +13344,18 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
name
Optional
String
-
Falls vorhanden, muss es ein nicht-leerer String sein.
+
Falls vorhanden, muss es ein nicht-leerer String sein. Name des Eintrags innerhalb der Baugruppe.
part
Optional
Objekt/Array
- Falls angegeben, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+ Falls ein Bauteil zugeordnet werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -13353,35 +13367,35 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
-
part.name
+
part.mpnr
Optional
String
-
Nicht-leerer String, falls keine part.mpnr- bzw. part.ipn-Angabe gegeben ist.
+
Nicht-leerer String, falls keine part.id-, part-ipn- bzw. part.name-Angabe gegeben ist.
-
part.mpnr
+
part.ipn
Optional
String
-
Nicht-leerer String, falls keine part.name- bzw. part-ipn-Angabe gegeben ist.
+
Nicht-leerer String, falls keine part.id-, part.mpnr bzw. part.name-Angabe gegeben ist.
-
part.ipn
+
part.name
Optional
String
-
Nicht-leerer String, falls keine part.name- bzw. part.mpnr-Angabe gegeben ist.
+
Nicht-leerer String, falls keine part.id-, part.mpnr- bzw. part.ipn-Angabe gegeben ist.
part.description
Optional
String oder null
-
Falls vorhanden, muss es ein nicht-leerer String sein oder null.
+
Falls vorhanden, muss es ein nicht-leerer String sein oder null. Wird in das Bauteil übernommen, d.h. der dortige Wert überschrieben.
part.manufacturer
Optional
Objekt/Array
- Falls vorhanden, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+ Falls der Hersteller eines Bauteils mit angepasst werden oder das Bauteil anhand der part.mpnr-Angabe eindeutig gesucht werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
manufacturer.id
manufacturer.name
@@ -13405,7 +13419,7 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Optional
Objekt/Array
- Falls vorhanden, muss es ein Objekt/Array sein und mindestens eines der Felder ausgefüllt sein:
+ Falls die Kategorie eine Bauteils mit angepasst werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
category.id
category.name
@@ -13430,6 +13444,131 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
+
+
+ assembly.bom_import.template.csv.exptected_columns
+ Mögliche Spalten:
+
+
+
+
+ assembly.bom_import.template.csv.table
+
+
+
+
+
Spalte
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
quantity
+
Pflichtfeld
+
Gleitkommazahl (Float)
+
Muss gegeben sein und enthält einen Gleitkommawert (Float), der größer als 0.0 ist.
+
+
+
name
+
Optional
+
String
+
Name des Eintrags innerhalb der Baugruppe.
+
+
+
Spalten beginnend mit part_
+
+ Falls ein Bauteil zugeordnet werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
+
+
+
part_mpnr
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_ipn- bzw. part_name-Spalte ausgefüllt gegeben ist.
+
+
+
part_ipn
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_mpnr- bzw. part_name-Spalte ausgefüllt gegeben ist.
+
+
+
part_name
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_mpnr- bzw. part_ipn-Spalte ausgefüllt gegeben ist.
+
+
+
part_description
+
Optional
+
String
+
Wird in das Bauteil übernommen, d.h. der dortige Wert überschrieben sofern ein nicht-leerer String gegeben ist.
+
+
+
Spalten beginnend mit part_manufacturer_
+
+ Falls der Hersteller eines Bauteils mit angepasst werden oder das Bauteil anhand der part_mpnr-Angabe eindeutig gesucht werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID des Herstellers.
+
+
+
part_manufacturer_name
+
Optional
+
String
+
Anzugeben, falls keine part_manufacturer_id-Spalte ausgefüllt gegeben ist.
+
+
+
Spalten beginnend mit part.category_
+
+ Falls die Kategorie eines Bauteils mit angepasst werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID der Kategorie des Bauteils.
+
+
+
part_category_name
+
Optional
+
String
+
Anzugeben, falls keine part_category_id-Spalte ausgefüllt gegeben ist.
+
+
+
+ ]]>
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index b54131896..c97f06304 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -1925,6 +1925,12 @@
JSON για συναρμολόγηση
+
+
+ assembly.bom_import.type.csv
+ CSV για μια συναρμολόγηση
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -1949,6 +1955,12 @@
Πρότυπο εισαγωγής JSON για συναρμολόγηση
+
+
+ assembly.import_bom.template.header.csv
+ Πρότυπο CSV εισαγωγής για μια συναρμολόγηση
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -2001,7 +2013,7 @@
Πεδίο
Προϋπόθεση
-
Τύπος Δεδομένων
+
Τύπος δεδομένων
Περιγραφή
@@ -2010,22 +2022,24 @@
quantity
Υποχρεωτικό πεδίο
Αριθμός κινητής υποδιαστολής (Float)
-
Πρέπει να παρέχεται και να περιέχει τιμή κινητής υποδιαστολής (Float) μεγαλύτερη από 0.0.
+
Πρέπει να είναι συμπληρωμένος και να περιέχει μια αριθμητική τιμή (Float) μεγαλύτερη από 0.0.
name
Προαιρετικό
-
Κείμενο (String)
-
Εάν υπάρχει, πρέπει να είναι μη κενό κείμενο.
+
Χαρακτηριστική ακολουθία (String)
+
Αν υπάρχει, πρέπει να είναι μη κενό κείμενο. Το όνομα του είδους μέσα στη συλλογή.
part
Προαιρετικό
Αντικείμενο/Πίνακας
- Εάν παρέχεται, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+ Αν πρόκειται να ανατεθεί ένα εξάρτημα, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα παρακάτω πεδία πρέπει να έχει συμπληρωθεί:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -2034,38 +2048,38 @@
part.id
Προαιρετικό
Ακέραιος αριθμός (Integer)
-
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) του εξαρτήματος στη βάση δεδομένων.
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID του εξαρτήματος στη βάση δεδομένων.
-
part.name
+
part.mpnr
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.mpnr ή part.ipn.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το part.id, part.ipn ή part.name.
-
part.mpnr
+
part.ipn
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.name ή part.ipn.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το part.id, part.mpnr ή part.name.
-
part.ipn
+
part.name
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχονται οι ενδείξεις part.name ή part.mpnr.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το part.id, part.mpnr ή part.ipn.
part.description
Προαιρετικό
-
Κείμενο ή null
-
Εάν υπάρχει, πρέπει να είναι μη κενό κείμενο, ή null.
+
Χαρακτηριστική ακολουθία ή null
+
Αν υπάρχει, πρέπει να είναι μη κενό κείμενο ή null. Υπερισχύει της υπάρχουσας τιμής στο εξάρτημα.
part.manufacturer
Προαιρετικό
Αντικείμενο/Πίνακας
- Εάν υπάρχει, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+ Αν ο κατασκευαστής ενός εξαρτήματος χρειάζεται να αλλάξει ή να αναζητηθεί μονοσήμαντα μέσω της τιμής part.mpnr, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα παρακάτω πεδία να είναι συμπληρωμένα:
manufacturer.id
manufacturer.name
@@ -2076,20 +2090,20 @@
manufacturer.id
Προαιρετικό
Ακέραιος αριθμός (Integer)
-
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) του κατασκευαστή.
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID του κατασκευαστή.
manufacturer.name
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχεται η ένδειξη manufacturer.id.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το manufacturer.id.
part.category
Προαιρετικό
Αντικείμενο/Πίνακας
- Εάν υπάρχει, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα πεδία του να είναι συμπληρωμένο:
+ Αν χρειάζεται να τροποποιηθεί η κατηγορία του εξαρτήματος, πρέπει να είναι αντικείμενο/πίνακας και τουλάχιστον ένα από τα παρακάτω πεδία να είναι συμπληρωμένα:
category.id
category.name
@@ -2100,13 +2114,138 @@
category.id
Προαιρετικό
Ακέραιος αριθμός (Integer)
-
Ακέραιος (Integer) > 0. Αντιστοιχεί στην εσωτερική αριθμητική ταυτότητα (ID) της κατηγορίας του εξαρτήματος.
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID της κατηγορίας εξαρτήματος.
category.name
Προαιρετικό
-
Κείμενο (String)
-
Μη κενό κείμενο, εάν δεν παρέχεται η ένδειξη category.id.
+
Χαρακτηριστική ακολουθία (String)
+
Μη κενό κείμενο, αν δεν έχει συμπληρωθεί το category.id.
Πρέπει να είναι συμπληρωμένος και να περιέχει μια αριθμητική τιμή (Float) μεγαλύτερη από 0.0.
+
+
+
name
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Το όνομα του είδους μέσα στη συλλογή.
+
+
+
Στήλες που ξεκινούν με part_
+
+ Αν χρειάζεται να αποδοθεί εξάρτημα, πρέπει να συμπληρωθεί μία από τις παρακάτω στήλες:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID του εξαρτήματος στη βάση δεδομένων.
+
+
+
part_mpnr
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσουν οι part_id, part_ipn ή part_name.
+
+
+
part_ipn
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσουν οι part_id, part_mpnr ή part_name.
+
+
+
part_name
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσουν οι part_id, part_mpnr ή part_ipn.
+
+
+
part_description
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία
+
Θα μεταφερθεί και θα αντικαταστήσει την τιμή στο εξάρτημα, αν δοθεί μια μη κενή ακολουθία.
+
+
+
Στήλες που ξεκινούν με part_manufacturer_
+
+ Αν ο κατασκευαστής του εξαρτήματος πρέπει να αλλάξει ή να αναζητηθεί μονοσήμαντα μέσω της part_mpnr, πρέπει να συμπληρωθεί μία από τις παρακάτω στήλες:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID του κατασκευαστή.
+
+
+
part_manufacturer_name
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσει το πεδίο part_manufacturer_id.
+
+
+
Στήλες που ξεκινούν με part.category_
+
+ Αν η κατηγορία του εξαρτήματος πρέπει να αλλάξει, πρέπει να συμπληρωθεί μία από τις παρακάτω στήλες:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Προαιρετικό
+
Ακέραιος αριθμός (Integer)
+
Ακέραιος αριθμός > 0. Αντιστοιχεί στο εσωτερικό αριθμητικό ID της κατηγορίας του εξαρτήματος.
+
+
+
part_category_name
+
Προαιρετικό
+
Χαρακτηριστική ακολουθία (String)
+
Πρέπει να συμπληρωθεί αν δεν γεμίσει το πεδίο part_category_id.
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 8ac704001..f8d762f2f 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -12987,7 +12987,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
assembly.edit.bom.import_bom
- Import BOM
+ Import part list
@@ -13191,7 +13191,7 @@ Please note, that you can not impersonate a disabled user. If you try you will g
assembly.import_bom
- Import BOM for project
+ Import part list for assembly
@@ -13239,7 +13239,13 @@ Please note, that you can not impersonate a disabled user. If you try you will g
assembly.bom_import.type.json
- JSON for one assembly
+ JSON for an assembly
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV for an assembly
@@ -13266,6 +13272,12 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Import template JSON format for one assembly
+
+
+ assembly.import_bom.template.header.csv
+ Import template CSV format for one assembly
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -13318,31 +13330,33 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Field
Condition
-
Data type
+
Data Type
Description
quantity
-
Required
-
Floating point (Float)
-
Must be provided and contains a floating-point value (Float) greater than 0.0.
+
Mandatory
+
Floating point number (Float)
+
Must be provided and contains a floating point value (Float), which is greater than 0.0.
name
Optional
String
-
If present, it must be a non-empty string.
+
If present, it must be a non-empty string. Name of the entry within the assembly.
part
Optional
Object/Array
- If provided, it must be an object/array and at least one of the fields must be filled:
+ If a part is to be associated, it must be an object/array with at least one of the following fields filled out:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -13351,38 +13365,38 @@ Please note, that you can not impersonate a disabled user. If you try you will g
part.id
Optional
Integer
-
Integer > 0. Matches the Part-DB internal numeric ID of the component.
+
Integer > 0. Corresponds to the part database internal numeric ID of the part.
-
part.name
+
part.mpnr
Optional
String
-
Non-empty string if no part.mpnr or part.ipn is provided.
+
Non-empty string, if no part.id, part.ipn, or part.name is provided.
-
part.mpnr
+
part.ipn
Optional
String
-
Non-empty string if no part.name or part.ipn is provided.
+
Non-empty string, if no part.id, part.mpnr, or part.name is provided.
-
part.ipn
+
part.name
Optional
String
-
Non-empty string if no part.name or part.mpnr is provided.
+
Non-empty string, if no part.id, part.mpnr, or part.ipn is provided.
part.description
Optional
String or null
-
If present, it must be a non-empty string or null.
+
If provided, it must be a non-empty string or null. It will be transferred to the part, overwriting its current value.
part.manufacturer
Optional
Object/Array
- If present, it must be an object/array and at least one of the fields must be filled:
+ If the manufacturer of a part is to be adjusted or the part is to be uniquely identified using the part.mpnr, it must be an object/array with at least one of the following fields filled out:
manufacturer.id
manufacturer.name
@@ -13393,20 +13407,20 @@ Please note, that you can not impersonate a disabled user. If you try you will g
manufacturer.id
Optional
Integer
-
Integer > 0. Matches the internal numeric ID of the manufacturer.
+
Integer > 0. Corresponds to the internal numeric ID of the manufacturer.
manufacturer.name
Optional
String
-
Non-empty string if no manufacturer.id is provided.
+
Non-empty string, if no manufacturer.id is provided.
part.category
Optional
Object/Array
- If present, it must be an object/array and at least one of the fields must be filled:
+ If the category of a part is to be adjusted, it must be an object/array with at least one of the following fields filled out:
category.id
category.name
@@ -13417,13 +13431,138 @@ Please note, that you can not impersonate a disabled user. If you try you will g
category.id
Optional
Integer
-
Integer > 0. Matches the internal numeric ID of the component's category.
+
Integer > 0. Corresponds to the internal numeric ID of the part category.
Must be provided and contains a floating point value (Float), which is greater than 0.0.
+
+
+
name
+
Optional
+
String
+
Name of the entry within the assembly.
+
+
+
Columns starting with part_
+
+ If a part is to be associated, one of the following columns must be provided and filled out:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the part database internal numeric ID of the part.
+
+
+
part_mpnr
+
Optional
+
String
+
Must be provided if no part_id, part_ipn, or part_name column is filled out.
+
+
+
part_ipn
+
Optional
+
String
+
Must be provided if no part_id, part_mpnr, or part_name column is filled out.
+
+
+
part_name
+
Optional
+
String
+
Must be provided if no part_id, part_mpnr, or part_ipn column is filled out.
+
+
+
part_description
+
Optional
+
String
+
Will be transferred to the part, overwriting its current value if a non-empty string is provided.
+
+
+
Columns starting with part_manufacturer_
+
+ If the manufacturer of a part is to be adjusted or the part is to be uniquely identified using the part_mpnr, one of the following columns must be provided and filled out:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the manufacturer.
+
+
+
part_manufacturer_name
+
Optional
+
String
+
Must be provided if no part_manufacturer_id column is filled out.
+
+
+
Columns starting with part.category_
+
+ If the category of a part is to be adjusted, one of the following columns must be provided and filled out:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the part category.
+
+
+
part_category_name
+
Optional
+
String
+
Must be provided if no part_category_id column is filled out.
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index 7315f3760..1ee1188e4 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -12758,6 +12758,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
JSON para un ensamblaje
+
+
+ assembly.bom_import.type.csv
+ CSV para un ensamblaje
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -12782,6 +12788,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Plantilla de importación JSON para un ensamblaje
+
+
+ assembly.import_bom.template.header.csv
+ Plantilla de importación CSV para un ensamblaje
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -12834,31 +12846,33 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Campo
Condición
-
Tipo de dato
+
Tipo de datos
Descripción
quantity
-
Obligatorio
-
Número decimal (Float)
-
Debe estar presente y contener un valor decimal (Float) mayor que 0.0.
+
Campo obligatorio
+
Número de punto flotante (Float)
+
Debe completarse y contener un valor flotante (Float) mayor a 0.0.
name
Opcional
-
Cadena de texto (String)
-
Si está presente, debe ser una cadena de texto no vacía.
+
Cadena
+
Si se especifica, debe ser una cadena no vacía. El nombre del elemento dentro del conjunto.
part
Opcional
Objeto/Array
- Si se proporciona, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+ Si se debe asignar una pieza, debe ser un objeto/array, y al menos uno de los siguientes campos debe completarse:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -12867,38 +12881,38 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
part.id
Opcional
Entero (Integer)
-
Entero (Integer) > 0. Corresponde al ID numérico interno del componente en la base de datos.
+
Entero > 0. Corresponde al ID interno numérico de la pieza en la base de datos.
-
part.name
+
part.mpnr
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona part.mpnr o part.ipn.
+
Cadena
+
Cadena no vacía si no se rellenan los campos part.id, part.ipn o part.name.
-
part.mpnr
+
part.ipn
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona part.name o part.ipn.
+
Cadena
+
Cadena no vacía si no se rellenan los campos part.id, part.mpnr o part.name.
-
part.ipn
+
part.name
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona part.name o part.mpnr.
+
Cadena
+
Cadena no vacía si no se rellenan los campos part.id, part.mpnr o part.ipn.
part.description
Opcional
-
Cadena de texto (String) o null
-
Si está presente, debe ser una cadena de texto no vacía o null.
+
Cadena o null
+
Si se especifica, debe ser una cadena no vacía o null. Este valor sobrescribirá el existente en la pieza.
part.manufacturer
Opcional
Objeto/Array
- Si está presente, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+ Si se desea cambiar el fabricante de la pieza o buscarlo de forma única utilizando el valor part.mpnr, debe ser un objeto/array y al menos uno de los siguientes campos debe completarse:
manufacturer.id
manufacturer.name
@@ -12909,20 +12923,20 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
manufacturer.id
Opcional
Entero (Integer)
-
Entero (Integer) > 0. Corresponde al ID numérico interno del fabricante.
+
Entero > 0. Corresponde al ID interno numérico del fabricante.
manufacturer.name
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona manufacturer.id.
+
Cadena
+
Cadena no vacía si no se proporciona el campo manufacturer.id.
part.category
Opcional
Objeto/Array
- Si está presente, debe ser un objeto/array y al menos uno de los campos debe estar completado:
+ Si se desea cambiar la categoría de la pieza, debe ser un objeto/array y al menos uno de los siguientes campos debe completarse:
category.id
category.name
@@ -12933,13 +12947,138 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
category.id
Opcional
Entero (Integer)
-
Entero (Integer) > 0. Corresponde al ID numérico interno de la categoría del componente.
+
Entero > 0. Corresponde al ID interno numérico de la categoría de la pieza.
category.name
Opcional
-
Cadena de texto (String)
-
Cadena de texto no vacía, si no se proporciona category.id.
+
Cadena
+
Cadena no vacía si no se proporciona el campo category.id.
Debe completarse y contener un valor flotante (Float) mayor a 0.0.
+
+
+
name
+
Opcional
+
Cadena
+
El nombre del elemento dentro del conjunto.
+
+
+
Columnas que comienzan con part_
+
+ Si se debe asignar una pieza, al menos una de las siguientes columnas debe completarse:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opcional
+
Entero (Integer)
+
Entero > 0. Corresponde al ID interno numérico de la pieza en la base de datos.
+
+
+
part_mpnr
+
Opcional
+
Cadena
+
Debe completarse si no se han rellenado las columnas part_id, part_ipn o part_name.
+
+
+
part_ipn
+
Opcional
+
Cadena
+
Debe completarse si no se han rellenado las columnas part_id, part_mpnr o part_name.
+
+
+
part_name
+
Opcional
+
Cadena
+
Debe completarse si no se han rellenado las columnas part_id, part_mpnr o part_ipn.
+
+
+
part_description
+
Opcional
+
Cadena
+
Se transferirá y reemplazará el valor de la descripción de la pieza si se proporciona una cadena no vacía.
+
+
+
Columnas que comienzan con part_manufacturer_
+
+ Si el fabricante de la pieza debe cambiarse o buscarse exclusivamente mediante part_mpnr, al menos una de las siguientes columnas debe completarse:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opcional
+
Entero (Integer)
+
Entero > 0. Corresponde al ID interno numérico del fabricante.
+
+
+
part_manufacturer_name
+
Opcional
+
Cadena
+
Debe completarse si no se ha proporcionado el campo part_manufacturer_id.
+
+
+
Columnas que comienzan con part.category_
+
+ Si se necesita modificar la categoría de la pieza, al menos una de las siguientes columnas debe completarse:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Opcional
+
Entero (Integer)
+
Entero > 0. Corresponde al ID interno numérico de la categoría de la pieza.
+
+
+
part_category_name
+
Opcional
+
Cadena
+
Debe completarse si no se ha proporcionado el campo part_category_id.
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 320121909..9cd293219 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -9487,6 +9487,12 @@ exemple de villeJSON pour un assemblage
+
+
+ assembly.bom_import.type.csv
+ CSV pour un assemblage
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -9511,6 +9517,12 @@ exemple de ville
Modèle d’importation JSON pour un assemblage
+
+
+ assembly.import_bom.template.header.csv
+ Modèle d'importation CSV pour un assemblage
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -9570,24 +9582,26 @@ exemple de ville
quantity
-
Obligatoire
-
Nombre décimal (Float)
-
Doit être présent et contenir une valeur décimale (Float) supérieure à 0,0.
+
Champ obligatoire
+
Nombre à virgule flottante (Float)
+
Doit être rempli et contenir une valeur décimale (Float) supérieure à 0.0.
name
Optionnel
-
Chaîne (String)
-
Si présent, doit être une chaîne non vide.
+
Chaîne
+
Si renseigné, doit être une chaîne non vide. Le nom de l'élément dans l'assemblage.
part
Optionnel
Objet/Tableau
- Si fourni, doit être un objet/un tableau et au moins un des champs doit être rempli :
+ Si une pièce doit être assignée, cela doit être un objet/tableau et au moins un des champs suivants doit être renseigné :
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -9596,38 +9610,38 @@ exemple de ville
part.id
Optionnel
Entier (Integer)
-
Entier (Integer) > 0. Correspond à l'ID numérique interne dans Part-DB du composant.
+
Nombre entier > 0. Correspond à l'ID interne numérique de la pièce dans la base de données.
-
part.name
+
part.mpnr
Optionnel
-
Chaîne (String)
-
Chaîne non vide si part.mpnr ou part.ipn ne sont pas fournis.
+
Chaîne
+
Chaîne non vide si part.id, part.ipn ou part.name ne sont pas renseignés.
-
part.mpnr
+
part.ipn
Optionnel
-
Chaîne (String)
-
Chaîne non vide si part.name ou part.ipn ne sont pas fournis.
+
Chaîne
+
Chaîne non vide si part.id, part.mpnr ou part.name ne sont pas renseignés.
-
part.ipn
+
part.name
Optionnel
-
Chaîne (String)
-
Chaîne non vide si part.name ou part.mpnr ne sont pas fournis.
+
Chaîne
+
Chaîne non vide si part.id, part.mpnr ou part.ipn ne sont pas renseignés.
part.description
Optionnel
Chaîne ou null
-
Si présent, doit être une chaîne non vide ou null.
+
Si renseignée, doit être une chaîne non vide ou null. Ce champ remplacera la valeur existante de la pièce.
part.manufacturer
Optionnel
Objet/Tableau
- Si présent, doit être un objet/un tableau et au moins un des champs doit être rempli :
+ Si le fabricant de la pièce doit être modifié ou recherché de manière unique à l'aide de la valeur part.mpnr, cela doit être un objet/tableau et au moins un des champs suivants doit être renseigné :
manufacturer.id
manufacturer.name
@@ -9638,20 +9652,20 @@ exemple de ville
manufacturer.id
Optionnel
Entier (Integer)
-
Entier (Integer) > 0. Correspond à l'ID numérique interne du fabricant.
+
Nombre entier > 0. Correspond à l'ID interne numérique du fabricant.
manufacturer.name
Optionnel
-
Chaîne (String)
-
Chaîne non vide si manufacturer.id n'est pas fourni.
+
Chaîne
+
Chaîne non vide si manufacturer.id n'est pas renseigné.
part.category
Optionnel
Objet/Tableau
- Si présent, doit être un objet/un tableau et au moins un des champs doit être rempli :
+ Si la catégorie de la pièce doit être modifiée, cela doit être un objet/tableau et au moins un des champs suivants doit être renseigné :
category.id
category.name
@@ -9662,13 +9676,138 @@ exemple de ville
category.id
Optionnel
Entier (Integer)
-
Entier (Integer) > 0. Correspond à l'ID numérique interne de la catégorie du composant.
+
Nombre entier > 0. Correspond à l'ID interne numérique de la catégorie de la pièce.
category.name
Optionnel
-
Chaîne (String)
-
Chaîne non vide si category.id n'est pas fourni.
+
Chaîne
+
Chaîne non vide si category.id n'est pas renseigné.
Doit être rempli et contenir une valeur décimale (Float) supérieure à 0.0.
+
+
+
name
+
Optionnel
+
Chaîne
+
Le nom de l'élément dans l'assemblage.
+
+
+
Colonnes commençant par part_
+
+ Si une pièce doit être assignée, au moins une des colonnes suivantes doit être renseignée :
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optionnel
+
Entier (Integer)
+
Nombre entier > 0. Correspond à l'ID interne numérique de la pièce dans la base de données.
+
+
+
part_mpnr
+
Optionnel
+
Chaîne
+
Doit être renseignée si les colonnes part_id, part_ipn ou part_name ne sont pas remplies.
+
+
+
part_ipn
+
Optionnel
+
Chaîne
+
Doit être renseignée si les colonnes part_id, part_mpnr ou part_name ne sont pas remplies.
+
+
+
part_name
+
Optionnel
+
Chaîne
+
Doit être renseignée si les colonnes part_id, part_mpnr ou part_ipn ne sont pas remplies.
+
+
+
part_description
+
Optionnel
+
Chaîne
+
Sera transférée et remplacera la valeur existante de la description si une chaîne non vide est fournie.
+
+
+
Colonnes commençant par part_manufacturer_
+
+ Si le fabricant de la pièce doit être modifié ou recherché uniquement via part_mpnr, au moins une des colonnes suivantes doit être renseignée :
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optionnel
+
Entier (Integer)
+
Nombre entier > 0. Correspond à l'ID interne numérique du fabricant.
+
+
+
part_manufacturer_name
+
Optionnel
+
Chaîne
+
Doit être renseignée si part_manufacturer_id n'est pas fourni.
+
+
+
Colonnes commençant par part.category_
+
+ Si la catégorie de la pièce doit être modifiée, au moins une des colonnes suivantes doit être renseignée :
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Optionnel
+
Entier (Integer)
+
Nombre entier > 0. Correspond à l'ID interne numérique de la catégorie de la pièce.
+
+
+
part_category_name
+
Optionnel
+
Chaîne
+
Doit être renseignée si part_category_id n'est pas fourni.
@@ -9679,75 +9818,75 @@ exemple de villeassembly.bom_import.template.kicad_pcbnew.exptected_columns
- Colonnes attendues :
+ Colonnes attendues:assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
- Remarque : Aucun mappage n'est effectué avec des composants spécifiques issus de la gestion des catégories.
- ]]>
+ Remarque: Aucun mappage n'est effectué avec des composants spécifiques issus de la gestion des catégories.
+ ]]>
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Champ
-
Condition
-
Type de Données
-
Description
-
-
-
-
-
Id
-
Optionnel
-
Entier
-
Champ libre. Un numéro d'identification unique pour chaque composant.
-
-
-
Designator
-
Optionnel
-
Chaîne
-
Champ libre. Une désignation de référence unique pour le composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé comme le nom de l'emplacement de l'entrée composant dans l'assemblage.
-
-
-
Package
-
Optionnel
-
Chaîne
-
Champ libre. Le boîtier ou le format du composant, par exemple, "0805" pour les résistances CMS. Non inclus dans l'entrée composant pour l'assemblage.
-
-
-
Quantity
-
Obligatoire
-
Entier
-
Le nombre de composants identiques nécessaires pour créer une instance de l'assemblage. Utilisé comme la quantité dans l'entrée composant de l'assemblage.
-
-
-
Designation
-
Obligatoire
-
Chaîne
-
La description ou la fonction du composant, par exemple, valeur de résistance "10kΩ" ou valeur de condensateur "100nF". Utilisé comme le nom dans l'entrée composant pour l'assemblage.
-
-
-
Supplier and ref
-
Optionnel
-
Chaîne
-
Champ libre. Peut contenir par exemple des informations spécifiques sur le fournisseur. Utilisé comme une note dans l'entrée composant pour l'assemblage.
Champ libre. Un numéro d'identification unique pour chaque composant.
+
+
+
Designator
+
Optionnel
+
Chaîne
+
Champ libre. Une désignation de référence unique pour le composant sur le PCB, par exemple, "R1" pour la résistance 1. Utilisé comme le nom de l'emplacement de l'entrée composant dans l'assemblage.
+
+
+
Package
+
Optionnel
+
Chaîne
+
Champ libre. Le boîtier ou le format du composant, par exemple, "0805" pour les résistances CMS. Non inclus dans l'entrée composant pour l'assemblage.
+
+
+
Quantity
+
Obligatoire
+
Entier
+
Le nombre de composants identiques nécessaires pour créer une instance de l'assemblage. Utilisé comme la quantité dans l'entrée composant de l'assemblage.
+
+
+
Designation
+
Obligatoire
+
Chaîne
+
La description ou la fonction du composant, par exemple, valeur de résistance "10kΩ" ou valeur de condensateur "100nF". Utilisé comme le nom dans l'entrée composant pour l'assemblage.
+
+
+
Supplier and ref
+
Optionnel
+
Chaîne
+
Champ libre. Peut contenir par exemple des informations spécifiques sur le fournisseur. Utilisé comme une note dans l'entrée composant pour l'assemblage.
+
+
+
+ ]]>
+
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index f6e3c9446..8e39c0313 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -12736,6 +12736,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
JSON per un gruppo
+
+
+ assembly.bom_import.type.csv
+ CSV per un'assemblaggio
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -12760,6 +12766,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Template di importazione JSON per un gruppo
+
+
+ assembly.import_bom.template.header.csv
+ Modello di importazione CSV per un assemblaggio
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -12812,31 +12824,33 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Campo
Condizione
-
Tipo di dato
+
Tipo di dati
Descrizione
quantity
-
Obbligatorio
+
Campo obbligatorio
Numero decimale (Float)
-
Deve essere presente e contenere un valore decimale (Float) maggiore di 0,0.
+
Deve essere compilato e contenere un valore decimale (Float) maggiore di 0.0.
name
Opzionale
-
Stringa (String)
-
Se presente, deve essere una stringa non vuota.
+
Stringa
+
Se specificato, deve essere una stringa non vuota. Il nome del componente all'interno dell'assemblaggio.
part
Opzionale
Oggetto/Array
- Se fornito, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+ Se è necessario assegnare una parte, deve essere un Oggetto/Array e almeno uno dei seguenti campi deve essere compilato:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -12844,39 +12858,39 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
part.id
Opzionale
-
Intero (Integer)
-
Intero (Integer) > 0. Corrisponde all'ID numerico interno di Part-DB per il componente.
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico del componente nel database.
-
part.name
+
part.mpnr
Opzionale
-
Stringa (String)
-
Stringa non vuota se part.mpnr o part.ipn non sono forniti.
+
Stringa
+
Stringa non vuota se i campi part.id, part.ipn o part.name non sono compilati.
-
part.mpnr
+
part.ipn
Opzionale
-
Stringa (String)
-
Stringa non vuota se part.name o part.ipn non sono forniti.
+
Stringa
+
Stringa non vuota se i campi part.id, part.mpnr o part.name non sono compilati.
-
part.ipn
+
part.name
Opzionale
-
Stringa (String)
-
Stringa non vuota se part.name o part.mpnr non sono forniti.
+
Stringa
+
Stringa non vuota se i campi part.id, part.mpnr o part.ipn non sono compilati.
part.description
Opzionale
Stringa o null
-
Se presente, deve essere una stringa non vuota o null.
+
Se specificato, deve essere una stringa non vuota o null. Questo valore sovrascriverà quello esistente nella parte.
part.manufacturer
Opzionale
Oggetto/Array
- Se presente, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+ Se il produttore della parte deve essere cambiato o ricercato esclusivamente utilizzando il valore part.mpnr, deve essere un Oggetto/Array e almeno uno dei seguenti campi deve essere compilato:
manufacturer.id
manufacturer.name
@@ -12886,21 +12900,21 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
manufacturer.id
Opzionale
-
Intero (Integer)
-
Intero (Integer) > 0. Corrisponde all'ID numerico interno del produttore.
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico del produttore.
manufacturer.name
Opzionale
-
Stringa (String)
-
Stringa non vuota se manufacturer.id non è fornito.
+
Stringa
+
Stringa non vuota se il campo manufacturer.id non è compilato.
part.category
Opzionale
Oggetto/Array
- Se presente, deve essere un oggetto/un array e almeno uno dei campi deve essere compilato:
+ Se è necessario modificare la categoria della parte, deve essere un Oggetto/Array e almeno uno dei seguenti campi deve essere compilato:
category.id
category.name
@@ -12910,14 +12924,139 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
category.id
Opzionale
-
Intero (Integer)
-
Intero (Integer) > 0. Corrisponde all'ID numerico interno della categoria del componente.
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico della categoria della parte.
category.name
Opzionale
-
Stringa (String)
-
Stringa non vuota se category.id non è fornito.
+
Stringa
+
Stringa non vuota se il campo category.id non è compilato.
Deve essere compilato e contenere un valore decimale (Float) maggiore di 0.0.
+
+
+
name
+
Opzionale
+
Stringa
+
Il nome dell'elemento all'interno dell'assemblaggio.
+
+
+
Colonne che iniziano con part_
+
+ Se è necessario assegnare una parte, almeno una delle colonne seguenti deve essere compilata:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opzionale
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico del componente nel database.
+
+
+
part_mpnr
+
Opzionale
+
Stringa
+
Deve essere compilato se le colonne part_id, part_ipn o part_name non sono compilate.
+
+
+
part_ipn
+
Opzionale
+
Stringa
+
Deve essere compilato se le colonne part_id, part_mpnr o part_name non sono compilate.
+
+
+
part_name
+
Opzionale
+
Stringa
+
Deve essere compilato se le colonne part_id, part_mpnr o part_ipn non sono compilate.
+
+
+
part_description
+
Opzionale
+
Stringa
+
Sarà trasferita e sostituirà il valore esistente della descrizione se viene fornita una stringa non vuota.
+
+
+
Colonne che iniziano con part_manufacturer_
+
+ Se il produttore del componente deve essere modificato o ricercato esclusivamente tramite part_mpnr, almeno una delle seguenti colonne deve essere compilata:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opzionale
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico del produttore.
+
+
+
part_manufacturer_name
+
Opzionale
+
Stringa
+
Deve essere compilata se il campo part_manufacturer_id non è fornito.
+
+
+
Colonne che iniziano con part_category_
+
+ Se è necessario modificare la categoria della parte, almeno una delle seguenti colonne deve essere compilata:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Opzionale
+
Numero intero
+
Numero intero > 0. Corrisponde all'ID interno numerico della categoria del componente.
+
+
+
part_category_name
+
Opzionale
+
Stringa
+
Deve essere compilata se il campo part_category_id non è fornito.
@@ -12942,61 +13081,61 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Campo
-
Condizione
-
Tipo di Dati
-
Descrizione
-
-
-
-
-
Id
-
Opzionale
-
Intero
-
Campo libero. Un numero identificativo univoco per ogni componente.
-
-
-
Designator
-
Opzionale
-
Stringa
-
Campo libero. Un riferimento univoco al componente su PCB, ad esempio "R1" per il resistore 1. Utilizzato come nome della posizione nella voce componenti all'interno dell'assemblaggio.
-
-
-
Package
-
Opzionale
-
Stringa
-
Campo libero. L'involucro o il fattore di forma del componente, ad esempio "0805" per i resistori SMD. Non incluso nelle informazioni del componente nell'assemblaggio.
-
-
-
Quantity
-
Obbligatorio
-
Intero
-
Il numero di componenti identici richiesti per creare un'istanza dell'assemblaggio. Utilizzato come quantità nella voce componenti dell'assemblaggio.
-
-
-
Designation
-
Obbligatorio
-
Stringa
-
Descrizione o funzione del componente, ad esempio valore resistore "10kΩ" o valore condensatore "100nF". Utilizzato come nome nella voce componenti dell'assemblaggio.
-
-
-
Supplier and ref
-
Opzionale
-
Stringa
-
Campo libero. Può contenere, ad esempio, informazioni specifiche del fornitore. Utilizzato come nota nelle informazioni del componente nell'assemblaggio.
Campo libero. Un numero identificativo univoco per ogni componente.
+
+
+
Designator
+
Opzionale
+
Stringa
+
Campo libero. Un riferimento univoco al componente su PCB, ad esempio "R1" per il resistore 1. Utilizzato come nome della posizione nella voce componenti all'interno dell'assemblaggio.
+
+
+
Package
+
Opzionale
+
Stringa
+
Campo libero. L'involucro o il fattore di forma del componente, ad esempio "0805" per i resistori SMD. Non incluso nelle informazioni del componente nell'assemblaggio.
+
+
+
Quantity
+
Obbligatorio
+
Intero
+
Il numero di componenti identici richiesti per creare un'istanza dell'assemblaggio. Utilizzato come quantità nella voce componenti dell'assemblaggio.
+
+
+
Designation
+
Obbligatorio
+
Stringa
+
Descrizione o funzione del componente, ad esempio valore resistore "10kΩ" o valore condensatore "100nF". Utilizzato come nome nella voce componenti dell'assemblaggio.
+
+
+
Supplier and ref
+
Opzionale
+
Stringa
+
Campo libero. Può contenere, ad esempio, informazioni specifiche del fornitore. Utilizzato come nota nelle informazioni del componente nell'assemblaggio.
+
+
+ ]]>
+
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index f98e9c784..7cca59753 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -1150,6 +1150,12 @@
JSON voor assemblage
+
+
+ assembly.bom_import.type.csv
+ CSV voor een assemblage
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -1174,6 +1180,12 @@
JSON-sjabloon voor assemblage
+
+
+ assembly.import_bom.template.header.csv
+ CSV-importsjabloon voor een assemblage
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -1235,22 +1247,24 @@
quantity
Verplicht veld
Kommagetal (Float)
-
Moet opgegeven zijn en bevat een kommagetal (Float) dat groter is dan 0,0.
+
Moet worden ingevuld en een kommagetal (Float) bevatten dat groter is dan 0,0.
name
Optioneel
-
String
-
Indien aanwezig, moet het een niet-lege string zijn.
+
Tekst
+
Wanneer ingevuld, moet het een niet-lege tekst zijn. De naam van het item binnen de assemblage.
part
Optioneel
Object/Array
- Indien opgegeven, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+ Als een onderdeel moet worden toegewezen, moet dit een object/array zijn en moet ten minste één van de volgende velden worden ingevuld:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -1258,39 +1272,39 @@
part.id
Optioneel
-
Geheel getal (Integer)
-
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van het onderdeel in de Part-DB.
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van het onderdeel in de database.
-
part.name
+
part.mpnr
Optioneel
-
String
-
Niet-lege string, indien geen part.mpnr- of part.ipn-vermelding is gegeven.
+
Tekst
+
Niet-lege tekst, wanneer part.id, part.ipn of part.name niet zijn ingevuld.
-
part.mpnr
+
part.ipn
Optioneel
-
String
-
Niet-lege string, indien geen part.name- of part.ipn-vermelding is gegeven.
+
Tekst
+
Niet-lege tekst wanneer part.id, part.mpnr of part.name niet zijn ingevuld.
-
part.ipn
+
part.name
Optioneel
-
String
-
Niet-lege string, indien geen part.name- of part.mpnr-vermelding is gegeven.
+
Tekst
+
Niet-lege tekst, wanneer part.id, part.mpnr of part.ipn niet zijn ingevuld.
part.description
Optioneel
-
String of null
-
Indien aanwezig, moet het een niet-lege string zijn of null.
+
Tekst of null
+
Indien ingevuld, moet het een niet-lege tekst of null zijn. Deze waarde vervangt de bestaande waarde in het onderdeel.
part.manufacturer
Optioneel
Object/Array
- Indien aanwezig, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+ Als de fabrikant van het onderdeel moet worden gewijzigd of uniek moet worden opgezocht met de waarde part.mpnr, moet dit een object/array zijn en moet ten minste één van de volgende velden worden ingevuld:
manufacturer.id
manufacturer.name
@@ -1300,21 +1314,21 @@
manufacturer.id
Optioneel
-
Geheel getal (Integer)
-
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van de fabrikant.
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van de fabrikant.
manufacturer.name
Optioneel
-
String
-
Niet-lege string, indien geen manufacturer.id-vermelding is gegeven.
+
Tekst
+
Niet-lege tekst als manufacturer.id niet is ingevuld.
part.category
Optioneel
Object/Array
- Indien aanwezig, moet het een object/array zijn en ten minste één van de velden ingevuld zijn:
+ Als de categorie van het onderdeel moet worden gewijzigd, moet dit een object/array zijn en moet ten minste één van de volgende velden worden ingevuld:
category.id
category.name
@@ -1324,14 +1338,139 @@
category.id
Optioneel
-
Geheel getal (Integer)
-
Geheel getal (Integer) > 0. Komt overeen met de interne numerieke ID van de categorie van het onderdeel.
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van de categorie van het onderdeel.
category.name
Optioneel
-
String
-
Niet-lege string, indien geen category.id-vermelding is gegeven.
Moet worden ingevuld en moet een kommagetal (Float) bevatten dat groter is dan 0,0.
+
+
+
name
+
Optioneel
+
Tekst
+
De naam van het item binnen de assemblage.
+
+
+
Kolommen die beginnen met part_
+
+ Als een onderdeel moet worden toegewezen, moet ten minste één van de volgende kolommen worden ingevuld:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optioneel
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van het onderdeel in de database.
+
+
+
part_mpnr
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_id, part_ipn of part_name niet zijn ingevuld.
+
+
+
part_ipn
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_id, part_mpnr of part_name niet zijn ingevuld.
+
+
+
part_name
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_id, part_mpnr of part_ipn niet zijn ingevuld.
+
+
+
part_description
+
Optioneel
+
Tekst
+
Wordt overgenomen en vervangt de bestaande waarde van de beschrijving als er een niet-lege tekst wordt opgegeven.
+
+
+
Kolommen die beginnen met part_manufacturer_
+
+ Als de fabrikant van een onderdeel moet worden gewijzigd of uniek moet worden gezocht via part_mpnr, moet ten minste één van de volgende kolommen worden ingevuld:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optioneel
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van de fabrikant.
+
+
+
part_manufacturer_name
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_manufacturer_id niet wordt opgegeven.
+
+
+
Kolommen die beginnen met part_category_
+
+ Als de categorie van een onderdeel moet worden gewijzigd, moet ten minste één van de volgende kolommen worden ingevuld:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Optioneel
+
Hele getal
+
Een geheel getal > 0. Komt overeen met de interne numerieke ID van de categorie van het onderdeel.
+
+
+
part_category_name
+
Optioneel
+
Tekst
+
Moet worden ingevuld als part_category_id niet wordt opgegeven.
@@ -1346,71 +1485,71 @@
-
- assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
-
- Opmerking: Er wordt geen mapping uitgevoerd met specifieke componenten uit de categoriebeheer.
- ]]>
-
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Opmerking: Er wordt geen mapping uitgevoerd met specifieke componenten uit de categoriebeheer.
+ ]]>
+
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Veld
-
Voorwaarde
-
Gegevenstype
-
Beschrijving
-
-
-
-
-
Id
-
Optioneel
-
Integer
-
Vrij veld. Een unieke identificatienummer voor elk onderdeel.
-
-
-
Designator
-
Optioneel
-
String
-
Vrij veld. Een unieke referentienaam voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Wordt gebruikt als positioneringsnaam in de onderdelenlijst van de assemblage.
-
-
-
Package
-
Optioneel
-
String
-
Vrij veld. De behuizing of vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden. Wordt niet opgenomen in de onderdelenlijst binnen de assemblage.
-
-
-
Quantity
-
Vereist
-
Integer
-
Het aantal identieke onderdelen dat nodig is om een assemblage-instantie te creëren. Wordt gebruikt als hoeveelheid in de onderdelenlijst binnen de assemblage.
-
-
-
Designation
-
Vereist
-
String
-
De beschrijving of functie van het onderdeel, zoals weerstandwaarde "10kΩ" of condensatorwaarde "100nF". Wordt gebruikt als de naam in de onderdelenlijst binnen de assemblage.
-
-
-
Supplier and ref
-
Optioneel
-
String
-
Vrij veld. Kan bijvoorbeeld specifieke informatie over leveranciers bevatten. Wordt gebruikt als notitie in de onderdelenlijst binnen de assemblage.
Vrij veld. Een unieke identificatienummer voor elk onderdeel.
+
+
+
Designator
+
Optioneel
+
String
+
Vrij veld. Een unieke referentienaam voor het onderdeel op de PCB, bijvoorbeeld "R1" voor weerstand 1. Wordt gebruikt als positioneringsnaam in de onderdelenlijst van de assemblage.
+
+
+
Package
+
Optioneel
+
String
+
Vrij veld. De behuizing of vormfactor van het onderdeel, bijvoorbeeld "0805" voor SMD-weerstanden. Wordt niet opgenomen in de onderdelenlijst binnen de assemblage.
+
+
+
Quantity
+
Vereist
+
Integer
+
Het aantal identieke onderdelen dat nodig is om een assemblage-instantie te creëren. Wordt gebruikt als hoeveelheid in de onderdelenlijst binnen de assemblage.
+
+
+
Designation
+
Vereist
+
String
+
De beschrijving of functie van het onderdeel, zoals weerstandwaarde "10kΩ" of condensatorwaarde "100nF". Wordt gebruikt als de naam in de onderdelenlijst binnen de assemblage.
+
+
+
Supplier and ref
+
Optioneel
+
String
+
Vrij veld. Kan bijvoorbeeld specifieke informatie over leveranciers bevatten. Wordt gebruikt als notitie in de onderdelenlijst binnen de assemblage.
+
+
+
+ ]]>
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index d1a095072..86894d998 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -12613,6 +12613,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
JSON dla zespołu
+
+
+ assembly.bom_import.type.csv
+ CSV dla zestawienia
+
+ assembly.bom_import.type.kicad_pcbnew
@@ -12637,6 +12643,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Szablon importu JSON dla zespołu
+
+
+ assembly.import_bom.template.header.csv
+ Szablon importu CSV dla zespołu
+
+ assembly.import_bom.template.header.kicad_pcbnew
@@ -12696,24 +12708,26 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
quantity
-
Wymagane
-
Typ zmiennoprzecinkowy (Float)
-
Musi być obecne i zawierać wartość zmiennoprzecinkową (Float) większą niż 0,0.
+
Pole obowiązkowe
+
Liczba zmiennoprzecinkowa (Float)
+
Musi być wypełnione i zawierać liczbę zmiennoprzecinkową (Float) większą niż 0,0.
name
Opcjonalne
-
Ciąg znaków (String)
-
Jeśli obecne, musi być niepustym ciągiem znaków.
+
Tekst
+
Jeśli określono, musi to być niepusty tekst. Nazwa elementu w ramach montażu.
part
Opcjonalne
Obiekt/Tablica
- Jeśli podane, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+ Jeśli konieczne jest przypisanie części, musi to być Obiekt/Tablica, a przynajmniej jedno z poniższych pól powinno być wypełnione:
part.id
+
part.mpnr
+
part.ipn
part.name
@@ -12721,39 +12735,39 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
part.id
Opcjonalne
-
Liczba całkowita (Integer)
-
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu numerowi ID komponentu w Part-DB.
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID części w bazie danych.
-
part.name
+
part.mpnr
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli part.mpnr ani part.ipn nie są podane.
+
Tekst
+
Niepusty tekst, jeśli pola part.id, part.ipn lub part.name nie są wypełnione.
-
part.mpnr
+
part.ipn
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli part.name ani part.ipn nie są podane.
+
Tekst
+
Niepusty tekst, jeśli pola part.id, part.mpnr lub part.name nie są wypełnione.
-
part.ipn
+
part.name
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli part.name ani part.mpnr nie są podane.
+
Tekst
+
Niepusty tekst, jeśli pola part.id, part.mpnr lub part.ipn nie są wypełnione.
part.description
Opcjonalne
-
Ciąg znaków lub null
-
Jeśli obecne, musi być niepustym ciągiem znaków lub null.
+
Tekst lub null
+
Jeśli określono, musi to być niepusty tekst lub null. Ta wartość nadpisze istniejącą wartość w części.
part.manufacturer
Opcjonalne
Obiekt/Tablica
- Jeśli obecne, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+ Jeśli producent części ma zostać zmieniony lub wyszukany unikalnie za pomocą wartości part.mpnr, musi to być Obiekt/Tablica i przynajmniej jedno z poniższych pól powinno być wypełnione:
manufacturer.id
manufacturer.name
@@ -12763,21 +12777,21 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
manufacturer.id
Opcjonalne
-
Liczba całkowita (Integer)
-
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu identyfikatorowi numerowemu producenta.
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID producenta.
manufacturer.name
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli manufacturer.id nie jest podane.
+
Tekst
+
Niepusty tekst, jeśli pole manufacturer.id nie jest wypełnione.
part.category
Opcjonalne
Obiekt/Tablica
- Jeśli obecne, musi być obiektem/tablicą i co najmniej jedno z poniższych pól musi być wypełnione:
+ Jeśli konieczna jest zmiana kategorii części, musi to być Obiekt/Tablica i przynajmniej jedno z poniższych pól powinno być wypełnione:
category.id
category.name
@@ -12787,14 +12801,139 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
category.id
Opcjonalne
-
Liczba całkowita (Integer)
-
Liczba całkowita (Integer) > 0. Odpowiada wewnętrznemu numerowi ID kategorii komponentu.
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID kategorii części.
category.name
Opcjonalne
-
Ciąg znaków (String)
-
Niepusty ciąg znaków, jeśli category.id nie jest podane.
+
Tekst
+
Niepusty tekst, jeśli pole category.id nie jest wypełnione.
Musi być wypełnione i zawierać liczbę zmiennoprzecinkową (Float) większą niż 0,0.
+
+
+
name
+
Opcjonalne
+
Tekst
+
Nazwa elementu w ramach montażu.
+
+
+
Kolumny zaczynające się od part_
+
+ Jeśli konieczne jest przypisanie części, przynajmniej jedna z poniższych kolumn powinna być wypełniona:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opcjonalne
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID części w bazie danych.
+
+
+
part_mpnr
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, gdy kolumny part_id, part_ipn lub part_name nie są wypełnione.
+
+
+
part_ipn
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, gdy kolumny part_id, part_mpnr lub part_name nie są wypełnione.
+
+
+
part_name
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, gdy kolumny part_id, part_mpnr lub part_ipn nie są wypełnione.
+
+
+
part_description
+
Opcjonalne
+
Tekst
+
Zostanie przeniesione i zastąpi istniejącą wartość opisu, jeśli określono niepusty tekst.
+
+
+
Kolumny zaczynające się od part_manufacturer_
+
+ Jeśli producent części musi zostać zmieniony lub wyszukany unikalnie za pomocą part_mpnr, przynajmniej jedna z poniższych kolumn powinna być wypełniona:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opcjonalne
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID producenta.
+
+
+
part_manufacturer_name
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, jeśli part_manufacturer_id nie jest określony.
+
+
+
Kolumny zaczynające się od part_category_
+
+ Jeśli konieczna jest zmiana kategorii części, przynajmniej jedna z poniższych kolumn powinna być wypełniona:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Opcjonalne
+
Liczba całkowita
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID kategorii części.
+
+
+
part_category_name
+
Opcjonalne
+
Tekst
+
Musi być wypełnione, jeśli part_category_id nie jest określone.
@@ -12809,71 +12948,71 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
-
- assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
-
- Uwaga: Nie wykonano mapowania z określonymi komponentami z zarządzania kategoriami.
- ]]>
-
-
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Uwaga: Nie wykonano mapowania z określonymi komponentami z zarządzania kategoriami.
+ ]]>
+
+
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Pole
-
Warunek
-
Typ Danych
-
Opis
-
-
-
-
-
Id
-
Opcjonalne
-
Liczba całkowita
-
Pole dowolne. Unikalny numer identyfikacyjny dla każdego komponentu.
-
-
-
Designator
-
Opcjonalne
-
Tekst
-
Pole dowolne. Jednoznaczny znacznik referencyjny komponentu na PCB, np. "R1" dla rezystora 1. Używane jako nazwa pozycji w pozycji komponentu w montażu.
-
-
-
Package
-
Opcjonalne
-
Tekst
-
Pole dowolne. Obudowa lub forma komponentu, np. "0805" dla rezystorów SMD. Niewykorzystywane w pozycji komponentu w montażu.
-
-
-
Quantity
-
Wymagane
-
Liczba całkowita
-
Liczba identycznych komponentów potrzebna do utworzenia jednej instancji montażu. Używane jako ilość w pozycji komponentu w montażu.
-
-
-
Designation
-
Wymagane
-
Tekst
-
Opis lub funkcja komponentu, np. wartość rezystora "10kΩ" lub wartość kondensatora "100nF". Używane jako nazwa w pozycji komponentu w montażu.
-
-
-
Supplier and ref
-
Opcjonalne
-
Tekst
-
Pole dowolne. Może zawierać np. specyficzne informacje o dostawcy. Używane jako notatka w pozycji komponentu w montażu.
Pole dowolne. Unikalny numer identyfikacyjny dla każdego komponentu.
+
+
+
Designator
+
Opcjonalne
+
Tekst
+
Pole dowolne. Jednoznaczny znacznik referencyjny komponentu na PCB, np. "R1" dla rezystora 1. Używane jako nazwa pozycji w pozycji komponentu w montażu.
+
+
+
Package
+
Opcjonalne
+
Tekst
+
Pole dowolne. Obudowa lub forma komponentu, np. "0805" dla rezystorów SMD. Niewykorzystywane w pozycji komponentu w montażu.
+
+
+
Quantity
+
Wymagane
+
Liczba całkowita
+
Liczba identycznych komponentów potrzebna do utworzenia jednej instancji montażu. Używane jako ilość w pozycji komponentu w montażu.
+
+
+
Designation
+
Wymagane
+
Tekst
+
Opis lub funkcja komponentu, np. wartość rezystora "10kΩ" lub wartość kondensatora "100nF". Używane jako nazwa w pozycji komponentu w montażu.
+
+
+
Supplier and ref
+
Opcjonalne
+
Tekst
+
Pole dowolne. Może zawierać np. specyficzne informacje o dostawcy. Używane jako notatka w pozycji komponentu w montażu.
Поле должно быть заполнено и содержать дробное значение (Float), большее 0,0.
+
Обязательное поле
+
Число с плавающей точкой (Float)
+
Должно быть заполнено и содержать число с плавающей точкой (Float) больше 0,0.
name
-
Опциональное
-
Строка (String)
-
Если присутствует, должно быть непустой строкой.
+
Необязательное
+
Строка
+
Если указано, должно быть непустой строкой. Имя элемента внутри сборки.
part
-
Опциональное
+
Необязательное
Объект/Массив
- Если указано, должно быть объектом/массивом, и хотя бы одно из следующих полей должно быть заполнено:
+ Если необходимо назначить деталь, это должен быть объект/массив, и должно быть заполнено хотя бы одно из следующих полей:
part.id
+
part.mpnr
+
part.ipn
part.name
part.id
-
Опциональное
-
Целое число (Integer)
-
Целое число (Integer) > 0. Соответствует внутреннему цифровому идентификатору компонента в Part-DB.
-
-
-
part.name
-
Опциональное
-
Строка (String)
-
Непустая строка, если part.mpnr или part.ipn не указаны.
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому идентификатору детали в базе данных.
part.mpnr
-
Опциональное
-
Строка (String)
-
Непустая строка, если part.name или part.ipn не указаны.
+
Необязательное
+
Строка
+
Непустая строка, если part.id, part.ipn или part.name не указаны.
part.ipn
-
Опциональное
-
Строка (String)
-
Непустая строка, если part.name или part.mpnr не указаны.
+
Необязательное
+
Строка
+
Непустая строка, если part.id, part.mpnr или part.name не указаны.
+
+
+
part.name
+
Необязательное
+
Строка
+
Непустая строка, если part.id, part.mpnr или part.ipn не указаны.
part.description
-
Опциональное
+
Необязательное
Строка или null
-
Если присутствует, должно быть непустой строкой или null.
+
Если указано, должно быть непустой строкой или null. Это значение перезаписывает существующее значение в детали.
part.manufacturer
-
Опциональное
+
Необязательное
Объект/Массив
- Если присутствует, должно быть объектом/массивом, и хотя бы одно из следующих полей должно быть заполнено:
+ Если необходимо изменить производителя детали или уникально найти по значению part.mpnr, это должен быть объект/массив, и должно быть заполнено хотя бы одно из следующих полей:
manufacturer.id
manufacturer.name
@@ -12862,22 +12876,22 @@
manufacturer.id
-
Опциональное
-
Целое число (Integer)
-
Целое число (Integer) > 0. Соответствует внутреннему идентификатору производителя.
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому идентификатору производителя.
manufacturer.name
-
Опциональное
-
Строка (String)
+
Необязательное
+
Строка
Непустая строка, если manufacturer.id не указано.
part.category
-
Опциональное
+
Необязательное
Объект/Массив
- Если присутствует, должно быть объектом/массивом, и хотя бы одно из следующих полей должно быть заполнено:
+ Если необходимо изменить категорию детали, это должен быть объект/массив, и должно быть заполнено хотя бы одно из следующих полей:
category.id
category.name
@@ -12886,14 +12900,14 @@
category.id
-
Опциональное
-
Целое число (Integer)
-
Целое число (Integer) > 0. Соответствует внутреннему цифровому идентификатору категории компонента.
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому идентификатору категории детали.
Должно быть заполнено и содержать число с плавающей точкой (Float), больше 0,0.
+
+
+
name
+
Необязательное
+
Строка
+
Название элемента в рамках сборки.
+
+
+
Столбцы, начинающиеся с part_
+
+ Если необходимо назначить деталь, то хотя бы один из следующих столбцов должен быть заполнен:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому ID детали в базе данных.
+
+
+
part_mpnr
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_id, part_ipn или part_name не указаны.
+
+
+
part_ipn
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_id, part_mpnr или part_name не указаны.
+
+
+
part_name
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_id, part_mpnr или part_ipn не указаны.
+
+
+
part_description
+
Необязательное
+
Строка
+
Если указано, заменяет существующее значение описания деталя не пустой строкой.
+
+
+
Столбцы, начинающиеся с part_manufacturer_
+
+ Если необходимо указать производителя детали или найти деталь уникально по part_mpnr, должно быть заполнено хотя бы одно из следующих полей:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому ID производителя.
+
+
+
part_manufacturer_name
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_manufacturer_id не указано.
+
+
+
Столбцы, начинающиеся с part_category_
+
+ Если необходимо изменить категорию детали, должно быть заполнено хотя бы одно из следующих полей:
+
+
part_category_id
+
part_category_name
+
+
+
+
+
part_category_id
+
Необязательное
+
Целое число
+
Целое число > 0. Соответствует внутреннему числовому ID категории детали.
+
+
+
part_category_name
+
Необязательное
+
Строка
+
Должно быть заполнено, если part_category_id не указано.
+
+
+
+ ]]>
+
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns
@@ -12909,71 +13048,71 @@
-
- assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
-
- Примечание: Сопоставление с конкретными компонентами из управления категориями не выполняется.
- ]]>
-
-
+
+ assembly.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Примечание: Сопоставление с конкретными компонентами из управления категориями не выполняется.
+ ]]>
+
+
-
- assembly.bom_import.template.kicad_pcbnew.table
-
-
-
-
-
Поле
-
Условие
-
Тип данных
-
Описание
-
-
-
-
-
Id
-
Опционально
-
Целое
-
Свободное поле. Уникальный идентификационный номер для каждого компонента.
-
-
-
Package
-
Designator
-
Строка
-
Свободное поле. Уникальная ссылочная метка компонента на печатной плате, например, "R1" для резистора 1. Используется как наименование позиции в компоненте сборки.
-
-
-
Package
-
Опционально
-
Строка
-
Свободное поле. Тип корпуса или форм-фактор компонента, например, "0805" для SMD-резисторов. Не включается в информацию о компоненте сборки.
-
-
-
Quantity
-
Обязательно
-
Целое
-
Количество одинаковых компонентов, необходимых для создания одной версии сборки. Используется как количество в информации о компоненте сборки.
-
-
-
Designation
-
Обязательно
-
Строка
-
Описание или функция компонента, например, значение резистора "10kΩ" или значение конденсатора "100nF". Используется как наименование в информации о компоненте сборки.
-
-
-
Supplier and ref
-
Опционально
-
Строка
-
Свободное поле. Может содержать, например, информацию о конкретных поставщиках. Используется как примечание в информации о компоненте сборки.
Свободное поле. Уникальный идентификационный номер для каждого компонента.
+
+
+
Package
+
Designator
+
Строка
+
Свободное поле. Уникальная ссылочная метка компонента на печатной плате, например, "R1" для резистора 1. Используется как наименование позиции в компоненте сборки.
+
+
+
Package
+
Опционально
+
Строка
+
Свободное поле. Тип корпуса или форм-фактор компонента, например, "0805" для SMD-резисторов. Не включается в информацию о компоненте сборки.
+
+
+
Quantity
+
Обязательно
+
Целое
+
Количество одинаковых компонентов, необходимых для создания одной версии сборки. Используется как количество в информации о компоненте сборки.
+
+
+
Designation
+
Обязательно
+
Строка
+
Описание или функция компонента, например, значение резистора "10kΩ" или значение конденсатора "100nF". Используется как наименование в информации о компоненте сборки.
+
+
+
Supplier and ref
+
Опционально
+
Строка
+
Свободное поле. Может содержать, например, информацию о конкретных поставщиках. Используется как примечание в информации о компоненте сборки.
+ {{ form_widget(form.part) }}
{{ form_errors(form.part) }}
-
- {% if form.vars.value is not null and form.vars.value.project is not null %}
- {% set hasAssembly = false %}
- {% if is_granted("@assemblies.read") or has_assembly(form.vars.value.project.bomEntries.toArray) %}
-
+ {{ form_row(form.part) }}
{{ form_errors(form.part) }}
+
+ {% if form.vars.value is not null and form.vars.value.assembly is not null %}
+ {% if is_granted("@projects.read") or has_project(form.vars.value.assembly.bomEntries.toArray) %}
+
{% set lots = build_request.partLotsForBOMEntry(bom_entry) %}
- {% set assemblyBomEntriesWithoutPart = build_request.assemblyBomEntriesWithoutPart(bom_entry) %}
- {% set assemblyBomEntriesWithPartNoStock = build_request.assemblyBomEntriesWithPartNoStock(bom_entry) %}
{% if lots is not null %}
- {% set previousLabel = null %}
-
{% for lot in lots %}
{# @var lot \App\Entity\Parts\PartLot #}
-
- {% set label = '' %}
- {% if form["lot_"~lot.id].vars.label is defined and form["lot_"~lot.id].vars.label is not empty %}
- {% set label = form["lot_"~lot.id].vars.label %}
- {% endif %}
-
- {% if label != '' and (previousLabel is null or label != previousLabel) %}
-
{% endfor %}
{% endif %}
- {% if assemblyBomEntriesWithoutPart is not null %}
- {% for bomEntryWithoutPart in assemblyBomEntriesWithoutPart %}
-
-
-
-
- / {% trans %}project.builds.no_stock{% endtrans %}
-
-
- {% endfor %}
- {% endif %}
- {% if assemblyBomEntriesWithPartNoStock is not null %}
- {% for bomEntryWithPartNoStock in assemblyBomEntriesWithPartNoStock %}
-
-
-
-
-
- / {% trans %}project.builds.no_stock{% endtrans %}
-
{% endblock %}
\ No newline at end of file
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index c4021c2c5..1acfef098 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -11046,6 +11046,18 @@ Element 3
Typ
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11064,6 +11076,319 @@ Element 3
Výběrem této možnosti odstraníte všechny existující položky BOM v projektu a přepíšete je importovaným souborem BOM!
+
+
+ project.import_bom.template.header.json
+ Šablona importu JSON
+
+
+
+
+ project.import_bom.template.header.csv
+ Šablona importu CSV
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ Šablona importu CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Název komponenty v projektu
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Jedinečné číslo produktu u výrobce
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ Jedinečné IPN součásti
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Jedinečný název součásti
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Jedinečný název výrobce
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Pole
+
Podmínka
+
Datový typ
+
Popis
+
+
+
+
+
quantity
+
Povinné
+
Desetinné číslo (Float)
+
Musí být zadáno a obsahovat desetinnou hodnotu (Float), která je větší než 0.0.
+
+
+
name
+
Volitelné
+
Řetězec (String)
+
Pokud je přítomen, musí být neprázdný řetězec. Název položky v kusovníku.
+
+
+
part
+
Volitelné
+
Objekt/Array
+
+ Pokud je potřeba přiřadit součástku, musí to být objekt/pole a musí být vyplněno alespoň jedno z následujících polí:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID součástky v Part-DB.
+
+
+
part.mpnr
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno part.id, part.ipn nebo part.name.
+
+
+
part.ipn
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno part.id, part.mpnr nebo part.name.
+
+
+
part.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno part.id, part.mpnr nebo part.ipn.
+
+
+
part.manufacturer
+
Volitelné
+
Objekt/Array
+
+ Pokud má být upraven výrobce součástky nebo pokud má být součástka nalezena jednoznačně na základě part.mpnr, musí to být objekt/pole a musí být vyplněno alespoň jedno z následujících polí:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID výrobce.
+
+
+
manufacturer.name
+
Volitelné
+
Řetězec (String)
+
Neprázdný řetězec, pokud není uvedeno manufacturer.id.
Musí být uvedeno a obsahovat hodnotu desetinného čísla (Float) větší než 0.0.
+
+
+
name
+
Optional
+
String
+
Název položky v kusovníku.
+
+
+
Sloupce začínající part_
+
+ Pokud má být přiřazena součástka, musí být uveden a vyplněn alespoň jeden z následujících sloupců:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID součástky v Part-DB.
+
+
+
part_mpnr
+
Volitelné
+
Řetězec (String)
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_ipn nebo part_name.
+
+
+
part_ipn
+
Volitelné
+
Řetězec (String)
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_mpnr nebo part_name.
+
+
+
part_name
+
Volitelné
+
Řetězec (String)
+
Musí být uvedeno, pokud nejsou vyplněny sloupce part_id, part_mpnr nebo part_ipn.
+
+
+
Sloupce začínající part_manufacturer_
+
+ Pokud má být upraven výrobce dílu nebo má být díl jednoznačně identifikován podle hodnoty part_mpnr, musí být uveden a vyplněn alespoň jeden z následujících sloupců:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Volitelné
+
Celé číslo (Integer)
+
Celé číslo (Integer) > 0. Odpovídá internímu číselnému ID výrobce.
+
+
+
part_manufacturer_name
+
Volitelné
+
Řetězec (String)
+
Musí být uvedeno, pokud není vyplněn sloupec part_manufacturer_id.
Volný údaj. Jedinečné identifikační číslo pro každou součástku.
+
+
+
Designator
+
Volitelné
+
Řetězec (String)
+
Volný údaj. Jedinečný referenční označovač součástky na desce plošných spojů, např. „R1“ pro odpor 1. Je převzat do osazovacího názvu záznamu součástky.
+
+
+
Package
+
Volitelné
+
Řetězec (String)
+
Volný údaj. Pouzdro nebo tvar součástky, např. „0805“ pro SMD odpory. Pro záznam součástky není převzato.
+
+
+
Quantity
+
Povinné pole
+
Celé číslo (Integer)
+
Počet identických komponent, které jsou potřebné k vytvoření instance. Je převzat jako počet položky komponenty.
+
+
+
Designation
+
Povinné pole
+
Řetězec (String)
+
Popis nebo funkce součástky, např. hodnota odporu „10kΩ“ nebo kapacita kondenzátoru „100nF“. Je převzato do názvu záznamu součástky.
+
+
+
Supplier and ref
+
Volitelné
+
Řetězec (String)
+
Volný údaj. Může obsahovat např. distribuční specifickou hodnotu. Je převzato jako poznámka ke záznamu součástky.
Skal være angivet og skal indeholde en decimaltalsværdi (Float), der er større end 0.0.
+
+
+
name
+
Valgfrit
+
String
+
Hvis til stede, skal det være en ikke-tom streng. Navnet på posten i stykliste.
+
+
+
part
+
Valgfrit
+
Objekt/Array
+
+ Hvis en komponent skal knyttes, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Valgfrit
+
Heltal (Integer)
+
Heltal (Integer) > 0. Svarer til det interne numeriske ID for komponenten i Part-DB.
+
+
+
part.mpnr
+
Valgfrit
+
String
+
En ikke-tom streng, hvis hverken part.id, part.ipn eller part.name er angivet.
+
+
+
part.ipn
+
Valgfrit
+
String
+
En ikke-tom streng, hvis hverken part.id, part.mpnr eller part.name er angivet.
+
+
+
part.name
+
Valgfrit
+
String
+
En ikke-tom streng, hvis hverken part.id, part.mpnr eller part.ipn er angivet.
+
+
+
part.manufacturer
+
Valgfrit
+
Objekt/Array
+
+ Hvis en komponents producent skal justeres, eller hvis komponenten skal findes entydigt via part.mpnr, skal det være et objekt/array, og mindst ét af felterne skal udfyldes:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Valgfrit
+
Heltal (Integer)
+
Heltal (Integer) > 0. Svarer til producentens interne numeriske ID.
+
+
+
manufacturer.name
+
Valgfrit
+
String
+
En ikke-tom streng, hvis manufacturer.id ikke er angivet.
Skal være angivet og indeholde en decimaltalsværdi (Float), som er større end 0,0.
+
+
+
name
+
Optional
+
String
+
Hvis tilgængelig, skal det være en ikke-tom streng. Navnet på elementet inden for stykliste.
+
+
+
Kolonner, der begynder med part_
+
+ Hvis en komponent skal tildeles, skal mindst én af følgende kolonner være angivet og udfyldt:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Valgfri
+
Heltal (Integer)
+
Heltal (Integer) > 0. Svarer til den interne numeriske ID for komponenten i Part-DB.
+
+
+
part_mpnr
+
Valgfri
+
Streng (String)
+
Skal angives, hvis kolonnerne part_id, part_ipn eller part_name ikke er udfyldt.
+
+
+
part_ipn
+
Valgfri
+
Streng (String)
+
Skal angives, hvis kolonnerne part_id, part_mpnr eller part_name ikke er udfyldt.
+
+
+
part_name
+
Valgfri
+
Streng (String)
+
Skal angives, hvis kolonnerne part_id, part_mpnr eller part_ipn ikke er udfyldt.
+
+
+
Kolonner, der begynder med part_manufacturer_
+
+ Hvis komponentens producent skal ændres eller identificeres entydigt baseret på part_mpnr, skal mindst én af følgende kolonner være angivet og udfyldt:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Valgfri
+
Heltal (Integer)
+
Heltal (Integer) > 0. Svarer til den interne numeriske ID for producenten.
+
+
+
part_manufacturer_name
+
Valgfri
+
Streng (String)
+
Skal angives, hvis kolonnen part_manufacturer_id ikke er udfyldt.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Forventede kolonner:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Bemærk: Der sker ingen tilknytning til specifikke komponenter fra kategoristyringen.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Felt
+
Betingelse
+
Datatype
+
Beskrivelse
+
+
+
+
+
Id
+
Valgfrit
+
Heltal (Integer)
+
Fri opgave. Et entydigt identifikationsnummer for hver komponent.
+
+
+
Designator
+
Valgfrit
+
Streng (String)
+
Fri opgave. En entydig referencemarkering for komponenten på PCB'et, fx "R1" for modstand 1. Bliver overført til monteringsnavnet på komponentindgangen.
+
+
+
Package
+
Valgfrit
+
Streng (String)
+
Fri opgave. Komponentens pakning eller form, fx "0805" for SMD-modstande. Bliver ikke overført til komponentindgangen.
+
+
+
Quantity
+
Obligatorisk felt
+
Heltal (Integer)
+
Antallet af identiske komponenter, der kræves for at oprette en instans. Overtages som antallet af komponentposter.
+
+
+
Designation
+
Obligatorisk felt
+
Streng (String)
+
Beskrivelse eller funktion af komponenten, fx modstandsværdi "10kΩ" eller kondensatorværdi "100nF". Bliver overført til komponentindgangens navn.
+
+
+
Supplier and ref
+
Valgfrit
+
Streng (String)
+
Fri opgave. Kan eksempelvis indeholde en distributørspecifik værdi. Bliver overført som en note til komponentindgangen.
+
+
+
+ ]]>
+
+
+ project.bom_import.clear_existing_bom.help
@@ -12777,13 +13102,13 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
-
+ assembly.bom_import.template.csv.exptected_columnsMulige kolonner:
-
+ assembly.bom_import.template.csv.table
@@ -12808,7 +13133,7 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
name
Valgfrit
Streng
-
Navnet på posten inden for samlingen.
+
Navnet på posten inden for stykliste.
Kolonner, der starter med part_
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index c25fd7e77..a7137b26a 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -11060,6 +11060,18 @@ Element 1 -> Element 1.2
Typ
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11078,6 +11090,319 @@ Element 1 -> Element 1.2
Wenn diese Option ausgewählt ist, werden alle bereits im Projekt existierenden BOM Einträge gelöscht und mit den importierten BOM Daten überschrieben.
+
+
+ project.import_bom.template.header.json
+ Import-Vorlage JSON
+
+
+
+
+ project.import_bom.template.header.csv
+ Import-Vorlage CSV
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ Import-Vorlage CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Name des Bauteils im Projekt
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Eindeutige Produktnummer innerhalb des Herstellers
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ Eideutige IPN des Bauteils
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Eindeutiger Name des Bauteils
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Eindeutiger Name des Herstellers
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
quantity
+
Pflichtfeld
+
Gleitkommazahl (Float)
+
Muss gegeben sein und enthält einen Gleitkommawert (Float), der größer als 0.0 ist.
+
+
+
name
+
Optional
+
String
+
Falls vorhanden, muss es ein nicht-leerer String sein. Name des Eintrags innerhalb der Stückliste.
+
+
+
part
+
Optional
+
Objekt/Array
+
+ Falls ein Bauteil zugeordnet werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
+
+
+
part.mpnr
+
Optional
+
String
+
Nicht-leerer String, falls keine part.id-, part-ipn- bzw. part.name-Angabe gegeben ist.
+
+
+
part.ipn
+
Optional
+
String
+
Nicht-leerer String, falls keine part.id-, part.mpnr bzw. part.name-Angabe gegeben ist.
+
+
+
part.name
+
Optional
+
String
+
Nicht-leerer String, falls keine part.id-, part.mpnr- bzw. part.ipn-Angabe gegeben ist.
+
+
+
part.manufacturer
+
Optional
+
Objekt/Array
+
+ Falls der Hersteller eines Bauteils mit angepasst werden oder das Bauteil anhand der part.mpnr-Angabe eindeutig gesucht werden soll, muss es ein Objekt/Array und mindestens eines der Felder ausgefüllt sein:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID des Herstellers.
+
+
+
manufacturer.name
+
Optional
+
String
+
Nicht-leerer String, falls keine manufacturer.id-Angabe gegeben ist.
Muss gegeben sein und enthält einen Gleitkommawert (Float), der größer als 0.0 ist.
+
+
+
name
+
Optional
+
String
+
Name des Eintrags innerhalb der Stückliste.
+
+
+
Spalten beginnend mit part_
+
+ Falls ein Bauteil zugeordnet werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der Part-DB internen numerischen ID des Bauteils.
+
+
+
part_mpnr
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_ipn- bzw. part_name-Spalte ausgefüllt gegeben ist.
+
+
+
part_ipn
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_mpnr- bzw. part_name-Spalte ausgefüllt gegeben ist.
+
+
+
part_name
+
Optional
+
String
+
Anzugeben, falls keine part_id-, part_mpnr- bzw. part_ipn-Spalte ausgefüllt gegeben ist.
+
+
+
Spalten beginnend mit part_manufacturer_
+
+ Falls der Hersteller eines Bauteils mit angepasst werden oder das Bauteil anhand der part_mpnr-Angabe eindeutig gesucht werden soll, muss eine der folgenden Spalten gegeben und ausgefüllt sein:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optional
+
Ganzzahl (Integer)
+
Ganzzahl (Integer) > 0. Entspricht der internen numerischen ID des Herstellers.
+
+
+
part_manufacturer_name
+
Optional
+
String
+
Anzugeben, falls keine part_manufacturer_id-Spalte ausgefüllt gegeben ist.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Erwartete Spalten:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Hinweis: Es findet keine Zuordnung zu konkreten Bauteilen aus der Kategorie-Verwaltung statt.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Feld
+
Bedingung
+
Datentyp
+
Beschreibung
+
+
+
+
+
Id
+
Optional
+
Ganzzahl (Integer)
+
Offene Angabe. Eine eindeutige Identifikationsnummer für jedes Bauteil.
+
+
+
Designator
+
Optional
+
String
+
Offene Angabe. Ein eindeutiger Referenzbezeichner des Bauteils auf der Leiterplatte, z.B. „R1“ für Widerstand 1. Wird in den Bestückungsnamen des Bauteil-Eintrags übernommen.
+
+
+
Package
+
Optional
+
String
+
Offene Angabe. Das Gehäuse oder die Bauform des Bauteils, z.B. „0805“ für SMD-Widerstände. Wird für ein Bauteil-Eintrag nicht übernommen.
+
+
+
Quantity
+
Pflichtfeld
+
Ganzzahl (Integer)
+
Anzahl der identischen Bauteile, die benötigt werden, um eine Instanz zu erstellen. Wird als Anzahl des Bauteil-Eintrags übernommen.
+
+
+
Designation
+
Pflichtfeld
+
String
+
Beschreibung oder Funktion des Bauteils, z.B. Widerstandswert „10kΩ“ oder Kondensatorwert „100nF“. Wird in den Namen des Bauteil-Eintrags übernommen.
+
+
+
Supplier and ref
+
Optional
+
String
+
Offene Angabe. Kann z.B. Distributor spezifischen Wert enthalten. Wird als Notiz zum Bauteil-Eintrag übernommen.
+
+
+
+ ]]>
+
+
+ project.bom_import.flash.invalid_file
@@ -13332,7 +13657,7 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
name
Optional
String
-
Falls vorhanden, muss es ein nicht-leerer String sein. Name des Eintrags innerhalb der Baugruppe.
+
Falls vorhanden, muss es ein nicht-leerer String sein. Name des Eintrags innerhalb der Stückliste.
part
@@ -13432,13 +13757,13 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
-
+ assembly.bom_import.template.csv.exptected_columnsMögliche Spalten:
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index a6dda3d47..3707e55dd 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -2116,13 +2116,13 @@
-
+ assembly.bom_import.template.csv.exptected_columnsΔυνατές στήλες:
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 763b6aff0..29c44ae44 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -11061,6 +11061,18 @@ Element 1 -> Element 1.2Type
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11073,6 +11085,319 @@ Element 1 -> Element 1.2
Clear existing BOM entries before importing
+
+
+ project.import_bom.template.header.json
+ JSON Import Template
+
+
+
+
+ project.import_bom.template.header.csv
+ CSV Import Template
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ CSV Import Template (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Component name in the project
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Unique product number within the manufacturer
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ Unique IPN of the component
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Unique name of the component
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Unique name of the manufacturer
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Field
+
Condition
+
Data Type
+
Description
+
+
+
+
+
quantity
+
Required
+
Decimal (Float)
+
Must be provided and contains a decimal value (Float) greater than 0.0.
+
+
+
name
+
Optional
+
String
+
If present, it must be a non-empty string. The name of the entry within the bill of materials.
+
+
+
part
+
Optional
+
Object/Array
+
+ If a component is to be assigned, it must be an object/array, and at least one of the following fields must be filled in:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the component in the Part-DB.
+
+
+
part.mpnr
+
Optional
+
String
+
A non-empty string if no part.id, part.ipn, or part.name is provided.
+
+
+
part.ipn
+
Optional
+
String
+
A non-empty string if no part.id, part.mpnr, or part.name is provided.
+
+
+
part.name
+
Optional
+
String
+
A non-empty string if no part.id, part.mpnr, or part.ipn is provided.
+
+
+
part.manufacturer
+
Optional
+
Object/Array
+
+ If a component's manufacturer is to be adjusted, or the component is to be unambiguously identified based on part.mpnr, it must be an object/array, and at least one of the following fields must be filled in:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the manufacturer.
+
+
+
manufacturer.name
+
Optional
+
String
+
A non-empty string if no manufacturer.id is provided.
Must be provided and contain a floating-point value (Float) greater than 0.0.
+
+
+
name
+
Optional
+
String
+
If available, it must be a non-empty string. The name of the entry within the bill of materials.
+
+
+
Columns starting with part_
+
+ If a component is to be assigned, at least one of the following columns must be provided and filled in:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the component in the Part-DB.
+
+
+
part_mpnr
+
Optional
+
String
+
Must be provided if the part_id, part_ipn, or part_name columns are not filled in.
+
+
+
part_ipn
+
Optional
+
String
+
Must be provided if the part_id, part_mpnr, or part_name columns are not filled in.
+
+
+
part_name
+
Optional
+
String
+
Must be provided if the part_id, part_mpnr, or part_ipn columns are not filled in.
+
+
+
Columns starting with part_manufacturer_
+
+ If the manufacturer of a component is to be adjusted or if the component is to be uniquely identified based on the part_mpnr, at least one of the following columns must be provided and filled in:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Optional
+
Integer
+
Integer > 0. Corresponds to the internal numeric ID of the manufacturer.
+
+
+
part_manufacturer_name
+
Optional
+
String
+
Must be provided if the part_manufacturer_id column is not filled in.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Expected columns:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Note: No assignment to specific components from the category management is performed.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Field
+
Condition
+
Data type
+
Description
+
+
+
+
+
Id
+
Optional
+
Integer
+
Free entry. A unique identification number for each component.
+
+
+
Designator
+
Optional
+
String
+
Free entry. A unique reference identifier of the component on the PCB, e.g., "R1" for resistor 1. It is adopted into the assembly name of the component entry.
+
+
+
Package
+
Optional
+
String
+
Free entry. The housing or package type of the component, e.g., "0805" for SMD resistors. It is not adopted into the component entry.
+
+
+
Quantity
+
Mandatory
+
Integer
+
The number of identical components required to create an instance. It is adopted as the quantity of the entry.
+
+
+
Designation
+
Mandatory
+
String
+
Description or function of the component, e.g., resistor value "10kΩ" or capacitor value "100nF". It is adopted into the name of the component entry.
+
+
+
Supplier and ref
+
Optional
+
String
+
Free entry. Can contain a distributor-specific value, for example. It is adopted as a note to the component entry.
+
+
+
+ ]]>
+
+
+ project.bom_import.clear_existing_bom.help
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index 0ff8df3f2..56bcf2a52 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -11076,6 +11076,18 @@ Elemento 3
Tipo
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11088,6 +11100,319 @@ Elemento 3
Eliminar entradas BOM existentes antes de importar
+
+
+ project.import_bom.template.header.json
+ Plantilla de importación JSON
+
+
+
+
+ project.import_bom.template.header.csv
+ Plantilla de importación CSV
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ Plantilla de importación CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Nombre del componente en el proyecto
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Número de producto único del fabricante
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ IPN único del componente
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Nombre único del componente
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Nombre único del fabricante
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Campo
+
Condición
+
Tipo de Datos
+
Descripción
+
+
+
+
+
quantity
+
Requerido
+
Decimal (Float)
+
Debe ser proporcionado y contener un valor decimal (Float) mayor que 0.0.
+
+
+
name
+
Opcional
+
Cadena (String)
+
Si está presente, debe ser una cadena no vacía. El nombre del elemento dentro de la lista de materiales.
+
+
+
part
+
Opcional
+
Objeto/Array
+
+ Si se debe asignar un componente, debe ser un objeto/array, y al menos uno de los siguientes campos debe estar cumplimentado:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno del componente en la base de datos de componentes (Part-DB).
+
+
+
part.mpnr
+
Opcional
+
Cadena (String)
+
Una cadena no vacía si no se proporciona part.id, part.ipn o part.name.
+
+
+
part.ipn
+
Opcional
+
Cadena (String)
+
Una cadena no vacía si no se proporciona part.id, part.mpnr o part.name.
+
+
+
part.name
+
Opcional
+
Cadena (String)
+
Una cadena no vacía si no se proporciona part.id, part.mpnr o part.ipn.
+
+
+
part.manufacturer
+
Opcional
+
Objeto/Array
+
+ Si se debe ajustar el fabricante de un componente, o si el componente debe identificarse de manera unívoca en base a part.mpnr, debe ser un objeto/array, y al menos uno de los siguientes campos debe estar cumplimentado:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opcional
+
Entero (Integer)
+
Entero (Integer) > 0. Corresponde al ID numérico interno del fabricante.
+
+
+
manufacturer.name
+
Opcional
+
Cadena (String)
+
Una cadena no vacía si no se proporciona manufacturer.id.
Debe proporcionarse y contener un valor decimal (Float) mayor que 0.0.
+
+
+
name
+
Optional
+
String
+
Si está disponible, debe ser una cadena no vacía. El nombre del elemento dentro de la lista de materiales.
+
+
+
Columnas que comienzan con part_
+
+ Si se va a asignar un componente, al menos una de las siguientes columnas debe proporcionarse y completarse:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opcional
+
Entero
+
Entero > 0. Corresponde al ID numérico interno del componente en la base de datos de partes (Part-DB).
+
+
+
part_mpnr
+
Opcional
+
Cadena (String)
+
Debe proporcionarse si las columnas part_id, part_ipn o part_name no están completas.
+
+
+
part_ipn
+
Opcional
+
Cadena (String)
+
Debe proporcionarse si las columnas part_id, part_mpnr o part_name no están completas.
+
+
+
part_name
+
Opcional
+
Cadena (String)
+
Debe proporcionarse si las columnas part_id, part_mpnr o part_ipn no están completas.
+
+
+
Columnas que comienzan con part_manufacturer_
+
+ Si el fabricante de un componente debe ajustarse o si el componente debe identificarse de forma única según el valor part_mpnr, al menos una de las siguientes columnas debe proporcionarse y completarse:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opcional
+
Entero
+
Entero > 0. Corresponde al ID numérico interno del fabricante.
+
+
+
part_manufacturer_name
+
Opcional
+
Cadena (String)
+
Debe proporcionarse si la columna part_manufacturer_id no está completa.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Columnas esperadas:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Nota: No se realiza ninguna asignación a componentes específicos desde la gestión de categorías.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Campo
+
Condición
+
Tipo de dato
+
Descripción
+
+
+
+
+
Id
+
Opcional
+
Entero
+
Entrada libre. Un número de identificación único para cada componente.
+
+
+
Designator
+
Opcional
+
Cadena (String)
+
Entrada libre. Un identificador de referencia único del componente en el PCB, por ejemplo, "R1" para la resistencia 1. Se adopta en el nombre de ensamblaje del registro del componente.
+
+
+
Package
+
Opcional
+
Cadena (String)
+
Entrada libre. El encapsulado o tipo de la carcasa del componente, por ejemplo, "0805" para resistencias SMD. No se adopta en el registro del componente.
+
+
+
Quantity
+
Obligatorio
+
Entero
+
El número de componentes idénticos necesarios para crear una instancia. Se toma como la cantidad de la entrada del componente.
+
+
+
Designation
+
Obligatorio
+
Cadena (String)
+
Descripción o función del componente, por ejemplo, valor de resistencia "10kΩ" o valor de condensador "100nF". Se adopta en el nombre del registro del componente.
+
+
+
Supplier and ref
+
Opcional
+
Cadena (String)
+
Entrada libre. Puede contener, por ejemplo, un valor específico del distribuidor. Se adopta como una nota en el registro del componente.
+
+
+
+ ]]>
+
+
+ project.bom_import.clear_existing_bom.help
@@ -12949,13 +13274,13 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
-
+ assembly.bom_import.template.csv.exptected_columnsColumnas posibles:
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 234dee6ef..6d455221e 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -9481,6 +9481,18 @@ exemple de villeCSV pour un assemblage
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ assembly.bom_import.type.kicad_pcbnew
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index 57654f44e..1f56dfc93 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -11078,6 +11078,18 @@ Element 3
Tipo
+
+
+ assembly.bom_import.type.json
+ JSON
+
+
+
+
+ assembly.bom_import.type.csv
+ CSV
+
+ project.bom_import.type.kicad_pcbnew
@@ -11090,6 +11102,319 @@ Element 3
Cancellare le voci della BOM (lista dei materiali) esistenti prima dell'importazione
+
+
+ project.import_bom.template.header.json
+ Modello di importazione JSON
+
+
+
+
+ project.import_bom.template.header.csv
+ Modello di importazione CSV
+
+
+
+
+ project.import_bom.template.header.kicad_pcbnew
+ Modello di importazione CSV (KiCAD Pcbnew BOM)
+
+
+
+
+ project.bom_import.template.entry.name
+ Nome del componente nel progetto
+
+
+
+
+ project.bom_import.template.entry.part.mpnr
+ Codice prodotto unico del produttore
+
+
+
+
+ project.bom_import.template.entry.part.ipn
+ IPN unico del componente
+
+
+
+
+ project.bom_import.template.entry.part.name
+ Nome unico del componente
+
+
+
+
+ project.bom_import.template.entry.part.manufacturer.name
+ Nome unico del produttore
+
+
+
+
+ project.bom_import.template.json.table
+
+
+
+
+
Campo
+
Condizione
+
Tipo di Dati
+
Descrizione
+
+
+
+
+
quantity
+
Obbligatorio
+
Decimale (Float)
+
Deve essere fornito e contenere un valore decimale (Float) maggiore di 0.0.
+
+
+
name
+
Opzionale
+
Stringa (String)
+
Se presente, deve essere una stringa non vuota. Il nome dell'elemento all'interno della distinta materiali.
+
+
+
part
+
Opzionale
+
Oggetto/Array
+
+ Se un componente deve essere assegnato, deve essere un oggetto/array e almeno uno dei seguenti campi deve essere compilato:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno del componente nel database delle parti (Part-DB).
+
+
+
part.mpnr
+
Opzionale
+
Stringa (String)
+
Una stringa non vuota se non sono forniti part.id, part.ipn o part.name.
+
+
+
part.ipn
+
Opzionale
+
Stringa (String)
+
Una stringa non vuota se non sono forniti part.id, part.mpnr o part.name.
+
+
+
part.name
+
Opzionale
+
Stringa (String)
+
Una stringa non vuota se non sono forniti part.id, part.mpnr o part.ipn.
+
+
+
part.manufacturer
+
Opzionale
+
Oggetto/Array
+
+ Se il produttore di un componente deve essere modificato o se è necessario identificare univocamente il componente basandosi su part.mpnr, deve essere un oggetto/array e almeno uno dei seguenti campi deve essere compilato:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opzionale
+
Intero (Integer)
+
Intero (Integer) > 0. Corrisponde all'ID numerico interno del produttore.
+
+
+
manufacturer.name
+
Opzionale
+
Stringa (String)
+
Una stringa non vuota se non è fornito manufacturer.id.
Deve essere fornita e contenere un valore decimale (Float) maggiore di 0.0.
+
+
+
name
+
Optional
+
String
+
Se disponibile, deve essere una stringa non vuota. Il nome della voce all'interno della distinta base.
+
+
+
Colonne che iniziano con part_
+
+ Se un componente deve essere assegnato, almeno una delle seguenti colonne deve essere fornita e compilata:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opzionale
+
Intero (Integer)
+
Intero > 0. Corrisponde all'ID numerico interno del componente nel database delle parti (Part-DB).
+
+
+
part_mpnr
+
Opzionale
+
Stringa (String)
+
Deve essere fornita se le colonne part_id, part_ipn o part_name non sono compilate.
+
+
+
part_ipn
+
Opzionale
+
Stringa (String)
+
Deve essere fornita se le colonne part_id, part_mpnr o part_name non sono compilate.
+
+
+
part_name
+
Opzionale
+
Stringa (String)
+
Deve essere fornita se le colonne part_id, part_mpnr o part_ipn non sono compilate.
+
+
+
Colonne che iniziano con part_manufacturer_
+
+ Se il produttore di un componente deve essere modificato o il componente deve essere identificato univocamente in base al valore part_mpnr, almeno una delle seguenti colonne deve essere fornita e compilata:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opzionale
+
Intero (Integer)
+
Intero > 0. Corrisponde all'ID numerico interno del produttore.
+
+
+
part_manufacturer_name
+
Opzionale
+
Stringa (String)
+
Deve essere fornita se la colonna part_manufacturer_id non è compilata.
+
+
+
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns
+ Colonne previste:
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.exptected_columns.note
+
+ Nota: Non viene effettuata alcuna associazione con componenti specifici dalla gestione delle categorie.
+ ]]>
+
+
+
+
+
+ project.bom_import.template.kicad_pcbnew.table
+
+
+
+
+
Campo
+
Condizione
+
Tipo di dato
+
Descrizione
+
+
+
+
+
Id
+
Opzionale
+
Numero intero
+
Valore libero. Un numero identificativo univoco per ciascun componente.
+
+
+
Designator
+
Opzionale
+
Stringa
+
Valore libero. Un identificatore di riferimento univoco del componente sul PCB, ad esempio "R1" per il resistore 1. Viene trasferito nel nome di montaggio del record del componente.
+
+
+
Package
+
Opzionale
+
Stringa
+
Valore libero. L'involucro o la forma del componente, ad esempio "0805" per i resistori SMD. Non viene trasferito nel record del componente.
+
+
+
Quantity
+
Campo obbligatorio
+
Numero intero
+
Il numero dei componenti identici necessari per creare un'istanza. Registrato come il numero della voce del componente.
+
+
+
Designation
+
Campo obbligatorio
+
Stringa
+
Descrizione o funzione del componente, ad esempio valore del resistore "10kΩ" o valore del condensatore "100nF". Viene trasferita nel nome del record del componente.
+
+
+
Supplier and ref
+
Opzionale
+
Stringa
+
Valore libero. Può contenere ad esempio un valore specifico del distributore. Viene trasferito come nota nel record del componente.
Musi być podane i zawierać wartość dziesiętną (Float) większą niż 0.0.
+
+
+
name
+
Opcjonalne
+
Ciąg (String)
+
Jeśli jest obecny, musi być niepustym ciągiem znaków. Nazwa elementu w wykazie materiałów.
+
+
+
part
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli komponent musi być przypisany, musi być obiektem/tablą i co najmniej jedno z następujących pól musi zostać wypełnione:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Opcjonalne
+
Całkowity (Integer)
+
Całkowity (Integer) > 0. Odpowiada wewnętrznemu numerycznemu identyfikatorowi komponentu w bazie danych części (Part-DB).
+
+
+
part.mpnr
+
Opcjonalne
+
Ciag (String)
+
Niepusty ciąg, jeśli part.id, part.ipn ani part.name nie zostały podane.
+
+
+
part.ipn
+
Opcjonalne
+
Ciag (String)
+
Niepusty ciąg, jeśli part.id, part.mpnr ani part.name nie zostały podane.
+
+
+
part.name
+
Opcjonalne
+
Ciag (String)
+
Niepusty ciąg, jeśli part.id, part.mpnr ani part.ipn nie zostały podane.
+
+
+
part.manufacturer
+
Opcjonalne
+
Obiekt/Tablica
+
+ Jeśli producent komponentu musi zostać dostosowany lub komponent musi zostać jednoznacznie zidentyfikowany na podstawie part.mpnr, musi być obiektem/tablą, a co najmniej jedno z następujących pól musi zostać wypełnione:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Opcjonalne
+
Całkowity (Integer)
+
Całkowity (Integer) > 0. Odpowiada wewnętrznemu numerycznemu identyfikatorowi producenta.
+
+
+
manufacturer.name
+
Opcjonalne
+
Ciag (String)
+
Niepusty ciąg, jeśli manufacturer.id nie został podany.
Liczba identycznych komponentów potrzebnych do utworzenia instancji. Traktowane jako liczba wpisów komponentu.
+
+
+
name
+
Optional
+
String
+
Jeśli dostępny, musi być niepustym ciągiem znaków. Nazwa elementu w wykazie materiałów.
+
+
+
Kolumny zaczynające się od part_
+
+ Jeśli ma zostać przypisany komponent, co najmniej jedna z poniższych kolumn musi zostać podana i uzupełniona:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Opcjonalna
+
Liczba całkowita (Integer)
+
Liczba całkowita > 0. Odpowiada wewnętrznemu ID numerycznemu komponentu w Part-DB.
+
+
+
part_mpnr
+
Opcjonalna
+
Cišg znaków (String)
+
Musi być podana, jeśli kolumny part_id, part_ipn ani part_name nie są podane.
+
+
+
part_ipn
+
Opcjonalna
+
Cišg znaków (String)
+
Musi być podana, jeśli kolumny part_id, part_mpnr ani part_name nie są podane.
+
+
+
part_name
+
Opcjonalna
+
Cišg znaków (String)
+
Musi być podana, jeśli kolumny part_id, part_mpnr ani part_ipn nie są podane.
+
+
+
Kolumny zaczynające się od part_manufacturer_
+
+ Jeśli producent komponentu ma zostać zmieniony lub komponent ma zostać jednoznacznie zidentyfikowany na podstawie wartości part_mpnr, co najmniej jedna z poniższych kolumn musi zostać podana i uzupełniona:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Opcjonalna
+
Liczba całkowita (Integer)
+
Liczba całkowita > 0. Odpowiada wewnętrznemu numerycznemu ID producenta.
+
+
+
part_manufacturer_name
+
Opcjonalna
+
Cišg znaków (String)
+
Musi być podana, jeśli kolumna part_manufacturer_id nie jest uzupełniona.
Dowolna wartość. Unikalny numer identyfikacyjny dla każdego komponentu.
+
+
+
Designator
+
Opcjonalne
+
String
+
Dowolna wartość. Unikalny identyfikator referencyjny komponentu na płytce PCB, np. „R1” dla rezystora 1. Zostaje przeniesiony do nazwy montażowej wpisu komponentu.
+
+
+
Package
+
Opcjonalne
+
String
+
Dowolna wartość. Obudowa lub typ komponentu, np. „0805” dla rezystorów SMD. Nie zostaje przeniesiony do wpisu komponentu.
+
+
+
Quantity
+
Pole obowiązkowe
+
Liczba całkowita (Integer)
+
Liczba identycznych komponentów potrzebnych do stworzenia instancji zestawu. Zostaje przeniesiona jako ilość wpisu komponentu.
+
+
+
Designation
+
Pole obowiązkowe
+
String
+
Opis lub funkcja komponentu, np. wartość rezystora „10kΩ” lub wartość kondensatora „100nF”. Zostaje przeniesiony do nazwy wpisu komponentu.
+
+
+
Supplier and ref
+
Opcjonalne
+
String
+
Dowolna wartość. Może zawierać np. wartość specyficzną dla dystrybutora. Zostaje przeniesiona jako notatka do wpisu komponentu.
Должно быть указано и содержать дробное значение (Float), большее 0.0.
+
+
+
name
+
Опционально
+
Строка (String)
+
Если присутствует, должно быть непустой строкой. Название элемента в спецификации материалов.
+
+
+
part
+
Опционально
+
Объект/Массив
+
+ Если необходимо назначить компонент, он должен быть объектом/массивом, и должно быть заполнено хотя бы одно из следующих полей:
+
+
part.id
+
part.mpnr
+
part.ipn
+
part.name
+
+
+
+
+
part.id
+
Опционально
+
Целое число (Integer)
+
Целое число (Integer) > 0. Соответствует внутреннему числовому идентификатору компонента в базе данных компонентов (Part-DB).
+
+
+
part.mpnr
+
Опционально
+
Строка (String)
+
Непустая строка, если не указаны part.id, part.ipn или part.name.
+
+
+
part.ipn
+
Опционально
+
Строка (String)
+
Непустая строка, если не указаны part.id, part.mpnr или part.name.
+
+
+
part.name
+
Опционально
+
Строка (String)
+
Непустая строка, если не указаны part.id, part.mpnr или part.ipn.
+
+
+
part.manufacturer
+
Опционально
+
Объект/Массив
+
+ Если необходимо указать производителя компонента или однозначно идентифицировать компонент на основе part.mpnr, он должен быть объектом/массивом, и хотя бы одно из следующих полей должно быть заполнено:
+
+
manufacturer.id
+
manufacturer.name
+
+
+
+
+
manufacturer.id
+
Опционально
+
Целое число (Integer)
+
Целое число (Integer) > 0. Соответствует внутреннему числовому идентификатору производителя.
Количество идентичных компонентов, необходимых для создания экземпляра. Считается количеством записей компонента.
+
+
+
name
+
Optional
+
String
+
Если доступно, должна быть непустая строка. Название элемента в спецификации материалов.
+
+
+
Колонки, начинающиеся с part_
+
+ Если нужно назначить компонент, должна быть указана и заполнена по крайней мере одна из следующих колонок:
+
+
part_id
+
part_mpnr
+
part_ipn
+
part_name
+
+
+
+
+
part_id
+
Необязательная
+
Целое число (Integer)
+
Целое > 0. Соответствует внутреннему числовому ID компонента в базе данных компонентов (Part-DB).
+
+
+
part_mpnr
+
Необязательная
+
Строка (String)
+
Должна быть указана, если колонки part_id, part_ipn или part_name не заполнены.
+
+
+
part_ipn
+
Необязательная
+
Строка (String)
+
Должна быть указана, если колонки part_id, part_mpnr или part_name не заполнены.
+
+
+
part_name
+
Необязательная
+
Строка (String)
+
Должна быть указана, если колонки part_id, part_mpnr или part_ipn не заполнены.
+
+
+
Колонки, начинающиеся с part_manufacturer_
+
+ Если требуется указать производителя компонента или уникально идентифицировать компонент на основе значения part_mpnr, должна быть указана и заполнена по крайней мере одна из следующих колонок:
+
+
part_manufacturer_id
+
part_manufacturer_name
+
+
+
+
+
part_manufacturer_id
+
Необязательная
+
Целое число (Integer)
+
Целое > 0. Соответствует внутреннему числовому ID производителя.
+
+
+
part_manufacturer_name
+
Необязательная
+
Строка (String)
+
Должна быть указана, если колонка part_manufacturer_id не заполнена.
Свободный ввод. Уникальный идентификационный номер для каждого компонента.
+
+
+
Designator
+
Необязательно
+
Строка (String)
+
Свободный ввод. Уникальный идентификатор компонента на печатной плате, например, «R1» для резистора 1. Добавляется в название сборочного узла записи компонента.
+
+
+
Package
+
Необязательно
+
Строка (String)
+
Свободный ввод. Корпус или тип компонента, например, «0805» для SMD резисторов. Не добавляется в запись компонента.
+
+
+
Quantity
+
Обязательно
+
Целое число (Integer)
+
Число идентичных компонентов, необходимых для создания экземпляра сборки. Добавляется как количество записи компонента.
+
+
+
Designation
+
Обязательно
+
Строка (String)
+
Описание или функция компонента, например, значение резистора «10kΩ» или значение конденсатора «100nF». Добавляется в название записи компонента.
+
+
+
Supplier and ref
+
Необязательно
+
Строка (String)
+
Свободный ввод. Может содержать дистрибьюторское значение, например. Добавляется как примечание к записи компонента.
+
+
+ ]]>
+
+
+ project.bom_import.clear_existing_bom.help
@@ -12789,13 +13114,13 @@ Element 3
-
+ assembly.bom_import.template.csv.exptected_columns可用列:
-
+ assembly.bom_import.template.csv.table
From b3e2986e8d74a6a37f07394663b58a2dde0e806c Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 24 Jun 2025 11:07:20 +0200
Subject: [PATCH 47/83] =?UTF-8?q?Part-=C3=9Cbersicht=20sowie=20-Detailansi?=
=?UTF-8?q?cht=20um=20Assembly=20Information=20erweitern?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/DataTables/PartsDataTable.php | 29 +++++++++++++++++
templates/parts/info/_assemblies.html.twig | 31 +++++++++++++++++++
templates/parts/info/show_part_info.html.twig | 27 ++++++++++------
translations/messages.cs.xlf | 6 ++++
translations/messages.da.xlf | 6 ++++
translations/messages.de.xlf | 6 ++++
translations/messages.el.xlf | 6 ++++
translations/messages.en.xlf | 6 ++++
translations/messages.es.xlf | 6 ++++
translations/messages.fr.xlf | 6 ++++
translations/messages.it.xlf | 6 ++++
translations/messages.ja.xlf | 6 ++++
translations/messages.nl.xlf | 6 ++++
translations/messages.pl.xlf | 6 ++++
translations/messages.ru.xlf | 6 ++++
translations/messages.zh.xlf | 6 ++++
16 files changed, 156 insertions(+), 9 deletions(-)
create mode 100644 templates/parts/info/_assemblies.html.twig
diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php
index f0decf271..b98c97629 100644
--- a/src/DataTables/PartsDataTable.php
+++ b/src/DataTables/PartsDataTable.php
@@ -39,6 +39,7 @@
use App\DataTables\Helpers\ColumnSortHelper;
use App\DataTables\Helpers\PartDataTableHelper;
use App\Doctrine\Helpers\FieldHelper;
+use App\Entity\AssemblySystem\Assembly;
use App\Entity\Parts\ManufacturingStatus;
use App\Entity\Parts\Part;
use App\Entity\Parts\PartLot;
@@ -238,6 +239,34 @@ public function configure(DataTable $dataTable, array $options): void
]);
}
+ //Add a assembly column to list where the part is used, when the user has the permission to see the assemblies
+ if ($this->security->isGranted('read', Assembly::class)) {
+ $this->csh->add('assemblies', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.labelp'),
+ 'render' => function ($value, Part $context): string {
+ //Only show the first 5 assembly names
+ $assemblies = $context->getAssemblies();
+ $tmp = "";
+
+ $max = 5;
+
+ for ($i = 0; $i < min($max, count($assemblies)); $i++) {
+ $url = $this->urlGenerator->infoURL($assemblies[$i]);
+ $tmp .= sprintf('%s', $url, htmlspecialchars($assemblies[$i]->getName()));
+ if ($i < count($assemblies) - 1) {
+ $tmp .= ", ";
+ }
+ }
+
+ if (count($assemblies) > $max) {
+ $tmp .= ", + ".(count($assemblies) - $max);
+ }
+
+ return $tmp;
+ }
+ ]);
+ }
+
$this->csh
->add('edit', IconLinkColumn::class, [
'label' => $this->translator->trans('part.table.edit'),
diff --git a/templates/parts/info/_assemblies.html.twig b/templates/parts/info/_assemblies.html.twig
new file mode 100644
index 000000000..d4996c592
--- /dev/null
+++ b/templates/parts/info/_assemblies.html.twig
@@ -0,0 +1,31 @@
+{% import "components/attachments.macro.html.twig" as attachments %}
+{% import "helper.twig" as helper %}
+
+
+
+
+
+
{% trans %}entity.info.name{% endtrans %}
+
{% trans %}description.label{% endtrans %}
+
{% trans %}assembly.bom.quantity{% endtrans %}
+
+
+
+
+ {% for bom_entry in part.assemblyBomEntries %}
+ {# @var bom_entry App\Entity\Assembly\AssemblyBOMEntry #}
+
+
{% if bom_entry.assembly.masterPictureAttachment is not null %}{{ attachments.attachment_icon(bom_entry.assembly.masterPictureAttachment, attachment_manager) }}{% endif %}
+
+
+
+ {% trans %}part.info.add_part_to_assembly{% endtrans %}
+
\ No newline at end of file
diff --git a/templates/parts/info/show_part_info.html.twig b/templates/parts/info/show_part_info.html.twig
index 96b5e2091..cd7b4ce7a 100644
--- a/templates/parts/info/show_part_info.html.twig
+++ b/templates/parts/info/show_part_info.html.twig
@@ -109,15 +109,20 @@
{% trans %}vendor.partinfo.history{% endtrans %}
- {% if part.projectBomEntries is not empty %}
-
\ No newline at end of file
diff --git a/templates/assemblies/info/info.html.twig b/templates/assemblies/info/info.html.twig
index 166535a64..d787ea086 100644
--- a/templates/assemblies/info/info.html.twig
+++ b/templates/assemblies/info/info.html.twig
@@ -108,7 +108,7 @@
{% include "assemblies/info/_builds.html.twig" %}
- {% include "parts/info/_attachments_info.html.twig" with {"part": assembly} %}
+ {% include "assemblies/info/_attachments_info.html.twig" with {"assembly": assembly} %}
{% trans %}assembly.bom.partOrProject{% endtrans %}
+
{% trans %}assembly.bom.partOrAssembly{% endtrans %}
{% trans %}assembly.bom.name{% endtrans %}
{# Remove button #}
@@ -44,18 +44,9 @@
{{ form_row(form.part) }}
{{ form_errors(form.part) }}
-
- {% if form.vars.value is not null and form.vars.value.assembly is not null %}
- {% if is_granted("@projects.read") or has_project(form.vars.value.assembly.bomEntries.toArray) %}
-
{{ form_widget(form.name) }}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index b8c4f6033..4191cf30c 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -9867,7 +9867,7 @@ Element 3
assembly.edit.status
- Stav
+ Stav sestavy
@@ -13852,6 +13852,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
%value% (Součást)
+
+
+ part.table.name.value.for_assembly
+ %value% (Sestava)
+
+ part.table.name.value.for_project
@@ -13888,6 +13894,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Sestavy
+
+
+ assembly.referencedAssembly.labelp
+ Odkazované sestavy
+
+ assembly.edit
@@ -14056,6 +14068,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Sestavit
+
+
+ assembly.build.form.referencedAssembly
+ Sestava "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -14110,6 +14128,12 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Projekt
+
+
+ assembly.bom.referencedAssembly
+ Sestava
+
+ assembly.bom.name
@@ -14146,10 +14170,10 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Importovat součásti do sestavy
-
+
- assembly.bom.partOrProject
- Součást
+ assembly.bom.partOrAssembly
+ Součást nebo sestava
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index 4cec94054..c68acdd4b 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -9893,7 +9893,7 @@ Element 3
assembly.edit.status
- Status
+ Samlingens status
@@ -12569,6 +12569,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
%value% (Del)
+
+
+ part.table.name.value.for_assembly
+ %value% (Samling)
+
+ part.table.name.value.for_project
@@ -12605,6 +12611,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Samlinger
+
+
+ assembly.referencedAssembly.labelp
+ Refererede samlinger
+
+ assembly.edit
@@ -12773,6 +12785,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Byg
+
+
+ assembly.build.form.referencedAssembly
+ Samling "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12827,6 +12845,12 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Projekt
+
+
+ assembly.bom.referencedAssembly
+ Sammenstilling
+
+ assembly.bom.name
@@ -12863,10 +12887,10 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Importer dele til samling
-
+
- assembly.bom.partOrProject
- Del
+ assembly.bom.partOrAssembly
+ Del eller samling
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index 3140a1368..bee171d41 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -4746,6 +4746,12 @@ Wenn Sie dies fehlerhafterweise gemacht haben oder ein Computer nicht mehr vertr
%value% (Bauteil)
+
+
+ part.table.name.value.for_assembly
+ %value% (Baugruppe)
+
+ part.table.name.value.for_project
@@ -9881,7 +9887,7 @@ Element 1 -> Element 1.2
assembly.edit.status
- Status
+ Status Baugruppe
@@ -13260,6 +13266,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Baugruppen
+
+
+ assembly.referencedAssembly.labelp
+ Referenzierte Baugruppen
+
+ assembly.edit
@@ -13428,6 +13440,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Bauen
+
+
+ asssembly.build.form.referencedAssembly
+ Baugruppe "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -13482,6 +13500,12 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Projekt
+
+
+ assembly.bom.referencedAssembly
+ Baugruppe
+
+ assembly.bom.name
@@ -13518,10 +13542,10 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Importiere Parts für Baugruppe
-
+
- assembly.bom.partOrProject
- Bauteil oder Projekt
+ assembly.bom.partOrAssembly
+ Bauteil oder Baugruppe
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index fc03f08be..97b27f53f 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -1541,6 +1541,12 @@
%value% (Μέρος)
+
+
+ part.table.name.value.for_assembly
+ %value% (Συναρμολόγηση)
+
+ part.table.name.value.for_project
@@ -1550,7 +1556,7 @@
assembly.edit.status
- Κατάσταση
+ Κατάσταση συναρμολόγησης
@@ -1613,6 +1619,12 @@
Συναρμολογήσεις
+
+
+ assembly.referencedAssembly.labelp
+ Αναφερόμενες συναρμολογήσεις
+
+ assembly.edit
@@ -1781,6 +1793,12 @@
Κατασκευή
+
+
+ assembly.build.form.referencedAssembly
+ Συναρμολόγηση "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -1835,6 +1853,12 @@
έργο
+
+
+ assembly.bom.referencedAssembly
+ Συναρμολόγηση
+
+ assembly.bom.name
@@ -1871,10 +1895,10 @@
Εισαγωγή εξαρτημάτων συναρμολόγησης
-
+
- assembly.bom.partOrProject
- Εξάρτημα
+ assembly.bom.partOrAssembly
+ Μέρος ή συναρμολόγηση
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 18c124ff7..2100548d3 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -4747,6 +4747,12 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
%value% (Part)
+
+
+ part.table.name.value.for_assembly
+ %value% (Assembly)
+
+ part.table.name.value.for_project
@@ -9882,7 +9888,7 @@ Element 1 -> Element 1.2
assembly.edit.status
- Project status
+ Assembly status
@@ -13261,6 +13267,12 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Assemblies
+
+
+ assembly.referencedAssembly.labelp
+ Referenced assemblies
+
+ assembly.edit
@@ -13429,6 +13441,12 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Build
+
+
+ assembly.build.form.referencedAssembly
+ Assembly "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -13483,6 +13501,12 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Project
+
+
+ assembly.bom.referencedAssembly
+ Assembly
+
+ assembly.bom.name
@@ -13519,10 +13543,10 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Import part list for assembly
-
+
- assembly.bom.partOrProject
- Part
+ assembly.bom.partOrAssembly
+ Part or assembly
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index edef6d968..d4ece66ea 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -4746,6 +4746,12 @@ Subelementos serán desplazados hacia arriba.
%value% (Componente)
+
+
+ part.table.name.value.for_assembly
+ %value% (Ensamblaje)
+
+ part.table.name.value.for_project
@@ -9897,7 +9903,7 @@ Elemento 3
assembly.edit.status
- Estatus
+ Estado del ensamblaje
@@ -12777,6 +12783,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Ensamblajes
+
+
+ assembly.referencedAssembly.labelp
+ Conjuntos referenciados
+
+ assembly.edit
@@ -12945,6 +12957,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Construir
+
+
+ assembly.build.form.referencedAssembly
+ Ensamblaje "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12999,6 +13017,12 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Proyecto
+
+
+ assembly.bom.referencedAssembly
+ Ensamblaje
+
+ assembly.bom.name
@@ -13035,10 +13059,10 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Importar piezas para ensamblaje
-
+
- assembly.bom.partOrProject
- Pieza
+ assembly.bom.partOrAssembly
+ Parte o conjunto
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index f5c7dc97d..a75db3a3a 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -4709,6 +4709,12 @@ Si vous avez fait cela de manière incorrecte ou si un ordinateur n'est plus fia
%value% (Componente)
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblage)
+
+ part.table.name.value.for_project
@@ -9112,7 +9118,7 @@ exemple de ville
assembly.edit.status
- Statut
+ Statut de l'assemblage
@@ -9175,6 +9181,12 @@ exemple de ville
Assemblages
+
+
+ assembly.referencedAssembly.labelp
+ Assemblages référencés
+
+ assembly.edit
@@ -9343,6 +9355,12 @@ exemple de ville
Construire
+
+
+ assembly.build.form.referencedAssembly
+ Assemblage "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -9397,6 +9415,12 @@ exemple de ville
Projet
+
+
+ assembly.bom.referencedAssembly
+ Assemblage
+
+ assembly.bom.name
@@ -9433,10 +9457,10 @@ exemple de ville
Importer des pièces pour l'assemblage
-
+
- assembly.bom.partOrProject
- Pièce
+ assembly.bom.partOrAssembly
+ Pièce ou assemblage
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index e7628984a..12e20ca2c 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -4748,6 +4748,12 @@ Se è stato fatto in modo errato o se un computer non è più attendibile, puoi
%value% (Componente)
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblaggio)
+
+ part.table.name.value.for_project
@@ -9899,7 +9905,7 @@ Element 3
assembly.edit.status
- Stato
+ Stato dell'assemblaggio
@@ -12755,6 +12761,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Assemblaggi
+
+
+ assembly.referencedAssembly.labelp
+ Assembly referenziati
+
+ assembly.edit
@@ -12923,6 +12935,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Costruire
+
+
+ assembly.build.form.referencedAssembly
+ Gruppo "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12977,6 +12995,12 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Progetto
+
+
+ assembly.bom.referencedAssembly
+ Assemblaggio
+
+ assembly.bom.name
@@ -13013,10 +13037,10 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Importa componenti per il gruppo
-
+
- assembly.bom.partOrProject
- Componente
+ assembly.bom.partOrAssembly
+ Parte o assieme
diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf
index b61b585f3..b7be7490d 100644
--- a/translations/messages.ja.xlf
+++ b/translations/messages.ja.xlf
@@ -4709,6 +4709,12 @@
%value%(部品)
+
+
+ part.table.name.value.for_assembly
+ %value%(アセンブリ)
+
+ part.table.name.value.for_project
@@ -8849,7 +8855,7 @@ Exampletown
assembly.edit.status
- ステータス
+ アセンブリのステータス
@@ -8912,6 +8918,12 @@ Exampletown
アセンブリ一覧
+
+
+ assembly.referencedAssembly.labelp
+ 参照されたアセンブリ
+
+ assembly.edit
@@ -9080,6 +9092,12 @@ Exampletown
ビルド
+
+
+ assembly.build.form.referencedAssembly
+ アセンブリ「%name%」
+
+ assembly.builds.no_stocked_builds
@@ -9134,6 +9152,12 @@ Exampletown
プロジェクト
+
+
+ assembly.bom.referencedAssembly
+ アセンブリ
+
+ assembly.bom.name
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index c52a4733a..fe17c3aca 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -730,6 +730,12 @@
%value% (Onderdeel)
+
+
+ part.table.name.value.for_assembly
+ %value% (Assemblage)
+
+ part.table.name.value.for_project
@@ -739,7 +745,7 @@
assembly.edit.status
- Κατάσταση
+ Montagestatus
@@ -802,6 +808,12 @@
Assemblages
+
+
+ assembly.referencedAssembly.labelp
+ Gerefereerde assemblages
+
+ assembly.edit
@@ -970,6 +982,12 @@
Bouwen
+
+
+ assembly.build.form.referencedAssembly
+ Assemblage "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -1024,6 +1042,12 @@
Project
+
+
+ assembly.bom.referencedAssembly
+ Assemblage
+
+ assembly.bom.name
@@ -1060,10 +1084,10 @@
Importeer onderdelen voor assemblage
-
+
- assembly.bom.partOrProject
- Onderdeel
+ assembly.bom.partOrAssembly
+ Onderdeel of samenstelling
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index fc6eba18d..73b6e4fcc 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -4751,6 +4751,12 @@ Jeśli zrobiłeś to niepoprawnie lub komputer nie jest już godny zaufania, mo
%value%(部品)
+
+
+ part.table.name.value.for_assembly
+ %value% (Złożenie)
+
+ part.table.name.value.for_project
@@ -9902,7 +9908,7 @@ Element 3
assembly.edit.status
- Status
+ Status montażu
@@ -12632,6 +12638,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Zespoły
+
+
+ assembly.referencedAssembly.labelp
+ Odwołane zestawy
+
+ assembly.edit
@@ -12800,6 +12812,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Zbuduj
+
+
+ assembly.build.form.referencedAssembly
+ Zespół "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12854,6 +12872,12 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Projekt
+
+
+ assembly.bom.referencedAssembly
+ Złożenie
+
+ assembly.bom.name
@@ -12890,10 +12914,10 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Importuj części dla zespołu
-
+
- assembly.bom.partOrProject
- Część
+ assembly.bom.partOrAssembly
+ Część lub zespół
diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf
index 252b857bd..751ff35f1 100644
--- a/translations/messages.ru.xlf
+++ b/translations/messages.ru.xlf
@@ -4757,6 +4757,12 @@
%value% (Часть)
+
+
+ part.table.name.value.for_assembly
+ %value% (Сборка)
+
+ part.table.name.value.for_project
@@ -9906,7 +9912,7 @@
assembly.edit.status
- Статус
+ Статус сборки
@@ -12732,6 +12738,12 @@
Сборки
+
+
+ assembly.referencedAssembly.labelp
+ Ссылочные сборки
+
+ assembly.edit
@@ -12900,6 +12912,12 @@
Собрать
+
+
+ assembly.build.form.referencedAssembly
+ Сборка "%name%"
+
+ assembly.builds.no_stocked_builds
@@ -12954,6 +12972,12 @@
Проект
+
+
+ assembly.bom.referencedAssembly
+ Сборка
+
+ assembly.bom.name
@@ -12990,10 +13014,10 @@
Импортировать детали для сборки
-
+
- assembly.bom.partOrProject
- Компонент
+ assembly.bom.partOrAssembly
+ Часть или сборка
diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf
index 9c0b5a76f..396feae3e 100644
--- a/translations/messages.zh.xlf
+++ b/translations/messages.zh.xlf
@@ -4755,6 +4755,12 @@
%value%(部件)
+
+
+ part.table.name.value.for_assembly
+ %value%(装配)
+
+ part.table.name.value.for_project
@@ -9905,7 +9911,7 @@ Element 3
assembly.edit.status
- 状态
+ 装配状态
@@ -12617,6 +12623,12 @@ Element 3
装配列表
+
+
+ assembly.referencedAssembly.labelp
+ 引用的程序集
+
+ assembly.edit
@@ -12785,6 +12797,12 @@ Element 3
构建
+
+
+ assembly.build.form.referencedAssembly
+ 组件“%name%”
+
+ assembly.builds.no_stocked_builds
@@ -12839,6 +12857,12 @@ Element 3
项目
+
+
+ assembly.bom.referencedAssembly
+ 组件
+
+ assembly.bom.name
@@ -12875,10 +12899,10 @@ Element 3
导入组件的零件
-
+
- assembly.bom.partOrProject
- 零件
+ assembly.bom.partOrAssembly
+ 部件或组件
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index 607b8a3b6..1731c90cb 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -251,12 +251,6 @@
Musíte vybrat díl pro položku BOM dílu nebo nastavit název pro položku BOM bez dílu.
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Je povoleno vybrat pouze jednu součástku nebo sestavu. Upravit prosím svůj výběr!
-
- project.bom_entry.name_already_in_bom
@@ -395,6 +389,12 @@
Tato součást již existuje ve skupině!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Tato sestava již existuje jako položka v seznamu materiálů!
+
+ assembly.bom_entry.project_already_in_bom
@@ -413,6 +413,12 @@
Musíte vybrat součást nebo nastavit název pro nesoučást!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Je povoleno vybrat pouze jednu součástku nebo sestavu. Upravit prosím svůj výběr!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index f25712719..239e3572a 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -251,12 +251,6 @@
Du skal vælge en komponent eller angive et navn til en ikke-komponent styklistepost!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
-
- project.bom_entry.name_already_in_bom
@@ -371,6 +365,12 @@
Denne del eksisterer allerede i gruppen!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Denne samling findes allerede som en post!
+
+ assembly.bom_entry.project_already_in_bom
@@ -389,6 +389,12 @@
Du skal vælge en del eller sætte et navn for en ikke-del!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index abd191d9e..86b31e583 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -251,12 +251,6 @@
Sie müssen ein Bauteil bzw. eine Baugruppe auswählen, oder einen Namen für ein nicht-Bauteil BOM-Eintrag setzen!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Es darf nur ein Bauteil oder eine Baugruppe ausgewählt werden. Bitte passen Sie Ihre Auswahl an!
-
- project.bom_entry.name_already_in_bom
@@ -395,6 +389,12 @@
Dieses Bauteil existiert bereits in der Gruppe!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Diese Baugruppe existiert bereits als Eintrag!
+
+ assembly.bom_entry.project_already_in_bom
@@ -413,6 +413,12 @@
Sie müssen ein Bauteil auswählen, oder einen Namen für den Eintrag setzen!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Es darf nur ein Bauteil oder eine Baugruppe ausgewählt werden. Bitte passen Sie Ihre Auswahl an!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index 580c91275..4e4278daf 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -13,12 +13,6 @@
Ο εσωτερικός αριθμός εξαρτήματος πρέπει να είναι μοναδικός. {{ value }} χρησιμοποιείται ήδη!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
-
- validator.bom_importer.invalid_import_type
@@ -37,6 +31,12 @@
Αυτό το εξάρτημα υπάρχει ήδη στην ομάδα!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Αυτή η συναρμολόγηση υπάρχει ήδη ως εγγραφή!
+
+ assembly.bom_entry.project_already_in_bom
@@ -55,6 +55,12 @@
Πρέπει να επιλέξετε ένα εξάρτημα ή να βάλετε ένα όνομα για ένα μη εξάρτημα!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Det er kun tilladt at vælge én del eller en samling. Venligst tilpas dit valg!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index e20e7ff8c..59cabf552 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -251,12 +251,6 @@
You have to select a part or assembly, or set a name for a non-component Bom entry!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Only one part or assembly may be selected. Please modify your selection!
-
- project.bom_entry.name_already_in_bom
@@ -395,6 +389,12 @@
This part already exists in the list!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ This assembly already exists as an entry!
+
+ assembly.bom_entry.project_already_in_bom
@@ -413,6 +413,12 @@
You must select a part or set a name for the entry!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Only one part or assembly may be selected. Please modify your selection!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index e603bdaf8..aff68a185 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -203,12 +203,6 @@
L'emplacement de stockage a été marqué comme "Composant seul", par conséquent aucun nouveau composant ne peut être ajouté.
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Seule une pièce ou un assemblage peut être sélectionné. Veuillez ajuster votre sélection!
-
- validator.bom_importer.invalid_import_type
@@ -227,6 +221,12 @@
Cette pièce existe déjà dans le groupe!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Cet assemblage existe déjà en tant qu'entrée !
+
+ assembly.bom_entry.project_already_in_bom
@@ -245,6 +245,12 @@
Vous devez sélectionner une pièce ou attribuer un nom pour un non-élément!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Seule une pièce ou un assemblage peut être sélectionné. Veuillez ajuster votre sélection!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index c0af03354..1ee5c06fe 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -251,12 +251,6 @@
Morate odabrati dio za unos u BOM ili postaviti naziv za unos koji nije dio.
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Dozvoljeno je odabrati samo jednu komponentu ili sklop. Molimo prilagodite svoj odabir!
-
- project.bom_entry.name_already_in_bom
@@ -389,6 +383,12 @@
Ovaj dio već postoji u grupi!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Ova se montaža već nalazi kao zapis!
+
+ assembly.bom_entry.project_already_in_bom
@@ -407,6 +407,12 @@
Morate odabrati dio ili unijeti naziv za nedio!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Dozvoljeno je odabrati samo jednu komponentu ili sklop. Molimo prilagodite svoj odabir!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index 88369640f..ac57a2cc4 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -251,12 +251,6 @@
È necessario selezionare un componente o assegnare un nome ad una voce BOM che non indica un componente!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- È consentito selezionare solo una parte o un assieme. Si prega di modificare la selezione!
-
- project.bom_entry.name_already_in_bom
@@ -389,6 +383,12 @@
Questa parte è già presente nel gruppo!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Questo assemblaggio è già presente come voce!
+
+ assembly.bom_entry.project_already_in_bom
@@ -407,6 +407,12 @@
È necessario selezionare una parte o inserire un nome per un non-parte!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ È consentito selezionare solo una parte o un assieme. Si prega di modificare la selezione!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index 070281ccc..a316707ad 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -203,12 +203,6 @@
新しい部品を追加できません。保管場所は「1つの部品のみ」とマークされています。
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- 部品またはアセンブリのみ選択可能です。選択内容を調整してください!
-
- validator.bom_importer.invalid_import_type
@@ -227,6 +221,12 @@
この部品はすでにグループに存在します!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ このアセンブリはすでにエントリとして存在します!
+
+ assembly.bom_entry.project_already_in_bom
@@ -245,6 +245,12 @@
部品を選択するか、非部品の名前を入力する必要があります!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ 部品またはアセンブリのみ選択可能です。選択内容を調整してください!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 60713fa02..95c44ab4d 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -251,12 +251,6 @@
Należy wybrać część dla wpisu BOM części lub ustawić nazwę dla wpisu BOM niebędącego częścią.
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Można wybrać tylko jedną część lub zespół. Proszę dostosować swój wybór!
-
- project.bom_entry.name_already_in_bom
@@ -389,6 +383,12 @@
Ten element już istnieje w grupie!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ To zestawienie jest już dodane jako wpis!
+
+ assembly.bom_entry.project_already_in_bom
@@ -407,6 +407,12 @@
Musisz wybrać element lub przypisać nazwę dla elementu niestandardowego!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Można wybrać tylko jedną część lub zespół. Proszę dostosować swój wybór!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index 32540f8c7..425ede5f1 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -251,12 +251,6 @@
Вам необходимо выбрать компонент или задать имя для BOM, не относящейся к компоненту!
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- Можно выбрать только деталь или сборку. Пожалуйста, измените ваш выбор!
-
- project.bom_entry.name_already_in_bom
@@ -389,6 +383,12 @@
Эта деталь уже существует в группе!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ Этот сборочный узел уже добавлен как запись!
+
+ assembly.bom_entry.project_already_in_bom
@@ -407,6 +407,12 @@
Необходимо выбрать деталь или ввести название для недетали!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ Можно выбрать только деталь или сборку. Пожалуйста, измените ваш выбор!
+
+ validator.bom_importer.json_csv.quantity.required
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 4a0ec79e8..4a02523bb 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -251,12 +251,6 @@
您必须为 BOM 条目选择部件,或为非部件 BOM 条目设置名称。
-
-
- validator.project.bom_entry.only_part_or_assembly_allowed
- 只能选择一个零件或组件。请修改您的选择!
-
- project.bom_entry.name_already_in_bom
@@ -377,6 +371,12 @@
此零件已存在于组中!
+
+
+ assembly.bom_entry.assembly_already_in_bom
+ 此装配已经作为条目存在!
+
+ assembly.bom_entry.project_already_in_bom
@@ -395,6 +395,12 @@
必须选择零件或为非零件指定名称!
+
+
+ validator.assembly.bom_entry.only_part_or_assembly_allowed
+ 只能选择一个零件或组件。请修改您的选择!
+
+ validator.bom_importer.json_csv.quantity.required
From 47f2801f5616e6e01a4d2bbdd13e4b5ca75b24ae Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 3 Jul 2025 13:43:55 +0200
Subject: [PATCH 50/83] AssemblyBomEntriesDataTable anpassen
---
.../AssemblyBomEntriesDataTable.php | 82 ++++++-------------
1 file changed, 23 insertions(+), 59 deletions(-)
diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php
index b31c72bc0..fed6850f4 100644
--- a/src/DataTables/AssemblyBomEntriesDataTable.php
+++ b/src/DataTables/AssemblyBomEntriesDataTable.php
@@ -22,12 +22,13 @@
*/
namespace App\DataTables;
-use App\DataTables\Column\EntityColumn;
use App\DataTables\Column\LocaleDateTimeColumn;
use App\DataTables\Column\MarkdownColumn;
+use App\DataTables\Helpers\AssemblyDataTableHelper;
use App\DataTables\Helpers\ProjectDataTableHelper;
use App\DataTables\Helpers\ColumnSortHelper;
use App\DataTables\Helpers\PartDataTableHelper;
+use App\Entity\AssemblySystem\Assembly;
use App\Entity\Attachments\Attachment;
use App\Entity\Parts\Part;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
@@ -45,20 +46,20 @@
class AssemblyBomEntriesDataTable implements DataTableTypeInterface
{
public function __construct(
- protected TranslatorInterface $translator,
- protected PartDataTableHelper $partDataTableHelper,
- protected ProjectDataTableHelper $projectDataTableHelper,
- protected EntityURLGenerator $entityURLGenerator,
- protected AmountFormatter $amountFormatter,
- private string $visible_columns,
- private ColumnSortHelper $csh
+ protected TranslatorInterface $translator,
+ protected PartDataTableHelper $partDataTableHelper,
+ protected ProjectDataTableHelper $projectDataTableHelper,
+ protected AssemblyDataTableHelper $assemblyDataTableHelper,
+ protected EntityURLGenerator $entityURLGenerator,
+ protected AmountFormatter $amountFormatter,
+ private string $visible_columns,
+ private ColumnSortHelper $csh
){
}
public function configure(DataTable $dataTable, array $options): void
{
$this->csh
- //->add('select', SelectColumn::class)
->add('picture', TextColumn::class, [
'label' => '',
'className' => 'no-colvis',
@@ -89,7 +90,7 @@ public function configure(DataTable $dataTable, array $options): void
'label' => $this->translator->trans('part.table.name'),
'orderField' => 'NATSORT(part.name)',
'render' => function ($value, AssemblyBOMEntry $context) {
- if(!$context->getPart() instanceof Part && !$context->getProject() instanceof Project) {
+ if(!$context->getPart() instanceof Part && !$context->getReferencedAssembly() instanceof Assembly && !$context->getProject() instanceof Project) {
return htmlspecialchars((string) $context->getName());
}
@@ -97,6 +98,13 @@ public function configure(DataTable $dataTable, array $options): void
$tmp = $this->partDataTableHelper->renderName($context->getPart());
$tmp = $this->translator->trans('part.table.name.value.for_part', ['%value%' => $tmp]);
+ if($context->getName() !== null && $context->getName() !== '') {
+ $tmp .= ' '.htmlspecialchars($context->getName()).'';
+ }
+ } elseif ($context->getReferencedAssembly() !== null) {
+ $tmp = $this->assemblyDataTableHelper->renderName($context->getReferencedAssembly());
+ $tmp = $this->translator->trans('part.table.name.value.for_assembly', ['%value%' => $tmp]);
+
if($context->getName() !== null && $context->getName() !== '') {
$tmp .= ' '.htmlspecialchars($context->getName()).'';
}
@@ -127,59 +135,15 @@ public function configure(DataTable $dataTable, array $options): void
->add('description', MarkdownColumn::class, [
'label' => $this->translator->trans('part.table.description'),
'data' => function (AssemblyBOMEntry $context) {
- if($context->getPart() instanceof Part) {
+ if ($context->getPart() instanceof Part) {
return $context->getPart()->getDescription();
+ } elseif ($context->getReferencedAssembly() instanceof Assembly) {
+ return $context->getReferencedAssembly()->getDescription();
}
//For non-part BOM entries show the comment field
return $context->getComment();
},
])
- ->add('category', EntityColumn::class, [
- 'label' => $this->translator->trans('part.table.category'),
- 'property' => 'part.category',
- 'orderField' => 'NATSORT(category.name)',
- ])
- ->add('footprint', EntityColumn::class, [
- 'property' => 'part.footprint',
- 'label' => $this->translator->trans('part.table.footprint'),
- 'orderField' => 'NATSORT(footprint.name)',
- ])
- ->add('manufacturer', EntityColumn::class, [
- 'property' => 'part.manufacturer',
- 'label' => $this->translator->trans('part.table.manufacturer'),
- 'orderField' => 'NATSORT(manufacturer.name)',
- ])
- ->add('mountnames', TextColumn::class, [
- 'label' => 'assembly.bom.mountnames',
- 'render' => function ($value, AssemblyBOMEntry $context) {
- $html = '';
-
- foreach (explode(',', $context->getMountnames()) as $mountname) {
- $html .= sprintf('%s ', htmlspecialchars($mountname));
- }
- return $html;
- },
- ])
- ->add('instockAmount', TextColumn::class, [
- 'label' => 'assembly.bom.instockAmount',
- 'render' => function ($value, AssemblyBOMEntry $context) {
- if ($context->getPart() !== null) {
- return $this->partDataTableHelper->renderAmount($context->getPart());
- }
-
- return '';
- }
- ])
- ->add('storageLocations', TextColumn::class, [
- 'label' => 'part.table.storeLocations',
- 'render' => function ($value, AssemblyBOMEntry $context) {
- if ($context->getPart() !== null) {
- return $this->partDataTableHelper->renderStorageLocations($context->getPart());
- }
-
- return '';
- }
- ])
->add('addedDate', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.addedDate'),
])
@@ -189,8 +153,7 @@ public function configure(DataTable $dataTable, array $options): void
;
//Apply the user configured order and visibility and add the columns to the table
- $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,
- "TABLE_ASSEMBLIES_DEFAULT_COLUMNS");
+ $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,"TABLE_ASSEMBLIES_BOM_DEFAULT_COLUMNS");
$dataTable->addOrderBy('name');
@@ -214,6 +177,7 @@ private function getQuery(QueryBuilder $builder, array $options): void
->addSelect('part')
->from(AssemblyBOMEntry::class, 'bom_entry')
->leftJoin('bom_entry.part', 'part')
+ ->leftJoin('bom_entry.referencedAssembly', 'referencedAssembly')
->leftJoin('part.category', 'category')
->leftJoin('part.footprint', 'footprint')
->leftJoin('part.manufacturer', 'manufacturer')
From 195f1903f45fbfe7c7648fab9068bc025d4b433c Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 3 Jul 2025 13:47:20 +0200
Subject: [PATCH 51/83] =?UTF-8?q?Assembly=20Listen=C3=BCbersicht=20umsetze?=
=?UTF-8?q?n?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
assets/css/app/images.css | 5 +
config/parameters.yaml | 6 -
docs/configuration.md | 3 +-
src/Controller/AssemblyController.php | 74 ++++++
src/DataTables/AssemblyDataTable.php | 249 ++++++++++++++++++
src/DataTables/Filters/AssemblyFilter.php | 68 +++++
.../Filters/AssemblySearchFilter.php | 183 +++++++++++++
.../Helpers/AssemblyDataTableHelper.php | 77 ++++++
.../Helpers/ProjectDataTableHelper.php | 2 +-
src/Form/Filters/AssemblyFilterType.php | 114 ++++++++
.../assemblies/lists/_action_bar.html.twig | 6 +
templates/assemblies/lists/_filter.html.twig | 62 +++++
templates/assemblies/lists/all_list.html.twig | 30 +++
templates/assemblies/lists/data.html.twig | 3 +
translations/messages.cs.xlf | 126 +++++++++
translations/messages.da.xlf | 126 +++++++++
translations/messages.de.xlf | 126 +++++++++
translations/messages.el.xlf | 126 +++++++++
translations/messages.en.xlf | 126 +++++++++
translations/messages.es.xlf | 126 +++++++++
translations/messages.fr.xlf | 126 +++++++++
translations/messages.it.xlf | 126 +++++++++
translations/messages.ja.xlf | 126 +++++++++
translations/messages.nl.xlf | 126 +++++++++
translations/messages.pl.xlf | 126 +++++++++
translations/messages.ru.xlf | 126 +++++++++
translations/messages.zh.xlf | 126 +++++++++
27 files changed, 2511 insertions(+), 9 deletions(-)
create mode 100644 src/DataTables/AssemblyDataTable.php
create mode 100644 src/DataTables/Filters/AssemblyFilter.php
create mode 100644 src/DataTables/Filters/AssemblySearchFilter.php
create mode 100644 src/DataTables/Helpers/AssemblyDataTableHelper.php
create mode 100644 src/Form/Filters/AssemblyFilterType.php
create mode 100644 templates/assemblies/lists/_action_bar.html.twig
create mode 100644 templates/assemblies/lists/_filter.html.twig
create mode 100644 templates/assemblies/lists/all_list.html.twig
create mode 100644 templates/assemblies/lists/data.html.twig
diff --git a/assets/css/app/images.css b/assets/css/app/images.css
index 0212a85b7..132cab99b 100644
--- a/assets/css/app/images.css
+++ b/assets/css/app/images.css
@@ -61,3 +61,8 @@
.object-fit-cover {
object-fit: cover;
}
+
+.assembly-table-image {
+ max-height: 40px;
+ object-fit: contain;
+}
diff --git a/config/parameters.yaml b/config/parameters.yaml
index 8c45b95a9..599fbe595 100644
--- a/config/parameters.yaml
+++ b/config/parameters.yaml
@@ -48,14 +48,8 @@ parameters:
######################################################################################################################
# Table settings
######################################################################################################################
-<<<<<<< HEAD
partdb.table.assemblies.default_columns: '%env(trim:string:TABLE_ASSEMBLIES_DEFAULT_COLUMNS)%' # The default columns in assembly tables and their order
-=======
- partdb.table.default_page_size: '%env(int:TABLE_DEFAULT_PAGE_SIZE)%' # The default number of entries shown per page in tables
- partdb.table.parts.default_columns: '%env(trim:string:TABLE_PARTS_DEFAULT_COLUMNS)%' # The default columns in part tables and their order
- partdb.table.assemblies.default_columns: '%env(trim:string:TABLE_ASSEMBLIES_DEFAULT_COLUMNS)%' # The default columns in assembly tables and their order
partdb.table.assemblies_bom.default_columns: '%env(trim:string:TABLE_ASSEMBLIES_BOM_DEFAULT_COLUMNS)%' # The default columns in assembly bom tables and their order
->>>>>>> 2779c55a (Baugruppen Stückliste um referenzierte Baugruppe erweitern)
######################################################################################################################
# Miscellaneous
diff --git a/docs/configuration.md b/docs/configuration.md
index 498308b00..242164bf5 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -137,8 +137,7 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `category`, `footprint`, `manufacturer`, `storage_location`, `amount`, `minamount`, `partUnit`, `addedDate`, `lastModified`, `needs_review`, `favorite`, `manufacturing_status`, `manufacturer_product_number`, `mass`, `tags`, `attachments`, `edit`.
-* `TABLE_ASSEMBLIES_DEFAULT_COLUMNS`: The columns in assemblies tables, which are visible by default (when loading table for first
- time).
+* `TABLE_ASSEMBLIES_DEFAULT_COLUMNS`: The columns in assemblies tables, which are visible by default (when loading table for first time).
Also specify the default order of the columns. This is a comma separated list of column names. Available columns
are: `name`, `id`, `ipn`, `description`, `referencedAssemblies`, `edit`, `addedDate`, `lastModified`.
* `TABLE_ASSEMBLIES_BOM_DEFAULT_COLUMNS`: The columns in assemblies bom tables, which are visible by default (when loading table for first time).
diff --git a/src/Controller/AssemblyController.php b/src/Controller/AssemblyController.php
index 9106f6775..a1ba7fa65 100644
--- a/src/Controller/AssemblyController.php
+++ b/src/Controller/AssemblyController.php
@@ -23,15 +23,22 @@
namespace App\Controller;
use App\DataTables\AssemblyBomEntriesDataTable;
+use App\DataTables\AssemblyDataTable;
+use App\DataTables\ErrorDataTable;
+use App\DataTables\Filters\AssemblyFilter;
use App\Entity\AssemblySystem\Assembly;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
use App\Entity\Parts\Part;
+use App\Exceptions\InvalidRegexException;
use App\Form\AssemblySystem\AssemblyAddPartsType;
use App\Form\AssemblySystem\AssemblyBuildType;
+use App\Form\Filters\AssemblyFilterType;
use App\Helpers\Assemblies\AssemblyBuildRequest;
use App\Services\ImportExportSystem\BOMImporter;
use App\Services\AssemblySystem\AssemblyBuildHelper;
+use App\Services\Trees\NodesListBuilder;
use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\DBAL\Exception\DriverException;
use Doctrine\ORM\EntityManagerInterface;
use League\Csv\SyntaxError;
use Omines\DataTablesBundle\DataTableFactory;
@@ -54,9 +61,76 @@ class AssemblyController extends AbstractController
public function __construct(
private readonly DataTableFactory $dataTableFactory,
private readonly TranslatorInterface $translator,
+ private readonly NodesListBuilder $nodesListBuilder
) {
}
+ #[Route(path: '/list', name: 'assemblies_list')]
+ public function showAll(Request $request): Response
+ {
+ return $this->showListWithFilter($request,'assemblies/lists/all_list.html.twig');
+ }
+
+ /**
+ * Common implementation for the part list pages.
+ * @param Request $request The request to parse
+ * @param string $template The template that should be rendered
+ * @param callable|null $filter_changer A function that is called with the filter object as parameter. This function can be used to customize the filter
+ * @param callable|null $form_changer A function that is called with the form object as parameter. This function can be used to customize the form
+ * @param array $additonal_template_vars Any additional template variables that should be passed to the template
+ * @param array $additional_table_vars Any additional variables that should be passed to the table creation
+ */
+ protected function showListWithFilter(Request $request, string $template, ?callable $filter_changer = null, ?callable $form_changer = null, array $additonal_template_vars = [], array $additional_table_vars = []): Response
+ {
+ $this->denyAccessUnlessGranted('@assemblies.read');
+
+ $formRequest = clone $request;
+ $formRequest->setMethod('GET');
+ $filter = new AssemblyFilter($this->nodesListBuilder);
+ if($filter_changer !== null){
+ $filter_changer($filter);
+ }
+
+ $filterForm = $this->createForm(AssemblyFilterType::class, $filter, ['method' => 'GET']);
+ if($form_changer !== null) {
+ $form_changer($filterForm);
+ }
+
+ $filterForm->handleRequest($formRequest);
+
+ $table = $this->dataTableFactory->createFromType(
+ AssemblyDataTable::class,
+ array_merge(['filter' => $filter], $additional_table_vars),
+ ['lengthMenu' => AssemblyDataTable::LENGTH_MENU]
+ )
+ ->handleRequest($request);
+
+ if ($table->isCallback()) {
+ try {
+ try {
+ return $table->getResponse();
+ } catch (DriverException $driverException) {
+ if ($driverException->getCode() === 1139) {
+ //Convert the driver exception to InvalidRegexException so it has the same handler as for SQLite
+ throw InvalidRegexException::fromDriverException($driverException);
+ } else {
+ throw $driverException;
+ }
+ }
+ } catch (InvalidRegexException $exception) {
+ $errors = $this->translator->trans('assembly.table.invalid_regex').': '.$exception->getReason();
+ $request->request->set('order', []);
+
+ return ErrorDataTable::errorTable($this->dataTableFactory, $request, $errors);
+ }
+ }
+
+ return $this->render($template, array_merge([
+ 'datatable' => $table,
+ 'filterForm' => $filterForm->createView(),
+ ], $additonal_template_vars));
+ }
+
#[Route(path: '/{id}/info', name: 'assembly_info', requirements: ['id' => '\d+'])]
public function info(Assembly $assembly, Request $request, AssemblyBuildHelper $buildHelper): Response
{
diff --git a/src/DataTables/AssemblyDataTable.php b/src/DataTables/AssemblyDataTable.php
new file mode 100644
index 000000000..f3854ebca
--- /dev/null
+++ b/src/DataTables/AssemblyDataTable.php
@@ -0,0 +1,249 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace App\DataTables;
+
+use App\DataTables\Adapters\TwoStepORMAdapter;
+use App\DataTables\Column\IconLinkColumn;
+use App\DataTables\Column\LocaleDateTimeColumn;
+use App\DataTables\Column\MarkdownColumn;
+use App\DataTables\Column\SelectColumn;
+use App\DataTables\Filters\AssemblyFilter;
+use App\DataTables\Filters\AssemblySearchFilter;
+use App\DataTables\Helpers\AssemblyDataTableHelper;
+use App\DataTables\Helpers\ColumnSortHelper;
+use App\Doctrine\Helpers\FieldHelper;
+use App\Entity\AssemblySystem\Assembly;
+use App\Services\EntityURLGenerator;
+use Doctrine\ORM\AbstractQuery;
+use Doctrine\ORM\QueryBuilder;
+use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
+use Omines\DataTablesBundle\Column\TextColumn;
+use Omines\DataTablesBundle\DataTable;
+use Omines\DataTablesBundle\DataTableTypeInterface;
+use Symfony\Bundle\SecurityBundle\Security;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+final class AssemblyDataTable implements DataTableTypeInterface
+{
+ const LENGTH_MENU = [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]];
+
+ public function __construct(
+ private readonly EntityURLGenerator $urlGenerator,
+ private readonly TranslatorInterface $translator,
+ private readonly AssemblyDataTableHelper $assemblyDataTableHelper,
+ private readonly Security $security,
+ private readonly string $visible_columns,
+ private readonly ColumnSortHelper $csh,
+ ) {
+ }
+
+ public function configureOptions(OptionsResolver $optionsResolver): void
+ {
+ $optionsResolver->setDefaults([
+ 'filter' => null,
+ 'search' => null
+ ]);
+
+ $optionsResolver->setAllowedTypes('filter', [AssemblyFilter::class, 'null']);
+ $optionsResolver->setAllowedTypes('search', [AssemblySearchFilter::class, 'null']);
+ }
+
+ public function configure(DataTable $dataTable, array $options): void
+ {
+ $resolver = new OptionsResolver();
+ $this->configureOptions($resolver);
+ $options = $resolver->resolve($options);
+
+ $this->csh
+ ->add('select', SelectColumn::class, visibility_configurable: false)
+ ->add('picture', TextColumn::class, [
+ 'label' => '',
+ 'className' => 'no-colvis',
+ 'render' => fn($value, Assembly $context) => $this->assemblyDataTableHelper->renderPicture($context),
+ ], visibility_configurable: false)
+ ->add('name', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.name'),
+ 'render' => fn($value, Assembly $context) => $this->assemblyDataTableHelper->renderName($context),
+ 'orderField' => 'NATSORT(assembly.name)'
+ ])
+ ->add('id', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.id'),
+ ])
+ ->add('ipn', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.ipn'),
+ 'orderField' => 'NATSORT(assembly.ipn)'
+ ])
+ ->add('description', MarkdownColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.description'),
+ ])
+ ->add('addedDate', LocaleDateTimeColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.addedDate'),
+ ])
+ ->add('lastModified', LocaleDateTimeColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.lastModified'),
+ ]);
+
+ //Add a assembly column to list where the assembly is used as referenced assembly as bom-entry, when the user has the permission to see the assemblies
+ if ($this->security->isGranted('read', Assembly::class)) {
+ $this->csh->add('referencedAssemblies', TextColumn::class, [
+ 'label' => $this->translator->trans('assembly.referencedAssembly.labelp'),
+ 'render' => function ($value, Assembly $context): string {
+ $assemblies = $context->getReferencedAssemblies();
+
+ $max = 5;
+ $tmp = "";
+
+ for ($i = 0; $i < min($max, count($assemblies)); $i++) {
+ $url = $this->urlGenerator->infoURL($assemblies[$i]);
+ $tmp .= sprintf('%s', $url, htmlspecialchars($assemblies[$i]->getName()));
+ if ($i < count($assemblies) - 1) {
+ $tmp .= ", ";
+ }
+ }
+
+ if (count($assemblies) > $max) {
+ $tmp .= ", + ".(count($assemblies) - $max);
+ }
+
+ return $tmp;
+ }
+ ]);
+ }
+
+ $this->csh
+ ->add('edit', IconLinkColumn::class, [
+ 'label' => $this->translator->trans('assembly.table.edit'),
+ 'href' => fn($value, Assembly $context) => $this->urlGenerator->editURL($context),
+ 'disabled' => fn($value, Assembly $context) => !$this->security->isGranted('edit', $context),
+ 'title' => $this->translator->trans('assembly.table.edit.title'),
+ ]);
+
+ //Apply the user configured order and visibility and add the columns to the table
+ $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns, "TABLE_ASSEMBLIES_DEFAULT_COLUMNS");
+
+ $dataTable->addOrderBy('name')
+ ->createAdapter(TwoStepORMAdapter::class, [
+ 'filter_query' => $this->getFilterQuery(...),
+ 'detail_query' => $this->getDetailQuery(...),
+ 'entity' => Assembly::class,
+ 'hydrate' => AbstractQuery::HYDRATE_OBJECT,
+ //Use the simple total query, as we just want to get the total number of assemblies without any conditions
+ //For this the normal query would be pretty slow
+ 'simple_total_query' => true,
+ 'criteria' => [
+ function (QueryBuilder $builder) use ($options): void {
+ $this->buildCriteria($builder, $options);
+ },
+ new SearchCriteriaProvider(),
+ ],
+ 'query_modifier' => $this->addJoins(...),
+ ]);
+ }
+
+
+ private function getFilterQuery(QueryBuilder $builder): void
+ {
+ /* In the filter query we only select the IDs. The fetching of the full entities is done in the detail query.
+ * We only need to join the entities here, so we can filter by them.
+ * The filter conditions are added to this QB in the buildCriteria method.
+ *
+ * The amountSum field and the joins are dynamically added by the addJoins method, if the fields are used in the query.
+ * This improves the performance, as we do not need to join all tables, if we do not need them.
+ */
+ $builder
+ ->select('assembly.id')
+ ->from(Assembly::class, 'assembly')
+
+ //The other group by fields, are dynamically added by the addJoins method
+ ->addGroupBy('assembly');
+ }
+
+ private function getDetailQuery(QueryBuilder $builder, array $filter_results): void
+ {
+ $ids = array_map(static fn($row) => $row['id'], $filter_results);
+
+ /*
+ * In this query we take the IDs which were filtered, paginated and sorted in the filter query, and fetch the
+ * full entities.
+ * We can do complex fetch joins, as we do not need to filter or sort here (which would kill the performance).
+ * The only condition should be for the IDs.
+ * It is important that elements are ordered the same way, as the IDs are passed, or ordering will be wrong.
+ *
+ * We do not require the subqueries like amountSum here, as it is not used to render the table (and only for sorting)
+ */
+ $builder
+ ->select('assembly')
+ ->addSelect('master_picture_attachment')
+ ->addSelect('attachments')
+ ->from(Assembly::class, 'assembly')
+ ->leftJoin('assembly.master_picture_attachment', 'master_picture_attachment')
+ ->leftJoin('assembly.attachments', 'attachments')
+ ->where('assembly.id IN (:ids)')
+ ->setParameter('ids', $ids)
+ ->addGroupBy('assembly')
+ ->addGroupBy('master_picture_attachment')
+ ->addGroupBy('attachments');
+
+ //Get the results in the same order as the IDs were passed
+ FieldHelper::addOrderByFieldParam($builder, 'assembly.id', 'ids');
+ }
+
+ /**
+ * This function is called right before the filter query is executed.
+ * We use it to dynamically add joins to the query, if the fields are used in the query.
+ * @param QueryBuilder $builder
+ * @return QueryBuilder
+ */
+ private function addJoins(QueryBuilder $builder): QueryBuilder
+ {
+ //Check if the query contains certain conditions, for which we need to add additional joins
+ //The join fields get prefixed with an underscore, so we can check if they are used in the query easy without confusing them for a assembly subfield
+ $dql = $builder->getDQL();
+
+ if (str_contains($dql, '_master_picture_attachment')) {
+ $builder->leftJoin('assembly.master_picture_attachment', '_master_picture_attachment');
+ $builder->addGroupBy('_master_picture_attachment');
+ }
+ if (str_contains($dql, '_attachments')) {
+ $builder->leftJoin('assembly.attachments', '_attachments');
+ }
+
+ return $builder;
+ }
+
+ private function buildCriteria(QueryBuilder $builder, array $options): void
+ {
+ //Apply the search criterias first
+ if ($options['search'] instanceof AssemblySearchFilter) {
+ $search = $options['search'];
+ $search->apply($builder);
+ }
+
+ //We do the most stuff here in the filter class
+ if ($options['filter'] instanceof AssemblyFilter) {
+ $filter = $options['filter'];
+ $filter->apply($builder);
+ }
+ }
+}
diff --git a/src/DataTables/Filters/AssemblyFilter.php b/src/DataTables/Filters/AssemblyFilter.php
new file mode 100644
index 000000000..d8d07a1ec
--- /dev/null
+++ b/src/DataTables/Filters/AssemblyFilter.php
@@ -0,0 +1,68 @@
+.
+ */
+namespace App\DataTables\Filters;
+
+use App\DataTables\Filters\Constraints\DateTimeConstraint;
+use App\DataTables\Filters\Constraints\EntityConstraint;
+use App\DataTables\Filters\Constraints\IntConstraint;
+use App\DataTables\Filters\Constraints\TextConstraint;
+use App\Entity\Attachments\AttachmentType;
+use App\Services\Trees\NodesListBuilder;
+use Doctrine\ORM\QueryBuilder;
+
+class AssemblyFilter implements FilterInterface
+{
+
+ use CompoundFilterTrait;
+
+ public readonly IntConstraint $dbId;
+ public readonly TextConstraint $ipn;
+ public readonly TextConstraint $name;
+ public readonly TextConstraint $description;
+ public readonly TextConstraint $comment;
+ public readonly DateTimeConstraint $lastModified;
+ public readonly DateTimeConstraint $addedDate;
+
+ public readonly IntConstraint $attachmentsCount;
+ public readonly EntityConstraint $attachmentType;
+ public readonly TextConstraint $attachmentName;
+
+ public function __construct(NodesListBuilder $nodesListBuilder)
+ {
+ $this->name = new TextConstraint('assembly.name');
+ $this->description = new TextConstraint('assembly.description');
+ $this->comment = new TextConstraint('assembly.comment');
+ $this->dbId = new IntConstraint('assembly.id');
+ $this->ipn = new TextConstraint('assembly.ipn');
+ $this->addedDate = new DateTimeConstraint('assembly.addedDate');
+ $this->lastModified = new DateTimeConstraint('assembly.lastModified');
+ $this->attachmentsCount = new IntConstraint('COUNT(_attachments)');
+ $this->attachmentType = new EntityConstraint($nodesListBuilder, AttachmentType::class, '_attachments.attachment_type');
+ $this->attachmentName = new TextConstraint('_attachments.name');
+ }
+
+ public function apply(QueryBuilder $queryBuilder): void
+ {
+ $this->applyAllChildFilters($queryBuilder);
+ }
+}
diff --git a/src/DataTables/Filters/AssemblySearchFilter.php b/src/DataTables/Filters/AssemblySearchFilter.php
new file mode 100644
index 000000000..1627cc612
--- /dev/null
+++ b/src/DataTables/Filters/AssemblySearchFilter.php
@@ -0,0 +1,183 @@
+.
+ */
+namespace App\DataTables\Filters;
+use Doctrine\ORM\QueryBuilder;
+
+class AssemblySearchFilter implements FilterInterface
+{
+
+ /** @var boolean Whether to use regex for searching */
+ protected bool $regex = false;
+
+ /** @var bool Use name field for searching */
+ protected bool $name = true;
+
+ /** @var bool Use description for searching */
+ protected bool $description = true;
+
+ /** @var bool Use comment field for searching */
+ protected bool $comment = true;
+
+ /** @var bool Use ordernr for searching */
+ protected bool $ordernr = true;
+
+ /** @var bool Use Internal part number for searching */
+ protected bool $ipn = true;
+
+ public function __construct(
+ /** @var string The string to query for */
+ protected string $keyword
+ )
+ {
+ }
+
+ protected function getFieldsToSearch(): array
+ {
+ $fields_to_search = [];
+
+ if($this->name) {
+ $fields_to_search[] = 'assembly.name';
+ }
+ if($this->description) {
+ $fields_to_search[] = 'assembly.description';
+ }
+ if ($this->comment) {
+ $fields_to_search[] = 'assembly.comment';
+ }
+ if ($this->ipn) {
+ $fields_to_search[] = 'assembly.ipn';
+ }
+
+ return $fields_to_search;
+ }
+
+ public function apply(QueryBuilder $queryBuilder): void
+ {
+ $fields_to_search = $this->getFieldsToSearch();
+
+ //If we have nothing to search for, do nothing
+ if ($fields_to_search === [] || $this->keyword === '') {
+ return;
+ }
+
+ //Convert the fields to search to a list of expressions
+ $expressions = array_map(function (string $field): string {
+ if ($this->regex) {
+ return sprintf("REGEXP(%s, :search_query) = TRUE", $field);
+ }
+
+ return sprintf("ILIKE(%s, :search_query) = TRUE", $field);
+ }, $fields_to_search);
+
+ //Add Or concatenation of the expressions to our query
+ $queryBuilder->andWhere(
+ $queryBuilder->expr()->orX(...$expressions)
+ );
+
+ //For regex, we pass the query as is, for like we add % to the start and end as wildcards
+ if ($this->regex) {
+ $queryBuilder->setParameter('search_query', $this->keyword);
+ } else {
+ $queryBuilder->setParameter('search_query', '%' . $this->keyword . '%');
+ }
+ }
+
+ public function getKeyword(): string
+ {
+ return $this->keyword;
+ }
+
+ public function setKeyword(string $keyword): AssemblySearchFilter
+ {
+ $this->keyword = $keyword;
+ return $this;
+ }
+
+ public function isRegex(): bool
+ {
+ return $this->regex;
+ }
+
+ public function setRegex(bool $regex): AssemblySearchFilter
+ {
+ $this->regex = $regex;
+ return $this;
+ }
+
+ public function isName(): bool
+ {
+ return $this->name;
+ }
+
+ public function setName(bool $name): AssemblySearchFilter
+ {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function isCategory(): bool
+ {
+ return $this->category;
+ }
+
+ public function setCategory(bool $category): AssemblySearchFilter
+ {
+ $this->category = $category;
+ return $this;
+ }
+
+ public function isDescription(): bool
+ {
+ return $this->description;
+ }
+
+ public function setDescription(bool $description): AssemblySearchFilter
+ {
+ $this->description = $description;
+ return $this;
+ }
+
+ public function isIPN(): bool
+ {
+ return $this->ipn;
+ }
+
+ public function setIPN(bool $ipn): AssemblySearchFilter
+ {
+ $this->ipn = $ipn;
+ return $this;
+ }
+
+ public function isComment(): bool
+ {
+ return $this->comment;
+ }
+
+ public function setComment(bool $comment): AssemblySearchFilter
+ {
+ $this->comment = $comment;
+ return $this;
+ }
+
+
+}
diff --git a/src/DataTables/Helpers/AssemblyDataTableHelper.php b/src/DataTables/Helpers/AssemblyDataTableHelper.php
new file mode 100644
index 000000000..dda563ea4
--- /dev/null
+++ b/src/DataTables/Helpers/AssemblyDataTableHelper.php
@@ -0,0 +1,77 @@
+.
+ */
+
+namespace App\DataTables\Helpers;
+
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\Attachments\Attachment;
+use App\Services\Attachments\AssemblyPreviewGenerator;
+use App\Services\Attachments\AttachmentURLGenerator;
+use App\Services\EntityURLGenerator;
+
+/**
+ * A helper service which contains common code to render columns for assembly related tables
+ */
+class AssemblyDataTableHelper
+{
+ public function __construct(
+ private readonly EntityURLGenerator $entityURLGenerator,
+ private readonly AssemblyPreviewGenerator $previewGenerator,
+ private readonly AttachmentURLGenerator $attachmentURLGenerator
+ ) {
+ }
+
+ public function renderName(Assembly $context): string
+ {
+ $icon = '';
+
+ return sprintf(
+ '%s%s',
+ $this->entityURLGenerator->infoURL($context),
+ $icon,
+ htmlspecialchars($context->getName())
+ );
+ }
+
+ public function renderPicture(Assembly $context): string
+ {
+ $preview_attachment = $this->previewGenerator->getTablePreviewAttachment($context);
+ if (!$preview_attachment instanceof Attachment) {
+ return '';
+ }
+
+ $title = htmlspecialchars($preview_attachment->getName());
+ if ($preview_attachment->getFilename()) {
+ $title .= ' ('.htmlspecialchars($preview_attachment->getFilename()).')';
+ }
+
+ return sprintf(
+ '',
+ 'Assembly image',
+ $this->attachmentURLGenerator->getThumbnailURL($preview_attachment),
+ $this->attachmentURLGenerator->getThumbnailURL($preview_attachment, 'thumbnail_md'),
+ 'hoverpic assembly-table-image',
+ $title
+ );
+ }
+}
diff --git a/src/DataTables/Helpers/ProjectDataTableHelper.php b/src/DataTables/Helpers/ProjectDataTableHelper.php
index 0118d5d56..baa0e24e1 100644
--- a/src/DataTables/Helpers/ProjectDataTableHelper.php
+++ b/src/DataTables/Helpers/ProjectDataTableHelper.php
@@ -27,7 +27,7 @@
use App\Services\EntityURLGenerator;
/**
- * A helper service which contains common code to render columns for assembly related tables
+ * A helper service which contains common code to render columns for project related tables
*/
class ProjectDataTableHelper
{
diff --git a/src/Form/Filters/AssemblyFilterType.php b/src/Form/Filters/AssemblyFilterType.php
new file mode 100644
index 000000000..acfbb1a8e
--- /dev/null
+++ b/src/Form/Filters/AssemblyFilterType.php
@@ -0,0 +1,114 @@
+.
+ */
+namespace App\Form\Filters;
+
+use App\DataTables\Filters\AssemblyFilter;
+use App\Entity\Attachments\AttachmentType;
+use App\Form\Filters\Constraints\DateTimeConstraintType;
+use App\Form\Filters\Constraints\NumberConstraintType;
+use App\Form\Filters\Constraints\StructuralEntityConstraintType;
+use App\Form\Filters\Constraints\TextConstraintType;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\ResetType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class AssemblyFilterType extends AbstractType
+{
+ public function configureOptions(OptionsResolver $resolver): void
+ {
+ $resolver->setDefaults([
+ 'compound' => true,
+ 'data_class' => AssemblyFilter::class,
+ 'csrf_protection' => false,
+ ]);
+ }
+
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ /*
+ * Common tab
+ */
+
+ $builder->add('name', TextConstraintType::class, [
+ 'label' => 'assembly.filter.name',
+ ]);
+
+ $builder->add('description', TextConstraintType::class, [
+ 'label' => 'assembly.filter.description',
+ ]);
+
+ $builder->add('comment', TextConstraintType::class, [
+ 'label' => 'assembly.filter.comment'
+ ]);
+
+ /*
+ * Advanced tab
+ */
+
+ $builder->add('dbId', NumberConstraintType::class, [
+ 'label' => 'assembly.filter.dbId',
+ 'min' => 1,
+ 'step' => 1,
+ ]);
+
+ $builder->add('ipn', TextConstraintType::class, [
+ 'label' => 'assembly.filter.ipn',
+ ]);
+
+ $builder->add('lastModified', DateTimeConstraintType::class, [
+ 'label' => 'lastModified'
+ ]);
+
+ $builder->add('addedDate', DateTimeConstraintType::class, [
+ 'label' => 'createdAt'
+ ]);
+
+ /**
+ * Attachments count
+ */
+ $builder->add('attachmentsCount', NumberConstraintType::class, [
+ 'label' => 'assembly.filter.attachments_count',
+ 'step' => 1,
+ 'min' => 0,
+ ]);
+
+ $builder->add('attachmentType', StructuralEntityConstraintType::class, [
+ 'label' => 'attachment.attachment_type',
+ 'entity_class' => AttachmentType::class
+ ]);
+
+ $builder->add('attachmentName', TextConstraintType::class, [
+ 'label' => 'assembly.filter.attachmentName',
+ ]);
+
+ $builder->add('submit', SubmitType::class, [
+ 'label' => 'filter.submit',
+ ]);
+
+ $builder->add('discard', ResetType::class, [
+ 'label' => 'filter.discard',
+ ]);
+ }
+}
diff --git a/templates/assemblies/lists/_action_bar.html.twig b/templates/assemblies/lists/_action_bar.html.twig
new file mode 100644
index 000000000..37289812a
--- /dev/null
+++ b/templates/assemblies/lists/_action_bar.html.twig
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/templates/assemblies/lists/_filter.html.twig b/templates/assemblies/lists/_filter.html.twig
new file mode 100644
index 000000000..11be7bc24
--- /dev/null
+++ b/templates/assemblies/lists/_filter.html.twig
@@ -0,0 +1,62 @@
+
+
+ {% trans %}filter.title{% endtrans %}
+
+
+
+
+
+ {% trans %}assembly.edit.tab.common{% endtrans %}
+
+
+ {% trans %}assembly.edit.tab.advanced{% endtrans %}
+
+
+ {% trans %}assembly.edit.tab.attachments{% endtrans %}
+
+
+ {# Retain the query parameters of the search form if it is existing #}
+ {% if searchFilter is defined %}
+ {% for property, value in searchFilter|to_array %}
+
+ {% endfor %}
+
+ {% endif %}
+
+ {{ form_end(filterForm) }}
+
+
+
\ No newline at end of file
diff --git a/templates/assemblies/lists/all_list.html.twig b/templates/assemblies/lists/all_list.html.twig
new file mode 100644
index 000000000..70d75ad40
--- /dev/null
+++ b/templates/assemblies/lists/all_list.html.twig
@@ -0,0 +1,30 @@
+{% extends "base.html.twig" %}
+
+{% block title %}
+ {% trans %}assembly_list.all.title{% endtrans %}
+{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+ {% trans %}assembly_list.all.title{% endtrans %}
+
+
+
+
+
+
+
+
+
+ {% include "assemblies/lists/_filter.html.twig" %}
+
+
+ {% include "assemblies/lists/_action_bar.html.twig" with {'url_options': {}} %}
+ {% include "assemblies/lists/data.html.twig" %}
+
+{% endblock %}
diff --git a/templates/assemblies/lists/data.html.twig b/templates/assemblies/lists/data.html.twig
new file mode 100644
index 000000000..69e13e4f5
--- /dev/null
+++ b/templates/assemblies/lists/data.html.twig
@@ -0,0 +1,3 @@
+{% import "components/datatables.macro.html.twig" as datatables %}
+
+{{ datatables.partsDatatableWithForm(datatable) }}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index 4191cf30c..34e21fa34 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -14619,5 +14619,131 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
+
+
+ assembly_list.all.title
+ Všechny sestavy
+
+
+
+
+ assembly.edit.tab.common
+ Obecné
+
+
+
+
+ assembly.edit.tab.advanced
+ Pokročilé možnosti
+
+
+
+
+ assembly.edit.tab.attachments
+ Přílohy
+
+
+
+
+ assembly.filter.dbId
+ ID databáze
+
+
+
+
+ assembly.filter.ipn
+ Interní číslo dílu (IPN)
+
+
+
+
+ assembly.filter.name
+ Název
+
+
+
+
+ assembly.filter.description
+ Popis
+
+
+
+
+ assembly.filter.comment
+ Poznámky
+
+
+
+
+ assembly.filter.attachments_count
+ Počet příloh
+
+
+
+
+ assembly.filter.attachmentName
+ Název přílohy
+
+
+
+
+ assemblies.create.btn
+ Vytvořit novou sestavu
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Název
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Popis
+
+
+
+
+ assembly.table.addedDate
+ Přidáno
+
+
+
+
+ assembly.table.lastModified
+ Naposledy upraveno
+
+
+
+
+ assembly.table.edit
+ Upravit
+
+
+
+
+ assembly.table.edit.title
+ Upravit sestavu
+
+
+
+
+ assembly.table.invalid_regex
+ Neplatný regulární výraz (regex)
+
+
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index c68acdd4b..5901e9f5a 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -13336,5 +13336,131 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
+
+
+ assembly_list.all.title
+ Alle samlinger
+
+
+
+
+ assembly.edit.tab.common
+ Generelt
+
+
+
+
+ assembly.edit.tab.advanced
+ Avancerede indstillinger
+
+
+
+
+ assembly.edit.tab.attachments
+ Vedhæftede filer
+
+
+
+
+ assembly.filter.dbId
+ Database-ID
+
+
+
+
+ assembly.filter.ipn
+ Internt delnummer (IPN)
+
+
+
+
+ assembly.filter.name
+ Navn
+
+
+
+
+ assembly.filter.description
+ Beskrivelse
+
+
+
+
+ assembly.filter.comment
+ Kommentarer
+
+
+
+
+ assembly.filter.attachments_count
+ Antal vedhæftninger
+
+
+
+
+ assembly.filter.attachmentName
+ Vedhæftningens navn
+
+
+
+
+ assemblies.create.btn
+ Opret ny samling
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Navn
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Beskrivelse
+
+
+
+
+ assembly.table.addedDate
+ Tilføjet
+
+
+
+
+ assembly.table.lastModified
+ Sidst ændret
+
+
+
+
+ assembly.table.edit
+ Rediger
+
+
+
+
+ assembly.table.edit.title
+ Rediger samling
+
+
+
+
+ assembly.table.invalid_regex
+ Ugyldigt regulært udtryk (regex)
+
+
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index bee171d41..a7ece41a9 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -14621,5 +14621,131 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Min. Vorschaubilde-Breite (px)
+
+
+ assembly_list.all.title
+ Alle Baugruppen
+
+
+
+
+ assembly.edit.tab.common
+ Allgemein
+
+
+
+
+ assembly.edit.tab.advanced
+ Erweiterte Optionen
+
+
+
+
+ assembly.edit.tab.attachments
+ Dateianhänge
+
+
+
+
+ assembly.filter.dbId
+ Datenbank ID
+
+
+
+
+ assembly.filter.ipn
+ Internal Part Number (IPN)
+
+
+
+
+ assembly.filter.name
+ Name
+
+
+
+
+ assembly.filter.description
+ Beschreibung
+
+
+
+
+ assembly.filter.comment
+ Notizen
+
+
+
+
+ assembly.filter.attachments_count
+ Anzahl der Anhänge
+
+
+
+
+ assembly.filter.attachmentName
+ Name des Anhangs
+
+
+
+
+ assemblies.create.btn
+ Neue Baugruppe anlegen
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Name
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Beschreibung
+
+
+
+
+ assembly.table.addedDate
+ Hinzugefügt
+
+
+
+
+ assembly.table.lastModified
+ Zuletzt bearbeitet
+
+
+
+
+ assembly.table.edit
+ Ändern
+
+
+
+
+ assembly.table.edit.title
+ Baugruppe ändern
+
+
+
+
+ assembly.table.invalid_regex
+ Ungültiger regulärer Ausdruck (regex)
+
+
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index 97b27f53f..fd5114539 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -2344,5 +2344,131 @@
+
+
+ assembly_list.all.title
+ Όλες οι συναρμολογήσεις
+
+
+
+
+ assembly.edit.tab.common
+ Γενικά
+
+
+
+
+ assembly.edit.tab.advanced
+ Προηγμένες επιλογές
+
+
+
+
+ assembly.edit.tab.attachments
+ Συνημμένα
+
+
+
+
+ assembly.filter.dbId
+ Αναγνωριστικό βάσης δεδομένων
+
+
+
+
+ assembly.filter.ipn
+ Εσωτερικός αριθμός εξαρτήματος (IPN)
+
+
+
+
+ assembly.filter.name
+ Όνομα
+
+
+
+
+ assembly.filter.description
+ Περιγραφή
+
+
+
+
+ assembly.filter.comment
+ Σχόλια
+
+
+
+
+ assembly.filter.attachments_count
+ Αριθμός συνημμένων
+
+
+
+
+ assembly.filter.attachmentName
+ Όνομα συνημμένου
+
+
+
+
+ assemblies.create.btn
+ Δημιουργία νέας συναρμολόγησης
+
+
+
+
+ assembly.table.id
+ Αναγνωριστικό
+
+
+
+
+ assembly.table.name
+ Όνομα
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Περιγραφή
+
+
+
+
+ assembly.table.addedDate
+ Προστέθηκε
+
+
+
+
+ assembly.table.lastModified
+ Τελευταία επεξεργασία
+
+
+
+
+ assembly.table.edit
+ Επεξεργασία
+
+
+
+
+ assembly.table.edit.title
+ Επεξεργασία συναρμολόγησης
+
+
+
+
+ assembly.table.invalid_regex
+ Μη έγκυρη κανονική έκφραση (regex)
+
+
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 2100548d3..a1003f3f5 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -14622,5 +14622,131 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Preview image min width (px)
+
+
+ assembly_list.all.title
+ All assemblies
+
+
+
+
+ assembly.edit.tab.common
+ General
+
+
+
+
+ assembly.edit.tab.advanced
+ Advanced options
+
+
+
+
+ assembly.edit.tab.attachments
+ Attachments
+
+
+
+
+ assembly.filter.dbId
+ Database ID
+
+
+
+
+ assembly.filter.ipn
+ Internal Part Number (IPN)
+
+
+
+
+ assembly.filter.name
+ Name
+
+
+
+
+ assembly.filter.description
+ Description
+
+
+
+
+ assembly.filter.comment
+ Comments
+
+
+
+
+ assembly.filter.attachments_count
+ Number of attachments
+
+
+
+
+ assembly.filter.attachmentName
+ Attachment name
+
+
+
+
+ assemblies.create.btn
+ Create new assembly
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Name
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Description
+
+
+
+
+ assembly.table.addedDate
+ Added
+
+
+
+
+ assembly.table.lastModified
+ Last modified
+
+
+
+
+ assembly.table.edit
+ Edit
+
+
+
+
+ assembly.table.edit.title
+ Edit assembly
+
+
+
+
+ assembly.table.invalid_regex
+ Invalid regular expression (regex)
+
+
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index d4ece66ea..5854628c1 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -13508,5 +13508,131 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
+
+
+ assembly_list.all.title
+ Todas las ensamblajes
+
+
+
+
+ assembly.edit.tab.common
+ General
+
+
+
+
+ assembly.edit.tab.advanced
+ Opciones avanzadas
+
+
+
+
+ assembly.edit.tab.attachments
+ Archivos adjuntos
+
+
+
+
+ assembly.filter.dbId
+ ID de la base de datos
+
+
+
+
+ assembly.filter.ipn
+ Número interno de pieza (IPN)
+
+
+
+
+ assembly.filter.name
+ Nombre
+
+
+
+
+ assembly.filter.description
+ Descripción
+
+
+
+
+ assembly.filter.comment
+ Comentarios
+
+
+
+
+ assembly.filter.attachments_count
+ Cantidad de adjuntos
+
+
+
+
+ assembly.filter.attachmentName
+ Nombre del adjunto
+
+
+
+
+ assemblies.create.btn
+ Crear una nueva ensamblaje
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Nombre
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Descripción
+
+
+
+
+ assembly.table.addedDate
+ Añadido
+
+
+
+
+ assembly.table.lastModified
+ Última modificación
+
+
+
+
+ assembly.table.edit
+ Editar
+
+
+
+
+ assembly.table.edit.title
+ Editar ensamblaje
+
+
+
+
+ assembly.table.invalid_regex
+ Expresión regular no válida (regex)
+
+
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index a75db3a3a..2b4341ca2 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -9918,5 +9918,131 @@ exemple de ville
+
+
+ assembly_list.all.title
+ Toutes les assemblages
+
+
+
+
+ assembly.edit.tab.common
+ Général
+
+
+
+
+ assembly.edit.tab.advanced
+ Options avancées
+
+
+
+
+ assembly.edit.tab.attachments
+ Pièces jointes
+
+
+
+
+ assembly.filter.dbId
+ ID de la base de données
+
+
+
+
+ assembly.filter.ipn
+ Numéro de pièce interne (IPN)
+
+
+
+
+ assembly.filter.name
+ Nom
+
+
+
+
+ assembly.filter.description
+ Description
+
+
+
+
+ assembly.filter.comment
+ Commentaires
+
+
+
+
+ assembly.filter.attachments_count
+ Nombre de pièces jointes
+
+
+
+
+ assembly.filter.attachmentName
+ Nom de la pièce jointe
+
+
+
+
+ assemblies.create.btn
+ Créer un nouvel assemblage
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Nom
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Description
+
+
+
+
+ assembly.table.addedDate
+ Ajouté
+
+
+
+
+ assembly.table.lastModified
+ Dernière modification
+
+
+
+
+ assembly.table.edit
+ Modifier
+
+
+
+
+ assembly.table.edit.title
+ Modifier l'assemblage
+
+
+
+
+ assembly.table.invalid_regex
+ Expression régulière invalide (regex)
+
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index 12e20ca2c..c727eef82 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -13510,5 +13510,131 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Questo componente contiene più di uno stock. Cambia manualmente la posizione per selezionare quale stock scegliere.
+
+
+ assembly_list.all.title
+ Tutti gli assiemi
+
+
+
+
+ assembly.edit.tab.common
+ Generale
+
+
+
+
+ assembly.edit.tab.advanced
+ Opzioni avanzate
+
+
+
+
+ assembly.edit.tab.attachments
+ Allegati
+
+
+
+
+ assembly.filter.dbId
+ ID del database
+
+
+
+
+ assembly.filter.ipn
+ Numero interno di parte (IPN)
+
+
+
+
+ assembly.filter.name
+ Nome
+
+
+
+
+ assembly.filter.description
+ Descrizione
+
+
+
+
+ assembly.filter.comment
+ Commenti
+
+
+
+
+ assembly.filter.attachments_count
+ Numero di allegati
+
+
+
+
+ assembly.filter.attachmentName
+ Nome dell'allegato
+
+
+
+
+ assemblies.create.btn
+ Crea un nuovo assieme
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Nome
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Descrizione
+
+
+
+
+ assembly.table.addedDate
+ Aggiunto
+
+
+
+
+ assembly.table.lastModified
+ Ultima modifica
+
+
+
+
+ assembly.table.edit
+ Modifica
+
+
+
+
+ assembly.table.edit.title
+ Modifica l'assieme
+
+
+
+
+ assembly.table.invalid_regex
+ Espressione regolare non valida (regex)
+
+
diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf
index b7be7490d..157b1cf26 100644
--- a/translations/messages.ja.xlf
+++ b/translations/messages.ja.xlf
@@ -9631,5 +9631,131 @@ Exampletown
+
+
+ assembly_list.all.title
+ すべてのアセンブリ
+
+
+
+
+ assembly.edit.tab.common
+ 一般
+
+
+
+
+ assembly.edit.tab.advanced
+ 詳細オプション
+
+
+
+
+ assembly.edit.tab.attachments
+ 添付ファイル
+
+
+
+
+ assembly.filter.dbId
+ データベースID
+
+
+
+
+ assembly.filter.ipn
+ 内部部品番号(IPN)
+
+
+
+
+ assembly.filter.name
+ 名前
+
+
+
+
+ assembly.filter.description
+ 説明
+
+
+
+
+ assembly.filter.comment
+ コメント
+
+
+
+
+ assembly.filter.attachments_count
+ 添付ファイルの数
+
+
+
+
+ assembly.filter.attachmentName
+ 添付ファイル名
+
+
+
+
+ assemblies.create.btn
+ 新しいアセンブリを作成
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ 名前
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ 説明
+
+
+
+
+ assembly.table.addedDate
+ 追加日
+
+
+
+
+ assembly.table.lastModified
+ 最終変更
+
+
+
+
+ assembly.table.edit
+ 編集
+
+
+
+
+ assembly.table.edit.title
+ アセンブリを編集
+
+
+
+
+ assembly.table.invalid_regex
+ 無効な正規表現(regex)
+
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index fe17c3aca..44a48dcb3 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -1569,5 +1569,131 @@
+
+
+ assembly_list.all.title
+ Alle assemblages
+
+
+
+
+ assembly.edit.tab.common
+ Algemeen
+
+
+
+
+ assembly.edit.tab.advanced
+ Geavanceerde opties
+
+
+
+
+ assembly.edit.tab.attachments
+ Bijlagen
+
+
+
+
+ assembly.filter.dbId
+ Database-ID
+
+
+
+
+ assembly.filter.ipn
+ Intern partnummer (IPN)
+
+
+
+
+ assembly.filter.name
+ Naam
+
+
+
+
+ assembly.filter.description
+ Beschrijving
+
+
+
+
+ assembly.filter.comment
+ Opmerkingen
+
+
+
+
+ assembly.filter.attachments_count
+ Aantal bijlagen
+
+
+
+
+ assembly.filter.attachmentName
+ Naam van de bijlage
+
+
+
+
+ assemblies.create.btn
+ Nieuwe assemblage aanmaken
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Naam
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Beschrijving
+
+
+
+
+ assembly.table.addedDate
+ Toegevoegd
+
+
+
+
+ assembly.table.lastModified
+ Laatst gewijzigd
+
+
+
+
+ assembly.table.edit
+ Bewerken
+
+
+
+
+ assembly.table.edit.title
+ Assemblage bewerken
+
+
+
+
+ assembly.table.invalid_regex
+ Ongeldige reguliere expressie (regex)
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index 73b6e4fcc..171c585d6 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -13363,5 +13363,131 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
+
+
+ assembly_list.all.title
+ Wszystkie zespoły
+
+
+
+
+ assembly.edit.tab.common
+ Ogólne
+
+
+
+
+ assembly.edit.tab.advanced
+ Zaawansowane
+
+
+
+
+ assembly.edit.tab.attachments
+ Załączniki
+
+
+
+
+ assembly.filter.dbId
+ ID bazy danych
+
+
+
+
+ assembly.filter.ipn
+ Wewnętrzny numer części (IPN)
+
+
+
+
+ assembly.filter.name
+ Nazwa
+
+
+
+
+ assembly.filter.description
+ Opis
+
+
+
+
+ assembly.filter.comment
+ Komentarze
+
+
+
+
+ assembly.filter.attachments_count
+ Liczba załączników
+
+
+
+
+ assembly.filter.attachmentName
+ Nazwa załącznika
+
+
+
+
+ assemblies.create.btn
+ Utwórz nowy zespół
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Nazwa
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Opis
+
+
+
+
+ assembly.table.addedDate
+ Dodano
+
+
+
+
+ assembly.table.lastModified
+ Ostatnia modyfikacja
+
+
+
+
+ assembly.table.edit
+ Edytuj
+
+
+
+
+ assembly.table.edit.title
+ Edytuj zespół
+
+
+
+
+ assembly.table.invalid_regex
+ Nieprawidłowe wyrażenie regularne (regex)
+
+
diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf
index 751ff35f1..7bd0f3bc4 100644
--- a/translations/messages.ru.xlf
+++ b/translations/messages.ru.xlf
@@ -13463,5 +13463,131 @@
+
+
+ assembly_list.all.title
+ Все сборки
+
+
+
+
+ assembly.edit.tab.common
+ Общие
+
+
+
+
+ assembly.edit.tab.advanced
+ Дополнительные параметры
+
+
+
+
+ assembly.edit.tab.attachments
+ Вложения
+
+
+
+
+ assembly.filter.dbId
+ ID базы данных
+
+
+
+
+ assembly.filter.ipn
+ Внутренний номер детали (IPN)
+
+
+
+
+ assembly.filter.name
+ Название
+
+
+
+
+ assembly.filter.description
+ Описание
+
+
+
+
+ assembly.filter.comment
+ Комментарии
+
+
+
+
+ assembly.filter.attachments_count
+ Количество вложений
+
+
+
+
+ assembly.filter.attachmentName
+ Имя вложения
+
+
+
+
+ assemblies.create.btn
+ Создать новую сборку
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ Название
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ Описание
+
+
+
+
+ assembly.table.addedDate
+ Добавлено
+
+
+
+
+ assembly.table.lastModified
+ Последнее изменение
+
+
+
+
+ assembly.table.edit
+ Редактировать
+
+
+
+
+ assembly.table.edit.title
+ Редактировать сборку
+
+
+
+
+ assembly.table.invalid_regex
+ Неверное регулярное выражение (regex)
+
+
diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf
index 396feae3e..9e8d8aa1f 100644
--- a/translations/messages.zh.xlf
+++ b/translations/messages.zh.xlf
@@ -13348,5 +13348,131 @@ Element 3
+
+
+ assembly_list.all.title
+ 所有组件
+
+
+
+
+ assembly.edit.tab.common
+ 通用
+
+
+
+
+ assembly.edit.tab.advanced
+ 高级选项
+
+
+
+
+ assembly.edit.tab.attachments
+ 附件
+
+
+
+
+ assembly.filter.dbId
+ 数据库ID
+
+
+
+
+ assembly.filter.ipn
+ 内部零件编号(IPN)
+
+
+
+
+ assembly.filter.name
+ 名称
+
+
+
+
+ assembly.filter.description
+ 描述
+
+
+
+
+ assembly.filter.comment
+ 评论
+
+
+
+
+ assembly.filter.attachments_count
+ 附件数量
+
+
+
+
+ assembly.filter.attachmentName
+ 附件名称
+
+
+
+
+ assemblies.create.btn
+ 创建新组件
+
+
+
+
+ assembly.table.id
+ ID
+
+
+
+
+ assembly.table.name
+ 名称
+
+
+
+
+ assembly.table.ipn
+ IPN
+
+
+
+
+ assembly.table.description
+ 描述
+
+
+
+
+ assembly.table.addedDate
+ 添加日期
+
+
+
+
+ assembly.table.lastModified
+ 最后修改
+
+
+
+
+ assembly.table.edit
+ 编辑
+
+
+
+
+ assembly.table.edit.title
+ 编辑组件
+
+
+
+
+ assembly.table.invalid_regex
+ 无效的正则表达式(regex)
+
+
From 669ad371dfc0a7f46955b0be025c90a28a372fe9 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 3 Jul 2025 13:50:33 +0200
Subject: [PATCH 52/83] =?UTF-8?q?Assembly=20Konstanten=20in=20.env=20einf?=
=?UTF-8?q?=C3=BCgen=20bzw.=20anpassen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/.env b/.env
index cfa3bb053..8d89896a6 100644
--- a/.env
+++ b/.env
@@ -35,6 +35,9 @@ DATABASE_EMULATE_NATURAL_SORT=0
# This must end with a slash!
DEFAULT_URI="https://partdb.changeme.invalid/"
+# Use an %%ipn%% placeholder in the name of a assembly. Placeholder is replaced with the ipn input while saving.
+CREATE_ASSEMBLY_USE_IPN_PLACEHOLDER_IN_NAME=0
+
###################################################################################
# Email settings
###################################################################################
@@ -67,7 +70,8 @@ ERROR_PAGE_SHOW_HELP=1
# Configure which columns will be visible by default in the specific table (and in which order).
# This is a comma separated list of column names. See documentation for available values.
TABLE_PARTS_DEFAULT_COLUMNS=name,description,category,footprint,manufacturer,storage_location,amount
-TABLE_ASSEMBLIES_DEFAULT_COLUMNS=quantity,manufacturer,name,description,category
+TABLE_ASSEMBLIES_DEFAULT_COLUMNS=id,ipn,name,description,referencedAssemblies,edit
+TABLE_ASSEMBLIES_BOM_DEFAULT_COLUMNS=quantity,id,ipn,name,description
###################################################################################
From e1c6b42b500616d9ed0c4f81b97b6eed5c222772 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 3 Jul 2025 14:47:19 +0200
Subject: [PATCH 53/83] Assembly getReferencedAssemblies korrigieren
---
src/Entity/AssemblySystem/Assembly.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php
index 5991b9e1d..9593dbb53 100644
--- a/src/Entity/AssemblySystem/Assembly.php
+++ b/src/Entity/AssemblySystem/Assembly.php
@@ -400,7 +400,7 @@ public function getReferencedAssemblies(): array
$assemblies = [];
foreach($this->bom_entries as $entry) {
- if ($entry->getAssembly() !== null) {
+ if ($entry->getReferencedAssembly() !== null) {
$assemblies[] = $entry->getReferencedAssembly();
}
}
From 186105105794c52a02b834acec0d19ece04065a1 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 7 Jul 2025 10:08:19 +0200
Subject: [PATCH 54/83] =?UTF-8?q?F=C3=BCge=20Unterst=C3=BCtzung=20f=C3=BCr?=
=?UTF-8?q?=20Datenquellen-Synonyme=20hinzu.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ermöglicht benutzerdefinierte Synonyme für Datenquellen basierend auf Locale. Synonyme werden in verschiedenen Bereichen wie Bäumen, Übersetzungen und Vorlagen genutzt, um anpassbare Namen anzuzeigen.
---
config/parameters.yaml | 14 ++++++
config/services.yaml | 19 ++++++++
src/Controller/AssemblyController.php | 1 +
src/Services/Trees/ToolsTreeBuilder.php | 43 +++++++++++++++----
src/Services/Trees/TreeViewGenerator.php | 36 +++++++++++++---
src/Twig/DataSourceNameExtension.php | 42 ++++++++++++++++++
templates/admin/assembly_admin.html.twig | 4 +-
templates/admin/category_admin.html.twig | 4 +-
templates/admin/footprint_admin.html.twig | 4 +-
templates/admin/manufacturer_admin.html.twig | 4 +-
templates/admin/project_admin.html.twig | 4 +-
templates/admin/storelocation_admin.html.twig | 4 +-
templates/admin/supplier_admin.html.twig | 4 +-
templates/components/tree_macros.html.twig | 24 ++++++-----
templates/form/permission_layout.html.twig | 23 +++++++++-
translations/messages.cs.xlf | 6 +++
translations/messages.da.xlf | 6 +++
translations/messages.de.xlf | 6 +++
translations/messages.el.xlf | 6 +++
translations/messages.en.xlf | 6 +++
translations/messages.es.xlf | 6 +++
translations/messages.fr.xlf | 6 +++
translations/messages.it.xlf | 6 +++
translations/messages.ja.xlf | 6 +++
translations/messages.nl.xlf | 6 +++
translations/messages.pl.xlf | 6 +++
translations/messages.ru.xlf | 6 +++
translations/messages.zh.xlf | 6 +++
28 files changed, 272 insertions(+), 36 deletions(-)
create mode 100644 src/Twig/DataSourceNameExtension.php
diff --git a/config/parameters.yaml b/config/parameters.yaml
index 599fbe595..0c0c9c81e 100644
--- a/config/parameters.yaml
+++ b/config/parameters.yaml
@@ -16,6 +16,20 @@ parameters:
partdb.create_assembly_use_ipn_placeholder_in_name: '%env(bool:CREATE_ASSEMBLY_USE_IPN_PLACEHOLDER_IN_NAME)%' # Use an %%ipn%% placeholder in the name of an assembly. Placeholder is replaced with the ipn input while saving.
+ partdb.data_sources.synonyms: # Define your own synonyms for the given data sources
+ # Possible datasources: category, storagelocation, footprint, manufacturer, supplier, project, assembly
+ # Possible locales like the ones in 'partdb.locale_menu': en, de, it, fr, ru, ja, cs, da, zh, pl
+ #category:
+ #de: 'Bauteil Kategorien'
+ #en: 'Part categories'
+ #project:
+ #de: 'Geräte'
+ #en: 'Devices'
+ #assembly:
+ #de: 'Zusammengestellte Baugruppe'
+ #en: 'Combined assembly'
+
+
######################################################################################################################
# Users and Privacy
######################################################################################################################
diff --git a/config/services.yaml b/config/services.yaml
index ff8ce2ec2..8256daa1f 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -198,6 +198,25 @@ services:
$fontDirectory: '%kernel.project_dir%/var/dompdf/fonts/'
$tmpDirectory: '%kernel.project_dir%/var/dompdf/tmp/'
+ ####################################################################################################################
+ # Trees
+ ####################################################################################################################
+ App\Services\Trees\TreeViewGenerator:
+ arguments:
+ $dataSourceSynonyms: '%partdb.data_sources.synonyms%'
+ App\Services\Trees\ToolsTreeBuilder:
+ arguments:
+ $dataSourceSynonyms: '%partdb.data_sources.synonyms%'
+
+ ####################################################################################################################
+ # Twig Extensions
+ ####################################################################################################################
+
+ App\Twig\DataSourceNameExtension:
+ arguments:
+ $dataSourceSynonyms: '%partdb.data_sources.synonyms%'
+ tags: [ 'twig.extension' ]
+
####################################################################################################################
# Part info provider system
####################################################################################################################
diff --git a/src/Controller/AssemblyController.php b/src/Controller/AssemblyController.php
index a1ba7fa65..94e129643 100644
--- a/src/Controller/AssemblyController.php
+++ b/src/Controller/AssemblyController.php
@@ -29,6 +29,7 @@
use App\Entity\AssemblySystem\Assembly;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
use App\Entity\Parts\Part;
+use App\Entity\UserSystem\User;
use App\Exceptions\InvalidRegexException;
use App\Form\AssemblySystem\AssemblyAddPartsType;
use App\Form\AssemblySystem\AssemblyBuildType;
diff --git a/src/Services/Trees/ToolsTreeBuilder.php b/src/Services/Trees/ToolsTreeBuilder.php
index 5f08b8183..a2c86b7e8 100644
--- a/src/Services/Trees/ToolsTreeBuilder.php
+++ b/src/Services/Trees/ToolsTreeBuilder.php
@@ -50,8 +50,15 @@
*/
class ToolsTreeBuilder
{
- public function __construct(protected TranslatorInterface $translator, protected UrlGeneratorInterface $urlGenerator, protected TagAwareCacheInterface $cache, protected UserCacheKeyGenerator $keyGenerator, protected Security $security)
- {
+ public function __construct(
+ protected TranslatorInterface $translator,
+ protected UrlGeneratorInterface $urlGenerator,
+ protected TagAwareCacheInterface $cache,
+ protected UserCacheKeyGenerator $keyGenerator,
+ protected Security $security,
+ protected ?array $dataSourceSynonyms = [],
+ ) {
+ $this->dataSourceSynonyms = $dataSourceSynonyms ?? [];
}
/**
@@ -161,43 +168,43 @@ protected function getEditNodes(): array
}
if ($this->security->isGranted('read', new Category())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.categories'),
+ $this->getTranslatedDataSourceOrSynonym('category', 'tree.tools.edit.categories', $this->translator->getLocale()),
$this->urlGenerator->generate('category_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-tags');
}
if ($this->security->isGranted('read', new Project())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.projects'),
+ $this->getTranslatedDataSourceOrSynonym('project', 'tree.tools.edit.projects', $this->translator->getLocale()),
$this->urlGenerator->generate('project_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-archive');
}
if ($this->security->isGranted('read', new Assembly())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.assemblies'),
+ $this->getTranslatedDataSourceOrSynonym('assembly', 'tree.tools.edit.assemblies', $this->translator->getLocale()),
$this->urlGenerator->generate('assembly_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-list');
}
if ($this->security->isGranted('read', new Supplier())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.suppliers'),
+ $this->getTranslatedDataSourceOrSynonym('supplier', 'tree.tools.edit.suppliers', $this->translator->getLocale()),
$this->urlGenerator->generate('supplier_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-truck');
}
if ($this->security->isGranted('read', new Manufacturer())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.manufacturer'),
+ $this->getTranslatedDataSourceOrSynonym('manufacturer', 'tree.tools.edit.manufacturer', $this->translator->getLocale()),
$this->urlGenerator->generate('manufacturer_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-industry');
}
if ($this->security->isGranted('read', new StorageLocation())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.storelocation'),
+ $this->getTranslatedDataSourceOrSynonym('storagelocation', 'tree.tools.edit.storelocation', $this->translator->getLocale()),
$this->urlGenerator->generate('store_location_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-cube');
}
if ($this->security->isGranted('read', new Footprint())) {
$nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.edit.footprint'),
+ $this->getTranslatedDataSourceOrSynonym('footprint', 'tree.tools.edit.footprint', $this->translator->getLocale()),
$this->urlGenerator->generate('footprint_new')
))->setIcon('fa-fw fa-treeview fa-solid fa-microchip');
}
@@ -305,4 +312,22 @@ protected function getSystemNodes(): array
return $nodes;
}
+
+ protected function getTranslatedDataSourceOrSynonym(string $dataSource, string $translationKey, string $locale): string
+ {
+ $currentTranslation = $this->translator->trans($translationKey);
+
+ // Call alternatives from DataSourcesynonyms (if available)
+ if (!empty($this->dataSourceSynonyms[$dataSource][$locale])) {
+ $alternativeTranslation = $this->dataSourceSynonyms[$dataSource][$locale];
+
+ // Use alternative translation when it deviates from the standard translation
+ if ($alternativeTranslation !== $currentTranslation) {
+ return $alternativeTranslation;
+ }
+ }
+
+ // Otherwise return the standard translation
+ return $currentTranslation;
+ }
}
diff --git a/src/Services/Trees/TreeViewGenerator.php b/src/Services/Trees/TreeViewGenerator.php
index 3a0979028..d5358bfa2 100644
--- a/src/Services/Trees/TreeViewGenerator.php
+++ b/src/Services/Trees/TreeViewGenerator.php
@@ -68,9 +68,11 @@ public function __construct(
protected TranslatorInterface $translator,
private readonly UrlGeneratorInterface $router,
private readonly SidebarSettings $sidebarSettings,
+ protected ?array $dataSourceSynonyms = [],
) {
$this->rootNodeEnabled = $this->sidebarSettings->rootNodeEnabled;
$this->rootNodeExpandedByDefault = $this->sidebarSettings->rootNodeExpanded;
+ $this->dataSourceSynonyms = $dataSourceSynonyms ?? [];
}
/**
@@ -226,14 +228,16 @@ protected function entityClassToRootNodeHref(string $class): ?string
protected function entityClassToRootNodeString(string $class): string
{
+ $locale = $this->translator->getLocale();
+
return match ($class) {
- Category::class => $this->translator->trans('category.labelp'),
- StorageLocation::class => $this->translator->trans('storelocation.labelp'),
- Footprint::class => $this->translator->trans('footprint.labelp'),
- Manufacturer::class => $this->translator->trans('manufacturer.labelp'),
- Supplier::class => $this->translator->trans('supplier.labelp'),
- Project::class => $this->translator->trans('project.labelp'),
- Assembly::class => $this->translator->trans('assembly.labelp'),
+ Category::class => $this->getTranslatedOrSynonym('category', $locale),
+ StorageLocation::class => $this->getTranslatedOrSynonym('storelocation', $locale),
+ Footprint::class => $this->getTranslatedOrSynonym('footprint', $locale),
+ Manufacturer::class => $this->getTranslatedOrSynonym('manufacturer', $locale),
+ Supplier::class => $this->getTranslatedOrSynonym('supplier', $locale),
+ Project::class => $this->getTranslatedOrSynonym('project', $locale),
+ Assembly::class => $this->getTranslatedOrSynonym('assembly', $locale),
default => $this->translator->trans('tree.root_node.text'),
};
}
@@ -290,4 +294,22 @@ public function getGenericTree(string $class, ?AbstractStructuralDBElement $pare
return $repo->getGenericNodeTree($parent); //@phpstan-ignore-line
});
}
+
+ protected function getTranslatedOrSynonym(string $key, string $locale): string
+ {
+ $currentTranslation = $this->translator->trans($key . '.labelp');
+
+ // Call alternatives from DataSourcesynonyms (if available)
+ if (!empty($this->dataSourceSynonyms[$key][$locale])) {
+ $alternativeTranslation = $this->dataSourceSynonyms[$key][$locale];
+
+ // Use alternative translation when it deviates from the standard translation
+ if ($alternativeTranslation !== $currentTranslation) {
+ return $alternativeTranslation;
+ }
+ }
+
+ // Otherwise return the standard translation
+ return $currentTranslation;
+ }
}
diff --git a/src/Twig/DataSourceNameExtension.php b/src/Twig/DataSourceNameExtension.php
new file mode 100644
index 000000000..1c02243f7
--- /dev/null
+++ b/src/Twig/DataSourceNameExtension.php
@@ -0,0 +1,42 @@
+translator = $translator;
+ $this->dataSourceSynonyms = $dataSourceSynonyms ?? [];
+ }
+
+ public function getFunctions(): array
+ {
+ return [
+ new TwigFunction('get_data_source_name', [$this, 'getDataSourceName']),
+ ];
+ }
+
+ /**
+ * Based on the locale and data source names, gives the right synonym value back or the default translator value.
+ */
+ public function getDataSourceName(string $dataSourceName, string $defaultKey): string
+ {
+ $locale = $this->translator->getLocale();
+
+ // Use alternative dataSource synonym (if available)
+ if (isset($this->dataSourceSynonyms[$dataSourceName][$locale])) {
+ return $this->dataSourceSynonyms[$dataSourceName][$locale];
+ }
+
+ // Otherwise return the standard translation
+ return $this->translator->trans($defaultKey);
+ }
+}
\ No newline at end of file
diff --git a/templates/admin/assembly_admin.html.twig b/templates/admin/assembly_admin.html.twig
index e6a90dc09..def4eeb2e 100644
--- a/templates/admin/assembly_admin.html.twig
+++ b/templates/admin/assembly_admin.html.twig
@@ -3,7 +3,9 @@
{# @var entity App\Entity\AssemblySystem\Assembly #}
{% block card_title %}
- {% trans %}assembly.caption{% endtrans %}
+ {% set dataSourceName = get_data_source_name('assembly', 'assembly.caption') %}
+ {% set translatedSource = 'assembly.caption'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block edit_title %}
diff --git a/templates/admin/category_admin.html.twig b/templates/admin/category_admin.html.twig
index 5811640b9..f1fe7663a 100644
--- a/templates/admin/category_admin.html.twig
+++ b/templates/admin/category_admin.html.twig
@@ -1,7 +1,9 @@
{% extends "admin/base_admin.html.twig" %}
{% block card_title %}
- {% trans %}category.labelp{% endtrans %}
+ {% set dataSourceName = get_data_source_name('category', 'category.labelp') %}
+ {% set translatedSource = 'category.labelp'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block additional_pills %}
diff --git a/templates/admin/footprint_admin.html.twig b/templates/admin/footprint_admin.html.twig
index a2c3e4afd..a6acbe84e 100644
--- a/templates/admin/footprint_admin.html.twig
+++ b/templates/admin/footprint_admin.html.twig
@@ -1,7 +1,9 @@
{% extends "admin/base_admin.html.twig" %}
{% block card_title %}
- {% trans %}footprint.labelp{% endtrans %}
+ {% set dataSourceName = get_data_source_name('footprint', 'footprint.labelp') %}
+ {% set translatedSource = 'footprint.labelp'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block master_picture_block %}
diff --git a/templates/admin/manufacturer_admin.html.twig b/templates/admin/manufacturer_admin.html.twig
index 5db892c04..3ce9a124c 100644
--- a/templates/admin/manufacturer_admin.html.twig
+++ b/templates/admin/manufacturer_admin.html.twig
@@ -1,7 +1,9 @@
{% extends "admin/base_company_admin.html.twig" %}
{% block card_title %}
- {% trans %}manufacturer.caption{% endtrans %}
+ {% set dataSourceName = get_data_source_name('manufacturer', 'manufacturer.caption') %}
+ {% set translatedSource = 'manufacturer.caption'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block edit_title %}
diff --git a/templates/admin/project_admin.html.twig b/templates/admin/project_admin.html.twig
index dcf8c64cf..401be7cf7 100644
--- a/templates/admin/project_admin.html.twig
+++ b/templates/admin/project_admin.html.twig
@@ -3,7 +3,9 @@
{# @var entity App\Entity\ProjectSystem\Project #}
{% block card_title %}
- {% trans %}project.caption{% endtrans %}
+ {% set dataSourceName = get_data_source_name('project', 'project.caption') %}
+ {% set translatedSource = 'project.caption'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block edit_title %}
diff --git a/templates/admin/storelocation_admin.html.twig b/templates/admin/storelocation_admin.html.twig
index c93339dc1..1e60eeea2 100644
--- a/templates/admin/storelocation_admin.html.twig
+++ b/templates/admin/storelocation_admin.html.twig
@@ -2,7 +2,9 @@
{% import "label_system/dropdown_macro.html.twig" as dropdown %}
{% block card_title %}
- {% trans %}storelocation.labelp{% endtrans %}
+ {% set dataSourceName = get_data_source_name('storagelocation', 'storelocation.labelp') %}
+ {% set translatedSource = 'storelocation.labelp'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block additional_controls %}
diff --git a/templates/admin/supplier_admin.html.twig b/templates/admin/supplier_admin.html.twig
index ce38a5ca4..b5cf7b236 100644
--- a/templates/admin/supplier_admin.html.twig
+++ b/templates/admin/supplier_admin.html.twig
@@ -1,7 +1,9 @@
{% extends "admin/base_company_admin.html.twig" %}
{% block card_title %}
- {% trans %}supplier.caption{% endtrans %}
+ {% set dataSourceName = get_data_source_name('supplier', 'supplier.caption') %}
+ {% set translatedSource = 'supplier.caption'|trans %}
+ {% if dataSourceName != translatedSource %}{{ 'datasource.synonym'|trans({'%name%': translatedSource, '%synonym%': dataSourceName}) }}{% else %}{{ translatedSource }}{% endif %}
{% endblock %}
{% block additional_panes %}
diff --git a/templates/components/tree_macros.html.twig b/templates/components/tree_macros.html.twig
index 2e55147a1..210a00633 100644
--- a/templates/components/tree_macros.html.twig
+++ b/templates/components/tree_macros.html.twig
@@ -1,14 +1,16 @@
{% macro sidebar_dropdown() %}
+ {% set currentLocale = app.request.locale %}
+
{# Format is [mode, route, label, show_condition] #}
{% set data_sources = [
- ['categories', path('tree_category_root'), 'category.labelp', is_granted('@categories.read') and is_granted('@parts.read')],
- ['locations', path('tree_location_root'), 'storelocation.labelp', is_granted('@storelocations.read') and is_granted('@parts.read')],
- ['footprints', path('tree_footprint_root'), 'footprint.labelp', is_granted('@footprints.read') and is_granted('@parts.read')],
- ['manufacturers', path('tree_manufacturer_root'), 'manufacturer.labelp', is_granted('@manufacturers.read') and is_granted('@parts.read')],
- ['suppliers', path('tree_supplier_root'), 'supplier.labelp', is_granted('@suppliers.read') and is_granted('@parts.read')],
- ['projects', path('tree_device_root'), 'project.labelp', is_granted('@projects.read')],
- ['assembly', path('tree_assembly_root'), 'assembly.labelp', is_granted('@assemblies.read')],
- ['tools', path('tree_tools'), 'tools.label', true],
+ ['categories', path('tree_category_root'), 'category.labelp', is_granted('@categories.read') and is_granted('@parts.read'), 'category'],
+ ['locations', path('tree_location_root'), 'storelocation.labelp', is_granted('@storelocations.read') and is_granted('@parts.read'), 'storagelocation'],
+ ['footprints', path('tree_footprint_root'), 'footprint.labelp', is_granted('@footprints.read') and is_granted('@parts.read'), 'footprint'],
+ ['manufacturers', path('tree_manufacturer_root'), 'manufacturer.labelp', is_granted('@manufacturers.read') and is_granted('@parts.read'), 'manufacturer'],
+ ['suppliers', path('tree_supplier_root'), 'supplier.labelp', is_granted('@suppliers.read') and is_granted('@parts.read'), 'supplier'],
+ ['projects', path('tree_device_root'), 'project.labelp', is_granted('@projects.read'), 'project'],
+ ['assembly', path('tree_assembly_root'), 'assembly.labelp', is_granted('@assemblies.read'), 'assembly'],
+ ['tools', path('tree_tools'), 'tools.label', true, 'tool'],
] %}
{% trans %}actions{% endtrans %}
@@ -19,9 +21,9 @@
{% for source in data_sources %}
{% if source[3] %} {# show_condition #}
-
{{ source[2] | trans }}
+ >{{ get_data_source_name(source[4], source[2]) }}
{% endif %}
{% endfor %}
{% endmacro %}
@@ -62,4 +64,4 @@
-{% endmacro %}
\ No newline at end of file
+{% endmacro %}
diff --git a/templates/form/permission_layout.html.twig b/templates/form/permission_layout.html.twig
index 166147b4c..896a2defa 100644
--- a/templates/form/permission_layout.html.twig
+++ b/templates/form/permission_layout.html.twig
@@ -6,12 +6,31 @@
{% else %}
- {{ form.vars.label | trans }}
+ def{{ form.vars.label | trans }}
{% endif %}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index 34e21fa34..baecebb90 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -14745,5 +14745,11 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz
Neplatný regulární výraz (regex)
+
+
+ datasource.synonym
+ %name% (Váš synonymum: %synonym%)
+
+
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index 5901e9f5a..07f6c1b37 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -13462,5 +13462,11 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver
Ugyldigt regulært udtryk (regex)
+
+
+ datasource.synonym
+ %name% (Dit synonym: %synonym%)
+
+
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index a7ece41a9..7e2c84385 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -14747,5 +14747,11 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön
Ungültiger regulärer Ausdruck (regex)
+
+
+ datasource.synonym
+ %name% (Ihr Synonym: %synonym%)
+
+
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index fd5114539..07143e5b7 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -2470,5 +2470,11 @@
Μη έγκυρη κανονική έκφραση (regex)
+
+
+ datasource.synonym
+ %name% (Το συνώνυμό σας: %synonym%)
+
+
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index a1003f3f5..66292192f 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -14748,5 +14748,11 @@ Please note, that you can not impersonate a disabled user. If you try you will g
Invalid regular expression (regex)
+
+
+ datasource.synonym
+ %name% (Your synonym: %synonym%)
+
+
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index 5854628c1..d635333ff 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -13634,5 +13634,11 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S
Expresión regular no válida (regex)
+
+
+ datasource.synonym
+ %name% (Tu sinónimo: %synonym%)
+
+
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index 2b4341ca2..34ebcd1f1 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -10044,5 +10044,11 @@ exemple de ville
Expression régulière invalide (regex)
+
+
+ datasource.synonym
+ %name% (Votre synonyme : %synonym%)
+
+
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index c727eef82..b018468bb 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -13636,5 +13636,11 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a
Espressione regolare non valida (regex)
+
+
+ datasource.synonym
+ %name% (Il tuo sinonimo: %synonym%)
+
+
diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf
index 157b1cf26..4d1c82edf 100644
--- a/translations/messages.ja.xlf
+++ b/translations/messages.ja.xlf
@@ -9757,5 +9757,11 @@ Exampletown
無効な正規表現(regex)
+
+
+ datasource.synonym
+ %name% (あなたの同義語: %synonym%)
+
+
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index 44a48dcb3..822191818 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -1695,5 +1695,11 @@
Ongeldige reguliere expressie (regex)
+
+
+ datasource.synonym
+ %name% (Uw synoniem: %synonym%)
+
+
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index 171c585d6..6a7e5d591 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -13489,5 +13489,11 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli
Nieprawidłowe wyrażenie regularne (regex)
+
+
+ datasource.synonym
+ %name% (Twój synonim: %synonym%)
+
+
diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf
index 7bd0f3bc4..2add6347a 100644
--- a/translations/messages.ru.xlf
+++ b/translations/messages.ru.xlf
@@ -13589,5 +13589,11 @@
Неверное регулярное выражение (regex)
+
+
+ datasource.synonym
+ %name% (Ваш синоним: %synonym%)
+
+
diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf
index 9e8d8aa1f..cd6b34b2c 100644
--- a/translations/messages.zh.xlf
+++ b/translations/messages.zh.xlf
@@ -13474,5 +13474,11 @@ Element 3
无效的正则表达式(regex)
+
+
+ datasource.synonym
+ %name% (您的同义词: %synonym%)
+
+
From 9bf1d2bab7ed4be5076b4a50e8b60656c7473d8a Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 8 Jul 2025 09:05:53 +0200
Subject: [PATCH 55/83] =?UTF-8?q?F=C3=BCge=20Validierung=20f=C3=BCr=20zykl?=
=?UTF-8?q?ische=20Baugruppenreferenzen=20hinzu?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Eine neue Validierung wurde implementiert, um zyklische Referenzen in Baugruppen zu erkennen. Entsprechende Fehlertexte wurden in allen unterstützten Sprachen hinzugefügt. Zudem wurde der Validator in die Entität AssemblyBOMEntry integriert.
---
config/services.yaml | 3 +
src/Entity/AssemblySystem/Assembly.php | 2 +
.../AssemblySystem/AssemblyBOMEntry.php | 2 +
.../AssemblySystem/AssemblyCycle.php | 39 +++++
.../AssemblySystem/AssemblyCycleValidator.php | 139 ++++++++++++++++++
translations/validators.cs.xlf | 6 +
translations/validators.da.xlf | 6 +
translations/validators.de.xlf | 6 +
translations/validators.el.xlf | 6 +
translations/validators.en.xlf | 6 +
translations/validators.fr.xlf | 6 +
translations/validators.hr.xlf | 6 +
translations/validators.it.xlf | 6 +
translations/validators.ja.xlf | 6 +
translations/validators.pl.xlf | 6 +
translations/validators.ru.xlf | 6 +
translations/validators.zh.xlf | 6 +
17 files changed, 257 insertions(+)
create mode 100644 src/Validator/Constraints/AssemblySystem/AssemblyCycle.php
create mode 100644 src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
diff --git a/config/services.yaml b/config/services.yaml
index 8256daa1f..659098ff3 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -168,6 +168,9 @@ services:
arguments:
$useAssemblyIpnPlaceholder: '%partdb.create_assembly_use_ipn_placeholder_in_name%'
+ App\Validator\Constraints\AssemblySystem\AssemblyCycleValidator:
+ tags: [ 'validator.constraint_validator' ]
+
####################################################################################################################
# Table settings
####################################################################################################################
diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php
index 9593dbb53..5ce060d8e 100644
--- a/src/Entity/AssemblySystem/Assembly.php
+++ b/src/Entity/AssemblySystem/Assembly.php
@@ -23,6 +23,7 @@
namespace App\Entity\AssemblySystem;
use App\Repository\AssemblyRepository;
+use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
use Doctrine\Common\Collections\Criteria;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Metadata\ApiFilter;
@@ -113,6 +114,7 @@ class Assembly extends AbstractStructuralDBElement
#[Groups(['extended', 'full', 'import'])]
#[ORM\OneToMany(targetEntity: AssemblyBOMEntry::class, mappedBy: 'assembly', cascade: ['persist', 'remove'], orphanRemoval: true)]
#[UniqueObjectCollection(message: 'assembly.bom_entry.part_already_in_bom', fields: ['part'])]
+ #[AssemblyCycle]
#[UniqueReferencedAssembly]
#[UniqueObjectCollection(message: 'assembly.bom_entry.project_already_in_bom', fields: ['project'])]
#[UniqueObjectCollection(message: 'assembly.bom_entry.name_already_in_bom', fields: ['name'])]
diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
index 820fc2f5c..6a3e82d3c 100644
--- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php
+++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
@@ -38,6 +38,7 @@
use App\Entity\Contracts\TimeStampableInterface;
use App\Entity\ProjectSystem\Project;
use App\Repository\DBElementRepository;
+use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
use App\Validator\UniqueValidatableInterface;
use Doctrine\DBAL\Types\Types;
use App\Entity\Base\AbstractDBElement;
@@ -140,6 +141,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
'(this.getPart() === null or this.getReferencedAssembly() === null) and (this.getName() === null or (this.getName() != null and this.getName() != ""))',
message: 'validator.assembly.bom_entry.only_part_or_assembly_allowed'
)]
+ #[AssemblyCycle]
#[ORM\ManyToOne(targetEntity: Assembly::class)]
#[ORM\JoinColumn(name: 'id_referenced_assembly', nullable: true, onDelete: 'SET NULL')]
#[Groups(['bom_entry:read', 'bom_entry:write', ])]
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycle.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycle.php
new file mode 100644
index 000000000..9d79b879c
--- /dev/null
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycle.php
@@ -0,0 +1,39 @@
+.
+ */
+namespace App\Validator\Constraints\AssemblySystem;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * This constraint checks that there is no cycle in bom configuration of the assembly
+ */
+#[\Attribute(\Attribute::TARGET_PROPERTY)]
+class AssemblyCycle extends Constraint
+{
+ public string $message = 'assembly.bom_entry.assembly_cycle';
+
+ public function validatedBy(): string
+ {
+ return AssemblyCycleValidator::class;
+ }
+}
\ No newline at end of file
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
new file mode 100644
index 000000000..3483f94a1
--- /dev/null
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
@@ -0,0 +1,139 @@
+.
+ */
+namespace App\Validator\Constraints\AssemblySystem;
+
+use App\Entity\AssemblySystem\Assembly;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\Validator\Violation\ConstraintViolationBuilder;
+use ReflectionClass;
+
+/**
+ * Validator class to check for cycles in assemblies based on BOM entries.
+ *
+ * This validator ensures that the structure of assemblies does not contain circular dependencies
+ * by validating each entry in the Bill of Materials (BOM) of the given assembly. Additionally,
+ * it can handle form-submitted BOM entries to include these in the validation process.
+ */
+class AssemblyCycleValidator extends ConstraintValidator
+{
+ public function validate($value, Constraint $constraint): void
+ {
+ if (!$constraint instanceof AssemblyCycle) {
+ throw new UnexpectedTypeException($constraint, AssemblyCycle::class);
+ }
+
+ if (!$value instanceof Assembly) {
+ return;
+ }
+
+ $bomEntries = $value->getBomEntries()->toArray();
+
+ // Consider additional entries from the form
+ if ($this->context->getRoot()->has('bom_entries')) {
+ $formBomEntries = $this->context->getRoot()->get('bom_entries')->getData();
+ if ($formBomEntries) {
+ $given = is_array($formBomEntries) ? $formBomEntries : iterator_to_array($formBomEntries);
+ foreach ($given as $givenIdx => $entry) {
+ if (in_array($entry, $bomEntries, true)) {
+ continue;
+ } else {
+ $bomEntries[$givenIdx] = $entry;
+ }
+ }
+ }
+ }
+
+ $visitedAssemblies = [];
+ foreach ($bomEntries as $bomEntry) {
+ if ($this->hasCycle($bomEntry->getReferencedAssembly(), $value, $visitedAssemblies)) {
+ $this->addViolation($value, $constraint);
+ }
+ }
+ }
+
+ private function hasCycle(?Assembly $currentAssembly, Assembly $originalAssembly, array &$visitedAssemblies): bool
+ {
+ if ($currentAssembly === null) {
+ return false;
+ }
+
+ if (in_array($currentAssembly, $visitedAssemblies, true)) {
+ return true;
+ }
+
+ $visitedAssemblies[] = $currentAssembly;
+
+ foreach ($currentAssembly->getBomEntries() as $bomEntry) {
+ if ($this->hasCycle($bomEntry->getReferencedAssembly(), $originalAssembly, $visitedAssemblies)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds a violation to the current context if it hasn’t already been added.
+ *
+ * This method checks whether a violation with the same property path as the current violation
+ * already exists in the context. If such a violation is found, the current violation is not added again.
+ * The process involves reflection to access private or protected properties of violation objects.
+ *
+ * @param mixed $value The value that triggered the violation.
+ * @param Constraint $constraint The constraint containing the validation details.
+ *
+ */
+ private function addViolation($value, Constraint $constraint): void
+ {
+ /** @var ConstraintViolationBuilder $buildViolation */
+ $buildViolation = $this->context->buildViolation($constraint->message)
+ ->setParameter('%name%', $value->getName());
+
+ $alreadyAdded = false;
+
+ try {
+ $reflectionClass = new ReflectionClass($buildViolation);
+ $property = $reflectionClass->getProperty('propertyPath');
+ $propertyPath = $property->getValue($buildViolation);
+
+ $availableViolations = $this->context->getViolations();
+
+ foreach ($availableViolations as $tmpViolation) {
+ $tmpReflectionClass = new ReflectionClass($tmpViolation);
+ $tmpProperty = $tmpReflectionClass->getProperty('propertyPath');
+ $tmpPropertyPath = $tmpProperty->getValue($tmpViolation);
+
+ if ($tmpPropertyPath === $propertyPath) {
+ $alreadyAdded = true;
+ }
+ }
+ } catch (\ReflectionException) {
+ }
+
+ if (!$alreadyAdded) {
+ $buildViolation->addViolation();
+ }
+ }
+}
\ No newline at end of file
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index 1731c90cb..7ee171b26 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -395,6 +395,12 @@
Tato sestava již existuje jako položka v seznamu materiálů!
+
+
+ assembly.bom_entry.assembly_cycle
+ Byl zjištěn cyklus: Sestava "%name%" nepřímo odkazuje sama na sebe.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index 239e3572a..24fa330af 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -371,6 +371,12 @@
Denne samling findes allerede som en post!
+
+
+ assembly.bom_entry.assembly_cycle
+ En cyklus blev opdaget: Samlingen "%name%" refererer indirekte til sig selv.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index 86b31e583..fa84354b9 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -395,6 +395,12 @@
Diese Baugruppe existiert bereits als Eintrag!
+
+
+ assembly.bom_entry.assembly_cycle
+ Ein Zyklus wurde entdeckt: Die Baugruppe "%name%" referenziert sich indirekt selbst.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index 4e4278daf..bc9b0947e 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -37,6 +37,12 @@
Αυτή η συναρμολόγηση υπάρχει ήδη ως εγγραφή!
+
+
+ assembly.bom_entry.assembly_cycle
+ Εντοπίστηκε κύκλος: Η συναρμολόγηση "%name%" αναφέρεται έμμεσα στον εαυτό της.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index 59cabf552..7d9beb4ec 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -395,6 +395,12 @@
This assembly already exists as an entry!
+
+
+ assembly.bom_entry.assembly_cycle
+ A cycle was detected: the assembly "%name%" indirectly references itself.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index aff68a185..1c9c53029 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -227,6 +227,12 @@
Cet assemblage existe déjà en tant qu'entrée !
+
+
+ assembly.bom_entry.assembly_cycle
+ Un cycle a été détecté : L'assemblage "%name%" se réfère indirectement à lui-même.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index 1ee5c06fe..89d470e7e 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -389,6 +389,12 @@
Ova se montaža već nalazi kao zapis!
+
+
+ assembly.bom_entry.assembly_cycle
+ Otkriven je ciklus: Sklop "%name%" neizravno referencira samog sebe.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index ac57a2cc4..e9b528bb7 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -389,6 +389,12 @@
Questo assemblaggio è già presente come voce!
+
+
+ assembly.bom_entry.assembly_cycle
+ È stato rilevato un ciclo: L'assemblaggio "%name%" fa riferimento indirettamente a sé stesso.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index a316707ad..80ec65ff2 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -227,6 +227,12 @@
このアセンブリはすでにエントリとして存在します!
+
+
+ assembly.bom_entry.assembly_cycle
+ 循環が検出されました: アセンブリ「%name%」が間接的に自身を参照しています。
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 95c44ab4d..5df01cd6a 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -389,6 +389,12 @@
To zestawienie jest już dodane jako wpis!
+
+
+ assembly.bom_entry.assembly_cycle
+ 循環が検出されました: アセンブリ「%name%」が間接的に自身を参照しています。
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index 425ede5f1..8bf08ab3c 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -389,6 +389,12 @@
Этот сборочный узел уже добавлен как запись!
+
+
+ assembly.bom_entry.assembly_cycle
+ Обнаружен цикл: Сборка «%name%» косвенно ссылается на саму себя.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 4a02523bb..87c507c19 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -377,6 +377,12 @@
此装配已经作为条目存在!
+
+
+ assembly.bom_entry.assembly_cycle
+ 检测到循环:装配体“%name%”间接引用了其自身。
+
+ assembly.bom_entry.project_already_in_bom
From 3d4f55d9eee5e39b203de0d05c8f3b2af8a5358f Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 1 Apr 2025 16:10:10 +0200
Subject: [PATCH 56/83] =?UTF-8?q?Erweiterungst=C3=A4tigkeiten=20zur=20IPN-?=
=?UTF-8?q?Vorschlagsliste=20anhand=20von=20Pr=C3=A4fixen=20aus=20den=20Ka?=
=?UTF-8?q?tegorien?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env | 18 ++
.../elements/ipn_suggestion_controller.js | 220 ++++++++++++++++++
config/parameters.yaml | 3 +
config/services.yaml | 24 ++
docs/configuration.md | 6 +
migrations/Version20250325073036.php | 23 ++
src/Controller/PartController.php | 16 +-
src/Controller/TypeaheadController.php | 27 ++-
src/Entity/Parts/Category.php | 17 ++
src/Entity/Parts/Part.php | 2 -
.../PartTraits/AdvancedPropertyTrait.php | 4 +-
.../UserSystem/PartUniqueIpnSubscriber.php | 73 ++++++
src/Form/AdminPages/CategoryAdminForm.php | 11 +
src/Form/Part/PartBaseType.php | 8 +
src/Repository/PartRepository.php | 119 ++++++++++
.../Constraints/UniquePartIpnConstraint.php | 20 ++
.../Constraints/UniquePartIpnValidator.php | 38 +++
templates/admin/category_admin.html.twig | 1 +
templates/parts/edit/_advanced.html.twig | 11 +-
translations/messages.cs.xlf | 66 ++++++
translations/messages.da.xlf | 66 ++++++
translations/messages.de.xlf | 66 ++++++
translations/messages.el.xlf | 66 ++++++
translations/messages.en.xlf | 66 ++++++
translations/messages.es.xlf | 66 ++++++
translations/messages.fr.xlf | 66 ++++++
translations/messages.it.xlf | 66 ++++++
translations/messages.ja.xlf | 66 ++++++
translations/messages.nl.xlf | 66 ++++++
translations/messages.pl.xlf | 66 ++++++
translations/messages.ru.xlf | 66 ++++++
translations/messages.zh.xlf | 66 ++++++
32 files changed, 1489 insertions(+), 10 deletions(-)
create mode 100644 assets/controllers/elements/ipn_suggestion_controller.js
create mode 100644 migrations/Version20250325073036.php
create mode 100644 src/EventSubscriber/UserSystem/PartUniqueIpnSubscriber.php
create mode 100644 src/Validator/Constraints/UniquePartIpnConstraint.php
create mode 100644 src/Validator/Constraints/UniquePartIpnValidator.php
diff --git a/.env b/.env
index 8d89896a6..2b98255f1 100644
--- a/.env
+++ b/.env
@@ -53,6 +53,8 @@ EMAIL_SENDER_EMAIL=noreply@partdb.changeme
EMAIL_SENDER_NAME="Part-DB Mailer"
# Set this to 1 to allow reset of a password per email
ALLOW_EMAIL_PW_RESET=0
+# Set this to 0 to allow to enter already available IPN. In this case a unique increment is appended to the user input.
+ENFORCE_UNIQUE_IPN=1
###################################################################################
# Error pages settings
@@ -126,6 +128,22 @@ NO_URL_REWRITE_AVAILABLE=0
# Set to 1, if Part-DB should redirect all HTTP requests to HTTPS. You dont need to configure this, if your webserver already does this.
REDIRECT_TO_HTTPS=0
+# If you want to use fixer.io for currency conversion, you have to set this to your API key
+FIXER_API_KEY=CHANGEME
+
+# Override value if you want to show to show a given text on homepage.
+# When this is empty the content of config/banner.md is used as banner
+BANNER=""
+
+# Enable the part image overlay which shows name and filename of the picture
+SHOW_PART_IMAGE_OVERLAY=1
+
+# Define the number of digits used for the incremental numbering of parts in the IPN (Internal Part Number) autocomplete system.
+AUTOCOMPLETE_PART_DIGITS=4
+
+APP_ENV=prod
+APP_SECRET=a03498528f5a5fc089273ec9ae5b2849
+
# Set this to zero, if you want to disable the year 2038 bug check on 32-bit systems (it will cause errors with current 32-bit PHP versions)
DISABLE_YEAR2038_BUG_CHECK=0
diff --git a/assets/controllers/elements/ipn_suggestion_controller.js b/assets/controllers/elements/ipn_suggestion_controller.js
new file mode 100644
index 000000000..088c07b33
--- /dev/null
+++ b/assets/controllers/elements/ipn_suggestion_controller.js
@@ -0,0 +1,220 @@
+import { Controller } from "@hotwired/stimulus";
+import "../../css/components/autocomplete_bootstrap_theme.css";
+
+export default class extends Controller {
+ static targets = ["input"];
+ static values = {
+ partId: Number,
+ partCategoryId: Number,
+ suggestions: Object,
+ commonSectionHeader: String, // Dynamic header for common Prefixes
+ partIncrementHeader: String, // Dynamic header for new possible part increment
+ suggestUrl: String,
+ };
+
+ connect() {
+ this.configureAutocomplete();
+ this.watchCategoryChanges();
+ }
+
+ templates = {
+ commonSectionHeader({ title, html }) {
+ return html`
+
+
- {% include "assemblies/info/_part.html.twig" %}
-
{% include "assemblies/info/_info.html.twig" %}
+
+ {% include "assemblies/info/_part.html.twig" %}
+
{% include "assemblies/info/_builds.html.twig" %}
From 6ed084f9131a4fdf793ee3af214312318f1e2cb6 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Tue, 22 Jul 2025 15:52:57 +0200
Subject: [PATCH 74/83] BOMImporter und AssemblyCycleValidator: Verbesserte
Import-Logik
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Die Importmethoden wurden vereinheitlicht, um Projekte und Baugruppen gleichermaßen zu unterstützen. Zudem wurde die Validierung optimiert und die CSV-, JSON- und KiCAD-Parsing-Methoden angepasst, um kontextbasierte BOM-Einträge effizienter zu erstellen.
---
.../ImportExportSystem/BOMImporter.php | 180 ++++++++++++------
.../AssemblySystem/AssemblyCycleValidator.php | 3 +-
2 files changed, 123 insertions(+), 60 deletions(-)
diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php
index 5332d5588..f022fb5e4 100644
--- a/src/Services/ImportExportSystem/BOMImporter.php
+++ b/src/Services/ImportExportSystem/BOMImporter.php
@@ -114,7 +114,7 @@ protected function configureOptions(OptionsResolver $resolver): OptionsResolver
*/
public function importFileIntoProject(UploadedFile $file, Project $project, array $options): ImporterResult
{
- $importerResult = $this->fileToImporterResult($file, $options);
+ $importerResult = $this->fileToImporterResult($project, $file, $options);
if ($importerResult->getViolations()->count() === 0) {
//Assign the bom_entries to the project
@@ -127,12 +127,21 @@ public function importFileIntoProject(UploadedFile $file, Project $project, arra
}
/**
- * Converts the given file into an ImporterResult with an array of BOM entries using the given options and save them into the given assembly.
- * The changes are not saved into the database yet.
+ * Imports a file into an Assembly object and processes its contents.
+ *
+ * This method converts the provided file into an ImporterResult object that contains BOM entries and potential
+ * validation violations. If no violations are found, the BOM entries extracted from the file are added to the
+ * provided Assembly object.
+ *
+ * @param UploadedFile $file The file to be imported and processed.
+ * @param Assembly $assembly The target Assembly object to which the BOM entries are added.
+ * @param array $options Options or configurations related to the import process.
+ *
+ * @return ImporterResult An object containing the result of the import process, including BOM entries and any violations.
*/
public function importFileIntoAssembly(UploadedFile $file, Assembly $assembly, array $options): ImporterResult
{
- $importerResult = $this->fileToImporterResult($file, $options, AssemblyBOMEntry::class);
+ $importerResult = $this->fileToImporterResult($assembly, $file, $options);
if ($importerResult->getViolations()->count() === 0) {
//Assign the bom_entries to the assembly
@@ -145,12 +154,20 @@ public function importFileIntoAssembly(UploadedFile $file, Assembly $assembly, a
}
/**
- * Converts the given file into an array of BOM entries using the given options.
- * @return ProjectBOMEntry[]|AssemblyBOMEntry[]
+ * Converts the content of a file into an array of BOM (Bill of Materials) entries.
+ *
+ * This method processes the content of the provided file and delegates the conversion
+ * to a helper method that generates BOM entries based on the provided import object and options.
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entries (either a Project or Assembly).
+ * @param File $file The file whose content will be converted into BOM entries.
+ * @param array $options Additional options or configurations to be applied during the conversion process.
+ *
+ * @return array An array of BOM entries created from the file content.
*/
- public function fileToBOMEntries(File $file, array $options, string $objectType = ProjectBOMEntry::class): array
+ public function fileToBOMEntries(Project|Assembly $importObject, File $file, array $options): array
{
- return $this->stringToBOMEntries($file->getContent(), $options, $objectType);
+ return $this->stringToBOMEntries($importObject, $file->getContent(), $options);
}
/**
@@ -171,9 +188,19 @@ public function validateBOMData(string $data, array $options): array
}
/**
- * Converts the given file into an ImporterResult with an array of BOM entries using the given options.
+ * Handles the conversion of an uploaded file into an ImporterResult for a given project or assembly.
+ *
+ * This method processes the uploaded file by validating its file extension based on the provided import type
+ * options and then proceeds to convert the file content into an ImporterResult. If the file extension is
+ * invalid or unsupported, the result will contain a corresponding violation.
+ *
+ * @param Project|Assembly $importObject The context of the import operation (either a Project or Assembly).
+ * @param UploadedFile $file The uploaded file to be processed.
+ * @param array $options An array of options, expected to include an 'type' key to determine valid file types.
+ *
+ * @return ImporterResult An object containing the results of the import process, including any detected violations.
*/
- public function fileToImporterResult(UploadedFile $file, array $options, string $objectType = ProjectBOMEntry::class): ImporterResult
+ public function fileToImporterResult(Project|Assembly $importObject, UploadedFile $file, array $options): ImporterResult
{
$result = new ImporterResult();
@@ -203,7 +230,7 @@ public function fileToImporterResult(UploadedFile $file, array $options, string
$fileExtension,
[
'%extension%' => $fileExtension,
- '%importType%' => $this->translator->trans($objectType === ProjectBOMEntry::class ? 'project.bom_import.type.'.$options['type'] : 'assembly.bom_import.type.'.$options['type']),
+ '%importType%' => $this->translator->trans($importObject instanceof Project ? 'project.bom_import.type.'.$options['type'] : 'assembly.bom_import.type.'.$options['type']),
'%allowedExtensions%' => implode(', ', $validExtensions),
]
));
@@ -211,16 +238,19 @@ public function fileToImporterResult(UploadedFile $file, array $options, string
return $result;
}
- return $this->stringToImporterResult($file->getContent(), $options, $objectType);
+ return $this->stringToImporterResult($importObject, $file->getContent(), $options);
}
/**
* Import string data into an array of BOM entries, which are not yet assigned to a project.
- * @param string $data The data to import
- * @param array $options An array of options
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $data The data to import
+ * @param array $options An array of options
+ *
* @return ProjectBOMEntry[]|AssemblyBOMEntry[] An array of imported entries
*/
- public function stringToBOMEntries(string $data, array $options, string $objectType = ProjectBOMEntry::class): array
+ public function stringToBOMEntries(Project|Assembly $importObject, string $data, array $options): array
{
$resolver = new OptionsResolver();
$resolver = $this->configureOptions($resolver);
@@ -234,11 +264,14 @@ public function stringToBOMEntries(string $data, array $options, string $objectT
/**
* Import string data into an array of BOM entries, which are not yet assigned to a project.
- * @param string $data The data to import
- * @param array $options An array of options
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $data The data to import
+ * @param array $options An array of options
+ *
* @return ImporterResult An result of imported entries or a violation list
*/
- public function stringToImporterResult(string $data, array $options, string $objectType = ProjectBOMEntry::class): ImporterResult
+ public function stringToImporterResult(Project|Assembly $importObject, string $data, array $options): ImporterResult
{
$resolver = new OptionsResolver();
$resolver = $this->configureOptions($resolver);
@@ -251,14 +284,28 @@ public function stringToImporterResult(string $data, array $options, string $obj
));
return match ($options['type']) {
- self::IMPORT_TYPE_KICAD_PCB => $this->parseKiCADPCB($data, $objectType),
- self::IMPORT_TYPE_JSON => $this->parseJson($data, $objectType),
- self::IMPORT_TYPE_CSV => $this->parseCsv($data, $objectType),
+ self::IMPORT_TYPE_KICAD_PCB => $this->parseKiCADPCB($data, $importObject),
+ self::IMPORT_TYPE_JSON => $this->parseJson($data, $importObject),
+ self::IMPORT_TYPE_CSV => $this->parseCsv($data, $importObject),
default => $defaultImporterResult,
};
}
- private function parseKiCADPCB(string $data, string $objectType = ProjectBOMEntry::class): ImporterResult
+ /**
+ * Parses a KiCAD PCB file and imports its BOM (Bill of Materials) entries into the given Project or Assembly context.
+ *
+ * This method processes a semicolon-delimited CSV data string, normalizes column names,
+ * validates the required fields, and creates BOM entries for each record in the data.
+ * The BOM entries are added to the provided Project or Assembly, depending on the context.
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $data The semicolon- or comma-delimited CSV data to be parsed
+ *
+ * @return ImporterResult The result of the import process, containing the created BOM entries.
+ *
+ * @throws UnexpectedValueException If required fields are missing in the provided data.
+ */
+ private function parseKiCADPCB(string $data, Project|Assembly $importObject): ImporterResult
{
$result = new ImporterResult();
@@ -284,8 +331,8 @@ private function parseKiCADPCB(string $data, string $objectType = ProjectBOMEntr
throw new \UnexpectedValueException('Quantity missing at line ' . ($offset + 1) . '!');
}
- $bom_entry = $objectType === ProjectBOMEntry::class ? new ProjectBOMEntry() : new AssemblyBOMEntry();
- if ($objectType === ProjectBOMEntry::class) {
+ $bom_entry = $importObject instanceof Project ? new ProjectBOMEntry() : new AssemblyBOMEntry();
+ if ($bom_entry instanceof ProjectBOMEntry) {
$bom_entry->setName($entry['Designation'] . ' (' . $entry['Package'] . ')');
} else {
$bom_entry->setName($entry['Designation']);
@@ -383,15 +430,15 @@ private function validateKiCADSchematicData(string $data, array $options): array
* - Checking for empty or invalid descriptions.
* - Ensuring manufacturers, if specified, have valid `name` or `id` values.
*
- * @param string $data JSON encoded string containing BOM entries data.
- * @param string $objectType The type of entries expected during import (e.g., `ProjectBOMEntry` or `AssemblyBOMEntry`).
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $data JSON encoded string containing BOM entries data.
*
* @return ImporterResult The result containing parsed data and any violations encountered during the parsing process.
*/
- private function parseJson(string $data, array $options = [], string $objectType = ProjectBOMEntry::class): ImporterResult
+ private function parseJson(Project|Assembly $importObject, string $data): ImporterResult
{
$result = new ImporterResult();
- $this->jsonRoot = 'JSON Import for '.$objectType === ProjectBOMEntry::class ? 'Project' : 'Assembly';
+ $this->jsonRoot = 'JSON Import for '.($importObject instanceof Project ? 'Project' : 'Assembly');
$data = json_decode($data, true);
@@ -420,9 +467,9 @@ private function parseJson(string $data, array $options = [], string $objectType
}
if (isset($entry['part'])) {
- $this->processPart($entry, $result, $key, $objectType,self::IMPORT_TYPE_JSON);
+ $this->processPart($importObject, $entry, $result, $key, self::IMPORT_TYPE_JSON);
} else {
- $bomEntry = $this->getOrCreateBomEntry($objectType, $entry['name'] ?? null);
+ $bomEntry = $this->getOrCreateBomEntry($importObject, $entry['name'] ?? null);
$bomEntry->setQuantity((float) $entry['quantity']);
$result->addBomEntry($bomEntry);
@@ -438,16 +485,16 @@ private function parseJson(string $data, array $options = [], string $objectType
* performing validations and converting data based on the provided headers.
* Handles potential violations and manages the creation of BOM entries based on the given type.
*
- * @param string $csvData The raw CSV data to parse, with rows separated by newlines.
- * @param string $objectType The class type to instantiate for BOM entries, defaults to ProjectBOMEntry.
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string $csvData The raw CSV data to parse, with rows separated by newlines.
*
* @return ImporterResult Returns an ImporterResult instance containing BOM entries and any validation violations encountered.
*/
- function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class): ImporterResult
+ function parseCsv(Project|Assembly $importObject, string $csvData): ImporterResult
{
$result = new ImporterResult();
$rows = explode("\r\n", trim($csvData));
- $headers = str_getcsv(array_shift($rows), ',');
+ $headers = str_getcsv(array_shift($rows));
if (count($headers) === 1 && isset($headers[0])) {
//If only one column was recognized, try fallback with semicolon as a separator
@@ -456,7 +503,7 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
foreach ($rows as $key => $row) {
$entry = [];
- $values = str_getcsv($row, ',');
+ $values = str_getcsv($row);
if (count($values) === 1 || count($values) !== count($headers)) {
//If only one column was recognized, try fallback with semicolon as a separator
@@ -484,7 +531,7 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
//Check whether the value is numerical
if (is_numeric($values[$index])) {
//Convert to integer or float
- $temp = (strpos($values[$index], '.') !== false)
+ $temp = (str_contains($values[$index], '.'))
? floatval($values[$index])
: intval($values[$index]);
} else {
@@ -525,9 +572,9 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
}
if (isset($entry['part'])) {
- $this->processPart($entry, $result, $key, $objectType, self::IMPORT_TYPE_CSV);
+ $this->processPart($importObject, $entry, $result, $key, self::IMPORT_TYPE_CSV);
} else {
- $bomEntry = $this->getOrCreateBomEntry($objectType, $entry['name'] ?? null);
+ $bomEntry = $this->getOrCreateBomEntry($importObject, $entry['name'] ?? null);
$bomEntry->setQuantity((float) $entry['quantity'] ?? 0);
$result->addBomEntry($bomEntry);
@@ -544,15 +591,15 @@ function parseCsv(string $csvData, string $objectType = ProjectBOMEntry::class):
* to identify corresponding objects in the database. The result is recorded, and violations are
* logged if issues or discrepancies exist in the validation or database matching process.
*
- * @param array $entry The array representation of the part entry.
- * @param ImporterResult $result The result object used for recording validation violations.
- * @param int $key The index of the entry in the data array.
- * @param string $objectType The type of object being processed.
- * @param string $importType The type of import being performed.
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param array $entry The array representation of the part entry.
+ * @param ImporterResult $result The result object used for recording validation violations.
+ * @param int $key The index of the entry in the data array.
+ * @param string $importType The type of import being performed.
*
* @return void
*/
- private function processPart(array $entry, ImporterResult $result, int $key, string $objectType, string $importType): void
+ private function processPart(Project|Assembly $importObject, array $entry, ImporterResult $result, int $key, string $importType): void
{
$prefix = $importType === self::IMPORT_TYPE_JSON ? 'entry' : 'row';
@@ -777,12 +824,12 @@ private function processPart(array $entry, ImporterResult $result, int $key, str
$part->setCategory($category);
}
- if ($objectType === AssemblyBOMEntry::class) {
- $bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['part' => $part]);
+ if ($importObject instanceof Assembly) {
+ $bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['assembly' => $importObject, 'part' => $part]);
if ($bomEntry === null) {
if (isset($entry['name']) && $entry['name'] !== '') {
- $bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['name' => $entry['name']]);
+ $bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['assembly' => $importObject, 'name' => $entry['name']]);
}
if ($bomEntry === null) {
@@ -790,11 +837,11 @@ private function processPart(array $entry, ImporterResult $result, int $key, str
}
}
} else {
- $bomEntry = $this->projectBOMEntryRepository->findOneBy(['part' => $part]);
+ $bomEntry = $this->projectBOMEntryRepository->findOneBy(['project' => $importObject, 'part' => $part]);
if ($bomEntry === null) {
if (isset($entry['name']) && $entry['name'] !== '') {
- $bomEntry = $this->projectBOMEntryRepository->findOneBy(['name' => $entry['name']]);
+ $bomEntry = $this->projectBOMEntryRepository->findOneBy(['project' => $importObject, 'name' => $entry['name']]);
}
if ($bomEntry === null) {
@@ -841,22 +888,38 @@ private function removeEmptyProperties(array $data): array
return $data;
}
- private function getOrCreateBomEntry(string $objectType, ?string $name)
+ /**
+ * Retrieves an existing BOM (Bill of Materials) entry by name or creates a new one if not found.
+ *
+ * Depending on whether the provided import object is a Project or Assembly, this method attempts to locate
+ * a corresponding BOM entry in the appropriate repository. If no entry is located, a new BOM entry object
+ * is instantiated according to the type of the import object.
+ *
+ * @param Project|Assembly $importObject The object determining the context of the BOM entry (either a Project or Assembly).
+ * @param string|null $name The name of the BOM entry to search for or assign to a new entry.
+ *
+ * @return ProjectBOMEntry|AssemblyBOMEntry An existing or newly created BOM entry.
+ */
+ private function getOrCreateBomEntry(Project|Assembly $importObject, ?string $name): ProjectBOMEntry|AssemblyBOMEntry
{
$bomEntry = null;
//Check whether there is a name
if (!empty($name)) {
- if ($objectType === ProjectBOMEntry::class) {
+ if ($importObject instanceof Project) {
$bomEntry = $this->projectBOMEntryRepository->findOneBy(['name' => $name]);
- } elseif ($objectType === AssemblyBOMEntry::class) {
+ } else {
$bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['name' => $name]);
}
}
- //If no bom enttry was found, a new object create
+ //If no bom entry was found, a new object create
if ($bomEntry === null) {
- $bomEntry = new $objectType();
+ if ($importObject instanceof Project) {
+ $bomEntry = new ProjectBOMEntry();
+ } else {
+ $bomEntry = new AssemblyBOMEntry();
+ }
}
$bomEntry->setName($name);
@@ -887,7 +950,6 @@ private function normalizeColumnNames(array $entry): array
return $out;
}
-
/**
* Builds a JSON-based constraint violation.
*
@@ -895,10 +957,10 @@ private function normalizeColumnNames(array $entry): array
* The violation includes a message, property path, invalid value, and other contextual information.
* Translations for the violation message can be applied through the translator service.
*
- * @param string $message The translation key for the validation message.
- * @param string $propertyPath The property path where the violation occurred.
- * @param mixed|null $invalidValue The value that caused the violation (optional).
- * @param array $parameters Additional parameters for message placeholders (default is an empty array).
+ * @param string $message The translation key for the validation message.
+ * @param string $propertyPath The property path where the violation occurred.
+ * @param mixed|null $invalidValue The value that caused the violation (optional).
+ * @param array $parameters Additional parameters for message placeholders (default is an empty array).
*
* @return ConstraintViolation The created constraint violation object.
*/
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
index 3483f94a1..73df284dd 100644
--- a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
@@ -23,6 +23,7 @@
namespace App\Validator\Constraints\AssemblySystem;
use App\Entity\AssemblySystem\Assembly;
+use Symfony\Component\Form\Form;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
@@ -51,7 +52,7 @@ public function validate($value, Constraint $constraint): void
$bomEntries = $value->getBomEntries()->toArray();
// Consider additional entries from the form
- if ($this->context->getRoot()->has('bom_entries')) {
+ if ($this->context->getRoot() instanceof Form && $this->context->getRoot()->has('bom_entries')) {
$formBomEntries = $this->context->getRoot()->get('bom_entries')->getData();
if ($formBomEntries) {
$given = is_array($formBomEntries) ? $formBomEntries : iterator_to_array($formBomEntries);
From 31b1829761268388756ee43dc762613a98e21d59 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 24 Jul 2025 09:11:28 +0200
Subject: [PATCH 75/83] =?UTF-8?q?BOMValidator:=20Validierung=20f=C3=BCr=20?=
=?UTF-8?q?rekursive=20Baugruppen-Eintragspr=C3=BCfung=20erg=C3=A4nzt?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Es wurde eine neue Validierung hinzugefügt, um sicherzustellen, dass keine Baugruppe in ihrer eigenen Hierarchie als Unterbaugruppe referenziert wird. Diese Logik wurde in die entsprechenden Dateien integriert und unterstützt Mehrsprachigkeit durch neue Übersetzungen.
---
src/Entity/AssemblySystem/Assembly.php | 6 +-
.../AssemblySystem/AssemblyBOMEntry.php | 2 +
.../AssemblySystem/AssemblyCycleValidator.php | 67 +++++---
.../AssemblyInvalidBomEntry.php | 21 +++
.../AssemblyInvalidBomEntryValidator.php | 155 ++++++++++++++++++
translations/validators.cs.xlf | 6 +
translations/validators.da.xlf | 6 +
translations/validators.de.xlf | 6 +
translations/validators.el.xlf | 6 +
translations/validators.en.xlf | 6 +
translations/validators.fr.xlf | 6 +
translations/validators.hr.xlf | 6 +
translations/validators.it.xlf | 6 +
translations/validators.ja.xlf | 6 +
translations/validators.pl.xlf | 6 +
translations/validators.ru.xlf | 6 +
translations/validators.zh.xlf | 6 +
17 files changed, 302 insertions(+), 21 deletions(-)
create mode 100644 src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntry.php
create mode 100644 src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntryValidator.php
diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php
index cb6e94def..c65ca71fe 100644
--- a/src/Entity/AssemblySystem/Assembly.php
+++ b/src/Entity/AssemblySystem/Assembly.php
@@ -24,6 +24,7 @@
use App\Repository\AssemblyRepository;
use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
+use App\Validator\Constraints\AssemblySystem\AssemblyInvalidBomEntry;
use Doctrine\Common\Collections\Criteria;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Metadata\ApiFilter;
@@ -111,11 +112,12 @@ class Assembly extends AbstractStructuralDBElement
* @var Collection
*/
#[Assert\Valid]
+ #[AssemblyCycle]
+ #[AssemblyInvalidBomEntry]
+ #[UniqueReferencedAssembly]
#[Groups(['extended', 'full', 'import'])]
#[ORM\OneToMany(targetEntity: AssemblyBOMEntry::class, mappedBy: 'assembly', cascade: ['persist', 'remove'], orphanRemoval: true)]
#[UniqueObjectCollection(message: 'assembly.bom_entry.part_already_in_bom', fields: ['part'])]
- #[AssemblyCycle]
- #[UniqueReferencedAssembly]
#[UniqueObjectCollection(message: 'assembly.bom_entry.project_already_in_bom', fields: ['project'])]
#[UniqueObjectCollection(message: 'assembly.bom_entry.name_already_in_bom', fields: ['name'])]
protected Collection $bom_entries;
diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
index 8a4cdbc24..7d54fe684 100644
--- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php
+++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
@@ -39,6 +39,7 @@
use App\Entity\ProjectSystem\Project;
use App\Repository\DBElementRepository;
use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
+use App\Validator\Constraints\AssemblySystem\AssemblyInvalidBomEntry;
use App\Validator\UniqueValidatableInterface;
use Doctrine\DBAL\Types\Types;
use App\Entity\Base\AbstractDBElement;
@@ -142,6 +143,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
message: 'validator.assembly.bom_entry.only_part_or_assembly_allowed'
)]
#[AssemblyCycle]
+ #[AssemblyInvalidBomEntry]
#[ORM\ManyToOne(targetEntity: Assembly::class)]
#[ORM\JoinColumn(name: 'id_referenced_assembly', nullable: true, onDelete: 'SET NULL')]
#[Groups(['bom_entry:read', 'bom_entry:write', ])]
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
index 73df284dd..f12f19a73 100644
--- a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php
@@ -49,49 +49,78 @@ public function validate($value, Constraint $constraint): void
return;
}
- $bomEntries = $value->getBomEntries()->toArray();
+ $availableViolations = $this->context->getViolations();
+ if (count($availableViolations) > 0) {
+ //already violations given, currently no more needed to check
+
+ return;
+ }
+
+ $bomEntries = [];
- // Consider additional entries from the form
if ($this->context->getRoot() instanceof Form && $this->context->getRoot()->has('bom_entries')) {
- $formBomEntries = $this->context->getRoot()->get('bom_entries')->getData();
- if ($formBomEntries) {
- $given = is_array($formBomEntries) ? $formBomEntries : iterator_to_array($formBomEntries);
- foreach ($given as $givenIdx => $entry) {
- if (in_array($entry, $bomEntries, true)) {
- continue;
- } else {
- $bomEntries[$givenIdx] = $entry;
- }
- }
+ $bomEntries = $this->context->getRoot()->get('bom_entries')->getData();
+ $bomEntries = is_array($bomEntries) ? $bomEntries : iterator_to_array($bomEntries);
+ } elseif ($this->context->getRoot() instanceof Assembly) {
+ $bomEntries = $value->getBomEntries()->toArray();
+ }
+
+ $relevantEntries = [];
+
+ foreach ($bomEntries as $bomEntry) {
+ if ($bomEntry->getReferencedAssembly() !== null) {
+ $relevantEntries[$bomEntry->getId()] = $bomEntry;
}
}
$visitedAssemblies = [];
- foreach ($bomEntries as $bomEntry) {
+ foreach ($relevantEntries as $bomEntry) {
if ($this->hasCycle($bomEntry->getReferencedAssembly(), $value, $visitedAssemblies)) {
$this->addViolation($value, $constraint);
}
}
}
- private function hasCycle(?Assembly $currentAssembly, Assembly $originalAssembly, array &$visitedAssemblies): bool
+ /**
+ * Determines if there is a cyclic dependency in the assembly hierarchy.
+ *
+ * This method checks if a cycle exists in the hierarchy of referenced assemblies starting
+ * from a given assembly. It traverses through the Bill of Materials (BOM) entries of each
+ * assembly recursively and keeps track of visited assemblies to detect cycles.
+ *
+ * @param Assembly|null $currentAssembly The current assembly being checked for cycles.
+ * @param Assembly $originalAssembly The original assembly from where the cycle detection started.
+ * @param Assembly[] $visitedAssemblies A list of assemblies that have been visited during the current traversal.
+ *
+ * @return bool True if a cycle is detected, false otherwise.
+ */
+ private function hasCycle(?Assembly $currentAssembly, Assembly $originalAssembly, array $visitedAssemblies = []): bool
{
+ //No referenced assembly → no cycle
if ($currentAssembly === null) {
return false;
}
- if (in_array($currentAssembly, $visitedAssemblies, true)) {
+ //If the assembly has already been visited, there is a cycle
+ if (in_array($currentAssembly->getId(), array_map(fn($a) => $a->getId(), $visitedAssemblies), true)) {
return true;
}
+ //Add the current assembly to the visited
$visitedAssemblies[] = $currentAssembly;
+ //Go through the bom entries of the current assembly
foreach ($currentAssembly->getBomEntries() as $bomEntry) {
- if ($this->hasCycle($bomEntry->getReferencedAssembly(), $originalAssembly, $visitedAssemblies)) {
+ $referencedAssembly = $bomEntry->getReferencedAssembly();
+
+ if ($referencedAssembly !== null && $this->hasCycle($referencedAssembly, $originalAssembly, $visitedAssemblies)) {
return true;
}
}
+ //Remove the current assembly from the list of visit (recursion completed)
+ array_pop($visitedAssemblies);
+
return false;
}
@@ -102,11 +131,11 @@ private function hasCycle(?Assembly $currentAssembly, Assembly $originalAssembly
* already exists in the context. If such a violation is found, the current violation is not added again.
* The process involves reflection to access private or protected properties of violation objects.
*
- * @param mixed $value The value that triggered the violation.
- * @param Constraint $constraint The constraint containing the validation details.
+ * @param mixed $value The value that triggered the violation.
+ * @param Constraint $constraint The constraint containing the validation details.
*
*/
- private function addViolation($value, Constraint $constraint): void
+ private function addViolation(mixed $value, Constraint $constraint): void
{
/** @var ConstraintViolationBuilder $buildViolation */
$buildViolation = $this->context->buildViolation($constraint->message)
diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntry.php b/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntry.php
new file mode 100644
index 000000000..73234c86e
--- /dev/null
+++ b/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntry.php
@@ -0,0 +1,21 @@
+context->getViolations();
+ if (count($availableViolations) > 0) {
+ //already violations given, currently no more needed to check
+
+ return;
+ }
+
+ $bomEntries = [];
+
+ if ($this->context->getRoot() instanceof Form && $this->context->getRoot()->has('bom_entries')) {
+ $bomEntries = $this->context->getRoot()->get('bom_entries')->getData();
+ $bomEntries = is_array($bomEntries) ? $bomEntries : iterator_to_array($bomEntries);
+ } elseif ($this->context->getRoot() instanceof Assembly) {
+ $bomEntries = $value->getBomEntries()->toArray();
+ }
+
+ $relevantEntries = [];
+
+ foreach ($bomEntries as $bomEntry) {
+ if ($bomEntry->getReferencedAssembly() !== null) {
+ $relevantEntries[$bomEntry->getId()] = $bomEntry;
+ }
+ }
+
+ foreach ($relevantEntries as $bomEntry) {
+ $referencedAssembly = $bomEntry->getReferencedAssembly();
+
+ if ($bomEntry->getAssembly()->getParent()?->getId() === $referencedAssembly->getParent()?->getId()) {
+ //Save on the same assembly level
+ continue;
+ } elseif ($this->isInvalidBomEntry($referencedAssembly, $bomEntry->getAssembly())) {
+ $this->addViolation($value, $constraint);
+ }
+ }
+ }
+
+ /**
+ * Determines whether a Bill of Materials (BOM) entry is invalid based on the relationship
+ * between the current assembly and the parent assembly.
+ *
+ * @param Assembly|null $currentAssembly The current assembly being analyzed. Null indicates no assembly is referenced.
+ * @param Assembly $parentAssembly The parent assembly to check against the current assembly.
+ *
+ * @return bool Returns
+ */
+ private function isInvalidBomEntry(?Assembly $currentAssembly, Assembly $parentAssembly): bool
+ {
+ //No assembly referenced -> no problems
+ if ($currentAssembly === null) {
+ return false;
+ }
+
+ //Check: is the current assembly a descendant of the parent assembly?
+ if ($currentAssembly->isChildOf($parentAssembly)) {
+ return true;
+ }
+
+ //Recursive check: Analyze the current assembly list
+ foreach ($currentAssembly->getBomEntries() as $bomEntry) {
+ $referencedAssembly = $bomEntry->getReferencedAssembly();
+
+ if ($this->isInvalidBomEntry($referencedAssembly, $parentAssembly)) {
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+ private function isOnSameLevel(Assembly $assembly1, Assembly $assembly2): bool
+ {
+ $parent1 = $assembly1->getParent();
+ $parent2 = $assembly2->getParent();
+
+ if ($parent1 === null || $parent2 === null) {
+ return false;
+ }
+
+ // Beide Assemblies teilen denselben Parent
+ return $parent1 !== null && $parent2 !== null && $parent1->getId() === $parent2->getId();
+ }
+
+ /**
+ * Adds a violation to the current context if it hasn’t already been added.
+ *
+ * This method checks whether a violation with the same property path as the current violation
+ * already exists in the context. If such a violation is found, the current violation is not added again.
+ * The process involves reflection to access private or protected properties of violation objects.
+ *
+ * @param mixed $value The value that triggered the violation.
+ * @param Constraint $constraint The constraint containing the validation details.
+ *
+ */
+ private function addViolation($value, Constraint $constraint): void
+ {
+ /** @var ConstraintViolationBuilder $buildViolation */
+ $buildViolation = $this->context->buildViolation($constraint->message)
+ ->setParameter('%name%', $value->getName());
+
+ $alreadyAdded = false;
+
+ try {
+ $reflectionClass = new ReflectionClass($buildViolation);
+ $property = $reflectionClass->getProperty('propertyPath');
+ $propertyPath = $property->getValue($buildViolation);
+
+ $availableViolations = $this->context->getViolations();
+
+ foreach ($availableViolations as $tmpViolation) {
+ $tmpReflectionClass = new ReflectionClass($tmpViolation);
+ $tmpProperty = $tmpReflectionClass->getProperty('propertyPath');
+ $tmpPropertyPath = $tmpProperty->getValue($tmpViolation);
+
+ if ($tmpPropertyPath === $propertyPath) {
+ $alreadyAdded = true;
+ }
+ }
+ } catch (\ReflectionException) {
+ }
+
+ if (!$alreadyAdded) {
+ $buildViolation->addViolation();
+ }
+ }
+}
\ No newline at end of file
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index 7ee171b26..245e61e3b 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -401,6 +401,12 @@
Byl zjištěn cyklus: Sestava "%name%" nepřímo odkazuje sama na sebe.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Sestava nesmí ve svém seznamu materiálů (BOM) odkazovat na podskupinu, která je součástí její vlastní hierarchie.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index 24fa330af..f30dd2116 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -377,6 +377,12 @@
En cyklus blev opdaget: Samlingen "%name%" refererer indirekte til sig selv.
+
+
+ assembly.bom_entry.invalid_child_entry
+ En samling må ikke referere til en undergruppe fra sin egen hierarki i BOM-listerne.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index fa84354b9..645d72ed1 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -401,6 +401,12 @@
Ein Zyklus wurde entdeckt: Die Baugruppe "%name%" referenziert sich indirekt selbst.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Eine Baugruppe darf keine Unterbaugruppe aus seiner eigenen Hierarchie in den BOM-Einträgen referenzieren.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index bc9b0947e..9464f2886 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -43,6 +43,12 @@
Εντοπίστηκε κύκλος: Η συναρμολόγηση "%name%" αναφέρεται έμμεσα στον εαυτό της.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Μία συναρμολόγηση δεν πρέπει να αναφέρεται σε μία υποσυναρμολόγηση από την ίδια την ιεραρχία της στη λίστα BOM.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index 7d9beb4ec..53ad4cde6 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -401,6 +401,12 @@
A cycle was detected: the assembly "%name%" indirectly references itself.
+
+
+ assembly.bom_entry.invalid_child_entry
+ An assembly must not reference a subassembly from its own hierarchy in the BOM entries.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index 1c9c53029..440468295 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -233,6 +233,12 @@
Un cycle a été détecté : L'assemblage "%name%" se réfère indirectement à lui-même.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Un assemblage ne doit pas référencer un sous-assemblage de sa propre hiérarchie dans les entrées de la nomenclature (BOM).
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index 89d470e7e..485cb0e2f 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -395,6 +395,12 @@
Otkriven je ciklus: Sklop "%name%" neizravno referencira samog sebe.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Sklop ne smije referencirati podsklop iz vlastite hijerarhije u unosima BOM-a.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index e9b528bb7..74d3969f7 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -395,6 +395,12 @@
È stato rilevato un ciclo: L'assemblaggio "%name%" fa riferimento indirettamente a sé stesso.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Un assemblaggio non deve fare riferimento a un sottoassemblaggio nella propria gerarchia nelle voci della distinta base (BOM).
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index 80ec65ff2..f9f8a54f8 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -233,6 +233,12 @@
循環が検出されました: アセンブリ「%name%」が間接的に自身を参照しています。
+
+
+ assembly.bom_entry.invalid_child_entry
+ アセンブリは、BOMエントリで自身の階層内のサブアセンブリを参照してはいけません。
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 5df01cd6a..9916178ca 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -395,6 +395,12 @@
循環が検出されました: アセンブリ「%name%」が間接的に自身を参照しています。
+
+
+ assembly.bom_entry.invalid_child_entry
+ Zespół nie może odwoływać się do podzespołu w swojej własnej hierarchii w wpisach BOM.
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index 8bf08ab3c..b8029e47f 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -395,6 +395,12 @@
Обнаружен цикл: Сборка «%name%» косвенно ссылается на саму себя.
+
+
+ assembly.bom_entry.invalid_child_entry
+ Сборка не должна ссылаться на подсборку внутри своей собственной иерархии в записях спецификации (BOM).
+
+ assembly.bom_entry.project_already_in_bom
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 87c507c19..6e4fc0568 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -383,6 +383,12 @@
检测到循环:装配体“%name%”间接引用了其自身。
+
+
+ assembly.bom_entry.invalid_child_entry
+ Сборка не должна ссылаться на подсборку внутри своей собственной иерархии в записях спецификации (BOM).
+
+ assembly.bom_entry.project_already_in_bom
From 412818a7ccdd797fd4949b0d7834adf4aa3f3fce Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Thu, 24 Jul 2025 10:31:19 +0200
Subject: [PATCH 76/83] Tabs und BOMImporter: Verbesserte Anzeige und
Validierung
Die Standardanzeige des Tabs "Details" wurde korrigiert. Im BOMImporter wurden nichtnumerische Spalten kategorisch ausgeschlossen und eine Validation-message angepasst.
---
src/Services/ImportExportSystem/BOMImporter.php | 4 ++--
templates/assemblies/info/info.html.twig | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php
index f022fb5e4..ddad05585 100644
--- a/src/Services/ImportExportSystem/BOMImporter.php
+++ b/src/Services/ImportExportSystem/BOMImporter.php
@@ -529,7 +529,7 @@ function parseCsv(Project|Assembly $importObject, string $csvData): ImporterResu
//If there is no value, skip
if (isset($values[$index]) && $values[$index] !== '') {
//Check whether the value is numerical
- if (is_numeric($values[$index])) {
+ if (is_numeric($values[$index]) && !in_array($column, ['name','description','manufacturer','designator'])) {
//Convert to integer or float
$temp = (str_contains($values[$index], '.'))
? floatval($values[$index])
@@ -560,7 +560,7 @@ function parseCsv(Project|Assembly $importObject, string $csvData): ImporterResu
if (isset($entry['name']) && !is_string($entry['name'])) {
$result->addViolation($this->buildJsonViolation(
- 'validator.bom_importer.csv.parameter.string.notEmpty',
+ 'validator.bom_importer.json_csv.parameter.string.notEmpty',
"row[$key].name",
$entry['name']
));
diff --git a/templates/assemblies/info/info.html.twig b/templates/assemblies/info/info.html.twig
index 098173861..5a419e364 100644
--- a/templates/assemblies/info/info.html.twig
+++ b/templates/assemblies/info/info.html.twig
@@ -98,10 +98,10 @@
-
+
{% include "assemblies/info/_info.html.twig" %}
-
+
{% include "assemblies/info/_part.html.twig" %}
From e21ed95bfd3c7598cf39ab98443638a2589c7ba6 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 28 Jul 2025 10:33:30 +0200
Subject: [PATCH 77/83] =?UTF-8?q?BOMImporter=20und=20AssemblyBomEntriesDat?=
=?UTF-8?q?aTable:=20Mountnames=20hinzugef=C3=BCgt?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Die Verarbeitung der Designators im BOMImporter wurde ergänzt, um Mountnames zu setzen. Zudem wurden neue Spalten wie Kategorie, Footprint, Hersteller und Mountnames in der AssemblyBomEntriesDataTable hinzugefügt. Dies verbessert die Darstellung und Handhabung von Bauteildaten in der Stücklisten-Ansicht.
---
.../AssemblyBomEntriesDataTable.php | 49 +++++++++++++++++++
.../ImportExportSystem/BOMImporter.php | 9 ++++
2 files changed, 58 insertions(+)
diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php
index b2c3e118d..e506dccd2 100644
--- a/src/DataTables/AssemblyBomEntriesDataTable.php
+++ b/src/DataTables/AssemblyBomEntriesDataTable.php
@@ -22,6 +22,7 @@
*/
namespace App\DataTables;
+use App\DataTables\Column\EntityColumn;
use App\DataTables\Column\LocaleDateTimeColumn;
use App\DataTables\Column\MarkdownColumn;
use App\DataTables\Helpers\AssemblyDataTableHelper;
@@ -146,6 +147,54 @@ public function configure(DataTable $dataTable, array $options): void
return $context->getComment();
},
])
+ ->add('category', EntityColumn::class, [
+ 'label' => $this->translator->trans('part.table.category'),
+ 'property' => 'part.category',
+ 'orderField' => 'NATSORT(category.name)',
+ ])
+ ->add('footprint', EntityColumn::class, [
+ 'property' => 'part.footprint',
+ 'label' => $this->translator->trans('part.table.footprint'),
+ 'orderField' => 'NATSORT(footprint.name)',
+ ])
+ ->add('manufacturer', EntityColumn::class, [
+ 'property' => 'part.manufacturer',
+ 'label' => $this->translator->trans('part.table.manufacturer'),
+ 'orderField' => 'NATSORT(manufacturer.name)',
+ ])
+ ->add('mountnames', TextColumn::class, [
+ 'label' => 'assembly.bom.mountnames',
+ 'render' => function ($value, AssemblyBOMEntry $context) {
+ $html = '';
+
+ foreach (explode(',', $context->getMountnames()) as $mountname) {
+ $html .= sprintf('%s ', htmlspecialchars($mountname));
+ }
+ return $html;
+ },
+ ])
+ ->add('instockAmount', TextColumn::class, [
+ 'label' => 'assembly.bom.instockAmount',
+ 'visible' => false,
+ 'render' => function ($value, AssemblyBOMEntry $context) {
+ if ($context->getPart() !== null) {
+ return $this->partDataTableHelper->renderAmount($context->getPart());
+ }
+
+ return '';
+ }
+ ])
+ ->add('storageLocations', TextColumn::class, [
+ 'label' => 'part.table.storeLocations',
+ 'visible' => false,
+ 'render' => function ($value, AssemblyBOMEntry $context) {
+ if ($context->getPart() !== null) {
+ return $this->partDataTableHelper->renderStorageLocations($context->getPart());
+ }
+
+ return '';
+ }
+ ])
->add('addedDate', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.addedDate'),
])
diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php
index ddad05585..ecda3c5ea 100644
--- a/src/Services/ImportExportSystem/BOMImporter.php
+++ b/src/Services/ImportExportSystem/BOMImporter.php
@@ -575,6 +575,11 @@ function parseCsv(Project|Assembly $importObject, string $csvData): ImporterResu
$this->processPart($importObject, $entry, $result, $key, self::IMPORT_TYPE_CSV);
} else {
$bomEntry = $this->getOrCreateBomEntry($importObject, $entry['name'] ?? null);
+
+ if (isset($entry['designator'])) {
+ $bomEntry->setMountnames(trim($entry['designator']) === '' ? '' : trim($entry['designator']));
+ }
+
$bomEntry->setQuantity((float) $entry['quantity'] ?? 0);
$result->addBomEntry($bomEntry);
@@ -863,6 +868,10 @@ private function processPart(Project|Assembly $importObject, array $entry, Impor
$bomEntry->setName(null);
}
+ if (isset($entry['designator'])) {
+ $bomEntry->setMountnames(trim($entry['designator']) === '' ? '' : trim($entry['designator']));
+ }
+
$bomEntry->setPart($part);
$result->addBomEntry($bomEntry);
From 9e8eb93eb83ff61f87d50fea0f16365b578c859e Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 25 Aug 2025 10:43:58 +0200
Subject: [PATCH 78/83] =?UTF-8?q?IPN-Validierung=20f=C3=BCr=20Parts=20?=
=?UTF-8?q?=C3=BCberarbeiten?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Constraints/UniquePartIpnValidator.php | 25 ++++++++++++++-----
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/src/Validator/Constraints/UniquePartIpnValidator.php b/src/Validator/Constraints/UniquePartIpnValidator.php
index 51b5402b8..019202f8e 100644
--- a/src/Validator/Constraints/UniquePartIpnValidator.php
+++ b/src/Validator/Constraints/UniquePartIpnValidator.php
@@ -24,14 +24,27 @@ public function validate($value, Constraint $constraint)
return;
}
+ if (!$this->enforceUniqueIpn) {
+ return;
+ }
+
+ /** @var Part $currentPart */
+ $currentPart = $this->context->getObject();
+
+ if (!$currentPart instanceof Part) {
+ return;
+ }
+
$repository = $this->entityManager->getRepository(Part::class);
- $existingPart = $repository->findOneBy(['ipn' => $value]);
+ $existingParts = $repository->findBy(['ipn' => $value]);
- if ($existingPart) {
- if ($this->enforceUniqueIpn) {
- $this->context->buildViolation($constraint->message)
- ->setParameter('{{ value }}', $value)
- ->addViolation();
+ foreach ($existingParts as $existingPart) {
+ if ($currentPart->getId() !== $existingPart->getId()) {
+ if ($this->enforceUniqueIpn) {
+ $this->context->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $value)
+ ->addViolation();
+ }
}
}
}
From b2f8e21d4e2b601ea095c9e9fe5afaaaf383a00d Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 8 Sep 2025 13:32:34 +0200
Subject: [PATCH 79/83] =?UTF-8?q?F=C3=BCge=20Option=20f=C3=BCr=20lesbares?=
=?UTF-8?q?=20CSV=20beim=20Export=20hinzu=20(APS-3)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../elements/toggle_visibility_controller.js | 52 ++++
.../AssemblySystem/AssemblyBOMEntry.php | 6 +-
.../ImportExportSystem/EntityExporter.php | 291 +++++++++++++++++-
templates/admin/_export_form.html.twig | 19 +-
translations/messages.cs.xlf | 6 +
translations/messages.da.xlf | 6 +
translations/messages.de.xlf | 6 +
translations/messages.el.xlf | 6 +
translations/messages.en.xlf | 6 +
translations/messages.es.xlf | 6 +
translations/messages.fr.xlf | 10 +-
translations/messages.it.xlf | 6 +
translations/messages.ja.xlf | 6 +
translations/messages.nl.xlf | 6 +
translations/messages.pl.xlf | 6 +
translations/messages.ru.xlf | 6 +
translations/messages.zh.xlf | 6 +
17 files changed, 434 insertions(+), 16 deletions(-)
create mode 100644 assets/controllers/elements/toggle_visibility_controller.js
diff --git a/assets/controllers/elements/toggle_visibility_controller.js b/assets/controllers/elements/toggle_visibility_controller.js
new file mode 100644
index 000000000..4600dfb29
--- /dev/null
+++ b/assets/controllers/elements/toggle_visibility_controller.js
@@ -0,0 +1,52 @@
+import { Controller } from "@hotwired/stimulus";
+
+export default class extends Controller {
+
+ static values = {
+ classes: Array
+ };
+
+ connect() {
+ this.readableCheckbox = this.element.querySelector("#readable");
+
+ if (!this.readableCheckbox) {
+ return;
+ }
+
+ // Apply the initial visibility state based on the checkbox being checked or not
+ this.toggleContainers(this.readableCheckbox.checked);
+
+ // Add a change event listener to the 'readable' checkbox
+ this.readableCheckbox.addEventListener("change", (event) => {
+ // Toggle container visibility when the checkbox value changes
+ this.toggleContainers(event.target.checked);
+ });
+ }
+
+ /**
+ * Toggles the visibility of containers based on the checkbox state.
+ * Hides specified containers if the checkbox is checked and shows them otherwise.
+ *
+ * @param {boolean} isChecked - The current state of the checkbox:
+ * true if checked (hide elements), false if unchecked (show them).
+ */
+ toggleContainers(isChecked) {
+ if (!Array.isArray(this.classesValue) || this.classesValue.length === 0) {
+ return;
+ }
+
+ this.classesValue.forEach((cssClass) => {
+ const elements = document.querySelectorAll(`.${cssClass}`);
+
+ if (!elements.length) {
+ return;
+ }
+
+ // Update the visibility for each selected element
+ elements.forEach((element) => {
+ // If the checkbox is checked, hide the container; otherwise, show it
+ element.style.display = isChecked ? "none" : "";
+ });
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
index 7d54fe684..9bca209d0 100644
--- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php
+++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
@@ -124,7 +124,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
*/
#[ORM\ManyToOne(targetEntity: Assembly::class, inversedBy: 'bom_entries')]
#[ORM\JoinColumn(name: 'id_assembly', nullable: true)]
- #[Groups(['bom_entry:read', 'bom_entry:write', ])]
+ #[Groups(['bom_entry:read', 'bom_entry:write'])]
protected ?Assembly $assembly = null;
/**
@@ -146,7 +146,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
#[AssemblyInvalidBomEntry]
#[ORM\ManyToOne(targetEntity: Assembly::class)]
#[ORM\JoinColumn(name: 'id_referenced_assembly', nullable: true, onDelete: 'SET NULL')]
- #[Groups(['bom_entry:read', 'bom_entry:write', ])]
+ #[Groups(['bom_entry:read', 'bom_entry:write'])]
protected ?Assembly $referencedAssembly = null;
/**
@@ -158,7 +158,7 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt
)]
#[ORM\ManyToOne(targetEntity: Project::class)]
#[ORM\JoinColumn(name: 'id_project', nullable: true)]
- #[Groups(['bom_entry:read', 'bom_entry:write', ])]
+ #[Groups(['bom_entry:read', 'bom_entry:write'])]
protected ?Project $project = null;
/**
diff --git a/src/Services/ImportExportSystem/EntityExporter.php b/src/Services/ImportExportSystem/EntityExporter.php
index 271642dad..1adbcdcbb 100644
--- a/src/Services/ImportExportSystem/EntityExporter.php
+++ b/src/Services/ImportExportSystem/EntityExporter.php
@@ -22,8 +22,19 @@
namespace App\Services\ImportExportSystem;
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\Attachments\AttachmentType;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement;
+use App\Entity\LabelSystem\LabelProfile;
+use App\Entity\Parts\Category;
+use App\Entity\Parts\Footprint;
+use App\Entity\Parts\Manufacturer;
+use App\Entity\Parts\MeasurementUnit;
+use App\Entity\Parts\StorageLocation;
+use App\Entity\Parts\Supplier;
+use App\Entity\PriceInformations\Currency;
+use App\Entity\ProjectSystem\Project;
use App\Helpers\FilenameSanatizer;
use App\Serializer\APIPlatform\SkippableItemNormalizer;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -62,6 +73,9 @@ protected function configureOptions(OptionsResolver $resolver): void
$resolver->setDefault('include_children', false);
$resolver->setAllowedTypes('include_children', 'bool');
+
+ $resolver->setDefault('readable', false);
+ $resolver->setAllowedTypes('readable', 'bool');
}
/**
@@ -144,15 +158,50 @@ public function exportEntityFromRequest(AbstractNamedDBElement|array $entities,
$entities = [$entities];
}
- //Do the serialization with the given options
- $serialized_data = $this->exportEntities($entities, $options);
+ if ($request->get('readable', false)) {
+ // Map entity classes to export functions
+ $entityExportMap = [
+ AttachmentType::class => fn($entities) => $this->exportReadable($entities, AttachmentType::class),
+ Category::class => fn($entities) => $this->exportReadable($entities, Category::class),
+ Project::class => fn($entities) => $this->exportReadable($entities, Project::class),
+ Assembly::class => fn($entities) => $this->exportReadable($entities, Assembly::class),
+ Supplier::class => fn($entities) => $this->exportReadable($entities, Supplier::class),
+ Manufacturer::class => fn($entities) => $this->exportReadable($entities, Manufacturer::class),
+ StorageLocation::class => fn($entities) => $this->exportReadable($entities, StorageLocation::class),
+ Footprint::class => fn($entities) => $this->exportReadable($entities, Footprint::class),
+ Currency::class => fn($entities) => $this->exportReadable($entities, Currency::class),
+ MeasurementUnit::class => fn($entities) => $this->exportReadable($entities, MeasurementUnit::class),
+ LabelProfile::class => fn($entities) => $this->exportReadable($entities, LabelProfile::class, false),
+ ];
+
+ // Determine the type of the entity
+ $type = null;
+ foreach ($entities as $entity) {
+ $entityClass = get_class($entity);
+ if (isset($entityExportMap[$entityClass])) {
+ $type = $entityClass;
+ break;
+ }
+ }
+
+ // Generate the response
+ $response = isset($entityExportMap[$type])
+ ? new Response($entityExportMap[$type]($entities))
+ : new Response('');
+
+ $options['format'] = 'csv';
+ $options['level'] = 'readable';
+ } else {
+ //Do the serialization with the given options
+ $serialized_data = $this->exportEntities($entities, $options);
- $response = new Response($serialized_data);
+ $response = new Response($serialized_data);
- //Resolve the format
- $optionsResolver = new OptionsResolver();
- $this->configureOptions($optionsResolver);
- $options = $optionsResolver->resolve($options);
+ //Resolve the format
+ $optionsResolver = new OptionsResolver();
+ $this->configureOptions($optionsResolver);
+ $options = $optionsResolver->resolve($options);
+ }
//Determine the content type for the response
@@ -203,4 +252,232 @@ public function exportEntityFromRequest(AbstractNamedDBElement|array $entities,
return $response;
}
+
+ /**
+ * Exports data for multiple entity types in a readable CSV format.
+ *
+ * @param array $entities The entities to export.
+ * @param string $type The type of entities ('category', 'project', 'assembly', 'attachmentType', 'supplier').
+ * @return string The generated CSV content as a string.
+ */
+ public function exportReadable(array $entities, string $type, bool $isHierarchical = true): string
+ {
+ //Define headers and entity-specific processing logic
+ $defaultProcessEntity = fn($entity, $depth) => [
+ 'Id' => $entity->getId(),
+ 'ParentId' => $entity->getParent()?->getId() ?? '',
+ 'NameHierarchical' => str_repeat('--', $depth) . ' ' . $entity->getName(),
+ 'Name' => $entity->getName(),
+ 'FullName' => $this->getFullName($entity),
+ ];
+
+ $config = [
+ AttachmentType::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Category::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Project::class => [
+ 'header' => [
+ 'Id', 'ParentId', 'Type', 'ProjectNameHierarchical', 'ProjectName', 'ProjectFullName',
+ 'BomQuantity', 'BomPartId', 'BomPartIpn', 'BomPartName', 'BomName', 'BomPartDescription', 'BomMountNames'
+ ],
+ 'processEntity' => fn($entity, $depth) => [
+ 'ProjectId' => $entity->getId(),
+ 'ParentProjectId' => $entity->getParent()?->getId() ?? '',
+ 'Type' => 'project',
+ 'ProjectNameHierarchical' => str_repeat('--', $depth) . ' ' . $entity->getName(),
+ 'ProjectName' => $entity->getName(),
+ 'ProjectFullName' => $this->getFullName($entity),
+ 'BomQuantity' => '-',
+ 'BomPartId' => '-',
+ 'BomPartIpn' => '-',
+ 'BomPartName' => '-',
+ 'BomName' => '-',
+ 'BomPartDescription' => '-',
+ 'BomMountNames' => '-',
+ ],
+ 'processBomEntries' => fn($entity, $depth) => array_map(fn($bomEntry) => [
+ 'Id' => $entity->getId(),
+ 'ParentId' => '',
+ 'Type' => 'project_bom_entry',
+ 'ProjectNameHierarchical' => str_repeat('--', $depth) . '> ' . $entity->getName(),
+ 'ProjectName' => $entity->getName(),
+ 'ProjectFullName' => $this->getFullName($entity),
+ 'BomQuantity' => $bomEntry->getQuantity() ?? '',
+ 'BomPartId' => $bomEntry->getPart()?->getId() ?? '',
+ 'BomPartIpn' => $bomEntry->getPart()?->getIpn() ?? '',
+ 'BomPartName' => $bomEntry->getPart()?->getName() ?? '',
+ 'BomName' => $bomEntry->getName() ?? '',
+ 'BomPartDescription' => $bomEntry->getPart()?->getDescription() ?? '',
+ 'BomMountNames' => $bomEntry->getMountNames(),
+ ], $entity->getBomEntries()->toArray()),
+ ],
+ Assembly::class => [
+ 'header' => [
+ 'Id', 'ParentId', 'Type', 'AssemblyIpn', 'AssemblyNameHierarchical', 'AssemblyName',
+ 'AssemblyFullName', 'BomQuantity', 'BomPartId', 'BomPartIpn', 'BomPartName', 'BomName', 'BomPartDescription',
+ 'BomMountNames', 'BomReferencedAssemblyId', 'BomReferencedAssemblyIpn', 'BomReferencedAssemblyFullName'
+ ],
+ 'processEntity' => fn($entity, $depth) => [
+ 'Id' => $entity->getId(),
+ 'ParentId' => $entity->getParent()?->getId() ?? '',
+ 'Type' => 'assembly',
+ 'AssemblyIpn' => $entity->getIpn(),
+ 'AssemblyNameHierarchical' => str_repeat('--', $depth) . ' ' . $entity->getName(),
+ 'AssemblyName' => $entity->getName(),
+ 'AssemblyFullName' => $this->getFullName($entity),
+ 'BomQuantity' => '-',
+ 'BomPartId' => '-',
+ 'BomPartIpn' => '-',
+ 'BomPartName' => '-',
+ 'BomName' => '-',
+ 'BomPartDescription' => '-',
+ 'BomMountNames' => '-',
+ 'BomReferencedAssemblyId' => '-',
+ 'BomReferencedAssemblyIpn' => '-',
+ 'BomReferencedAssemblyFullName' => '-',
+ ],
+ 'processBomEntries' => fn($entity, $depth) => array_map(fn($bomEntry) => [
+ 'Id' => $entity->getId(),
+ 'ParentId' => '',
+ 'Type' => 'assembly_bom_entry',
+ 'AssemblyIpn' => $entity->getIpn(),
+ 'AssemblyNameHierarchical' => str_repeat('--', $depth) . '> ' . $entity->getName(),
+ 'AssemblyName' => $entity->getName(),
+ 'AssemblyFullName' => $this->getFullName($entity),
+ 'BomQuantity' => $bomEntry->getQuantity() ?? '',
+ 'BomPartId' => $bomEntry->getPart()?->getId() ?? '',
+ 'BomPartIpn' => $bomEntry->getPart()?->getIpn() ?? '',
+ 'BomPartName' => $bomEntry->getPart()?->getName() ?? '',
+ 'BomName' => $bomEntry->getName() ?? '',
+ 'BomPartDescription' => $bomEntry->getPart()?->getDescription() ?? '',
+ 'BomMountNames' => $bomEntry->getMountNames(),
+ 'BomReferencedAssemblyId' => $bomEntry->getReferencedAssembly()?->getId() ?? '',
+ 'BomReferencedAssemblyIpn' => $bomEntry->getReferencedAssembly()?->getIpn() ?? '',
+ 'BomReferencedAssemblyFullName' => $this->getFullName($bomEntry->getReferencedAssembly() ?? null),
+ ], $entity->getBomEntries()->toArray()),
+ ],
+ Supplier::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Manufacturer::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ StorageLocation::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Footprint::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ Currency::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ MeasurementUnit::class => [
+ 'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
+ 'processEntity' => $defaultProcessEntity,
+ ],
+ LabelProfile::class => [
+ 'header' => ['Id', 'SupportedElement', 'Name'],
+ 'processEntity' => fn(LabelProfile $entity, $depth) => [
+ 'Id' => $entity->getId(),
+ 'SupportedElement' => $entity->getOptions()->getSupportedElement()->name,
+ 'Name' => $entity->getName(),
+ ],
+ ],
+ ];
+
+ //Get configuration for the entity type
+ $entityConfig = $config[$type] ?? null;
+
+ if (!$entityConfig) {
+ return '';
+ }
+
+ //Initialize CSV data with the header
+ $csvData = [];
+ $csvData[] = $entityConfig['header'];
+
+ $relevantEntities = $entities;
+
+ if ($isHierarchical) {
+ //Filter root entities (those without parents)
+ $relevantEntities = array_filter($entities, fn($entity) => $entity->getParent() === null);
+
+ if (count($relevantEntities) === 0 && count($entities) > 0) {
+ //If no root entities are found, then we need to add all entities
+
+ $relevantEntities = $entities;
+ }
+ }
+
+ //Sort root entities alphabetically by `name`
+ usort($relevantEntities, fn($a, $b) => strnatcasecmp($a->getName(), $b->getName()));
+
+ //Recursive function to process an entity and its children
+ $processEntity = function ($entity, &$csvData, $depth = 0) use (&$processEntity, $entityConfig, $isHierarchical) {
+ //Add main entity data to CSV
+ $csvData[] = $entityConfig['processEntity']($entity, $depth);
+
+ //Process BOM entries if applicable
+ if (isset($entityConfig['processBomEntries'])) {
+ $bomRows = $entityConfig['processBomEntries']($entity, $depth);
+ foreach ($bomRows as $bomRow) {
+ $csvData[] = $bomRow;
+ }
+ }
+
+ if ($isHierarchical) {
+ //Retrieve children, sort alphabetically, then process them
+ $children = $entity->getChildren()->toArray();
+ usort($children, fn($a, $b) => strnatcasecmp($a->getName(), $b->getName()));
+ foreach ($children as $childEntity) {
+ $processEntity($childEntity, $csvData, $depth + 1);
+ }
+ }
+ };
+
+ //Start processing with root entities
+ foreach ($relevantEntities as $rootEntity) {
+ $processEntity($rootEntity, $csvData);
+ }
+
+ //Generate CSV string
+ $output = '';
+ foreach ($csvData as $line) {
+ $output .= implode(';', $line) . "\n"; // Use a semicolon as the delimiter
+ }
+
+ return $output;
+ }
+
+ /**
+ * Constructs the full hierarchical name of an object by traversing
+ * through its parent objects and concatenating their names using
+ * a specified separator.
+ *
+ * @param AttachmentType|Category|Project|Assembly|Supplier|Manufacturer|StorageLocation|Footprint|Currency|MeasurementUnit|LabelProfile|null $object The object whose full name is to be constructed. If null, the result will be an empty string.
+ * @param string $separator The string used to separate the names of the objects in the full hierarchy.
+ *
+ * @return string The full hierarchical name constructed by concatenating the names of the object and its parents.
+ */
+ private function getFullName(AttachmentType|Category|Project|Assembly|Supplier|Manufacturer|StorageLocation|Footprint|Currency|MeasurementUnit|LabelProfile|null $object, string $separator = '->'): string
+ {
+ $fullNameParts = [];
+
+ while ($object !== null) {
+ array_unshift($fullNameParts, $object->getName());
+ $object = $object->getParent();
+ }
+
+ return implode($separator, $fullNameParts);
+ }
}
diff --git a/templates/admin/_export_form.html.twig b/templates/admin/_export_form.html.twig
index 07b00d43c..527518640 100644
--- a/templates/admin/_export_form.html.twig
+++ b/templates/admin/_export_form.html.twig
@@ -1,6 +1,6 @@
-
+
-
+
-
+
-
+
@@ -34,6 +34,17 @@
+
+
+
+
+
+
+
+
+
{% trans %}export.btn{% endtrans %}
diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf
index 89edfb80f..21b1416e6 100644
--- a/translations/messages.cs.xlf
+++ b/translations/messages.cs.xlf
@@ -351,6 +351,12 @@
Exportovat všechny prvky
+
+
+ export.readable
+ Čitelné CSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf
index 8f28ef088..f4a3881d5 100644
--- a/translations/messages.da.xlf
+++ b/translations/messages.da.xlf
@@ -351,6 +351,12 @@
Eksportér alle elementer
+
+
+ export.readable
+ Læsbar CSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index fbe651ff4..22a36d1d5 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -1010,6 +1010,12 @@ Subelemente werden beim Löschen nach oben verschoben.
Unterelemente auch exportieren
+
+
+ export.readable
+ Lesbares CSV
+
+ Part-DB1\templates\AdminPages\_export_form.html.twig:39
diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf
index 98630c483..ccbed9fb7 100644
--- a/translations/messages.el.xlf
+++ b/translations/messages.el.xlf
@@ -228,6 +228,12 @@
Εξαγωγή όλων των στοιχείων
+
+
+ export.readable
+ Αναγνώσιμο CSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 9eeb1ef05..d58a1b4fb 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -351,6 +351,12 @@
Export all elements
+
+
+ export.readable
+ Readable CSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf
index 8b48e4428..999fd71a0 100644
--- a/translations/messages.es.xlf
+++ b/translations/messages.es.xlf
@@ -351,6 +351,12 @@
Exportar todos los elementos
+
+
+ export.readable
+ CSV legible
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf
index ee1d6ffe1..b5ed6a27b 100644
--- a/translations/messages.fr.xlf
+++ b/translations/messages.fr.xlf
@@ -320,6 +320,12 @@
Exporter tous les éléments
+
+
+ export.readable
+ CSV lisible
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
@@ -9822,13 +9828,13 @@ exemple de ville
-
+ assembly.bom_import.template.csv.exptected_columnsColonnes possibles :
-
+ assembly.bom_import.template.csv.table
diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf
index ac1344052..951a1bd3d 100644
--- a/translations/messages.it.xlf
+++ b/translations/messages.it.xlf
@@ -351,6 +351,12 @@
Esportare tutti gli elementi
+
+
+ export.readable
+ CSV leggibile
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf
index e892af9c4..101afd625 100644
--- a/translations/messages.ja.xlf
+++ b/translations/messages.ja.xlf
@@ -320,6 +320,12 @@
すべてエクスポートする
+
+
+ export.readable
+ 読みやすいCSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf
index b24e14b9a..ebf67d393 100644
--- a/translations/messages.nl.xlf
+++ b/translations/messages.nl.xlf
@@ -351,6 +351,12 @@
Exporteer alle elementen
+
+
+ export.readable
+ Leesbare CSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf
index a09e3ac33..d9d4eac22 100644
--- a/translations/messages.pl.xlf
+++ b/translations/messages.pl.xlf
@@ -351,6 +351,12 @@
Eksportuj wszystkie elementy
+
+
+ export.readable
+ Czytelny CSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf
index 8d6a0ba10..3589e4e16 100644
--- a/translations/messages.ru.xlf
+++ b/translations/messages.ru.xlf
@@ -351,6 +351,12 @@
Экспортировать всё
+
+
+ export.readable
+ Читаемый CSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf
index f257f9a2f..a3e44de66 100644
--- a/translations/messages.zh.xlf
+++ b/translations/messages.zh.xlf
@@ -351,6 +351,12 @@
导出所有元素
+
+
+ export.readable
+ 可读的 CSV
+
+ Part-DB1\templates\AdminPages\EntityAdminBase.html.twig:185
From 6bb20fb0cbb5937539cb107d9ec9e9d9567d8994 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Fri, 12 Sep 2025 16:05:42 +0200
Subject: [PATCH 80/83] =?UTF-8?q?Entferne=20Projektbezogene=20Logik=20bzw.?=
=?UTF-8?q?=20Verweise=20auf=20Baugruppen,=20da=20nicht=20ben=C3=B6tigt.?=
=?UTF-8?q?=20=C3=9Cberarbeitung=20Exporter:=20Aufnahme=20von=20Parts=20au?=
=?UTF-8?q?s=20Subassemblies.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Controller/AssemblyController.php | 1 -
.../AssemblyBomEntriesDataTable.php | 12 +-
src/Entity/AssemblySystem/Assembly.php | 3 +-
.../AssemblySystem/AssemblyBOMEntry.php | 23 ++--
.../UserSystem/PartUniqueIpnSubscriber.php | 2 +-
.../AssemblySystem/AssemblyBOMEntryType.php | 4 -
.../Assemblies/AssemblyPartAggregator.php | 83 ++++++++++++
.../AssemblySystem/AssemblyBuildHelper.php | 12 +-
.../ImportExportSystem/EntityExporter.php | 123 +++++++++++++-----
src/Twig/AssemblyTwigExtension.php | 30 -----
translations/validators.cs.xlf | 6 -
translations/validators.da.xlf | 6 -
translations/validators.de.xlf | 6 -
translations/validators.el.xlf | 6 -
translations/validators.en.xlf | 6 -
translations/validators.fr.xlf | 6 -
translations/validators.hr.xlf | 6 -
translations/validators.it.xlf | 6 -
translations/validators.ja.xlf | 6 -
translations/validators.pl.xlf | 6 -
translations/validators.ru.xlf | 6 -
translations/validators.zh.xlf | 6 -
22 files changed, 195 insertions(+), 170 deletions(-)
create mode 100644 src/Helpers/Assemblies/AssemblyPartAggregator.php
delete mode 100644 src/Twig/AssemblyTwigExtension.php
diff --git a/src/Controller/AssemblyController.php b/src/Controller/AssemblyController.php
index 520bc52de..5d8211216 100644
--- a/src/Controller/AssemblyController.php
+++ b/src/Controller/AssemblyController.php
@@ -29,7 +29,6 @@
use App\Entity\AssemblySystem\Assembly;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
use App\Entity\Parts\Part;
-use App\Entity\UserSystem\User;
use App\Exceptions\InvalidRegexException;
use App\Form\AssemblySystem\AssemblyAddPartsType;
use App\Form\AssemblySystem\AssemblyBuildType;
diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php
index f9baeb869..ddeedba22 100644
--- a/src/DataTables/AssemblyBomEntriesDataTable.php
+++ b/src/DataTables/AssemblyBomEntriesDataTable.php
@@ -26,14 +26,12 @@
use App\DataTables\Column\LocaleDateTimeColumn;
use App\DataTables\Column\MarkdownColumn;
use App\DataTables\Helpers\AssemblyDataTableHelper;
-use App\DataTables\Helpers\ProjectDataTableHelper;
use App\DataTables\Helpers\ColumnSortHelper;
use App\DataTables\Helpers\PartDataTableHelper;
use App\Entity\AssemblySystem\Assembly;
use App\Entity\Attachments\Attachment;
use App\Entity\Parts\Part;
use App\Entity\AssemblySystem\AssemblyBOMEntry;
-use App\Entity\ProjectSystem\Project;
use App\Services\Formatters\AmountFormatter;
use App\Settings\BehaviorSettings\TableSettings;
use Doctrine\ORM\QueryBuilder;
@@ -49,7 +47,6 @@ class AssemblyBomEntriesDataTable implements DataTableTypeInterface
public function __construct(
private readonly TranslatorInterface $translator,
private readonly PartDataTableHelper $partDataTableHelper,
- private readonly ProjectDataTableHelper $projectDataTableHelper,
private readonly AssemblyDataTableHelper $assemblyDataTableHelper,
private readonly AmountFormatter $amountFormatter,
private readonly ColumnSortHelper $csh,
@@ -90,7 +87,7 @@ public function configure(DataTable $dataTable, array $options): void
'label' => $this->translator->trans('part.table.name'),
'orderField' => 'NATSORT(part.name)',
'render' => function ($value, AssemblyBOMEntry $context) {
- if(!$context->getPart() instanceof Part && !$context->getReferencedAssembly() instanceof Assembly && !$context->getProject() instanceof Project) {
+ if(!$context->getPart() instanceof Part && !$context->getReferencedAssembly() instanceof Assembly) {
return htmlspecialchars((string) $context->getName());
}
@@ -105,13 +102,6 @@ public function configure(DataTable $dataTable, array $options): void
$tmp = $this->assemblyDataTableHelper->renderName($context->getReferencedAssembly());
$tmp = $this->translator->trans('part.table.name.value.for_assembly', ['%value%' => $tmp]);
- if($context->getName() !== null && $context->getName() !== '') {
- $tmp .= ' '.htmlspecialchars($context->getName()).'';
- }
- } elseif ($context->getProject() !== null) {
- $tmp = $this->projectDataTableHelper->renderName($context->getProject());
- $tmp = $this->translator->trans('part.table.name.value.for_project', ['%value%' => $tmp]);
-
if($context->getName() !== null && $context->getName() !== '') {
$tmp .= ' '.htmlspecialchars($context->getName()).'';
}
diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php
index c65ca71fe..fde61cd90 100644
--- a/src/Entity/AssemblySystem/Assembly.php
+++ b/src/Entity/AssemblySystem/Assembly.php
@@ -118,7 +118,6 @@ class Assembly extends AbstractStructuralDBElement
#[Groups(['extended', 'full', 'import'])]
#[ORM\OneToMany(targetEntity: AssemblyBOMEntry::class, mappedBy: 'assembly', cascade: ['persist', 'remove'], orphanRemoval: true)]
#[UniqueObjectCollection(message: 'assembly.bom_entry.part_already_in_bom', fields: ['part'])]
- #[UniqueObjectCollection(message: 'assembly.bom_entry.project_already_in_bom', fields: ['project'])]
#[UniqueObjectCollection(message: 'assembly.bom_entry.name_already_in_bom', fields: ['name'])]
protected Collection $bom_entries;
@@ -137,7 +136,7 @@ class Assembly extends AbstractStructuralDBElement
* @var string|null The internal ipn number of the assembly
*/
#[Assert\Length(max: 100)]
- #[Groups(['extended', 'full', 'project:read', 'project:write', 'import'])]
+ #[Groups(['extended', 'full', 'assembly:read', 'assembly:write', 'import'])]
#[ORM\Column(type: Types::STRING, length: 100, unique: true, nullable: true)]
#[Length(max: 100)]
protected ?string $ipn = null;
diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
index 6de6cc3a6..9620e4891 100644
--- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php
+++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php
@@ -36,7 +36,6 @@
use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Contracts\TimeStampableInterface;
-use App\Entity\ProjectSystem\Project;
use App\Repository\DBElementRepository;
use App\Validator\Constraints\AssemblySystem\AssemblyCycle;
use App\Validator\Constraints\AssemblySystem\AssemblyInvalidBomEntry;
@@ -252,17 +251,6 @@ public function setReferencedAssembly(?Assembly $referencedAssembly): AssemblyBO
return $this;
}
- public function getProject(): ?Project
- {
- return $this->project;
- }
-
- public function setProject(?Project $project): AssemblyBOMEntry
- {
- $this->project = $project;
- return $this;
- }
-
/**
* Returns the price of this BOM entry, if existing.
* Prices are only valid on non-Part BOM entries.
@@ -300,6 +288,15 @@ public function isPartBomEntry(): bool
return $this->part instanceof Part;
}
+ /**
+ * Checks whether this BOM entry is a assembly associated BOM entry or not.
+ * @return bool True if this BOM entry is a assembly associated BOM entry, false otherwise.
+ */
+ public function isAssemblyBomEntry(): bool
+ {
+ return $this->referencedAssembly !== null;
+ }
+
#[Assert\Callback]
public function validate(ExecutionContextInterface $context, $payload): void
{
@@ -335,7 +332,7 @@ public function getComparableFields(): array
return [
'name' => $this->getName(),
'part' => $this->getPart()?->getID(),
- 'project' => $this->getProject()?->getID(),
+ 'referencedAssembly' => $this->getReferencedAssembly()?->getID(),
];
}
}
diff --git a/src/EventSubscriber/UserSystem/PartUniqueIpnSubscriber.php b/src/EventSubscriber/UserSystem/PartUniqueIpnSubscriber.php
index 9cff3166d..c5d22dbef 100644
--- a/src/EventSubscriber/UserSystem/PartUniqueIpnSubscriber.php
+++ b/src/EventSubscriber/UserSystem/PartUniqueIpnSubscriber.php
@@ -70,4 +70,4 @@ private function ensureUniqueIpn(Part $part): void
$part->setIpn($originalIpn . "_$increment");
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Form/AssemblySystem/AssemblyBOMEntryType.php b/src/Form/AssemblySystem/AssemblyBOMEntryType.php
index b86b2fd1b..851ab8157 100644
--- a/src/Form/AssemblySystem/AssemblyBOMEntryType.php
+++ b/src/Form/AssemblySystem/AssemblyBOMEntryType.php
@@ -39,10 +39,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
->add('part', PartSelectType::class, [
'required' => false,
])
- ->add('project', ProjectSelectType::class, [
- 'label' => 'assembly.bom.project',
- 'required' => false,
- ])
->add('referencedAssembly', AssemblySelectType::class, [
'label' => 'assembly.bom.referencedAssembly',
'required' => false,
diff --git a/src/Helpers/Assemblies/AssemblyPartAggregator.php b/src/Helpers/Assemblies/AssemblyPartAggregator.php
new file mode 100644
index 000000000..94c102573
--- /dev/null
+++ b/src/Helpers/Assemblies/AssemblyPartAggregator.php
@@ -0,0 +1,83 @@
+.
+ */
+namespace App\Helpers\Assemblies;
+
+use App\Entity\AssemblySystem\Assembly;
+use App\Entity\Parts\Part;
+
+class AssemblyPartAggregator
+{
+ /**
+ * Aggregate the required parts and their total quantities for an assembly.
+ *
+ * @param Assembly $assembly The assembly to process.
+ * @param float $multiplier The quantity multiplier from the parent assembly.
+ * @return array Array of parts with their aggregated quantities, keyed by Part ID.
+ */
+ public function getAggregatedParts(Assembly $assembly, float $multiplier): array
+ {
+ $aggregatedParts = [];
+
+ // Start processing the assembly recursively
+ $this->processAssembly($assembly, $multiplier, $aggregatedParts);
+
+ // Return the final aggregated list of parts
+ return $aggregatedParts;
+ }
+
+ /**
+ * Recursive helper to process an assembly and all its BOM entries.
+ *
+ * @param Assembly $assembly The current assembly to process.
+ * @param float $multiplier The quantity multiplier from the parent assembly.
+ * @param array &$aggregatedParts The array to accumulate parts and their quantities.
+ */
+ private function processAssembly(Assembly $assembly, float $multiplier, array &$aggregatedParts): void
+ {
+ foreach ($assembly->getBomEntries() as $bomEntry) {
+ // If the BOM entry refers to a part, add its quantity
+ if ($bomEntry->getPart() instanceof Part) {
+ $part = $bomEntry->getPart();
+
+ if (!isset($aggregatedParts[$part->getId()])) {
+ $aggregatedParts[$part->getId()] = [
+ 'part' => $part,
+ 'assembly' => $assembly,
+ 'quantity' => $bomEntry->getQuantity(),
+ 'multiplier' => $multiplier,
+ ];
+ }
+ } elseif ($bomEntry->getReferencedAssembly() instanceof Assembly) {
+ // If the BOM entry refers to another assembly, process it recursively
+ $this->processAssembly($bomEntry->getReferencedAssembly(), $bomEntry->getQuantity(), $aggregatedParts);
+ } else {
+ $aggregatedParts[] = [
+ 'part' => null,
+ 'assembly' => $assembly,
+ 'quantity' => $bomEntry->getQuantity(),
+ 'multiplier' => $multiplier,
+ ];
+ }
+ }
+ }
+}
diff --git a/src/Services/AssemblySystem/AssemblyBuildHelper.php b/src/Services/AssemblySystem/AssemblyBuildHelper.php
index b7f2df3ce..9180f3e80 100644
--- a/src/Services/AssemblySystem/AssemblyBuildHelper.php
+++ b/src/Services/AssemblySystem/AssemblyBuildHelper.php
@@ -27,7 +27,6 @@
use App\Entity\Parts\Part;
use App\Helpers\Assemblies\AssemblyBuildRequest;
use App\Services\Parts\PartLotWithdrawAddHelper;
-use App\Services\ProjectSystem\ProjectBuildHelper;
/**
* @see \App\Tests\Services\AssemblySystem\AssemblyBuildHelperTest
@@ -35,8 +34,7 @@
class AssemblyBuildHelper
{
public function __construct(
- private readonly PartLotWithdrawAddHelper $withdraw_add_helper,
- private readonly ProjectBuildHelper $projectBuildHelper
+ private readonly PartLotWithdrawAddHelper $withdraw_add_helper
) {
}
@@ -70,15 +68,15 @@ public function getMaximumBuildableCount(Assembly $assembly): int
/** @var AssemblyBOMEntry $bom_entry */
foreach ($assembly->getBomEntries() as $bom_entry) {
//Skip BOM entries without a part (as we can not determine that)
- if (!$bom_entry->isPartBomEntry() && $bom_entry->getProject() === null) {
+ if (!$bom_entry->isPartBomEntry() && !$bom_entry->isAssemblyBomEntry()) {
continue;
}
- //The maximum buildable count for the whole project is the minimum of all BOM entries
+ //The maximum buildable count for the whole assembly is the minimum of all BOM entries
if ($bom_entry->getPart() !== null) {
$maximum_buildable_count = min($maximum_buildable_count, $this->getMaximumBuildableCountForBOMEntry($bom_entry));
} elseif ($bom_entry->getReferencedAssembly() !== null) {
- $maximum_buildable_count = min($maximum_buildable_count, $this->projectBuildHelper->getMaximumBuildableCount($bom_entry->getReferencedAssembly()));
+ $maximum_buildable_count = min($maximum_buildable_count, $this->getMaximumBuildableCount($bom_entry->getReferencedAssembly()));
}
}
@@ -105,7 +103,7 @@ public function isBOMEntryBuildable(AssemblyBOMEntry $bom_entry, int $number_of_
}
/**
- * Returns the project BOM entries for which parts are missing in the stock for the given number of builds
+ * Returns the referenced assembly BOM entries for which parts are missing in the stock for the given number of builds
* @param Assembly $assembly The assembly for which the BOM entries should be checked
* @param int $number_of_builds How often should the assembly be build?
* @return AssemblyBOMEntry[]
diff --git a/src/Services/ImportExportSystem/EntityExporter.php b/src/Services/ImportExportSystem/EntityExporter.php
index 1adbcdcbb..3e0aa27cf 100644
--- a/src/Services/ImportExportSystem/EntityExporter.php
+++ b/src/Services/ImportExportSystem/EntityExporter.php
@@ -23,6 +23,7 @@
namespace App\Services\ImportExportSystem;
use App\Entity\AssemblySystem\Assembly;
+use App\Entity\AssemblySystem\AssemblyBOMEntry;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement;
@@ -35,6 +36,7 @@
use App\Entity\Parts\Supplier;
use App\Entity\PriceInformations\Currency;
use App\Entity\ProjectSystem\Project;
+use App\Helpers\Assemblies\AssemblyPartAggregator;
use App\Helpers\FilenameSanatizer;
use App\Serializer\APIPlatform\SkippableItemNormalizer;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -56,8 +58,10 @@
*/
class EntityExporter
{
- public function __construct(protected SerializerInterface $serializer)
- {
+ public function __construct(
+ protected SerializerInterface $serializer,
+ protected AssemblyPartAggregator $partAggregator, private readonly AssemblyPartAggregator $assemblyPartAggregator,
+ ) {
}
protected function configureOptions(OptionsResolver $resolver): void
@@ -282,8 +286,9 @@ public function exportReadable(array $entities, string $type, bool $isHierarchic
],
Project::class => [
'header' => [
- 'Id', 'ParentId', 'Type', 'ProjectNameHierarchical', 'ProjectName', 'ProjectFullName',
- 'BomQuantity', 'BomPartId', 'BomPartIpn', 'BomPartName', 'BomName', 'BomPartDescription', 'BomMountNames'
+ 'Id', 'ParentId', 'Type', 'ProjectNameHierarchical', 'ProjectName', 'ProjectFullName', 'BomQuantity',
+ 'BomPartId', 'BomPartIpn', 'BomPartMpnr', 'BomPartName', 'BomDesignator', 'BomPartDescription',
+ 'BomMountNames'
],
'processEntity' => fn($entity, $depth) => [
'ProjectId' => $entity->getId(),
@@ -295,12 +300,13 @@ public function exportReadable(array $entities, string $type, bool $isHierarchic
'BomQuantity' => '-',
'BomPartId' => '-',
'BomPartIpn' => '-',
+ 'BomPartMpnr' => '-',
'BomPartName' => '-',
- 'BomName' => '-',
+ 'BomDesignator' => '-',
'BomPartDescription' => '-',
'BomMountNames' => '-',
],
- 'processBomEntries' => fn($entity, $depth) => array_map(fn($bomEntry) => [
+ 'processBomEntries' => fn($entity, $depth) => array_map(fn(AssemblyBOMEntry $bomEntry) => [
'Id' => $entity->getId(),
'ParentId' => '',
'Type' => 'project_bom_entry',
@@ -310,8 +316,9 @@ public function exportReadable(array $entities, string $type, bool $isHierarchic
'BomQuantity' => $bomEntry->getQuantity() ?? '',
'BomPartId' => $bomEntry->getPart()?->getId() ?? '',
'BomPartIpn' => $bomEntry->getPart()?->getIpn() ?? '',
+ 'BomPartMpnr' => $bomEntry->getPart()?->getManufacturerProductNumber() ?? '',
'BomPartName' => $bomEntry->getPart()?->getName() ?? '',
- 'BomName' => $bomEntry->getName() ?? '',
+ 'BomDesignator' => $bomEntry->getName() ?? '',
'BomPartDescription' => $bomEntry->getPart()?->getDescription() ?? '',
'BomMountNames' => $bomEntry->getMountNames(),
], $entity->getBomEntries()->toArray()),
@@ -319,8 +326,9 @@ public function exportReadable(array $entities, string $type, bool $isHierarchic
Assembly::class => [
'header' => [
'Id', 'ParentId', 'Type', 'AssemblyIpn', 'AssemblyNameHierarchical', 'AssemblyName',
- 'AssemblyFullName', 'BomQuantity', 'BomPartId', 'BomPartIpn', 'BomPartName', 'BomName', 'BomPartDescription',
- 'BomMountNames', 'BomReferencedAssemblyId', 'BomReferencedAssemblyIpn', 'BomReferencedAssemblyFullName'
+ 'AssemblyFullName', 'BomQuantity', 'BomMultiplier', 'BomPartId', 'BomPartIpn', 'BomPartMpnr',
+ 'BomPartName', 'BomDesignator', 'BomPartDescription', 'BomMountNames', 'BomReferencedAssemblyId',
+ 'BomReferencedAssemblyIpn', 'BomReferencedAssemblyFullName'
],
'processEntity' => fn($entity, $depth) => [
'Id' => $entity->getId(),
@@ -331,35 +339,19 @@ public function exportReadable(array $entities, string $type, bool $isHierarchic
'AssemblyName' => $entity->getName(),
'AssemblyFullName' => $this->getFullName($entity),
'BomQuantity' => '-',
+ 'BomMultiplier' => '-',
'BomPartId' => '-',
'BomPartIpn' => '-',
+ 'BomPartMpnr' => '-',
'BomPartName' => '-',
- 'BomName' => '-',
+ 'BomDesignator' => '-',
'BomPartDescription' => '-',
'BomMountNames' => '-',
'BomReferencedAssemblyId' => '-',
'BomReferencedAssemblyIpn' => '-',
'BomReferencedAssemblyFullName' => '-',
],
- 'processBomEntries' => fn($entity, $depth) => array_map(fn($bomEntry) => [
- 'Id' => $entity->getId(),
- 'ParentId' => '',
- 'Type' => 'assembly_bom_entry',
- 'AssemblyIpn' => $entity->getIpn(),
- 'AssemblyNameHierarchical' => str_repeat('--', $depth) . '> ' . $entity->getName(),
- 'AssemblyName' => $entity->getName(),
- 'AssemblyFullName' => $this->getFullName($entity),
- 'BomQuantity' => $bomEntry->getQuantity() ?? '',
- 'BomPartId' => $bomEntry->getPart()?->getId() ?? '',
- 'BomPartIpn' => $bomEntry->getPart()?->getIpn() ?? '',
- 'BomPartName' => $bomEntry->getPart()?->getName() ?? '',
- 'BomName' => $bomEntry->getName() ?? '',
- 'BomPartDescription' => $bomEntry->getPart()?->getDescription() ?? '',
- 'BomMountNames' => $bomEntry->getMountNames(),
- 'BomReferencedAssemblyId' => $bomEntry->getReferencedAssembly()?->getId() ?? '',
- 'BomReferencedAssemblyIpn' => $bomEntry->getReferencedAssembly()?->getIpn() ?? '',
- 'BomReferencedAssemblyFullName' => $this->getFullName($bomEntry->getReferencedAssembly() ?? null),
- ], $entity->getBomEntries()->toArray()),
+ 'processBomEntries' => fn($entity, $depth) => $this->processBomEntriesWithAggregatedParts($entity, $depth),
],
Supplier::class => [
'header' => ['Id', 'ParentId', 'NameHierarchical', 'Name', 'FullName'],
@@ -459,6 +451,79 @@ public function exportReadable(array $entities, string $type, bool $isHierarchic
return $output;
}
+ /**
+ * Process BOM entries and include aggregated parts as "complete_part_list".
+ *
+ * @param Assembly $assembly The assembly being processed.
+ * @param int $depth The current depth in the hierarchy.
+ * @return array Processed BOM entries and aggregated parts rows.
+ */
+ private function processBomEntriesWithAggregatedParts(Assembly $assembly, int $depth): array
+ {
+ $rows = [];
+
+ foreach ($assembly->getBomEntries() as $bomEntry) {
+ // Add the BOM entry itself
+ $rows[] = [
+ 'Id' => $assembly->getId(),
+ 'ParentId' => '',
+ 'Type' => 'assembly_bom_entry',
+ 'AssemblyIpn' => $assembly->getIpn(),
+ 'AssemblyNameHierarchical' => str_repeat('--', $depth) . '> ' . $assembly->getName(),
+ 'AssemblyName' => $assembly->getName(),
+ 'AssemblyFullName' => $this->getFullName($assembly),
+ 'BomQuantity' => $bomEntry->getQuantity() ?? '',
+ 'BomMultiplier' => '',
+ 'BomPartId' => $bomEntry->getPart()?->getId() ?? '-',
+ 'BomPartIpn' => $bomEntry->getPart()?->getIpn() ?? '-',
+ 'BomPartMpnr' => $bomEntry->getPart()?->getManufacturerProductNumber() ?? '-',
+ 'BomPartName' => $bomEntry->getPart()?->getName() ?? '-',
+ 'BomDesignator' => $bomEntry->getName() ?? '-',
+ 'BomPartDescription' => $bomEntry->getPart()?->getDescription() ?? '-',
+ 'BomMountNames' => $bomEntry->getMountNames(),
+ 'BomReferencedAssemblyId' => $bomEntry->getReferencedAssembly()?->getId() ?? '-',
+ 'BomReferencedAssemblyIpn' => $bomEntry->getReferencedAssembly()?->getIpn() ?? '-',
+ 'BomReferencedAssemblyFullName' => $this->getFullName($bomEntry->getReferencedAssembly() ?? null),
+ ];
+
+ // If a referenced assembly exists, add aggregated parts
+ if ($bomEntry->getReferencedAssembly() instanceof Assembly) {
+ $referencedAssembly = $bomEntry->getReferencedAssembly();
+
+ // Get aggregated parts for the referenced assembly
+ $aggregatedParts = $this->assemblyPartAggregator->getAggregatedParts($referencedAssembly, $bomEntry->getQuantity());;
+
+ foreach ($aggregatedParts as $partData) {
+ $partAssembly = $partData['assembly'] ?? null;
+
+ $rows[] = [
+ 'Id' => $assembly->getId(),
+ 'ParentId' => '',
+ 'Type' => 'subassembly_part_list',
+ 'AssemblyIpn' => $partAssembly ? $partAssembly->getIpn() : '',
+ 'AssemblyNameHierarchical' => '',
+ 'AssemblyName' => $partAssembly ? $partAssembly->getName() : '',
+ 'AssemblyFullName' => $this->getFullName($partAssembly),
+ 'BomQuantity' => $partData['quantity'],
+ 'BomMultiplier' => $partData['multiplier'],
+ 'BomPartId' => $partData['part']?->getId(),
+ 'BomPartIpn' => $partData['part']?->getIpn(),
+ 'BomPartMpnr' => $partData['part']?->getManufacturerProductNumber(),
+ 'BomPartName' => $partData['part']?->getName(),
+ 'BomDesignator' => $partData['part']?->getName(),
+ 'BomPartDescription' => $partData['part']?->getDescription(),
+ 'BomMountNames' => '-',
+ 'BomReferencedAssemblyId' => '-',
+ 'BomReferencedAssemblyIpn' => '-',
+ 'BomReferencedAssemblyFullName' => '-',
+ ];
+ }
+ }
+ }
+
+ return $rows;
+ }
+
/**
* Constructs the full hierarchical name of an object by traversing
* through its parent objects and concatenating their names using
diff --git a/src/Twig/AssemblyTwigExtension.php b/src/Twig/AssemblyTwigExtension.php
deleted file mode 100644
index a8ca7719a..000000000
--- a/src/Twig/AssemblyTwigExtension.php
+++ /dev/null
@@ -1,30 +0,0 @@
-getProject() !== null) {
- return true;
- }
- }
- return false;
- }
-}
\ No newline at end of file
diff --git a/translations/validators.cs.xlf b/translations/validators.cs.xlf
index 66f440d12..652cc2d5f 100644
--- a/translations/validators.cs.xlf
+++ b/translations/validators.cs.xlf
@@ -407,12 +407,6 @@
Sestava nesmí ve svém seznamu materiálů (BOM) odkazovat na podskupinu, která je součástí její vlastní hierarchie.
-
-
- assembly.bom_entry.project_already_in_bom
- Tento projekt již v této skupině existuje!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.da.xlf b/translations/validators.da.xlf
index f30dd2116..98d107755 100644
--- a/translations/validators.da.xlf
+++ b/translations/validators.da.xlf
@@ -383,12 +383,6 @@
En samling må ikke referere til en undergruppe fra sin egen hierarki i BOM-listerne.
-
-
- assembly.bom_entry.project_already_in_bom
- Dette projekt eksisterer allerede i gruppen!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.de.xlf b/translations/validators.de.xlf
index 645d72ed1..d7b9591f5 100644
--- a/translations/validators.de.xlf
+++ b/translations/validators.de.xlf
@@ -407,12 +407,6 @@
Eine Baugruppe darf keine Unterbaugruppe aus seiner eigenen Hierarchie in den BOM-Einträgen referenzieren.
-
-
- assembly.bom_entry.project_already_in_bom
- Dieses Projekt existiert bereits in der Gruppe!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.el.xlf b/translations/validators.el.xlf
index 9464f2886..320155fff 100644
--- a/translations/validators.el.xlf
+++ b/translations/validators.el.xlf
@@ -49,12 +49,6 @@
Μία συναρμολόγηση δεν πρέπει να αναφέρεται σε μία υποσυναρμολόγηση από την ίδια την ιεραρχία της στη λίστα BOM.
-
-
- assembly.bom_entry.project_already_in_bom
- Αυτό το έργο υπάρχει ήδη στην ομάδα!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf
index 53ad4cde6..95a558bff 100644
--- a/translations/validators.en.xlf
+++ b/translations/validators.en.xlf
@@ -407,12 +407,6 @@
An assembly must not reference a subassembly from its own hierarchy in the BOM entries.
-
-
- assembly.bom_entry.project_already_in_bom
- This project already exists in the list!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.fr.xlf b/translations/validators.fr.xlf
index 440468295..d8e824af9 100644
--- a/translations/validators.fr.xlf
+++ b/translations/validators.fr.xlf
@@ -239,12 +239,6 @@
Un assemblage ne doit pas référencer un sous-assemblage de sa propre hiérarchie dans les entrées de la nomenclature (BOM).
-
-
- assembly.bom_entry.project_already_in_bom
- Ce projet existe déjà dans le groupe!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.hr.xlf b/translations/validators.hr.xlf
index 485cb0e2f..23ea0e849 100644
--- a/translations/validators.hr.xlf
+++ b/translations/validators.hr.xlf
@@ -401,12 +401,6 @@
Sklop ne smije referencirati podsklop iz vlastite hijerarhije u unosima BOM-a.
-
-
- assembly.bom_entry.project_already_in_bom
- Ovaj projekt već postoji u grupi!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.it.xlf b/translations/validators.it.xlf
index 74d3969f7..4851ab6eb 100644
--- a/translations/validators.it.xlf
+++ b/translations/validators.it.xlf
@@ -401,12 +401,6 @@
Un assemblaggio non deve fare riferimento a un sottoassemblaggio nella propria gerarchia nelle voci della distinta base (BOM).
-
-
- assembly.bom_entry.project_already_in_bom
- Questo progetto esiste già nel gruppo!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.ja.xlf b/translations/validators.ja.xlf
index f9f8a54f8..aed026eac 100644
--- a/translations/validators.ja.xlf
+++ b/translations/validators.ja.xlf
@@ -239,12 +239,6 @@
アセンブリは、BOMエントリで自身の階層内のサブアセンブリを参照してはいけません。
-
-
- assembly.bom_entry.project_already_in_bom
- このプロジェクトは既にグループに存在しています!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.pl.xlf b/translations/validators.pl.xlf
index 9916178ca..68d65a4ad 100644
--- a/translations/validators.pl.xlf
+++ b/translations/validators.pl.xlf
@@ -401,12 +401,6 @@
Zespół nie może odwoływać się do podzespołu w swojej własnej hierarchii w wpisach BOM.
-
-
- assembly.bom_entry.project_already_in_bom
- Ten projekt już znajduje się w grupie!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.ru.xlf b/translations/validators.ru.xlf
index b8029e47f..f80d91d72 100644
--- a/translations/validators.ru.xlf
+++ b/translations/validators.ru.xlf
@@ -401,12 +401,6 @@
Сборка не должна ссылаться на подсборку внутри своей собственной иерархии в записях спецификации (BOM).
-
-
- assembly.bom_entry.project_already_in_bom
- Этот проект уже находится в группе!
-
- assembly.bom_entry.name_already_in_bom
diff --git a/translations/validators.zh.xlf b/translations/validators.zh.xlf
index 6e4fc0568..c7425081b 100644
--- a/translations/validators.zh.xlf
+++ b/translations/validators.zh.xlf
@@ -389,12 +389,6 @@
Сборка не должна ссылаться на подсборку внутри своей собственной иерархии в записях спецификации (BOM).
-
-
- assembly.bom_entry.project_already_in_bom
- 该项目已在组中!
-
- assembly.bom_entry.name_already_in_bom
From 7befa53e8c6317b1b1e27fee02bbf70cecdf7108 Mon Sep 17 00:00:00 2001
From: Marcel Diegelmann
Date: Mon, 15 Sep 2025 16:04:00 +0200
Subject: [PATCH 81/83] Erweitere Exportfunktion um lesbare BOM-Option
(PDF-Ausgabe).
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Neue Auswahloption "Lesbarer Export" hinzugefügt, die den Export hierarchischer Baugruppen als PDF ermöglicht.
---
.../elements/toggle_visibility_controller.js | 48 +++--
.../Assemblies/AssemblyPartAggregator.php | 184 ++++++++++++++++++
.../ImportExportSystem/EntityExporter.php | 27 ++-
templates/admin/_export_form.html.twig | 16 +-
templates/assemblies/export_bom_pdf.html.twig | 103 ++++++++++
...port_bom_referenced_assembly_pdf.html.twig | 55 ++++++
translations/messages.cs.xlf | 14 +-
translations/messages.da.xlf | 14 +-
translations/messages.de.xlf | 14 +-
translations/messages.el.xlf | 14 +-
translations/messages.en.xlf | 14 +-
translations/messages.es.xlf | 14 +-
translations/messages.fr.xlf | 14 +-
translations/messages.it.xlf | 14 +-
translations/messages.ja.xlf | 14 +-
translations/messages.nl.xlf | 14 +-
translations/messages.pl.xlf | 14 +-
translations/messages.ru.xlf | 14 +-
translations/messages.zh.xlf | 14 +-
19 files changed, 572 insertions(+), 43 deletions(-)
create mode 100644 templates/assemblies/export_bom_pdf.html.twig
create mode 100644 templates/assemblies/export_bom_referenced_assembly_pdf.html.twig
diff --git a/assets/controllers/elements/toggle_visibility_controller.js b/assets/controllers/elements/toggle_visibility_controller.js
index 4600dfb29..51c9cb338 100644
--- a/assets/controllers/elements/toggle_visibility_controller.js
+++ b/assets/controllers/elements/toggle_visibility_controller.js
@@ -7,30 +7,41 @@ export default class extends Controller {
};
connect() {
- this.readableCheckbox = this.element.querySelector("#readable");
+ this.displayCheckbox = this.element.querySelector("#display");
+ this.displaySelect = this.element.querySelector("select#display");
- if (!this.readableCheckbox) {
- return;
+ if (this.displayCheckbox) {
+ this.toggleContainers(this.displayCheckbox.checked);
+
+ this.displayCheckbox.addEventListener("change", (event) => {
+ this.toggleContainers(event.target.checked);
+ });
}
- // Apply the initial visibility state based on the checkbox being checked or not
- this.toggleContainers(this.readableCheckbox.checked);
+ if (this.displaySelect) {
+ this.toggleContainers(this.hasDisplaySelectValue());
- // Add a change event listener to the 'readable' checkbox
- this.readableCheckbox.addEventListener("change", (event) => {
- // Toggle container visibility when the checkbox value changes
- this.toggleContainers(event.target.checked);
- });
+ this.displaySelect.addEventListener("change", () => {
+ this.toggleContainers(this.hasDisplaySelectValue());
+ });
+ }
+
+ }
+
+ /**
+ * Check whether a value was selected in the selectbox
+ * @returns {boolean} True when a value has not been selected that is not empty
+ */
+ hasDisplaySelectValue() {
+ return this.displaySelect && this.displaySelect.value !== "";
}
/**
- * Toggles the visibility of containers based on the checkbox state.
- * Hides specified containers if the checkbox is checked and shows them otherwise.
+ * Hides specified containers if the state is active (checkbox checked or select with value).
*
- * @param {boolean} isChecked - The current state of the checkbox:
- * true if checked (hide elements), false if unchecked (show them).
+ * @param {boolean} isActive - True when the checkbox is activated or the selectbox has a value.
*/
- toggleContainers(isChecked) {
+ toggleContainers(isActive) {
if (!Array.isArray(this.classesValue) || this.classesValue.length === 0) {
return;
}
@@ -42,11 +53,10 @@ export default class extends Controller {
return;
}
- // Update the visibility for each selected element
elements.forEach((element) => {
- // If the checkbox is checked, hide the container; otherwise, show it
- element.style.display = isChecked ? "none" : "";
+ element.style.display = isActive ? "none" : "";
});
});
}
-}
\ No newline at end of file
+
+}
diff --git a/src/Helpers/Assemblies/AssemblyPartAggregator.php b/src/Helpers/Assemblies/AssemblyPartAggregator.php
index 94c102573..2346075a1 100644
--- a/src/Helpers/Assemblies/AssemblyPartAggregator.php
+++ b/src/Helpers/Assemblies/AssemblyPartAggregator.php
@@ -24,9 +24,16 @@
use App\Entity\AssemblySystem\Assembly;
use App\Entity\Parts\Part;
+use Dompdf\Dompdf;
+use Dompdf\Options;
+use Twig\Environment;
class AssemblyPartAggregator
{
+ public function __construct(private readonly Environment $twig)
+ {
+ }
+
/**
* Aggregate the required parts and their total quantities for an assembly.
*
@@ -80,4 +87,181 @@ private function processAssembly(Assembly $assembly, float $multiplier, array &$
}
}
}
+
+ /**
+ * Exports a hierarchical Bill of Materials (BOM) for assemblies and parts in a readable format,
+ * including the multiplier for each part and assembly.
+ *
+ * @param Assembly $assembly The root assembly to export.
+ * @param string $indentationSymbol The symbol used for indentation (e.g., ' ').
+ * @param int $initialDepth The starting depth for formatting (default: 0).
+ * @return string Human-readable hierarchical BOM list.
+ */
+ public function exportReadableHierarchy(Assembly $assembly, string $indentationSymbol = ' ', int $initialDepth = 0): string
+ {
+ // Start building the hierarchy
+ $output = '';
+ $this->processAssemblyHierarchy($assembly, $initialDepth, 1, $indentationSymbol, $output);
+
+ return $output;
+ }
+
+ public function exportReadableHierarchyForPdf(array $assemblyHierarchies): string
+ {
+ $html = $this->twig->render('assemblies/export_bom_pdf.html.twig', [
+ 'assemblies' => $assemblyHierarchies,
+ ]);
+
+ $options = new Options();
+ $options->set('isHtml5ParserEnabled', true);
+ $options->set('isPhpEnabled', true);
+
+ $dompdf = new Dompdf($options);
+ $dompdf->loadHtml($html);
+ $dompdf->setPaper('A4');
+ $dompdf->render();
+
+ $canvas = $dompdf->getCanvas();
+ $font = $dompdf->getFontMetrics()->getFont('Arial', 'normal');
+
+ return $dompdf->output();
+ }
+
+ /**
+ * Recursive method to process assemblies and their parts.
+ *
+ * @param Assembly $assembly The current assembly to process.
+ * @param int $depth The current depth in the hierarchy.
+ * @param float $parentMultiplier The multiplier inherited from the parent (default is 1 for root).
+ * @param string $indentationSymbol The symbol used for indentation.
+ * @param string &$output The cumulative output string.
+ */
+ private function processAssemblyHierarchy(Assembly $assembly, int $depth, float $parentMultiplier, string $indentationSymbol, string &$output): void
+ {
+ // Add the current assembly to the output
+ if ($depth === 0) {
+ $output .= sprintf(
+ "%sAssembly: %s [IPN: %s]\n\n",
+ str_repeat($indentationSymbol, $depth),
+ $assembly->getName(),
+ $assembly->getIpn(),
+ );
+ } else {
+ $output .= sprintf(
+ "%sAssembly: %s [IPN: %s, Multiplier: %.2f]\n\n",
+ str_repeat($indentationSymbol, $depth),
+ $assembly->getName(),
+ $assembly->getIpn(),
+ $parentMultiplier
+ );
+ }
+
+ // Gruppiere BOM-Einträge in Kategorien
+ $parts = [];
+ $referencedAssemblies = [];
+ $others = [];
+
+ foreach ($assembly->getBomEntries() as $bomEntry) {
+ if ($bomEntry->getPart() instanceof Part) {
+ $parts[] = $bomEntry;
+ } elseif ($bomEntry->getReferencedAssembly() instanceof Assembly) {
+ $referencedAssemblies[] = $bomEntry;
+ } else {
+ $others[] = $bomEntry;
+ }
+ }
+
+ if (!empty($parts)) {
+ // Process each BOM entry for the current assembly
+ foreach ($parts as $bomEntry) {
+ $effectiveQuantity = $bomEntry->getQuantity() * $parentMultiplier;
+
+ $output .= sprintf(
+ "%sPart: %s [IPN: %s, MPNR: %s, Quantity: %.2f%s, EffectiveQuantity: %.2f]\n",
+ str_repeat($indentationSymbol, $depth + 1),
+ $bomEntry->getPart()?->getName(),
+ $bomEntry->getPart()?->getIpn() ?? '-',
+ $bomEntry->getPart()?->getManufacturerProductNumber() ?? '-',
+ $bomEntry->getQuantity(),
+ $parentMultiplier > 1 ? sprintf(", Multiplier: %.2f", $parentMultiplier) : '',
+ $effectiveQuantity,
+ );
+ }
+
+ $output .= "\n";
+ }
+
+ foreach ($referencedAssemblies as $bomEntry) {
+ // Add referenced assembly details
+ $referencedQuantity = $bomEntry->getQuantity() * $parentMultiplier;
+
+ $output .= sprintf(
+ "%sReferenced Assembly: %s [IPN: %s, Quantity: %.2f%s, EffectiveQuantity: %.2f]\n",
+ str_repeat($indentationSymbol, $depth + 1),
+ $bomEntry->getReferencedAssembly()->getName(),
+ $bomEntry->getReferencedAssembly()->getIpn() ?? '-',
+ $bomEntry->getQuantity(),
+ $parentMultiplier > 1 ? sprintf(", Multiplier: %.2f", $parentMultiplier) : '',
+ $referencedQuantity,
+ );
+
+ // Recurse into the referenced assembly
+ $this->processAssemblyHierarchy(
+ $bomEntry->getReferencedAssembly(),
+ $depth + 2, // Increase depth for nested assemblies
+ $referencedQuantity, // Pass the calculated multiplier
+ $indentationSymbol,
+ $output
+ );
+ }
+
+ foreach ($others as $bomEntry) {
+ $output .= sprintf(
+ "%sOther: %s [Quantity: %.2f, Multiplier: %.2f]\n",
+ str_repeat($indentationSymbol, $depth + 1),
+ $bomEntry->getName(),
+ $bomEntry->getQuantity(),
+ $parentMultiplier,
+ );
+ }
+ }
+
+ public function processAssemblyHierarchyForPdf(Assembly $assembly, int $depth, float $quantity, float $parentMultiplier): array
+ {
+ $result = [
+ 'name' => $assembly->getName(),
+ 'ipn' => $assembly->getIpn(),
+ 'quantity' => $quantity,
+ 'multiplier' => $depth === 0 ? null : $parentMultiplier,
+ 'parts' => [],
+ 'referencedAssemblies' => [],
+ 'others' => [],
+ ];
+
+ foreach ($assembly->getBomEntries() as $bomEntry) {
+ if ($bomEntry->getPart() instanceof Part) {
+ $result['parts'][] = [
+ 'name' => $bomEntry->getPart()->getName(),
+ 'ipn' => $bomEntry->getPart()->getIpn(),
+ 'quantity' => $bomEntry->getQuantity(),
+ 'effectiveQuantity' => $bomEntry->getQuantity() * $parentMultiplier,
+ ];
+ } elseif ($bomEntry->getReferencedAssembly() instanceof Assembly) {
+ $result['referencedAssemblies'][] = $this->processAssemblyHierarchyForPdf(
+ $bomEntry->getReferencedAssembly(),
+ $depth + 1,
+ $bomEntry->getQuantity(),
+ $parentMultiplier * $bomEntry->getQuantity()
+ );
+ } else {
+ $result['others'][] = [
+ 'name' => $bomEntry->getName(),
+ 'quantity' => $bomEntry->getQuantity(),
+ 'multiplier' => $parentMultiplier,
+ ];
+ }
+ }
+
+ return $result;
+ }
}
diff --git a/src/Services/ImportExportSystem/EntityExporter.php b/src/Services/ImportExportSystem/EntityExporter.php
index 3e0aa27cf..f5c827549 100644
--- a/src/Services/ImportExportSystem/EntityExporter.php
+++ b/src/Services/ImportExportSystem/EntityExporter.php
@@ -78,8 +78,9 @@ protected function configureOptions(OptionsResolver $resolver): void
$resolver->setDefault('include_children', false);
$resolver->setAllowedTypes('include_children', 'bool');
- $resolver->setDefault('readable', false);
- $resolver->setAllowedTypes('readable', 'bool');
+ $resolver->setDefault('readableSelect', null);
+ $resolver->setAllowedValues('readableSelect', [null, 'readable', 'readable_bom']);
+
}
/**
@@ -162,7 +163,7 @@ public function exportEntityFromRequest(AbstractNamedDBElement|array $entities,
$entities = [$entities];
}
- if ($request->get('readable', false)) {
+ if ($request->get('readableSelect', false) === 'readable') {
// Map entity classes to export functions
$entityExportMap = [
AttachmentType::class => fn($entities) => $this->exportReadable($entities, AttachmentType::class),
@@ -195,6 +196,23 @@ public function exportEntityFromRequest(AbstractNamedDBElement|array $entities,
$options['format'] = 'csv';
$options['level'] = 'readable';
+ } if ($request->get('readableSelect', false) === 'readable_bom') {
+ $hierarchies = [];
+
+ foreach ($entities as $entity) {
+ if (!$entity instanceof Assembly) {
+ throw new InvalidArgumentException('Only assemblies can be exported in readable BOM format');
+ }
+
+ $hierarchies[] = $this->assemblyPartAggregator->processAssemblyHierarchyForPdf($entity, 0, 1, 1);
+ }
+
+ $pdfContent = $this->assemblyPartAggregator->exportReadableHierarchyForPdf($hierarchies);
+
+ $response = new Response($pdfContent);
+
+ $options['format'] = 'pdf';
+ $options['level'] = 'readable_bom';
} else {
//Do the serialization with the given options
$serialized_data = $this->exportEntities($entities, $options);
@@ -221,6 +239,9 @@ public function exportEntityFromRequest(AbstractNamedDBElement|array $entities,
case 'json':
$content_type = 'application/json';
break;
+ case 'pdf':
+ $content_type = 'application/pdf';
+ break;
}
$response->headers->set('Content-Type', $content_type);
diff --git a/templates/admin/_export_form.html.twig b/templates/admin/_export_form.html.twig
index 527518640..4810f67fd 100644
--- a/templates/admin/_export_form.html.twig
+++ b/templates/admin/_export_form.html.twig
@@ -35,13 +35,13 @@
-
-
-
-
-
+
+
+
@@ -50,4 +50,4 @@
{% trans %}export.btn{% endtrans %}
-
\ No newline at end of file
+
diff --git a/templates/assemblies/export_bom_pdf.html.twig b/templates/assemblies/export_bom_pdf.html.twig
new file mode 100644
index 000000000..15bf5d883
--- /dev/null
+++ b/templates/assemblies/export_bom_pdf.html.twig
@@ -0,0 +1,103 @@
+
+
+
+ Assembly Hierarchy
+
+
+
+
+
+
{% if assembly.multiplier %}{{ assembly.multiplier }}{% else %}-{% endif %}
+
{{ part.effectiveQuantity }}
+
+ {% endfor %}
+
+ {% for other in assembly.others %}
+
+
Other
+
{{ other.name }}
+
-
+
{{ other.quantity }}
+
{{ other.multiplier }}
+
-
+
+ {% endfor %}
+
+ {% for referencedAssembly in assembly.referencedAssemblies %}
+
+
Referenced assembly
+
{{ referencedAssembly.name }}
+
-
+
{{ referencedAssembly.quantity }}
+
+
{{ referencedAssembly.multiplier }}
+
+ {% endfor %}
+
+
+
+
+ {% for refAssembly in assembly.referencedAssemblies %}
+ {% include 'assemblies/export_bom_referenced_assembly_pdf.html.twig' with {'assembly': refAssembly} only %}
+ {% endfor %}
+