Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/usage/import_export.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ supplier is not specified, the price and supplier product number fields will be
* **`supplier_product_number`** or **`supplier_part_number`** or * **`spn`**: The supplier product number of the part.
* **`price`**: The price of the part in the base currency of the database (by default euro).

The following fields set the EDA / KiCad metadata of the part (see [EDA / KiCad integration](eda_integration.md)).
These can be given either as the flat column names below, or in the nested `eda_info.*` form used by the
CSV/JSON export and the [example file](#example-data) (e.g. `eda_info.kicad_symbol`), so a file exported from
Part-DB can be re-imported without renaming its headers:

* **`eda_kicad_symbol`** or **`kicad_symbol`**: The KiCad symbol of the part, e.g. `Device:R`.
* **`eda_kicad_footprint`** or **`kicad_footprint`**: The KiCad footprint, e.g. `Resistor_SMD:R_0805_2012Metric`.
* **`eda_reference_prefix`** or **`kicad_reference`**: The schematic reference prefix, e.g. `R`, `C`, `L`.
* **`eda_value`** or **`kicad_value`**: The value shown in the EDA tool, e.g. `10k`.
* **`eda_exclude_from_bom`** (or **`eda_exclude_bom`**), **`eda_exclude_from_board`** (or **`eda_exclude_board`**),
**`eda_exclude_from_sim`** (or **`eda_exclude_sim`**): Booleans (`1`/`0`) to exclude the part from the BOM, board
or simulation.
* **`eda_visibility`**: Boolean (`1`/`0`) controlling whether the part is exposed to the EDA tool. The inverse
convenience alias **`eda_invisible`** is also accepted (so `eda_invisible=1` hides the part).

#### Example data

Here you can find some example data for the import of parts, you can use it as a template for your own import (
Expand Down
7 changes: 6 additions & 1 deletion src/Serializer/PartNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface, Norm
'eda_exclude_bom' => 'eda_exclude_from_bom',
'eda_exclude_board' => 'eda_exclude_from_board',
'eda_exclude_sim' => 'eda_exclude_from_sim',
'eda_invisible' => 'eda_visibility',
//NOTE: "eda_invisible" is intentionally NOT mapped here: it is the *inverse* of
//"eda_visibility", so a plain key rename would store the wrong value. It is handled
//(and inverted) explicitly in applyEdaFields().
];

public function __construct(
Expand Down Expand Up @@ -235,6 +237,9 @@ private function applyEdaFields(Part $part, array $data): void
}
if (isset($data['eda_visibility']) && $data['eda_visibility'] !== '') {
$edaInfo->setVisibility(filter_var($data['eda_visibility'], FILTER_VALIDATE_BOOLEAN));
} elseif (isset($data['eda_invisible']) && $data['eda_invisible'] !== '') {
//"eda_invisible" is the inverse convenience alias of "eda_visibility"
$edaInfo->setVisibility(!filter_var($data['eda_invisible'], FILTER_VALIDATE_BOOLEAN));
}
}

Expand Down
78 changes: 78 additions & 0 deletions tests/Services/ImportExportSystem/EntityImporterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,84 @@ public function testImportStringParts(): void
$this->assertSame('test,test2', $results[0]->getTags());
}

public function testImportAcceptsNestedEdaInfoColumns(): void
{
//The API / JSON export writes EDA columns as "eda_info.kicad_symbol"; re-importing such a
//file must fill the EDA fields (previously these columns were silently dropped).
$input = "name;eda_info.kicad_symbol;eda_info.kicad_footprint;eda_info.reference_prefix;eda_info.value\n"
."Nested EDA part;Device:L;Inductor_THT:L_Axial_0307;L;100uH";

$category = new Category();
$category->setName('Test EDA category');

$errors = [];
$results = $this->service->importString($input, [
'class' => Part::class,
'format' => 'csv',
'csv_delimiter' => ';',
'create_unknown_datastructures' => true,
'part_category' => $category,
], $errors);

$this->assertCount(1, $results);
$this->assertEmpty($errors);
$eda = $results[0]->getEdaInfo();
$this->assertSame('Device:L', $eda->getKicadSymbol());
$this->assertSame('Inductor_THT:L_Axial_0307', $eda->getKicadFootprint());
$this->assertSame('L', $eda->getReferencePrefix());
$this->assertSame('100uH', $eda->getValue());
}

public function testImportAcceptsFlatEdaColumns(): void
{
//The documented flat form (and its short aliases) must keep working.
$input = "name;eda_kicad_symbol;kicad_footprint;kicad_reference\n"
."Flat EDA part;Device:R;Resistor_SMD:R_0805_2012Metric;R";

$category = new Category();
$category->setName('Test EDA category');

$errors = [];
$results = $this->service->importString($input, [
'class' => Part::class,
'format' => 'csv',
'csv_delimiter' => ';',
'create_unknown_datastructures' => true,
'part_category' => $category,
], $errors);

$this->assertCount(1, $results);
$this->assertEmpty($errors);
$eda = $results[0]->getEdaInfo();
$this->assertSame('Device:R', $eda->getKicadSymbol());
$this->assertSame('Resistor_SMD:R_0805_2012Metric', $eda->getKicadFootprint());
$this->assertSame('R', $eda->getReferencePrefix());
}

public function testImportInvisibleAliasInvertsVisibility(): void
{
//"eda_invisible" is the inverse convenience alias of "eda_visibility": eda_invisible=1
//must make the part NOT visible to the EDA tool (visibility=false), not visible.
$input = "name;eda_invisible\n"
."Hidden EDA part;1";

$category = new Category();
$category->setName('Test EDA category');

$errors = [];
$results = $this->service->importString($input, [
'class' => Part::class,
'format' => 'csv',
'csv_delimiter' => ';',
'create_unknown_datastructures' => true,
'part_category' => $category,
], $errors);

$this->assertCount(1, $results);
$this->assertEmpty($errors);
$this->assertFalse($results[0]->getEdaInfo()->getVisibility());
}

public function testImportExcelFileProjects(): void
{
$spreadsheet = new Spreadsheet();
Expand Down
Loading