Support dynamic supplier SPNs in BOM import comments (#1208)

* Fix: Use correct field name for LCSC supplier part numbers in BOM import

The field mapping system uses 'LCSC SPN' as the target field name for LCSC
supplier part numbers (following the pattern SupplierName + ' SPN'), but the
code in parseKiCADSchematic() was incorrectly checking for 'LCSC'.

This caused LCSC supplier part numbers to be silently ignored and not included
in the BOM entry comments during schematic import.

Changed isset($mapped_entry['LCSC']) to isset($mapped_entry['LCSC SPN']) to
match the actual field name produced by the field mapping system.

* regression test: check for LCSC SPN in comment

* Support dynamic supplier SPNs in BOM import comments

Replace hardcoded LCSC SPN handling with dynamic supplier lookup to support all configured suppliers in BOM import. This allows any supplier defined in
Part-DB to have their SPN fields recognized and included in the BOM entry
comments during BOM import.

* Optimize BOM import by only calculating supplier SPN keys once
This commit is contained in:
Niklas 2026-01-25 21:32:14 +01:00 committed by GitHub
parent e15d12c0bf
commit 3aad70934b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 34 additions and 2 deletions

View file

@ -274,6 +274,13 @@ class BOMImporter
$entries_by_key = []; // Track entries by name+part combination
$mapped_entries = []; // Collect all mapped entries for validation
// Fetch suppliers once for efficiency
$suppliers = $this->entityManager->getRepository(\App\Entity\Parts\Supplier::class)->findAll();
$supplierSPNKeys = [];
foreach ($suppliers as $supplier) {
$supplierSPNKeys[] = $supplier->getName() . ' SPN';
}
foreach ($csv->getRecords() as $offset => $entry) {
// Apply field mapping to translate column names
$mapped_entry = $this->applyFieldMapping($entry, $field_mapping, $field_priorities);
@ -400,9 +407,14 @@ class BOMImporter
if (isset($mapped_entry['Manufacturer'])) {
$comment_parts[] = 'Manf: ' . $mapped_entry['Manufacturer'];
}
if (isset($mapped_entry['LCSC'])) {
$comment_parts[] = 'LCSC: ' . $mapped_entry['LCSC'];
// Add supplier part numbers dynamically
foreach ($supplierSPNKeys as $spnKey) {
if (isset($mapped_entry[$spnKey]) && !empty($mapped_entry[$spnKey])) {
$comment_parts[] = $spnKey . ': ' . $mapped_entry[$spnKey];
}
}
if (isset($mapped_entry['Supplier and ref'])) {
$comment_parts[] = $mapped_entry['Supplier and ref'];
}

View file

@ -353,6 +353,16 @@ class BOMImporterTest extends WebTestCase
public function testStringToBOMEntriesKiCADSchematic(): void
{
// Create test suppliers for this test
$lcscSupplier = new Supplier();
$lcscSupplier->setName('LCSC');
$mouserSupplier = new Supplier();
$mouserSupplier->setName('Mouser');
$this->entityManager->persist($lcscSupplier);
$this->entityManager->persist($mouserSupplier);
$this->entityManager->flush();
$input = <<<CSV
"Reference","Value","Footprint","Quantity","MPN","Manufacturer","LCSC SPN","Mouser SPN"
"R1,R2","10k","R_0805_2012Metric",2,"CRCW080510K0FKEA","Vishay","C123456","123-M10K"
@ -386,10 +396,20 @@ class BOMImporterTest extends WebTestCase
$this->assertStringContainsString('Value: 10k', $bom_entries[0]->getComment());
$this->assertStringContainsString('MPN: CRCW080510K0FKEA', $bom_entries[0]->getComment());
$this->assertStringContainsString('Manf: Vishay', $bom_entries[0]->getComment());
$this->assertStringContainsString('LCSC SPN: C123456', $bom_entries[0]->getComment());
$this->assertStringContainsString('Mouser SPN: 123-M10K', $bom_entries[0]->getComment());
// Check second entry
$this->assertEquals('C1', $bom_entries[1]->getMountnames());
$this->assertEquals(1.0, $bom_entries[1]->getQuantity());
$this->assertStringContainsString('LCSC SPN: C789012', $bom_entries[1]->getComment());
$this->assertStringContainsString('Mouser SPN: 80-CL21A104KOCLRNC', $bom_entries[1]->getComment());
// Clean up
$this->entityManager->remove($lcscSupplier);
$this->entityManager->remove($mouserSupplier);
$this->entityManager->flush();
}
public function testStringToBOMEntriesKiCADSchematicWithPriority(): void