mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-01-13 05:39:33 +00:00
JSON Importer mit Minimaldaten weiterentwickeln. Validierung mit Violations einführen und beim Import-Versuch zusätzlich mit ausgeben
This commit is contained in:
parent
b227bacdb0
commit
23e4b00e77
16 changed files with 984 additions and 98 deletions
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
60
src/Services/ImportExportSystem/ImporterResult.php
Normal file
60
src/Services/ImportExportSystem/ImporterResult.php
Normal 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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue