From ea64f5a301e155dfe88392e3cdf5e535275fd922 Mon Sep 17 00:00:00 2001 From: Lukas Runge Date: Wed, 9 Sep 2026 18:04:43 +0200 Subject: [PATCH 1/2] Fix stale KiCad category listing after EDA settings change The KiCad category parts listing is cached and only invalidated by entity changes (parts, categories, footprints). Settings that change the exported fields (datasheet as PDF, default parameter/orderdetail visibility) did not invalidate it, so KiCad kept receiving the old listing until any part was edited. Include a fingerprint of these settings in the cache key, so a settings change results in a fresh listing. Co-Authored-By: Claude Fable 5.1 --- src/Services/EDA/KiCadHelper.php | 18 ++++++++++++- tests/Services/EDA/KiCadHelperTest.php | 35 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/Services/EDA/KiCadHelper.php b/src/Services/EDA/KiCadHelper.php index 85159c51d..16bdf3695 100644 --- a/src/Services/EDA/KiCadHelper.php +++ b/src/Services/EDA/KiCadHelper.php @@ -145,7 +145,10 @@ public function getCategories(): array */ public function getCategoryParts(?Category $category): array { - $cacheKey = 'kicad_category_parts_'.($category?->getID() ?? 0) . '_' . $this->category_depth; + // Settings fingerprint keeps cached responses from surviving settings changes + // (tag-based invalidation only fires on part/category/footprint edits) + $cacheKey = 'kicad_category_parts_'.($category?->getID() ?? 0) . '_' . $this->category_depth + . '_' . $this->edaSettingsFingerprint(); return $this->kicadCache->get($cacheKey, function (ItemInterface $item) use ($category) { $item->tag([ @@ -355,6 +358,19 @@ public function getKiCADPart(Part $part): array return $result; } + /** + * Fingerprint of every setting that changes the content of a serialized part. + */ + private function edaSettingsFingerprint(): string + { + return md5(json_encode([ + $this->datasheetAsPdf, + $this->kiCadEDASettings->defaultOrderdetailsVisibility, + $this->kiCadEDASettings->defaultParameterVisibility, + $this->kiCadEDASettings->defaultParameterSymbolVisibility, + ], JSON_THROW_ON_ERROR)); + } + /** * Determine if the given part should be visible for the EDA. * @param Category $category diff --git a/tests/Services/EDA/KiCadHelperTest.php b/tests/Services/EDA/KiCadHelperTest.php index b043d5980..1d094d6e8 100644 --- a/tests/Services/EDA/KiCadHelperTest.php +++ b/tests/Services/EDA/KiCadHelperTest.php @@ -33,6 +33,7 @@ use App\Entity\Parts\Supplier; use App\Entity\PriceInformations\Orderdetail; use App\Services\EDA\KiCadHelper; +use App\Settings\MiscSettings\KiCadEDASettings; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\Attributes\Group; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; @@ -654,4 +655,38 @@ public function testCategoryPartsListingContainsFields(): void self::assertArrayHasKey('symbolIdStr', $part); } } + + /** + * The category listing is cached and only invalidated by entity changes. + * Changing a setting that affects the exported fields must not serve a stale listing. + */ + public function testCategoryPartsCacheIsInvalidatedBySettingsChange(): void + { + /** @var KiCadEDASettings $settings */ + $settings = self::getContainer()->get(KiCadEDASettings::class); + $category = $this->em->find(Category::class, 1); + + $part = new Part(); + $part->setName('Part for cache test'); + $part->setCategory($category); + $param = new PartParameter(); + $param->setName('CacheTestParam'); + $param->setValueText('42'); + $param->setEdaVisibility(null); + $part->addParameter($param); + $this->em->persist($part); + $this->em->flush(); + + $findFields = fn(array $listing): array => array_values(array_filter($listing, fn($p) => (int) $p['id'] === $part->getId()))[0]['fields']; + + $settings->defaultParameterVisibility = false; + $before = $findFields($this->helper->getCategoryParts($category)); + self::assertArrayNotHasKey('CacheTestParam', $before); + + // No entity changed, only the setting: the cached listing must not be reused + $settings->defaultParameterVisibility = true; + $after = $findFields($this->helper->getCategoryParts($category)); + self::assertArrayHasKey('CacheTestParam', $after); + self::assertSame('42', $after['CacheTestParam']['value']); + } } From 87c2a14bf9ccf6fd2c1e84bd0bbb0ac3de8901f4 Mon Sep 17 00:00:00 2001 From: Lukas Runge Date: Mon, 31 Aug 2026 13:33:23 +0200 Subject: [PATCH 2/2] Add settings to select which field groups are exported to KiCad KiCad reports every difference between a placed symbol and its library entry as a "library symbol mismatch" in the ERC. Since Part-DB exports stock, storage locations, supplier part numbers, KiCost fields, part info and tags as symbol fields, every stock booking, supplier edit or tag change in Part-DB triggers ERC warnings in all schematics using the part. This adds five settings (also configurable via env, EnvVarMode::OVERWRITE) to the KiCad integration settings that allow disabling these field groups: - EDA_KICAD_EXPORT_STOCK_FIELDS: Stock, Storage Location - EDA_KICAD_EXPORT_SUPPLIER_FIELDS: SPN - EDA_KICAD_EXPORT_KICOST_FIELDS: manf, manf#, # - EDA_KICAD_EXPORT_PART_INFO_FIELDS: Category, Manufacturing Status, Mass, Part-DB IPN/Footprint/Unit/Custom state - EDA_KICAD_EXPORT_TAGS_AS_KEYWORDS: symbol keywords All settings default to true, so the exported fields do not change for existing installations. The new settings are part of the category listing cache fingerprint. Co-Authored-By: Claude Fable 5.1 --- docs/usage/eda_integration.md | 24 +++ src/Services/EDA/KiCadHelper.php | 67 +++++---- .../MiscSettings/KiCadEDASettings.php | 35 +++++ tests/Services/EDA/KiCadHelperTest.php | 142 ++++++++++++++++++ translations/messages.en.xlf | 60 ++++++++ 5 files changed, 302 insertions(+), 26 deletions(-) diff --git a/docs/usage/eda_integration.md b/docs/usage/eda_integration.md index 9b09c5a08..0c42f461d 100644 --- a/docs/usage/eda_integration.md +++ b/docs/usage/eda_integration.md @@ -96,6 +96,30 @@ If you set this value to -1, all parts are shown inside a single category in KiC You can view the "real" category path of a part in the part details dialog in KiCad. +### Exported symbol fields + +Besides the fields KiCad needs (symbol, footprint, reference, value, datasheet, description) Part-DB exports additional +information as symbol fields: manufacturer and MPN, the Part-DB ID and URL, stock and storage locations, supplier part +numbers, KiCost compatible fields (`manf`, `manf#`, `#`), part info (category, manufacturing status, mass, IPN, ...) +and the tags as symbol keywords. + +KiCad compares the fields of a placed symbol with the library. Every difference is reported as a "library symbol mismatch" +by the ERC. If you use the stock or supplier fields, every stock booking or supplier edit in Part-DB therefore triggers +ERC warnings in all schematics that use the part. + +To avoid this, you can disable groups of fields that you do not need in your schematics in the server settings under +"KiCAD integration", or via the following env options (a value of `0` disables the group): + +| Option | Fields | +|---------------------------------------|--------------------------------------------------------------------------------------------------| +| `EDA_KICAD_EXPORT_STOCK_FIELDS` | `Stock`, `Storage Location` | +| `EDA_KICAD_EXPORT_SUPPLIER_FIELDS` | ` SPN` fields | +| `EDA_KICAD_EXPORT_KICOST_FIELDS` | `manf`, `manf#`, `#` | +| `EDA_KICAD_EXPORT_PART_INFO_FIELDS` | `Category`, `Manufacturing Status`, `Mass`, `Part-DB IPN`, `Part-DB Footprint`, `Part-DB Unit`, `Part-DB Custom state` | +| `EDA_KICAD_EXPORT_TAGS_AS_KEYWORDS` | symbol keywords (from the part tags) | + +All groups are enabled by default, so existing installations keep exporting the same fields as before. + ### Kicad:populate command Part-DB also provides a command that attempts to automatically populate the KiCad symbol and footprint fields based on the part's category and footprint names. diff --git a/src/Services/EDA/KiCadHelper.php b/src/Services/EDA/KiCadHelper.php index 16bdf3695..5be54e071 100644 --- a/src/Services/EDA/KiCadHelper.php +++ b/src/Services/EDA/KiCadHelper.php @@ -216,7 +216,9 @@ public function getKiCADPart(Part $part): array $result["fields"]["footprint"] = $this->createField($part->getEdaInfo()->getKicadFootprint() ?? $part->getFootprint()?->getEdaInfo()->getKicadFootprint() ?? ""); $result["fields"]["reference"] = $this->createField($part->getEdaInfo()->getReferencePrefix() ?? $part->getCategory()?->getEdaInfo()->getReferencePrefix() ?? 'U', true); $result["fields"]["value"] = $this->createField($part->getEdaInfo()->getValue() ?? $part->getName(), true); - $result["fields"]["keywords"] = $this->createField($part->getTags()); + if ($this->kiCadEDASettings->exportTagsAsKeywords) { + $result["fields"]["keywords"] = $this->createField($part->getTags()); + } //Use the part info page as Part-DB link. It must be an absolute URL. $partUrl = $this->urlGenerator->generate( @@ -236,7 +238,7 @@ public function getKiCADPart(Part $part): array //Add basic fields $result["fields"]["description"] = $this->createField($part->getDescription()); - if ($part->getCategory() !== null) { + if ($this->kiCadEDASettings->exportPartInfoFields && $part->getCategory() !== null) { $result["fields"]["Category"] = $this->createField($part->getCategory()->getFullPath('/')); } if ($part->getManufacturer() !== null) { @@ -245,39 +247,40 @@ public function getKiCADPart(Part $part): array if ($part->getManufacturerProductNumber() !== "") { $result['fields']["MPN"] = $this->createField($part->getManufacturerProductNumber()); } - if ($part->getManufacturingStatus() !== null) { + if ($this->kiCadEDASettings->exportPartInfoFields && $part->getManufacturingStatus() !== null) { $result["fields"]["Manufacturing Status"] = $this->createField( //Always use the english translation $this->translator->trans($part->getManufacturingStatus()->toTranslationKey(), locale: 'en') ); } - if ($part->getFootprint() !== null) { + if ($this->kiCadEDASettings->exportPartInfoFields && $part->getFootprint() !== null) { $result["fields"]["Part-DB Footprint"] = $this->createField($part->getFootprint()->getName()); } - if ($part->getPartUnit() !== null) { + if ($this->kiCadEDASettings->exportPartInfoFields && $part->getPartUnit() !== null) { $unit = $part->getPartUnit()->getName(); if ($part->getPartUnit()->getUnit() !== "") { $unit .= ' ('.$part->getPartUnit()->getUnit().')'; } $result["fields"]["Part-DB Unit"] = $this->createField($unit); } - if ($part->getPartCustomState() !== null) { + if ($this->kiCadEDASettings->exportPartInfoFields && $part->getPartCustomState() !== null) { $customState = $part->getPartCustomState()->getName(); $result["fields"]["Part-DB Custom state"] = $this->createField($customState); } - if ($part->getMass()) { + if ($this->kiCadEDASettings->exportPartInfoFields && $part->getMass()) { $result["fields"]["Mass"] = $this->createField($part->getMass() . ' g'); } $result["fields"]["Part-DB ID"] = $this->createField($part->getId()); - if ($part->getIpn() !== null && $part->getIpn() !== '' && $part->getIpn() !== '0') { + if ($this->kiCadEDASettings->exportPartInfoFields + && $part->getIpn() !== null && $part->getIpn() !== '' && $part->getIpn() !== '0') { $result["fields"]["Part-DB IPN"] = $this->createField($part->getIpn()); } //Add KiCost manufacturer fields (always present, independent of orderdetails) - if ($part->getManufacturer() !== null) { + if ($this->kiCadEDASettings->exportKicostFields && $part->getManufacturer() !== null) { $result["fields"]["manf"] = $this->createField($part->getManufacturer()->getName()); } - if ($part->getManufacturerProductNumber() !== "") { + if ($this->kiCadEDASettings->exportKicostFields && $part->getManufacturerProductNumber() !== "") { $result['fields']['manf#'] = $this->createField($part->getManufacturerProductNumber()); } @@ -285,7 +288,8 @@ public function getKiCADPart(Part $part): array // If any orderdetail has eda_visibility explicitly set to true, only export those; // otherwise export all (backward compat when no flags are set) $allOrderdetails = $part->getOrderdetails(false); - if ($allOrderdetails->count() > 0) { + if (($this->kiCadEDASettings->exportSupplierFields || $this->kiCadEDASettings->exportKicostFields) + && $allOrderdetails->count() > 0) { $hasExplicitEdaVisibility = false; foreach ($allOrderdetails as $od) { if ($od->isEdaVisibility() !== null) { @@ -315,30 +319,36 @@ public function getKiCADPart(Part $part): array ? $supplierName . ' ' . $supplierCounts[$supplierName] : $supplierName; - $result["fields"][$fieldName] = $this->createField($orderdetail->getSupplierPartNr()); + if ($this->kiCadEDASettings->exportSupplierFields) { + $result["fields"][$fieldName] = $this->createField($orderdetail->getSupplierPartNr()); + } //Also add a KiCost-compatible field (supplier_name# = SPN) - $kicostFieldName = mb_strtolower($orderdetail->getSupplier()->getName()) . '#'; - $result["fields"][$kicostFieldName] = $this->createField($orderdetail->getSupplierPartNr()); + if ($this->kiCadEDASettings->exportKicostFields) { + $kicostFieldName = mb_strtolower($orderdetail->getSupplier()->getName()) . '#'; + $result["fields"][$kicostFieldName] = $this->createField($orderdetail->getSupplierPartNr()); + } } } } //Add stock quantity and storage locations (only count non-expired lots with known quantity) - $totalStock = 0; - $locations = []; - foreach ($part->getPartLots() as $lot) { - $isAvailable = !$lot->isInstockUnknown() && $lot->isExpired() !== true; - if ($isAvailable) { - $totalStock += $lot->getAmount(); - if ($lot->getAmount() > 0 && $lot->getStorageLocation() !== null) { - $locations[] = $lot->getStorageLocation()->getName(); + if ($this->kiCadEDASettings->exportStockFields) { + $totalStock = 0; + $locations = []; + foreach ($part->getPartLots() as $lot) { + $isAvailable = !$lot->isInstockUnknown() && $lot->isExpired() !== true; + if ($isAvailable) { + $totalStock += $lot->getAmount(); + if ($lot->getAmount() > 0 && $lot->getStorageLocation() !== null) { + $locations[] = $lot->getStorageLocation()->getName(); + } } } - } - $result['fields']['Stock'] = $this->createField($totalStock); - if ($locations !== []) { - $result['fields']['Storage Location'] = $this->createField(implode(', ', array_unique($locations))); + $result['fields']['Stock'] = $this->createField($totalStock); + if ($locations !== []) { + $result['fields']['Storage Location'] = $this->createField(implode(', ', array_unique($locations))); + } } //Add parameters marked for EDA export (explicit true, or system default when null) @@ -368,6 +378,11 @@ private function edaSettingsFingerprint(): string $this->kiCadEDASettings->defaultOrderdetailsVisibility, $this->kiCadEDASettings->defaultParameterVisibility, $this->kiCadEDASettings->defaultParameterSymbolVisibility, + $this->kiCadEDASettings->exportStockFields, + $this->kiCadEDASettings->exportSupplierFields, + $this->kiCadEDASettings->exportKicostFields, + $this->kiCadEDASettings->exportPartInfoFields, + $this->kiCadEDASettings->exportTagsAsKeywords, ], JSON_THROW_ON_ERROR)); } diff --git a/src/Settings/MiscSettings/KiCadEDASettings.php b/src/Settings/MiscSettings/KiCadEDASettings.php index a32b31e5a..6f88dd049 100644 --- a/src/Settings/MiscSettings/KiCadEDASettings.php +++ b/src/Settings/MiscSettings/KiCadEDASettings.php @@ -75,4 +75,39 @@ class KiCadEDASettings description: new TM("settings.misc.kicad_eda.use_custom_list.help"), )] public bool $useCustomList = false; + + #[SettingsParameter( + label: new TM("settings.misc.kicad_eda.export_stock_fields"), + description: new TM("settings.misc.kicad_eda.export_stock_fields.help"), + envVar: "bool:EDA_KICAD_EXPORT_STOCK_FIELDS", envVarMode: EnvVarMode::OVERWRITE, + )] + public bool $exportStockFields = true; + + #[SettingsParameter( + label: new TM("settings.misc.kicad_eda.export_supplier_fields"), + description: new TM("settings.misc.kicad_eda.export_supplier_fields.help"), + envVar: "bool:EDA_KICAD_EXPORT_SUPPLIER_FIELDS", envVarMode: EnvVarMode::OVERWRITE, + )] + public bool $exportSupplierFields = true; + + #[SettingsParameter( + label: new TM("settings.misc.kicad_eda.export_kicost_fields"), + description: new TM("settings.misc.kicad_eda.export_kicost_fields.help"), + envVar: "bool:EDA_KICAD_EXPORT_KICOST_FIELDS", envVarMode: EnvVarMode::OVERWRITE, + )] + public bool $exportKicostFields = true; + + #[SettingsParameter( + label: new TM("settings.misc.kicad_eda.export_part_info_fields"), + description: new TM("settings.misc.kicad_eda.export_part_info_fields.help"), + envVar: "bool:EDA_KICAD_EXPORT_PART_INFO_FIELDS", envVarMode: EnvVarMode::OVERWRITE, + )] + public bool $exportPartInfoFields = true; + + #[SettingsParameter( + label: new TM("settings.misc.kicad_eda.export_tags_as_keywords"), + description: new TM("settings.misc.kicad_eda.export_tags_as_keywords.help"), + envVar: "bool:EDA_KICAD_EXPORT_TAGS_AS_KEYWORDS", envVarMode: EnvVarMode::OVERWRITE, + )] + public bool $exportTagsAsKeywords = true; } diff --git a/tests/Services/EDA/KiCadHelperTest.php b/tests/Services/EDA/KiCadHelperTest.php index 1d094d6e8..c661e6064 100644 --- a/tests/Services/EDA/KiCadHelperTest.php +++ b/tests/Services/EDA/KiCadHelperTest.php @@ -43,12 +43,14 @@ final class KiCadHelperTest extends KernelTestCase { private KiCadHelper $helper; private EntityManagerInterface $em; + private KiCadEDASettings $settings; protected function setUp(): void { self::bootKernel(); $this->helper = self::getContainer()->get(KiCadHelper::class); $this->em = self::getContainer()->get(EntityManagerInterface::class); + $this->settings = self::getContainer()->get(KiCadEDASettings::class); } /** @@ -689,4 +691,144 @@ public function testCategoryPartsCacheIsInvalidatedBySettingsChange(): void self::assertArrayHasKey('CacheTestParam', $after); self::assertSame('42', $after['CacheTestParam']['value']); } + + /** + * Creates a part that has data for every optional field group (stock, supplier, KiCost, part info, tags). + */ + private function createPartWithAllFieldGroups(): Part + { + $category = $this->em->find(Category::class, 1); + $location = $this->em->find(StorageLocation::class, 1); + + $manufacturer = new Manufacturer(); + $manufacturer->setName('Switch Corp'); + $this->em->persist($manufacturer); + + $supplier = new Supplier(); + $supplier->setName('SwitchSupplier'); + $this->em->persist($supplier); + + $part = new Part(); + $part->setName('Part with all field groups'); + $part->setCategory($category); + $part->setManufacturer($manufacturer); + $part->setManufacturerProductNumber('SW-1234'); + $part->setTags('tag1,tag2'); + $part->setMass(1.5); + + $lot = new PartLot(); + $lot->setAmount(5); + $lot->setStorageLocation($location); + $part->addPartLot($lot); + + $orderdetail = new Orderdetail(); + $orderdetail->setSupplier($supplier); + $orderdetail->setSupplierpartnr('SUP-999'); + $part->addOrderdetail($orderdetail); + + $this->em->persist($part); + $this->em->flush(); + + return $part; + } + + /** + * With the default settings every field group is exported. + */ + public function testAllFieldGroupsExportedByDefault(): void + { + $part = $this->createPartWithAllFieldGroups(); + $fields = $this->helper->getKiCADPart($part)['fields']; + + self::assertArrayHasKey('Stock', $fields); + self::assertArrayHasKey('Storage Location', $fields); + self::assertArrayHasKey('SwitchSupplier SPN', $fields); + self::assertArrayHasKey('manf', $fields); + self::assertArrayHasKey('manf#', $fields); + self::assertArrayHasKey('switchsupplier#', $fields); + self::assertArrayHasKey('Category', $fields); + self::assertArrayHasKey('Mass', $fields); + self::assertArrayHasKey('keywords', $fields); + self::assertSame('tag1,tag2', $fields['keywords']['value']); + } + + public function testStockFieldsCanBeDisabled(): void + { + $this->settings->exportStockFields = false; + $part = $this->createPartWithAllFieldGroups(); + $fields = $this->helper->getKiCADPart($part)['fields']; + + self::assertArrayNotHasKey('Stock', $fields); + self::assertArrayNotHasKey('Storage Location', $fields); + // Other groups are unaffected + self::assertArrayHasKey('SwitchSupplier SPN', $fields); + self::assertArrayHasKey('manf#', $fields); + } + + public function testSupplierFieldsCanBeDisabledIndependentlyOfKicostFields(): void + { + $this->settings->exportSupplierFields = false; + $part = $this->createPartWithAllFieldGroups(); + $fields = $this->helper->getKiCADPart($part)['fields']; + + self::assertArrayNotHasKey('SwitchSupplier SPN', $fields); + // KiCost supplier field is still exported, as it is controlled by its own switch + self::assertArrayHasKey('switchsupplier#', $fields); + self::assertSame('SUP-999', $fields['switchsupplier#']['value']); + } + + public function testKicostFieldsCanBeDisabledIndependentlyOfSupplierFields(): void + { + $this->settings->exportKicostFields = false; + $part = $this->createPartWithAllFieldGroups(); + $fields = $this->helper->getKiCADPart($part)['fields']; + + self::assertArrayNotHasKey('manf', $fields); + self::assertArrayNotHasKey('manf#', $fields); + self::assertArrayNotHasKey('switchsupplier#', $fields); + // The regular supplier and manufacturer fields stay + self::assertArrayHasKey('SwitchSupplier SPN', $fields); + self::assertArrayHasKey('Manufacturer', $fields); + self::assertArrayHasKey('MPN', $fields); + } + + public function testPartInfoFieldsCanBeDisabled(): void + { + $this->settings->exportPartInfoFields = false; + $part = $this->createPartWithAllFieldGroups(); + $fields = $this->helper->getKiCADPart($part)['fields']; + + self::assertArrayNotHasKey('Category', $fields); + self::assertArrayNotHasKey('Mass', $fields); + // Fields needed by KiCad itself and for identification are always present + self::assertArrayHasKey('Part-DB ID', $fields); + self::assertArrayHasKey('Part-DB URL', $fields); + self::assertArrayHasKey('MPN', $fields); + self::assertArrayHasKey('description', $fields); + } + + public function testTagsAsKeywordsCanBeDisabled(): void + { + $this->settings->exportTagsAsKeywords = false; + $part = $this->createPartWithAllFieldGroups(); + $fields = $this->helper->getKiCADPart($part)['fields']; + + self::assertArrayNotHasKey('keywords', $fields); + } + + /** + * The new export switches must also be part of the cache fingerprint. + */ + public function testCategoryPartsCacheIsInvalidatedByExportSettingsChange(): void + { + $category = $this->em->find(Category::class, 1); + + $before = $this->helper->getCategoryParts($category); + self::assertNotEmpty($before); + self::assertArrayHasKey('Stock', $before[0]['fields']); + + $this->settings->exportStockFields = false; + $after = $this->helper->getCategoryParts($category); + self::assertArrayNotHasKey('Stock', $after[0]['fields']); + } } diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index f7a9d4e9f..1a7208f9e 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -10224,6 +10224,66 @@ Please note, that you can not impersonate a disabled user. If you try you will g When enabled, KiCad autocomplete uses public/kicad/footprints_custom.txt and public/kicad/symbols_custom.txt instead of the autogenerated default files. + + + settings.misc.kicad_eda.export_stock_fields + Export stock fields (Stock, Storage Location) + + + + + settings.misc.kicad_eda.export_stock_fields.help + When enabled, the current stock and the storage locations are exported as symbol fields. Disable this if stock changes should not modify the KiCad symbols (each change is reported as a library symbol mismatch by the KiCad ERC). + + + + + settings.misc.kicad_eda.export_supplier_fields + Export supplier part number fields + + + + + settings.misc.kicad_eda.export_supplier_fields.help + When enabled, one "<Supplier> SPN" field per order detail is exported. + + + + + settings.misc.kicad_eda.export_kicost_fields + Export KiCost fields (manf, manf#, <supplier>#) + + + + + settings.misc.kicad_eda.export_kicost_fields.help + When enabled, KiCost-compatible copies of the manufacturer, manufacturer part number and supplier part numbers are exported. + + + + + settings.misc.kicad_eda.export_part_info_fields + Export part info fields (Category, Manufacturing Status, Mass, IPN, ...) + + + + + settings.misc.kicad_eda.export_part_info_fields.help + When enabled, the Category, Manufacturing Status, Mass, Part-DB IPN, Part-DB Footprint, Part-DB Unit and Part-DB Custom state fields are exported. + + + + + settings.misc.kicad_eda.export_tags_as_keywords + Export tags as keywords + + + + + settings.misc.kicad_eda.export_tags_as_keywords.help + When enabled, the part tags are exported as the KiCad symbol keywords. Disable this if tag changes should not modify the KiCad symbols. + + settings.misc.kicad_eda.editor.custom_footprints