feat: define core models

This commit is contained in:
Luca 2024-11-01 00:48:15 +01:00
parent 7dd8350cec
commit 4b4a85d1aa
7 changed files with 330 additions and 0 deletions

View File

@ -1,4 +1,86 @@
from django.apps import AppConfig from django.apps import AppConfig
from django.db.models.signals import post_migrate
def create_properties(sender, **kwargs):
from .models import Property
Property.objects.get_or_create(
name="Capacitance",
defaults={
"filterable": True,
"type": Property.Type.QUANTITY,
"unit": "F",
"scale": -12,
"searchable": False,
},
)
Property.objects.get_or_create(
name="Footprint",
defaults={
"filterable": True,
"type": Property.Type.TEXT,
"unit": "",
"scale": 0,
"searchable": False,
},
)
Property.objects.get_or_create(
name="LCSC part number",
defaults={
"filterable": False,
"type": Property.Type.TEXT,
"unit": "",
"scale": 0,
"searchable": True,
},
)
Property.objects.get_or_create(
name="Inductance",
defaults={
"filterable": True,
"type": Property.Type.QUANTITY,
"unit": "H",
"scale": -6,
"searchable": False,
},
)
Property.objects.get_or_create(
name="Rated power",
defaults={
"filterable": True,
"type": Property.Type.QUANTITY,
"unit": "W",
"scale": -4,
"searchable": False,
},
)
Property.objects.get_or_create(
name="Rated voltage",
defaults={
"filterable": True,
"type": Property.Type.QUANTITY,
"unit": "V",
"scale": -3,
"searchable": False,
},
)
Property.objects.get_or_create(
name="Resistance",
defaults={
"filterable": True,
"type": Property.Type.QUANTITY,
"unit": "Ω",
"scale": -3,
"searchable": False,
},
)
class CoreConfig(AppConfig): class CoreConfig(AppConfig):
@ -6,3 +88,6 @@ class CoreConfig(AppConfig):
label = "lelcsc_core" label = "lelcsc_core"
name = "lelcsc.core" name = "lelcsc.core"
verbose_name = "core" verbose_name = "core"
def ready(self):
post_migrate.connect(create_properties, sender=self)

View File

@ -0,0 +1,156 @@
# Generated by Django 5.1.1 on 2024-09-16 22:00
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("lelcsc_core", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="Component",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("part_number", models.CharField(max_length=30)),
],
),
migrations.CreateModel(
name="Property",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=50)),
(
"filterable",
models.BooleanField(
help_text="Whether this property can be used to filter components"
),
),
(
"type",
models.CharField(
choices=[("quantity", "Quantity"), ("text", "Text")],
max_length=8,
),
),
(
"searchable",
models.BooleanField(
help_text="Whether this property should be used in search"
),
),
(
"unit",
models.CharField(
help_text="Symbol of this quantity's unit of measurement",
max_length=3,
),
),
(
"scale",
models.SmallIntegerField(
help_text="Exponent of the smallest possible value"
),
),
],
),
migrations.CreateModel(
name="Stock",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
("quantity", models.PositiveIntegerField()),
("original_quantity", models.PositiveIntegerField()),
("total_value", models.DecimalField(decimal_places=2, max_digits=8)),
("location", models.TextField()),
("owner_name", models.CharField(max_length=150)),
(
"component",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
to="lelcsc_core.component",
),
),
(
"owner",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="Value",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("text", models.TextField()),
("integer", models.BigIntegerField()),
(
"component",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="lelcsc_core.component",
),
),
(
"property",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="lelcsc_core.property",
),
),
],
options={
"unique_together": {("component", "property")},
},
),
migrations.AddField(
model_name="component",
name="properties",
field=models.ManyToManyField(
through="lelcsc_core.Value", to="lelcsc_core.property"
),
),
]

View File

@ -0,0 +1,3 @@
from .auth import OIDCUser, User
from .component import Component, Property, Value
from .stock import Stock

View File

@ -0,0 +1,62 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
class Property(models.Model):
class Type(models.TextChoices):
QUANTITY = "quantity", _("Quantity")
TEXT = "text", _("Text")
name = models.CharField(max_length=50)
filterable = models.BooleanField(
help_text=_("Whether this property can be used to filter components")
)
type = models.CharField(choices=Type, max_length=8)
searchable = models.BooleanField(
help_text=_("Whether this property should be used in search")
)
unit = models.CharField(
max_length=3, help_text=_("Symbol of this quantity's unit of measurement")
)
scale = models.SmallIntegerField(
help_text=_("Exponent of the smallest possible value")
)
def __str__(self):
return (
self.name + f" [{self.unit}]" if self.type == Property.Type.QUANTITY else ""
)
class Component(models.Model):
part_number = models.CharField(max_length=30)
properties = models.ManyToManyField(Property, through="Value")
def __str__(self):
return self.part_number
class Value(models.Model):
class Meta:
unique_together = ("component", "property")
property = models.ForeignKey(Property, on_delete=models.CASCADE)
component = models.ForeignKey(Component, on_delete=models.CASCADE)
text = models.TextField()
integer = models.BigIntegerField()
def __str__(self):
match self.property.type:
case Property.Type.QUANTITY:
s = str(integer)
scale = self.property.scale
if scale > 0:
s += "0" * scale
elif scale < 0:
s = str(integer).rjust(abs(scale) + 1, "0")
s = s[:scale] + "." + s[scale:]
return f"{s} {self.property.unit}"
case Property.Type.TEXT:
return self.text

View File

@ -0,0 +1,9 @@
from django.db import models
class HasTimestamps(models.Model):
class Meta:
abstract = True
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

View File

@ -0,0 +1,15 @@
from django.db import models
from .auth import User
from .component import Component
from .mixins import HasTimestamps
class Stock(HasTimestamps):
component = models.ForeignKey(Component, on_delete=models.PROTECT)
quantity = models.PositiveIntegerField()
original_quantity = models.PositiveIntegerField()
total_value = models.DecimalField(max_digits=8, decimal_places=2)
location = models.TextField()
owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
owner_name = models.CharField(max_length=150)