JSON Importer mit Minimaldaten weiterentwickeln. Validierung mit Violations einführen und beim Import-Versuch zusätzlich mit ausgeben

This commit is contained in:
Marcel Diegelmann 2025-04-11 14:00:11 +02:00
parent b227bacdb0
commit 23e4b00e77
16 changed files with 984 additions and 98 deletions

View file

@ -29,7 +29,6 @@ use App\Entity\Parts\Part;
use App\Form\AssemblySystem\AssemblyAddPartsType;
use App\Form\AssemblySystem\AssemblyBuildType;
use App\Helpers\Assemblies\AssemblyBuildRequest;
use App\Repository\PartRepository;
use App\Services\ImportExportSystem\BOMImporter;
use App\Services\AssemblySystem\AssemblyBuildHelper;
use Doctrine\Common\Collections\ArrayCollection;
@ -52,14 +51,10 @@ use function Symfony\Component\Translation\t;
#[Route(path: '/assembly')]
class AssemblyController extends AbstractController
{
private PartRepository $partRepository;
public function __construct(
private readonly DataTableFactory $dataTableFactory,
private readonly EntityManagerInterface $entityManager,
private readonly TranslatorInterface $translator,
) {
$this->partRepository = $this->entityManager->getRepository(Part::class);
}
#[Route(path: '/{id}/info', name: 'assembly_info', requirements: ['id' => '\d+'])]
@ -161,15 +156,14 @@ class AssemblyController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//Clear existing BOM entries if requested
// Clear existing entries if requested
if ($form->get('clear_existing_bom')->getData()) {
$assembly->getBomEntries()->clear();
$entityManager->flush();
}
try {
$entries = $BOMImporter->importFileIntoAssembly($form->get('file')->getData(), $assembly, [
$importerResult = $BOMImporter->importFileIntoAssembly($form->get('file')->getData(), $assembly, [
'type' => $form->get('type')->getData(),
]);
@ -177,24 +171,17 @@ class AssemblyController extends AbstractController
$errors = $validator->validateProperty($assembly, 'bom_entries');
//If no validation errors occured, save the changes and redirect to edit page
if (count ($errors) === 0) {
foreach ($entries as $entry) {
if ($entry instanceof AssemblyBOMEntry && $entry->getPart() !== null) {
$part = $entry->getPart();
if ($part->getID() === null) {
$this->partRepository->save($part);
}
}
}
if (count ($errors) === 0 && $importerResult->getViolations()->count() === 0) {
$entries = $importerResult->getBomEntries();
$this->addFlash('success', t('assembly.bom_import.flash.success', ['%count%' => count($entries)]));
$entityManager->flush();
return $this->redirectToRoute('assembly_edit', ['id' => $assembly->getID()]);
}
//When we get here, there were validation errors
//Show validation errors
$this->addFlash('error', t('assembly.bom_import.flash.invalid_entries'));
} catch (\UnexpectedValueException|\RuntimeException|SyntaxError $e) {
$this->addFlash('error', t('assembly.bom_import.flash.invalid_file', ['%message%' => $e->getMessage()]));
}
@ -226,7 +213,8 @@ class AssemblyController extends AbstractController
'assembly' => $assembly,
'jsonTemplate' => $jsonTemplate,
'form' => $form,
'errors' => $errors ?? null,
'validationErrors' => $errors ?? null,
'importerErrors' => isset($importerResult) ? $importerResult->getViolations() : null,
]);
}

View file

@ -39,8 +39,9 @@ use League\Csv\Reader;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\OptionsResolver\OptionsResolver;
use RuntimeException;
use Symfony\Contracts\Translation\TranslatorInterface;
use UnexpectedValueException;
use Symfony\Component\Validator\ConstraintViolation;
/**
* @see \App\Tests\Services\ImportExportSystem\BOMImporterTest
@ -57,16 +58,21 @@ class BOMImporter
5 => 'Supplier and ref',
];
private readonly PartRepository $partRepository;
private string $jsonRoot = '';
private readonly ManufacturerRepository $manufacturerRepository;
private PartRepository $partRepository;
private readonly CategoryRepository $categoryRepository;
private ManufacturerRepository $manufacturerRepository;
private readonly DBElementRepository $assemblyBOMEntryRepository;
private CategoryRepository $categoryRepository;
private DBElementRepository $assemblyBOMEntryRepository;
private TranslatorInterface $translator;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly TranslatorInterface $translator,
private readonly LoggerInterface $logger,
private readonly BOMValidationService $validationService
) {
@ -74,6 +80,7 @@ class BOMImporter
$this->manufacturerRepository = $entityManager->getRepository(Manufacturer::class);
$this->categoryRepository = $entityManager->getRepository(Category::class);
$this->assemblyBOMEntryRepository = $entityManager->getRepository(AssemblyBOMEntry::class);
$this->translator = $translator;
}
protected function configureOptions(OptionsResolver $resolver): OptionsResolver
@ -110,20 +117,21 @@ class BOMImporter
}
/**
* Converts the given file into an array of BOM entries using the given options and save them into the given assembly.
* 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.
* @return AssemblyBOMEntry[]
*/
public function importFileIntoAssembly(File $file, Assembly $assembly, array $options): array
public function importFileIntoAssembly(File $file, Assembly $assembly, array $options): ImporterResult
{
$bomEntries = $this->fileToBOMEntries($file, $options, AssemblyBOMEntry::class);
$importerResult = $this->fileToImporterResult($file, $options, AssemblyBOMEntry::class);
//Assign the bom_entries to the assembly
foreach ($bomEntries as $bom_entry) {
$assembly->addBomEntry($bom_entry);
if ($importerResult->getViolations()->count() === 0) {
//Assign the bom_entries to the assembly
foreach ($importerResult->getBomEntries() as $bomEntry) {
$assembly->addBomEntry($bomEntry);
}
}
return $bomEntries;
return $importerResult;
}
/**
@ -152,6 +160,14 @@ class BOMImporter
};
}
/**
* Converts the given file into an ImporterResult with an array of BOM entries using the given options.
*/
public function fileToImporterResult(File $file, array $options, string $objectType = ProjectBOMEntry::class): ImporterResult
{
return $this->stringToImporterResult($file->getContent(), $options, $objectType);
}
/**
* Import string data into an array of BOM entries, which are not yet assigned to a project.
* @param string $data The data to import
@ -164,6 +180,24 @@ class BOMImporter
$resolver = $this->configureOptions($resolver);
$options = $resolver->resolve($options);
return match ($options['type']) {
'kicad_pcbnew' => $this->parseKiCADPCB($data, $options, $objectType)->getBomEntries(),
default => throw new InvalidArgumentException('Invalid import type!'),
};
}
/**
* 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
* @return ProjectBOMEntry[]|AssemblyBOMEntry[] An array of imported entries
*/
public function stringToImporterResult(string $data, array $options, string $objectType = ProjectBOMEntry::class): ImporterResult
{
$resolver = new OptionsResolver();
$resolver = $this->configureOptions($resolver);
$options = $resolver->resolve($options);
return match ($options['type']) {
'kicad_pcbnew' => $this->parseKiCADPCB($data, $objectType),
'json' => $this->parseJson($data, $options, $objectType),
@ -171,14 +205,14 @@ class BOMImporter
};
}
private function parseKiCADPCB(string $data, string $objectType = ProjectBOMEntry::class): array
private function parseKiCADPCB(string $data, string $objectType = ProjectBOMEntry::class): ImporterResult
{
$result = new ImporterResult();
$csv = Reader::createFromString($data);
$csv->setDelimiter(';');
$csv->setHeaderOffset(0);
$bom_entries = [];
foreach ($csv->getRecords() as $offset => $entry) {
//Translate the german field names to english
$entry = $this->normalizeColumnNames($entry);
@ -208,10 +242,10 @@ class BOMImporter
$bom_entry->setComment($entry['Supplier and ref'] ?? '');
$bom_entry->setQuantity((float) ($entry['Quantity'] ?? 1));
$bom_entries[] = $bom_entry;
$result->addBomEntry($bom_entry);
}
return $bom_entries;
return $result;
}
/**
@ -271,30 +305,47 @@ class BOMImporter
return $this->validationService->validateBOMEntries($mapped_entries, $options);
}
private function parseJson(string $data, array $options = [], string $objectType = ProjectBOMEntry::class): array
private function parseJson(string $data, array $options = [], string $objectType = ProjectBOMEntry::class): ImporterResult
{
$result = [];
$result = new ImporterResult();
$this->jsonRoot = 'JSON Import for '.$objectType === ProjectBOMEntry::class ? 'Project' : 'Assembly';
$data = json_decode($data, true);
foreach ($data as $entry) {
foreach ($data as $key => $entry) {
// Check quantity
if (!isset($entry['quantity'])) {
throw new UnexpectedValueException('quantity missing');
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.quantity.required',
"entry[$key].quantity"
));
}
if (!is_float($entry['quantity']) || $entry['quantity'] <= 0) {
throw new UnexpectedValueException('quantity expected as float greater than 0.0');
if (isset($entry['quantity']) && (!is_float($entry['quantity']) || $entry['quantity'] <= 0)) {
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.quantity.float',
"entry[$key].quantity",
$entry['quantity']
));
}
// Check name
if (isset($entry['name']) && !is_string($entry['name'])) {
throw new UnexpectedValueException('name of part list entry expected as string');
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.string.notEmpty',
"entry[$key].name",
$entry['name']
));
}
// Check if part is assigned with relevant information
if (isset($entry['part'])) {
if (!is_array($entry['part'])) {
throw new UnexpectedValueException('The property "part" should be an array');
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.array',
"entry[$key].part",
$entry['part']
));
}
$partIdValid = isset($entry['part']['id']) && is_int($entry['part']['id']) && $entry['part']['id'] > 0;
@ -303,9 +354,12 @@ class BOMImporter
$partIpnValid = isset($entry['part']['ipn']) && is_string($entry['part']['ipn']) && trim($entry['part']['ipn']) !== '';
if (!$partIdValid && !$partNameValid && !$partMpnrValid && !$partIpnValid) {
throw new UnexpectedValueException(
'The property "part" must have either assigned: "id" as integer greater than 0, "name", "mpnr", or "ipn" as non-empty string'
);
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.subproperties',
"entry[$key].part",
$entry['part'],
['%propertyString%' => '"id", "name", "mpnr", or "ipn"']
));
}
$part = $partIdValid ? $this->partRepository->findOneBy(['id' => $entry['part']['id']]) : null;
@ -314,28 +368,71 @@ class BOMImporter
$part = $part ?? ($partNameValid ? $this->partRepository->findOneBy(['name' => trim($entry['part']['name'])]) : null);
if ($part === null) {
$part = new Part();
$part->setName($entry['part']['name']);
$value = sprintf('part.id: %s, part.mpnr: %s, part.ipn: %s, part.name: %s',
isset($entry['part']['id']) ? '<strong>' . $entry['part']['id'] . '</strong>' : '-',
isset($entry['part']['mpnr']) ? '<strong>' . $entry['part']['mpnr'] . '</strong>' : '-',
isset($entry['part']['ipn']) ? '<strong>' . $entry['part']['ipn'] . '</strong>' : '-',
isset($entry['part']['name']) ? '<strong>' . $entry['part']['name'] . '</strong>' : '-',
);
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.notFoundFor',
"entry[$key].part",
$entry['part'],
['%value%' => $value]
));
}
if ($partNameValid && $part->getName() !== trim($entry['part']['name'])) {
throw new RuntimeException(sprintf('Part name does not match exact the given name. Given for import: %s, found part: %s', $entry['part']['name'], $part->getName()));
if ($partNameValid && $part !== null && isset($entry['part']['name']) && $part->getName() !== trim($entry['part']['name'])) {
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.noExactMatch',
"entry[$key].part.name",
$entry['part']['name'],
[
'%importValue%' => '<strong>' . $entry['part']['name'] . '</strong>',
'%foundId%' => $part->getID(),
'%foundValue%' => '<strong>' . $part->getName() . '</strong>'
]
));
}
if ($partIpnValid && $part->getManufacturerProductNumber() !== trim($entry['part']['mpnr'])) {
throw new RuntimeException(sprintf('Part mpnr does not match exact the given mpnr. Given for import: %s, found part: %s', $entry['part']['mpnr'], $part->getManufacturerProductNumber()));
if ($partMpnrValid && $part !== null && isset($entry['part']['mpnr']) && $part->getManufacturerProductNumber() !== trim($entry['part']['mpnr'])) {
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.noExactMatch',
"entry[$key].part.mpnr",
$entry['part']['mpnr'],
[
'%importValue%' => '<strong>' . $entry['part']['mpnr'] . '</strong>',
'%foundId%' => $part->getID(),
'%foundValue%' => '<strong>' . $part->getManufacturerProductNumber() . '</strong>'
]
));
}
if ($partIpnValid && $part->getIpn() !== trim($entry['part']['ipn'])) {
throw new RuntimeException(sprintf('Part ipn does not match exact the given ipn. Given for import: %s, found part: %s', $entry['part']['ipn'], $part->getIpn()));
if ($partIpnValid && $part !== null && isset($entry['part']['ipn']) && $part->getIpn() !== trim($entry['part']['ipn'])) {
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.noExactMatch',
"entry[$key].part.ipn",
$entry['part']['ipn'],
[
'%importValue%' => '<strong>' . $entry['part']['ipn'] . '</strong>',
'%foundId%' => $part->getID(),
'%foundValue%' => '<strong>' . $part->getIpn() . '</strong>'
]
));
}
// Part: Description check
if (isset($entry['part']['description']) && !is_null($entry['part']['description'])) {
if (isset($entry['part']['description'])) {
if (!is_string($entry['part']['description']) || trim($entry['part']['description']) === '') {
throw new UnexpectedValueException('The property path "part.description" must be a non-empty string if not null');
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.string.notEmpty',
'entry[$key].part.description',
$entry['part']['description']
));
}
}
$partDescription = $entry['part']['description'] ?? '';
// Part: Manufacturer check
@ -343,7 +440,11 @@ class BOMImporter
$manufacturerNameValid = false;
if (array_key_exists('manufacturer', $entry['part'])) {
if (!is_array($entry['part']['manufacturer'])) {
throw new UnexpectedValueException('The property path "part.manufacturer" must be an array');
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.array',
'entry[$key].part.manufacturer',
$entry['part']['manufacturer']) ?? null
);
}
$manufacturerIdValid = isset($entry['part']['manufacturer']['id']) && is_int($entry['part']['manufacturer']['id']) && $entry['part']['manufacturer']['id'] > 0;
@ -351,23 +452,43 @@ class BOMImporter
// Stellen sicher, dass mindestens eine Bedingung für manufacturer erfüllt sein muss
if (!$manufacturerIdValid && !$manufacturerNameValid) {
throw new UnexpectedValueException(
'The property "manufacturer" must have either assigned: "id" as integer greater than 0, or "name" as non-empty string'
);
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties',
"entry[$key].part.manufacturer",
$entry['part']['manufacturer'],
));
}
}
$manufacturer = $manufacturerIdValid ? $this->manufacturerRepository->findOneBy(['id' => $entry['part']['manufacturer']['id']]) : null;
$manufacturer = $manufacturer ?? ($manufacturerNameValid ? $this->manufacturerRepository->findOneBy(['name' => trim($entry['part']['manufacturer']['name'])]) : null);
if ($manufacturer === null) {
throw new RuntimeException(
'Manufacturer not found'
if (($manufacturerIdValid || $manufacturerNameValid) && $manufacturer === null) {
$value = sprintf(
'manufacturer.id: %s, manufacturer.name: %s',
isset($entry['part']['manufacturer']['id']) && $entry['part']['manufacturer']['id'] !== null ? '<strong>' . $entry['part']['manufacturer']['id'] . '</strong>' : '-',
isset($entry['part']['manufacturer']['name']) && $entry['part']['manufacturer']['name'] !== null ? '<strong>' . $entry['part']['manufacturer']['name'] . '</strong>' : '-'
);
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.notFoundFor',
"entry[$key].part.manufacturer",
$entry['part']['manufacturer'],
['%value%' => $value]
));
}
if ($manufacturerNameValid && $manufacturer->getName() !== trim($entry['part']['manufacturer']['name'])) {
throw new RuntimeException(sprintf('Manufacturer name does not match exact the given name. Given for import: %s, found manufacturer: %s', $entry['manufacturer']['name'], $manufacturer->getName()));
if ($manufacturerNameValid && $manufacturer !== null && isset($entry['part']['manufacturer']['name']) && $manufacturer->getName() !== trim($entry['part']['manufacturer']['name'])) {
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.noExactMatch',
"entry[$key].part.manufacturer.name",
$entry['part']['manufacturer']['name'],
[
'%importValue%' => '<strong>' . $entry['part']['manufacturer']['name'] . '</strong>',
'%foundId%' => $manufacturer->getID(),
'%foundValue%' => '<strong>' . $manufacturer->getName() . '</strong>'
]
));
}
// Part: Category check
@ -375,49 +496,82 @@ class BOMImporter
$categoryNameValid = false;
if (array_key_exists('category', $entry['part'])) {
if (!is_array($entry['part']['category'])) {
throw new UnexpectedValueException('part.category must be an array');
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.array',
'entry[$key].part.category',
$entry['part']['category']) ?? null
);
}
$categoryIdValid = isset($entry['part']['category']['id']) && is_int($entry['part']['category']['id']) && $entry['part']['category']['id'] > 0;
$categoryNameValid = isset($entry['part']['category']['name']) && is_string($entry['part']['category']['name']) && trim($entry['part']['category']['name']) !== '';
if (!$categoryIdValid && !$categoryNameValid) {
throw new UnexpectedValueException(
'The property "category" must have either assigned: "id" as integer greater than 0, or "name" as non-empty string'
);
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties',
"entry[$key].part.category",
$entry['part']['category']
));
}
}
$category = $categoryIdValid ? $this->categoryRepository->findOneBy(['id' => $entry['part']['category']['id']]) : null;
$category = $category ?? ($categoryNameValid ? $this->categoryRepository->findOneBy(['name' => trim($entry['part']['category']['name'])]) : null);
if ($category === null) {
throw new RuntimeException(
'Category not found'
if (($categoryIdValid || $categoryNameValid) && $category === null) {
$value = sprintf(
'category.id: %s, category.name: %s',
isset($entry['part']['category']['id']) && $entry['part']['category']['id'] !== null ? '<strong>' . $entry['part']['category']['id'] . '</strong>' : '-',
isset($entry['part']['category']['name']) && $entry['part']['category']['name'] !== null ? '<strong>' . $entry['part']['category']['name'] . '</strong>' : '-'
);
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.notFoundFor',
"entry[$key].part.category",
$entry['part']['category'],
['%value%' => $value]
));
}
if ($categoryNameValid && $category->getName() !== trim($entry['part']['category']['name'])) {
throw new RuntimeException(sprintf('Category name does not match exact the given name. Given for import: %s, found category: %s', $entry['category']['name'], $category->getName()));
if ($categoryNameValid && $category !== null && isset($entry['part']['category']['name']) && $category->getName() !== trim($entry['part']['category']['name'])) {
$result->addViolation($this->buildJsonViolation(
'validator.bom_importer.json.parameter.noExactMatch',
"entry[$key].part.category.name",
$entry['part']['category']['name'],
[
'%importValue%' => '<strong>' . $entry['part']['category']['name'] . '</strong>',
'%foundId%' => $category->getID(),
'%foundValue%' => '<strong>' . $category->getName() . '</strong>'
]
));
}
$part->setDescription($partDescription);
$part->setManufacturer($manufacturer);
$part->setCategory($category);
if ($partMpnrValid) {
$part->setManufacturerProductNumber($entry['part']['mpnr'] ?? '');
if ($result->getViolations()->count() > 0) {
continue;
}
if ($partIpnValid) {
$part->setIpn($entry['part']['ipn'] ?? '');
if ($partDescription !== '') {
//Beim Import / Aktualisieren von zugehörigen Bauteilen zu einer Baugruppe die Beschreibung des Bauteils mit übernehmen.
$part->setDescription($partDescription);
}
if ($manufacturer !== null && $manufacturer->getID() !== $part->getManufacturerID()) {
//Beim Import / Aktualisieren von zugehörigen Bauteilen zu einer Baugruppe des Hersteller des Bauteils mit übernehmen.
$part->setManufacturer($manufacturer);
}
if ($category !== null && $category->getID() !== $part->getCategoryID()) {
//Beim Import / Aktualisieren von zugehörigen Bauteilen zu einer Baugruppe die Kategorie des Bauteils mit übernehmen.
$part->setCategory($category);
}
if ($objectType === AssemblyBOMEntry::class) {
$bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['part' => $part]);
if ($bomEntry === null) {
$name = isset($entry['name']) && $entry['name'] !== null ? trim($entry['name']) : '';
$bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['name' => $name]);
if (isset($entry['name']) && $entry['name'] !== '') {
$bomEntry = $this->assemblyBOMEntryRepository->findOneBy(['name' => $entry['name']]);
}
if ($bomEntry === null) {
$bomEntry = new AssemblyBOMEntry();
@ -431,9 +585,22 @@ class BOMImporter
$bomEntry->setName($entry['name'] ?? '');
$bomEntry->setPart($part);
}
$result[] = $bomEntry;
$result->addBomEntry($bomEntry);
} else {
//Eintrag ohne Part-Relation in die Bauteilliste aufnehmen
if ($objectType === AssemblyBOMEntry::class) {
$bomEntry = new AssemblyBOMEntry();
} else {
$bomEntry = new ProjectBOMEntry();
}
$bomEntry->setQuantity($entry['quantity']);
$bomEntry->setName($entry['name'] ?? '');
$result->addBomEntry($bomEntry);
}
}
return $result;
@ -462,6 +629,18 @@ class BOMImporter
return $out;
}
private function buildJsonViolation(string $message, string $propertyPath, mixed $invalidValue = null, array $parameters = []): ConstraintViolation
{
return new ConstraintViolation(
message: $this->translator->trans($message, $parameters, 'validators'),
messageTemplate: $message,
parameters: $parameters,
root: $this->jsonRoot,
propertyPath: $propertyPath,
invalidValue: $invalidValue
);
}
/**
* Parse KiCad schematic BOM with flexible field mapping
*/

View file

@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace App\Services\ImportExportSystem;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
class ImporterResult
{
private array $bomEntries = [];
private ConstraintViolationList $violations;
public function __construct(array $bomEntries = [])
{
$this->bomEntries = $bomEntries;
$this->violations = new ConstraintViolationList();
}
/**
* Fügt einen neuen BOM-Eintrag hinzu.
*/
public function addBomEntry(object $bomEntry): void
{
$this->bomEntries[] = $bomEntry;
}
/**
* Gibt alle BOM-Einträge zurück.
*/
public function getBomEntries(): array
{
return $this->bomEntries;
}
/**
* Gibt die Liste der Violation zurück.
*/
public function getViolations(): ConstraintViolationList
{
return $this->violations;
}
/**
* Fügt eine neue `ConstraintViolation` zur Liste hinzu.
*/
public function addViolation(ConstraintViolation $violation): void
{
$this->violations->add($violation);
}
/**
* Prüft, ob die Liste der Violationen leer ist.
*/
public function hasViolations(): bool
{
return count($this->violations) > 0;
}
}

View file

@ -3,16 +3,27 @@
{% block title %}{% trans %}assembly.import_bom{% endtrans %}{% endblock %}
{% block before_card %}
{% if errors %}
{% if validationErrors or importerErrors %}
<div class="alert alert-danger">
<h4><i class="fa-solid fa-exclamation-triangle fa-fw"></i> {% trans %}parts.import.errors.title{% endtrans %}</h4>
<ul>
{% for violation in errors %}
<li>
<b>{{ violation.propertyPath }}: </b>
{{ violation.message|trans(violation.parameters, 'validators') }}
</li>
{% endfor %}
{% if validationErrors %}
{% for violation in validationErrors %}
<li>
<b>{{ violation.propertyPath }}: </b>
{{ violation.message|trans(violation.parameters, 'validators') }}
</li>
{% endfor %}
{% endif %}
{% if importerErrors %}
{% for violation in importerErrors %}
<li>
<b>{{ violation.propertyPath }}: </b>
{{ violation.message|trans(violation.parameters, 'validators')|raw }}
</li>
{% endfor %}
{% endif %}
</ul>
</div>
{% endif %}

View file

@ -389,5 +389,59 @@
<target>Musíte vybrat součást nebo nastavit název pro nesoučást!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Musíte zadat množství > 0!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>očekává se jako float větší než 0,0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>očekává se jako neprázdný řetězec</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>očekává se jako neprázdný řetězec nebo null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>očekává se jako pole (array)</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>musí mít alespoň jeden z následujících pod-parametrů: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>nenalezeno pro %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>se přesně neshoduje. Pro import zadáno: %importValue%, nalezeno (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>musí obsahovat jako pod-parametr buď: "id" jako celé číslo větší než 0 nebo "name" jako neprázdný řetězec</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -365,5 +365,59 @@
<target>Du skal vælge en del eller sætte et navn for en ikke-del!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Du skal angive en mængde > 0!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>forventet som en float større end 0,0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>forventet som en ikke-tom streng</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>forventet som en ikke-tom streng eller null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>forventet som en array</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>skal have mindst én af følgende underparametre: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>ikke fundet for %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>stemmer ikke helt overens. Givet til import: %importValue%, fundet (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>skal indeholde som en underparameter enten: "id" som et heltal større end 0 eller "name" som en ikke-tom streng</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -386,7 +386,61 @@
<unit id="KWc.wZ4" name="validator.assembly.bom_entry.name_or_part_needed">
<segment>
<source>validator.assembly.bom_entry.name_or_part_needed</source>
<target>Sie müssen ein Bauteil auswählen, oder einen Namen für ein nicht-Bauteil setzen!</target>
<target>Sie müssen ein Bauteil auswählen, oder einen Namen für den Eintrag setzen!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Sie müssen eine Stückzahl > 0 angeben!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>wird als float größer als 0.0 erwartet</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>als nicht leere Zeichenkette erwartet</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>als nicht leere Zeichenkette oder null erwartet</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>als array erwartet</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>muss mindestens eines der folgenden Unter-Parameter haben: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>nicht gefunden für %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>stimmt nicht genau überein. Für den Import gegeben: %importValue%, gefunden (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>muss entweder als Unter-Parameter zugewiesen haben: "id" als Ganzzahl größer als 0 oder "name" als nicht leere Zeichenfolge</target>
</segment>
</unit>
</file>

View file

@ -31,5 +31,59 @@
<target>Πρέπει να επιλέξετε ένα εξάρτημα ή να βάλετε ένα όνομα για ένα μη εξάρτημα!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Πρέπει να εισαγάγετε ποσότητα > 0!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>αναμένεται ως δεκαδικός αριθμός (float) μεγαλύτερος από 0,0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>αναμένεται ως μη κενή συμβολοσειρά</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>αναμένεται ως μη κενή συμβολοσειρά ή null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>αναμένεται ως array</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>πρέπει να έχει τουλάχιστον μία από τις ακόλουθες υπο-παραμέτρους: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>δεν βρέθηκε για %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>δεν ταιριάζει απόλυτα. Δόθηκε για εισαγωγή: %importValue%, βρέθηκε (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>πρέπει να περιέχει ως υπο-παράμετρο είτε: "id" ως ακέραιο αριθμό μεγαλύτερο από 0 είτε "name" ως μη κενή συμβολοσειρά</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -389,5 +389,59 @@
<target>__validator.assembly.bom_entry.name_or_part_needed</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>you must specify a quantity > 0!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>expected as float greater than 0.0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>expected as non-empty string</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>als nicht leere Zeichenkette oder null erwartet</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>expectd as array</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>must have at least one of the following sub-properties: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>not found for %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>does not match exactly. Given for import: %importValue%, found (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>must have either assigned as sub-property: "id" as an integer greater than 0, or "name" as a non-empty string</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -224,7 +224,61 @@
<unit id="KWc.wZ4" name="validator.assembly.bom_entry.name_or_part_needed">
<segment>
<source>validator.assembly.bom_entry.name_or_part_needed</source>
<target>Vous devez sélectionner une pièce ou attribuer un nom pour un non-élément!</target>
<target>Vous devez sélectionner une pièce ou attribuer un nom pour un non-élément!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Vous devez entrer une quantité > 0 !</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>attendu comme un nombre décimal (float) supérieur à 0,0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>attendu comme une chaîne de caractères non vide</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>attendu comme une chaîne de caractères non vide ou null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>attendu comme un tableau (array)</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>doit contenir au moins l'un des sous-paramètres suivants : %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>non trouvé pour %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>ne correspond pas exactement. Donné pour l'importation : %importValue%, trouvé (%foundId%) : %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>doit contenir comme sous-paramètre soit : "id" comme entier supérieur à 0 ou "name" comme chaîne de caractères non vide</target>
</segment>
</unit>
</file>

View file

@ -383,5 +383,59 @@
<target>Morate odabrati dio ili unijeti naziv za nedio!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Morate unijeti količinu > 0!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>očekuje se decimalni broj (float) veći od 0,0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>očekuje se kao neprazan niz znakova</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>očekuje se kao neprazan niz znakova ili null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>očekuje se kao niz</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>mora sadržavati barem jedan od sljedećih pod-parametara: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>nije pronađeno za %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>ne podudara se točno. Uneseno za uvoz: %importValue%, pronađeno (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>mora sadržavati kao pod-parametar bilo: "id" kao cijeli broj veći od 0 ili "name" kao neprazan niz znakova</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -383,5 +383,59 @@
<target>È necessario selezionare una parte o inserire un nome per un non-parte!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Devi inserire una quantità > 0!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>atteso come numero decimale (float) maggiore di 0,0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>atteso come stringa non vuota</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>atteso come stringa non vuota o null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>atteso come array</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>deve avere almeno uno dei seguenti sotto-parametri: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>non trovato per %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>non corrisponde esattamente. Valore dato per l'importazione: %importValue%, trovato (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>deve contenere come sotto-parametro: "id" come intero maggiore di 0 o "name" come stringa non vuota</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -227,5 +227,59 @@
<target>部品を選択するか、非部品の名前を入力する必要があります!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>数量 > 0 を入力する必要があります!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>0.0 より大きい小数 (float) である必要があります</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>空でない文字列が期待されます</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>空でない文字列または null が期待されます</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>配列として期待されます</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>以下のサブパラメーターのいずれかを含む必要があります:%propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>%value% に対する項目が見つかりません</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>完全には一致しません。インポートされた値:%importValue%、見つかった値 (%foundId%)%foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>サブパラメーターとして次のいずれかを含む必要があります:"id" は 0 より大きい整数、または "name" は空でない文字列</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -383,5 +383,59 @@
<target>Musisz wybrać element lub przypisać nazwę dla elementu niestandardowego!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Musisz wprowadzić ilość > 0!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>oczekiwano liczby zmiennoprzecinkowej (float) większej od 0,0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>oczekiwano jako niepusty ciąg znaków</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>oczekiwano jako niepusty ciąg znaków lub null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>oczekiwano jako tablicę</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>musi zawierać co najmniej jeden z następujących podparametrów: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>nie znaleziono dla %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>brak dokładnego dopasowania. Wprowadzone do importu: %importValue%, znalezione (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>musi zawierać jako podparametr: "id" jako liczbę całkowitą większą od 0 lub "name" jako niepusty ciąg znaków</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -383,5 +383,59 @@
<target>Необходимо выбрать деталь или ввести название для недетали!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>Необходимо указать количество > 0!</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>ожидается число с плавающей запятой (float), большее 0,0</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>ожидается непустая строка</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>ожидается непустая строка или null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>ожидается массив</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>должен содержать хотя бы один из следующих под-параметров: %propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>не найдено для %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>точное совпадение отсутствует. Указано для импорта: %importValue%, найдено (%foundId%): %foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>должен содержать под-параметр: "id" как целое число больше 0 или "name" как непустая строка</target>
</segment>
</unit>
</file>
</xliff>

View file

@ -371,5 +371,59 @@
<target>必须选择零件或为非零件指定名称!</target>
</segment>
</unit>
<unit id="a1dKro7" name="validator.bom_importer.json.quantity.required">
<segment>
<source>validator.bom_importer.json.quantity.required</source>
<target>必须输入数量 > 0</target>
</segment>
</unit>
<unit id="hlBA1Pd" name="validator.bom_importer.json.quantity.float">
<segment>
<source>validator.bom_importer.json.quantity.float</source>
<target>应为大于 0.0 的浮点数 (float)</target>
</segment>
</unit>
<unit id="eBCiG.1" name="validator.bom_importer.json.parameter.string.notEmpty">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty</source>
<target>应为非空字符串</target>
</segment>
</unit>
<unit id="aKg7qlT" name="validator.bom_importer.json.parameter.string.notEmpty.null">
<segment>
<source>validator.bom_importer.json.parameter.string.notEmpty.null</source>
<target>应为非空字符串或 null</target>
</segment>
</unit>
<unit id="g8HPqwx" name="validator.bom_importer.json.parameter.array">
<segment>
<source>validator.bom_importer.json.parameter.array</source>
<target>应为数组</target>
</segment>
</unit>
<unit id="adLRxnA" name="validator.bom_importer.json.parameter.subproperties">
<segment>
<source>validator.bom_importer.json.parameter.subproperties</source>
<target>必须包含以下子参数之一:%propertyString%</target>
</segment>
</unit>
<unit id="kt12PW4" name="validator.bom_importer.json.parameter.notFoundFor">
<segment>
<source>validator.bom_importer.json.parameter.notFoundFor</source>
<target>未找到对应值 %value%</target>
</segment>
</unit>
<unit id="bhc3WQf" name="validator.bom_importer.json.parameter.noExactMatch">
<segment>
<source>validator.bom_importer.json.parameter.noExactMatch</source>
<target>未精确匹配。用于导入的值:%importValue%,找到的值 (%foundId%)%foundValue%</target>
</segment>
</unit>
<unit id="Kb1hpq3" name="validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties">
<segment>
<source>validator.bom_importer.json.parameter.manufacturerOrCategoryWithSubProperties</source>
<target>必须包含子参数:"id" 为大于 0 的整数,或 "name" 为非空字符串</target>
</segment>
</unit>
</file>
</xliff>