Merge pull request #28 from inventree/supplier-pricing
Supplier pricing
22173
inventree_data.json
BIN
media/company_images/company_39_img.preview.webp
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
media/company_images/company_39_img.thumbnail.webp
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
media/company_images/company_39_img.webp
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
media/company_images/company_40_img.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
media/company_images/company_40_img.preview.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
media/company_images/company_40_img.thumbnail.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
media/company_images/company_41_img.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
media/company_images/company_41_img.preview.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
media/company_images/company_41_img.thumbnail.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
97
scripts/pin_headers.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
from inventree.api import InvenTreeAPI
|
||||||
|
|
||||||
|
from inventree.part import Part, Parameter, ParameterTemplate
|
||||||
|
from inventree.stock import StockItem
|
||||||
|
|
||||||
|
api = InvenTreeAPI("http://localhost:8000", username="admin", password="inventree")
|
||||||
|
|
||||||
|
# Pin headers category
|
||||||
|
cat_id = 21
|
||||||
|
|
||||||
|
# Storage location
|
||||||
|
loc_id = 10
|
||||||
|
|
||||||
|
rows = [1, 2]
|
||||||
|
pitch = [1.27, 2.0, 2.54]
|
||||||
|
ways = range(2, 11)
|
||||||
|
|
||||||
|
# Parameter templates
|
||||||
|
templates = {}
|
||||||
|
|
||||||
|
for tmp in ParameterTemplate.list(api):
|
||||||
|
templates[tmp.name] = tmp.pk
|
||||||
|
|
||||||
|
for r in rows:
|
||||||
|
for p in pitch:
|
||||||
|
for w in ways:
|
||||||
|
|
||||||
|
n = r * w
|
||||||
|
|
||||||
|
name = f"PinHeader_{r}x{w:02d}x{p}mm"
|
||||||
|
description = f"Male pin header connector, {r} rows, {n} positions, {p}mm pitch, vertical"
|
||||||
|
keywords = "pin header connector"
|
||||||
|
|
||||||
|
# Check if this part already exists
|
||||||
|
results = Part.list(api, search=name)
|
||||||
|
|
||||||
|
if len(results) > 0:
|
||||||
|
part = results[0]
|
||||||
|
else:
|
||||||
|
part = Part.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
'name': name,
|
||||||
|
'description': description,
|
||||||
|
'keywords': keywords,
|
||||||
|
'category': cat_id,
|
||||||
|
'purchaseable': True,
|
||||||
|
'component': True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create stock item for this item
|
||||||
|
items = StockItem.list(api, part=part.pk)
|
||||||
|
|
||||||
|
if len(items) == 0:
|
||||||
|
q = randint(0, 25)
|
||||||
|
|
||||||
|
if q > 0:
|
||||||
|
StockItem.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
'part': part.pk,
|
||||||
|
'quantity': q,
|
||||||
|
'location': loc_id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Generate parameters for each item
|
||||||
|
Parameter.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
'part': part.pk,
|
||||||
|
'template': templates['Pitch'],
|
||||||
|
'data': p
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Parameter.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
'part': part.pk,
|
||||||
|
'template': templates['Positions'],
|
||||||
|
'data': n
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Parameter.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
'part': part.pk,
|
||||||
|
'template': templates['Rows'],
|
||||||
|
'data': r
|
||||||
|
}
|
||||||
|
)
|
127
scripts/supplier_part_pricing.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
"""
|
||||||
|
This script adds new supplier data and supplier pricing for the demo dataset.
|
||||||
|
|
||||||
|
The supplier part numbers here are not real, neither is the pricing.
|
||||||
|
None of this data should be used for anything in the realm of sensible decision making.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
from progress.bar import Bar
|
||||||
|
|
||||||
|
from inventree.api import InvenTreeAPI
|
||||||
|
|
||||||
|
from inventree.company import Company, SupplierPart, SupplierPriceBreak
|
||||||
|
from inventree.part import Part
|
||||||
|
|
||||||
|
api = InvenTreeAPI("http://localhost:8000", username="admin", password="inventree")
|
||||||
|
|
||||||
|
# ID for the "passives" category
|
||||||
|
passives_category_id = 4
|
||||||
|
|
||||||
|
# List of electronics suppliers we wish to create supplier parts for
|
||||||
|
supplier_ids = [
|
||||||
|
1, # DigiKey
|
||||||
|
2, # Mouser
|
||||||
|
3, # Arrow
|
||||||
|
39, # LCSC
|
||||||
|
40, # Newark
|
||||||
|
41, # Future Electronics
|
||||||
|
]
|
||||||
|
|
||||||
|
# Special currency (default = USD)
|
||||||
|
currencies = {
|
||||||
|
2: 'AUD', # Mouser
|
||||||
|
39: 'CNY', # LCSC
|
||||||
|
41: 'CAD', # Future
|
||||||
|
}
|
||||||
|
|
||||||
|
parts = Part.list(api, category=passives_category_id, cascade=True)
|
||||||
|
|
||||||
|
bar = Bar('Creating Supplier Part Data', max=len(parts))
|
||||||
|
|
||||||
|
for part in parts:
|
||||||
|
|
||||||
|
bar.next()
|
||||||
|
|
||||||
|
# Create at least one supplier part for each supplier
|
||||||
|
for supplier_id in supplier_ids:
|
||||||
|
supplier_parts = SupplierPart.list(
|
||||||
|
api,
|
||||||
|
part=part.pk,
|
||||||
|
supplier=supplier_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Supplier part already exists for this supplier
|
||||||
|
if len(supplier_parts) > 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
supplier = Company(api, pk=supplier_id)
|
||||||
|
|
||||||
|
# Create a new supplier part for this supplier
|
||||||
|
SKU = supplier.name.upper()[0:3]
|
||||||
|
|
||||||
|
SKU += "-" + "".join(random.choice(string.digits) for _ in range(5))
|
||||||
|
SKU += "-"
|
||||||
|
SKU += "".join(random.choice(string.ascii_uppercase) for _ in range(3))
|
||||||
|
|
||||||
|
# Create a new supplier part based on randomly generated SKU
|
||||||
|
SupplierPart.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
"part": part.pk,
|
||||||
|
"supplier": supplier.pk,
|
||||||
|
"SKU": SKU,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now, ensure that each SupplierPart has some associated price break information
|
||||||
|
supplier_parts = SupplierPart.list(api, part=part.pk)
|
||||||
|
|
||||||
|
for sp in supplier_parts:
|
||||||
|
price_breaks = SupplierPriceBreak.list(api, part=sp.pk)
|
||||||
|
|
||||||
|
# Skip for any supplier pars which already have price-break information
|
||||||
|
if len(price_breaks) > 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
currency = currencies.get(sp.supplier, 'USD')
|
||||||
|
|
||||||
|
# Start with the highest price break for 1000x
|
||||||
|
pb_1000 = 0.0025 + random.random() * 0.025
|
||||||
|
pb_100 = pb_1000 * (10 + random.random() * 1.25)
|
||||||
|
pb_1 = pb_100 * (10 + random.random() * 2.5)
|
||||||
|
|
||||||
|
SupplierPriceBreak.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
"part": sp.pk,
|
||||||
|
"quantity": 1,
|
||||||
|
"price": round(pb_1, 4),
|
||||||
|
"price_currency": currency
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
SupplierPriceBreak.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
"part": sp.pk,
|
||||||
|
"quantity": 100,
|
||||||
|
"price": round(pb_100, 4),
|
||||||
|
"price_currency": currency
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
SupplierPriceBreak.create(
|
||||||
|
api,
|
||||||
|
{
|
||||||
|
"part": sp.pk,
|
||||||
|
"quantity": 1000,
|
||||||
|
"price": round(pb_1000, 4),
|
||||||
|
"price_currency": currency
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
bar.finish()
|