Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.0.5 #197

Merged
merged 18 commits into from
Jan 16, 2024
Merged

1.0.5 #197

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
4 changes: 2 additions & 2 deletions .github/workflows/test_deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11']

steps:
- name: Checkout code
Expand Down Expand Up @@ -57,7 +57,7 @@ jobs:
continue-on-error: true
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11']

steps:
- name: Checkout code
Expand Down
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![Coverage Status](https://coveralls.io/repos/github/sparkmicro/Ki-nTree/badge.svg?branch=main&service=github)](https://coveralls.io/github/sparkmicro/Ki-nTree?branch=main)

## :warning: InvenTree Compatibility
InvenTree `0.12` introduced a new parameter template system which was not supported until version `0.12.6` came out, see https://github.com/sparkmicro/Ki-nTree/issues/165 for more details. In short, Ki-nTree currently supports InvenTree `0.11` or older versions, and `0.12.6` and future versions.
InvenTree `0.12` introduced a new parameter template system which was not supported until version `0.12.6` came out, see https://github.com/sparkmicro/Ki-nTree/issues/165 for more details. In short, Ki-nTree currently supports InvenTree `0.11` or older versions, and `0.12.6` and future versions. From `0.13.0` onwards a InvenTree setting needs to be modified for Ki-nTree to work: `InvenTree Settings` -> `Part Parameters` -> `Enforce Parameter Units` -> **OFF** (requires administrator rights)

## :fast_forward: [Demo Video](https://youtu.be/YeWBqOCb4pw)

Expand All @@ -34,13 +34,13 @@ Ki-nTree works with:
>
> To use with KiCad version **5**, use older Ki-nTree `0.4.x` versions (`pip install kintree==0.4.8`).

Ki-nTree was developped by [@eeintech](https://github.com/eeintech) for [SPARK Microsystems](https://www.sparkmicro.com/), who generously accepted to make it open-source!
Ki-nTree was developed by [@eeintech](https://github.com/eeintech) for [SPARK Microsystems](https://www.sparkmicro.com/), who generously accepted to make it open-source!

## Get Started

### Requirements

* Ki-nTree is currently tested for Python 3.8 to 3.11 versions.
* Ki-nTree is currently tested for Python 3.9 to 3.11 versions.
* Ki-nTree requires a Digi-Key **production** API instance. To create one, go to https://developer.digikey.com/. Create an account, an organization and add a **production** API to your organization. Save both Client ID and Secret keys.
> [Here is a video](https://youtu.be/OI1EGEc0Ju0) to help with the different steps
* Ki-nTree requires a Mouser Search API key. To request one, head over to https://www.mouser.ca/api-search/ and click on "Sign Up for Search API"
Expand Down Expand Up @@ -131,7 +131,7 @@ Below is a summary table of the different configuration files, their function an
| `digikey_categories.yaml` | Mapping between InvenTree categories and Digi-Key categories | :x: |
| `digikey_parameters.yaml` | Mapping between InvenTree parameters and Digi-Key parameters/attributes | :x: |

> Ki-nTree only supports matching between InvenTree and Digi-Key categories and parameters/attibutes (help wanted!)
> Ki-nTree only supports matching between InvenTree and Digi-Key categories and parameters/attributes (help wanted!)

</p>
</details>
Expand Down Expand Up @@ -159,6 +159,7 @@ Note that each time you enable the "Add" permission to an object, InvenTree auto
b. Instead of user credential authentication token authentication is also supported. To use a token add it it to the "Password or Token" field and leave the "Username" empty. You can retrieve your personal access token from your InvenTree server by sending an get-request to its api url `api/user/token/`.
c. If needed this tool can try to download the parts datasheet from the suppliers and upload it it to the attachment section of each part. For this just activate "Upload Datasheets to InvenTree" in the InvenTree settings
d. It is also possible to sync the prices in InvenTree with the latest supplier prices. For this enable "Upload Pricing Data to InvenTree"
6. If your InvenTree server requires a IPN in a specific pattern make sure to adjust "Settings > InvenTree > Internal Part Number" to match it or adjust the servers pattern to the one yo set in Ki-nTree


#### Get Digi-Key API token
Expand Down Expand Up @@ -197,7 +198,7 @@ Refer to [this file](https://github.com/sparkmicro/Ki-nTree/blob/main/kintree/co

#### Part Number Search

Ki-nTree currently supports APIs for the following electronics suppliers: Digi-Key, Mouser, Element14 and LCSC.
Ki-nTree currently supports APIs for the following electronics suppliers: Digi-Key, Mouser, Element14, TME and LCSC.

1. In the main window, enter the part number and select the supplier in drop-down list, then click "CREATE". It will start by fetching part data using the supplier's API
2. In the case Digi-Key has been selected and the API token is not found or expired, a browser window will pop-up. To get a new token: [follow those steps](#get-digi-key-api-token)
Expand All @@ -210,9 +211,10 @@ Ki-nTree currently supports APIs for the following electronics suppliers: Digi-K

The automatic part generation in KiCad is controlled via templates:

* Template examples are shipped together with Ki-nTree, these can be adjusted to your likings or you also can create completely new ones.
* Template examples are shipped together with Ki-nTree, these can be adjusted to your liking or you also can create completely new ones.
* Each template has its own library file where the file name defines the templates name.
* The templates can use the parameters and attributes of the InvenTree part on a wildcard base. So you can add for example `Resistance @ Tolerance` into a field and the resulting part will then have the resitance and the tolerance value inside this text field.
* The templates can use the parameters and attributes of the InvenTree part on a wildcard base. So you can add for example `Resistance@Tolerance` into a field and the resulting part will then have the resistance and the tolerance value inside this text field.
* Using the templates and wildcards without the InvenTree functions enabled is also possible. In this case the library parameter wildcards need to be configured in the `supplier_parameters.yaml` for each library individually.


Enjoy!
Expand All @@ -223,7 +225,7 @@ Enjoy!

### Requirements

You need `python>=3.8` and `poetry`.
You need `python>=3.9` and `poetry`.

You can install poetry by following the instructions [on its official website](https://python-poetry.org/docs/master/#installation), by using `pip install poetry` or by installing a package on your Linux distro.

Expand Down
2 changes: 1 addition & 1 deletion images/python_versions.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion kintree/config/user/general.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ INVENTREE_ENV: null
DEFAULT_SUPPLIER: Digi-Key
ENABLE_KICAD: false
ENABLE_INVENTREE: false
ENABLE_ALTERNATE: false
ENABLE_ALTERNATE: false
CHECK_EXISTING: true
1 change: 1 addition & 0 deletions kintree/config/user/internal_part_number.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
IPN_ENABLE_CREATE: true
IPN_USE_MANUFACTURER_PART_NUMBER: false
IPN_PREFIX: null
IPN_CATEGORY_CODE: true
IPN_UNIQUE_ID_LENGTH: '6'
Expand Down
112 changes: 76 additions & 36 deletions kintree/database/inventree_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from inventree.api import InvenTreeAPI
from inventree.company import Company, ManufacturerPart, SupplierPart, SupplierPriceBreak
from inventree.part import Part, PartCategory, Parameter, ParameterTemplate
from inventree.currency import CurrencyManager


def connect(server: str,
Expand Down Expand Up @@ -49,6 +50,13 @@ def get_inventree_api_timeout():
return False


def set_inventree_db_test_mode():
''' InvenTree test database setup '''
global inventree_api

inventree_api.patch('settings/global/PART_PARAMETER_ENFORCE_UNITS', {'value': False})


def get_inventree_category_id(category_tree: list) -> int:
''' Get InvenTree category ID from name, specificy parent if subcategory '''
global inventree_api
Expand Down Expand Up @@ -401,21 +409,26 @@ def upload_part_datasheet(datasheet_url: str, part_id: int) -> str:
return ''


def create_part(category_id: int, name: str, description: str, revision: str, keywords=None) -> int:
def create_part(category_id: int, name: str, description: str, revision: str, ipn: str, keywords=None) -> int:
''' Create InvenTree part '''
global inventree_api

part = Part.create(inventree_api, {
'name': name,
'description': description,
'category': category_id,
'keywords': keywords,
'revision': revision,
'active': True,
'virtual': False,
'component': True,
'purchaseable': True,
})
try:
part = Part.create(inventree_api, {
'name': name,
'description': description,
'category': category_id,
'keywords': keywords,
'revision': revision,
'IPN': ipn,
'active': True,
'virtual': False,
'component': True,
'purchaseable': True,
})
except Exception:
cprint('[TREE]\tError: Part creation failed. Check if Ki-nTree settings match InvenTree part settings.', silent=settings.SILENT)
return 0

if part:
return part.pk
Expand Down Expand Up @@ -626,15 +639,27 @@ def create_supplier_part(part_id: int, manufacturer_name: str, manufacturer_mpn:
return False, False


def sanitize_price(price_in):
price = re.findall('\d+.\d+', price_in)[0]
price = price.replace(',', '.')
price = price.replace('\xa0', '')
return price


def update_price_breaks(supplier_part, price_breaks: dict) -> bool:
def update_price_breaks(supplier_part,
price_breaks: dict,
currency='USD') -> bool:
''' Update the Price Breaks associated with a supplier part '''
def sanitize_price(price_in):
price = re.findall('\d+.\d+', price_in)[0]
price = price.replace(',', '.')
price = price.replace('\xa0', '')
return price

def convert_currency(price):
manager = CurrencyManager(inventree_api)
base = manager.getBaseCurrency()
if base != currency:
try:
price = manager.convertCurrency(float(price), currency, base)
except Exception:
cprint('[TREE]\tWarning: Currency conversion failed.',
silent=settings.SILENT)
return price

if not isinstance(supplier_part, SupplierPart):
try:
supplier_part = SupplierPart(inventree_api, supplier_part)
Expand All @@ -651,11 +676,12 @@ def update_price_breaks(supplier_part, price_breaks: dict) -> bool:
# First process existing price breaks
for old_price_break in old_price_breaks:
quantity = old_price_break.quantity
price = price_breaks[quantity]
# remove everything but the numbers from the price break
if isinstance(price, str):
price = sanitize_price(price)
if quantity in price_breaks:
price = price_breaks[quantity]
# remove everything but the numbers from the price break
if isinstance(price, str):
price = sanitize_price(price)
price = convert_currency(price)
old_price_break.save(data={'price': price})
updated.append(quantity)
else:
Expand All @@ -667,6 +693,7 @@ def update_price_breaks(supplier_part, price_breaks: dict) -> bool:
# remove everything but the numbers from the price break
if isinstance(price, str):
price = sanitize_price(price)
price = convert_currency(price)
SupplierPriceBreak.create(inventree_api, {
'part': supplier_part.pk,
'quantity': quantity,
Expand All @@ -685,10 +712,13 @@ def create_parameter_template(name: str, units: str) -> int:
if name == item.name:
return 0

parameter_template = ParameterTemplate.create(inventree_api, {
'name': name,
'units': units if units else '',
})
try:
parameter_template = ParameterTemplate.create(inventree_api, {
'name': name,
'units': units if units else '',
})
except:
cprint(f'[TREE]\tError: Failed to create parameter template "{name}".', silent=settings.SILENT)

if parameter_template:
return parameter_template.pk
Expand Down Expand Up @@ -722,9 +752,14 @@ def create_parameter(part_id: int, template_name: int, value: str):
if value != item.data and value != '-':
parameter = item
was_updated = True
parameter.save(data={
'data': value
})
try:
parameter.save(data={
'data': value
})
except Exception as e:
cprint(f'[TREE]\tError: Failed to update part parameter "{template_name}".', silent=settings.SILENT)
if "Could not convert" in e.args[0]['body'].__str__():
cprint(f'[TREE]\tError: Parameter value "{value}" is not allowed by server settings.', silent=settings.SILENT)
break
# cprint(part_parameters, silent=SILENT)

Expand All @@ -734,11 +769,16 @@ def create_parameter(part_id: int, template_name: int, value: str):
- parameter does not exist for this part
'''
if template_id > 0 and is_new_part_parameters_template_id:
parameter = Parameter.create(inventree_api, {
'part': part_id,
'template': template_id,
'data': value,
})
try:
parameter = Parameter.create(inventree_api, {
'part': part_id,
'template': template_id,
'data': value,
})
except Exception as e:
cprint(f'[TREE]\tError: Failed to create part parameter "{template_name}".', silent=settings.SILENT)
if "Could not convert" in e.args[0]['body'].__str__():
cprint(f'[TREE]\tError: Parameter value "{value}" is not allowed by server settings.', silent=settings.SILENT)

if parameter:
return parameter.pk, is_new_part_parameters_template_id, was_updated
Expand Down
Loading
Loading