634 lines
22 KiB
Python
634 lines
22 KiB
Python
from django.db import models
|
|
from django.utils import timezone
|
|
from django.conf import settings
|
|
|
|
from django.db.models.signals import m2m_changed
|
|
from django.dispatch import receiver
|
|
from django.db.utils import IntegrityError
|
|
|
|
from .hierarchicalData import AncestorLevelsOf, SiblingLevelsOf
|
|
|
|
from treebeard.mp_tree import MP_Node
|
|
|
|
import os
|
|
|
|
# Create your models here.
|
|
|
|
class CharNullField(models.CharField):
|
|
"""
|
|
Subclass of the CharField that allows empty strings to be stored as NULL.
|
|
This class is used to set charfield be optional but unique when added.
|
|
Set blank=True, null=True when declaring the field
|
|
"""
|
|
description = "CharField that stores NULL but returns ''."
|
|
|
|
def get_prep_value(self, value):
|
|
"""
|
|
Catches value right before sending to db.
|
|
"""
|
|
if value == '': # If Django tries to save an empty string, send the db None (NULL).
|
|
return None
|
|
else: # Otherwise, just pass the value.
|
|
return value
|
|
|
|
def from_db_value(self, value, expression, connection):
|
|
"""
|
|
Gets value right out of the db and changes it if its ``None``.
|
|
"""
|
|
if value is None:
|
|
return ''
|
|
else:
|
|
return value
|
|
|
|
def to_python(self, value):
|
|
"""
|
|
Gets value right out of the db or an instance, and changes it if its ``None``.
|
|
"""
|
|
if isinstance(value, models.CharField): # If an instance, just return the instance.
|
|
return value
|
|
if value is None: # If db has NULL, convert it to ''.
|
|
return ''
|
|
return value # Otherwise, just return the value.
|
|
|
|
class ImageNullField(models.ImageField):
|
|
"""
|
|
Subclass of the CharField that allows empty strings to be stored as NULL.
|
|
This class is used to set charfield be optional but unique when added.
|
|
Set blank=True, null=True when declaring the field
|
|
"""
|
|
description = "ImageField that stores NULL but returns ''."
|
|
|
|
def get_prep_value(self, value):
|
|
"""
|
|
Catches value right before sending to db.
|
|
"""
|
|
if value == '': # If Django tries to save an empty string, send the db None (NULL).
|
|
return None
|
|
else: # Otherwise, just pass the value.
|
|
return value
|
|
|
|
def from_db_value(self, value, expression, connection):
|
|
"""
|
|
Gets value right out of the db and changes it if its ``None``.
|
|
"""
|
|
if value is None:
|
|
return ''
|
|
else:
|
|
return value
|
|
|
|
def to_python(self, value):
|
|
"""
|
|
Gets value right out of the db or an instance, and changes it if its ``None``.
|
|
"""
|
|
if isinstance(value, models.ImageField): # If an instance, just return the instance.
|
|
return value
|
|
if value is None: # If db has NULL, convert it to ''.
|
|
return ''
|
|
return value # Otherwise, just return the value.
|
|
|
|
|
|
class ReceipeImage(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
|
|
checksum = models.CharField(
|
|
"checksum",
|
|
max_length=32,
|
|
editable=False,
|
|
unique=True,
|
|
help_text="The checksum of the original image."
|
|
)
|
|
|
|
thrashed_checksum = models.CharField(
|
|
"threshed checksum",
|
|
max_length=32,
|
|
editable=False,
|
|
unique=True,
|
|
help_text="The checksum of the thrashed image."
|
|
)
|
|
|
|
filename = models.FilePathField(
|
|
"filename",
|
|
max_length=1024,
|
|
editable=False,
|
|
default=None,
|
|
unique=True,
|
|
null=True,
|
|
help_text="Current filename in storage"
|
|
)
|
|
|
|
filename_trashed = models.FilePathField(
|
|
"filename trashed",
|
|
max_length=1024,
|
|
editable=False,
|
|
default=None,
|
|
unique=True,
|
|
null=True,
|
|
help_text="Current filename of the modified picture in storage"
|
|
)
|
|
|
|
created = models.DateTimeField(
|
|
"created",
|
|
default=timezone.now, db_index=True)
|
|
|
|
modified = models.DateTimeField(
|
|
"modified",
|
|
auto_now=True, editable=False, db_index=True)
|
|
|
|
added = models.DateTimeField(
|
|
"added",
|
|
default=timezone.now, editable=False, db_index=True)
|
|
|
|
@property
|
|
def source_path(self):
|
|
fname = str(self.filename)
|
|
|
|
return os.path.join(
|
|
settings.ORIGINALS_DIR,
|
|
fname
|
|
)
|
|
|
|
@property
|
|
def source_path_trashed(self):
|
|
fname = str(self.filename_trashed)
|
|
|
|
return os.path.join(
|
|
settings.ORIGINALS_DIR,
|
|
fname
|
|
)
|
|
|
|
@property
|
|
def source_file(self):
|
|
return open(self.source_path, "rb")
|
|
|
|
@property
|
|
def source_file_trashed(self):
|
|
return open(self.source_path_trashed, "rb")
|
|
|
|
class Allergenes(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("allergene name", max_length=50, unique=True)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.name
|
|
|
|
class Brand(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("brand name", max_length=50, unique=True)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.name
|
|
|
|
class Packaging(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("packaging name", max_length=50, unique=True)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.name
|
|
|
|
|
|
class Ingredients(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("ingredient name", max_length=100)
|
|
allergenes = models.ManyToManyField(Allergenes, blank=True)
|
|
vegan = models.BooleanField("vegan?",default=False)
|
|
vegetarian = models.BooleanField("vegetarian?",default=False)
|
|
palmoilfree = models.BooleanField("Palm oil free?",default=True)
|
|
additive = models.BooleanField("Additiv?",default=False)
|
|
eNumber = CharNullField("E number", max_length=7,null=True, blank=True)
|
|
subIngredients = models.ManyToManyField('self', blank=True, symmetrical=False)
|
|
|
|
#class Meta:
|
|
# unique_together = ('name', 'subIngredients',)
|
|
|
|
def __unicode__(self):
|
|
return "Ingredients: "+str(self.id)+" "+self.name
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.name
|
|
|
|
@receiver(m2m_changed, sender=Ingredients.subIngredients.through)
|
|
def verify_uniqueness(sender, **kwargs):
|
|
ingredient = kwargs.get('instance', None)
|
|
action = kwargs.get('action', None)
|
|
subIngredients = kwargs.get('pk_set', None)
|
|
|
|
if action == 'pre_add':
|
|
for subIngredient in subIngredients:
|
|
if Ingredients.objects.filter(name=ingredient.name).filter(subIngredients=subIngredient):
|
|
raise IntegrityError('Ingredient with name %s already exists for subIngredient %s' % (ingredient.name, Ingredients.objects.get(pk=subIngredient)))
|
|
|
|
class Traces(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("trace name", max_length=50, unique=True)
|
|
|
|
class Labels(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("label name", max_length=50, unique=True)
|
|
|
|
class EMBs(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("emb name", max_length=50, unique=True)
|
|
|
|
class ManufacturingPlaces(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("manufacturing places name", max_length=50, unique=True)
|
|
|
|
class OriginIngredients(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("origin of igredients", max_length=50, unique=True)
|
|
|
|
class Category(MP_Node):
|
|
name = models.CharField("category name",max_length=30,unique=True)
|
|
|
|
node_order_by = ['name']
|
|
|
|
def __str__(self):
|
|
return 'Category: {}'.format(self.name)
|
|
|
|
|
|
class Nutrient(models.Model):
|
|
name = models.CharField("nutrient name", max_length=50, unique=True)
|
|
isMacroNutrient = models.BooleanField("Is macronutrient?", default=False)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.name
|
|
|
|
class NutrientAlias(models.Model):
|
|
nutrient = models.ForeignKey(
|
|
Nutrient,
|
|
on_delete=models.CASCADE,
|
|
verbose_name="Nutrient"
|
|
)
|
|
name = models.CharField("nutrient alias name", max_length=50, unique=True)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.name
|
|
|
|
#-------------------------------------------------------------------------------
|
|
class Article(models.Model):
|
|
#RowId = models.IntegerField(primary_key=True)
|
|
name = models.CharField("article name", max_length=100)
|
|
|
|
|
|
brand = models.ForeignKey(
|
|
Brand,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name="brand id"
|
|
)
|
|
|
|
EAN = CharNullField(
|
|
"EAN", max_length=50,
|
|
unique=True,
|
|
blank=True,
|
|
null=True
|
|
)
|
|
offlink = models.URLField("Open Food Fact link", blank=True, null=True)
|
|
|
|
category = models.ForeignKey(
|
|
Category,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name="category id"
|
|
)
|
|
|
|
quantityPerPackage = models.PositiveIntegerField("quantity per packages", blank=True, null=True)
|
|
unit = CharNullField("unit",max_length=4, blank=True, null=True)
|
|
novaGroup = models.PositiveIntegerField("NOVA group", blank=True, null=True)
|
|
nutritionGrade = models.CharField("nutri grade",max_length=1, blank=True, null=True)
|
|
ecoGrade = models.CharField("eco grade",max_length=1, blank=True, null=True)
|
|
MwSt = models.PositiveIntegerField("taxes", blank=True, null=True)
|
|
|
|
allergenes = models.ManyToManyField(Allergenes, blank=True)
|
|
ingredients = models.ManyToManyField(Ingredients, through='IngredientsArticle', blank=True)
|
|
traces = models.ManyToManyField(Traces, blank=True)
|
|
embs = models.ManyToManyField(EMBs, blank=True)
|
|
manufacturingPlaces = models.ManyToManyField(ManufacturingPlaces, blank=True)
|
|
originIngredients = models.ManyToManyField(OriginIngredients, blank=True)
|
|
|
|
packagings = models.ManyToManyField(Packaging, through='PackagingArticle', blank=True)
|
|
|
|
nutrients = models.ManyToManyField(Nutrient, through='NutrientArticle', blank=True)
|
|
|
|
labels = models.ManyToManyField(Labels, blank=True)
|
|
|
|
models.ForeignKey(
|
|
Category,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name="category id"
|
|
)
|
|
|
|
created = models.DateTimeField(
|
|
"created",
|
|
default=timezone.now,
|
|
db_index=True)
|
|
|
|
modified = models.DateTimeField(
|
|
"modified",
|
|
auto_now=True,
|
|
editable=False,
|
|
db_index=True)
|
|
|
|
|
|
|
|
nutritionImage = models.ImageField(
|
|
"nutriton image filepath",
|
|
default=None,
|
|
#unique=True,
|
|
blank=True,
|
|
null=True,
|
|
help_text="Nutrition image",
|
|
upload_to='nutritionImages'
|
|
)
|
|
|
|
ingredientsImage = models.ImageField(
|
|
"ingredients image filepath",
|
|
default=None,
|
|
#unique=True,
|
|
blank=True,
|
|
null=True,
|
|
help_text="Ingredients image",
|
|
upload_to='ingredientsImages'
|
|
)
|
|
|
|
frontImage = models.ImageField(
|
|
"front image",
|
|
default=None,
|
|
#unique=True,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Front image",
|
|
upload_to='frontImages'
|
|
)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.name
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
class IngredientsArticle(models.Model):
|
|
ingredient = models.ForeignKey(
|
|
Ingredients,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.CASCADE,
|
|
verbose_name="Ingredient"
|
|
)
|
|
|
|
article = models.ForeignKey(
|
|
Article,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.CASCADE,
|
|
verbose_name="article"
|
|
)
|
|
|
|
position = models.PositiveIntegerField("Position")
|
|
|
|
percent = models.FloatField(
|
|
"Percentage on total weight",
|
|
blank=True,
|
|
null=True,
|
|
default=None
|
|
)
|
|
|
|
#-------------------------------------------------------------------------------
|
|
class PackagingArticle(models.Model):
|
|
packaging_id = models.ForeignKey(
|
|
Packaging,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name="packaging id"
|
|
)
|
|
|
|
article_id = models.ForeignKey(
|
|
Article,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name="article id"
|
|
)
|
|
|
|
weight = models.PositiveIntegerField("weight")
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
|
|
class NutrientArticle(models.Model):
|
|
nutrient = models.ForeignKey(
|
|
Nutrient,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name="nutrient"
|
|
)
|
|
|
|
article = models.ForeignKey(
|
|
Article,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.CASCADE,
|
|
verbose_name="article"
|
|
)
|
|
|
|
value = models.DecimalField("value", max_digits=7, decimal_places=2, blank=True, null=True)
|
|
unit = models.CharField(max_length=4, blank=True, null=True)
|
|
|
|
isEstimated = models.BooleanField("Is nutrient exstimated?", default=False)
|
|
|
|
class Meta:
|
|
unique_together = ('article', 'nutrient',)
|
|
|
|
|
|
# Deprectated, will be deleted later
|
|
class NutritionalValues(models.Model):
|
|
article = models.OneToOneField(
|
|
Article,
|
|
on_delete=models.CASCADE,
|
|
primary_key=True,
|
|
)
|
|
energy = models.DecimalField("energy",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
energyUnit = models.CharField(max_length=4,blank=True, null=True,default='kJ')
|
|
fat = models.DecimalField("fat",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
fatUnit = models.CharField(max_length=2,blank=True, null=True,default='g')
|
|
saturatedFat = models.DecimalField("saturatedFat",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
saturatedFatUnit = models.CharField(max_length=2,blank=True, null=True,default='g')
|
|
carbohydrate = models.DecimalField("carbohydrate",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
carbohydrateUnit = models.CharField(max_length=2,blank=True, null=True,default='g')
|
|
sugars = models.DecimalField("sugars",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
sugarsUnit = models.CharField(max_length=2,blank=True, null=True,default='g')
|
|
dietaryFiber = models.DecimalField("dietaryFiber",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
dietaryFiberUnit = models.CharField(max_length=2,blank=True, null=True,default='g')
|
|
proteins = models.DecimalField("proteins",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
proteinsUnit = models.CharField(max_length=2,blank=True, null=True,default='g')
|
|
salt = models.DecimalField("salt",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
saltUnit = models.CharField(max_length=2,blank=True, null=True,default='g')
|
|
sodium = models.DecimalField("sodium",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
sodiumUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_a = models.DecimalField("vitamin_a",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_aUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_b1 = models.DecimalField("vitamin_b1",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_b1Unit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_b2 = models.DecimalField("vitamin_b2",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_b2Unit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_b3 = models.DecimalField("vitamin_b3",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_b3Unit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_b5 = models.DecimalField("vitamin_b5",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_b5Unit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_b7 = models.DecimalField("vitamin_b7",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_b7Unit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_b9 = models.DecimalField("vitamin_b9",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_b9Unit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_b12 = models.DecimalField("vitamin_b12",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_b12Unit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_c = models.DecimalField("vitamin_c",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_cUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_d = models.DecimalField("vitamin_d",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_dUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_e = models.DecimalField("vitamin_e",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_eUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
vitamin_k = models.DecimalField("vitamin_k",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
vitamin_kUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
potassium = models.DecimalField("potassium",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
potassiumUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
calcium = models.DecimalField("calcium",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
calciumUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
magnesium = models.DecimalField("magnesium",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
magnesiumUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
iron = models.DecimalField("iron",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
ironUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
zinc = models.DecimalField("zinc",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
zincUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
sulfat = models.DecimalField("sulfat",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
sulfatUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
chlorid = models.DecimalField("chlorid",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
chloridUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
hydrogencarbonat = models.DecimalField("hydrogencarbonat",max_digits=7,decimal_places=2,blank=True, null=True)
|
|
hydrogencarbonatUnit = models.CharField(max_length=2,blank=True, null=True)
|
|
|
|
class ReceipeString(models.Model):
|
|
name = models.CharField("receipe string", max_length=50, unique=True)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.receipeString
|
|
|
|
class ArticleMaps(models.Model):
|
|
article = models.ForeignKey(
|
|
Article,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.CASCADE,
|
|
verbose_name="article id"
|
|
)
|
|
#receipeString = models.CharField("receipe string", max_length=50)
|
|
receipeString = models.ForeignKey(
|
|
ReceipeString,
|
|
on_delete=models.CASCADE,
|
|
null=True,
|
|
verbose_name="receipe string"
|
|
)
|
|
location_x = models.PositiveIntegerField("x coordiante in image", null=True)
|
|
location_y = models.PositiveIntegerField("y coordiante in image", null=True)
|
|
location_h = models.PositiveIntegerField("height in image", null=True)
|
|
location_w = models.PositiveIntegerField("width in image", null=True)
|
|
|
|
receipeImage = models.ForeignKey(ReceipeImage, on_delete=models.CASCADE)
|
|
|
|
class Meta:
|
|
unique_together = ('article', 'receipeImage',)
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + ' ' + self.receipeString.name
|
|
|
|
class Market(models.Model):
|
|
#RowId = models.AutoField(primary_key=True)
|
|
name = models.CharField("market name", max_length=50)
|
|
street = models.CharField("street name", max_length=50)
|
|
street_number = models.PositiveIntegerField("street number")
|
|
zip_code = models.CharField("zip code", max_length=5)
|
|
city = models.CharField("city", max_length=50)
|
|
phone = CharNullField("phone number",max_length=50, blank=True, null=True)
|
|
articles = models.ManyToManyField(Article,blank=True)
|
|
created = models.DateTimeField(
|
|
"created",
|
|
default=timezone.now,
|
|
db_index=True)
|
|
|
|
modified = models.DateTimeField(
|
|
"modified",
|
|
auto_now=True,
|
|
editable=False,
|
|
db_index=True)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' ' + self.name + ' ' + self.street + ' ' + str(self.street_number) + ' ' + self.city
|
|
|
|
class Purchase(models.Model):
|
|
purchase_date = models.DateField("purchase date")
|
|
payment_type = models.CharField("payment type",max_length=10,default='EC')
|
|
total_price = models.DecimalField("total price",max_digits=7,decimal_places=2,default=0)
|
|
|
|
articles = models.ManyToManyField(Article, through='PurchaseArticle')
|
|
|
|
market = models.ForeignKey(
|
|
Market,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name="market id"
|
|
)
|
|
|
|
created = models.DateTimeField(
|
|
"created",
|
|
default=timezone.now,
|
|
db_index=True)
|
|
|
|
modified = models.DateTimeField(
|
|
"modified",
|
|
auto_now=True,
|
|
editable=False,
|
|
db_index=True)
|
|
|
|
receipeImage = models.OneToOneField(
|
|
ReceipeImage,
|
|
on_delete=models.CASCADE,
|
|
primary_key=True,
|
|
blank = True,
|
|
)
|
|
|
|
edit_finished = models.BooleanField("edit finished", default=False)
|
|
|
|
def __str__(self):
|
|
return 'PK: '+str(self.pk) + ' Datum: ' + self.purchase_date.strftime("%m/%d/%Y") + ' Preis: ' +str(self.total_price)
|
|
|
|
#-------------------------------------------------------------------------------
|
|
class PurchaseArticle(models.Model):
|
|
#shoud be renamed to article, but migrations will delete the current database
|
|
article_id = models.ForeignKey(
|
|
Article,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.CASCADE,
|
|
verbose_name="article id"
|
|
)
|
|
|
|
purchase_id = models.ForeignKey(
|
|
Purchase,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.CASCADE,
|
|
verbose_name="purchase id"
|
|
)
|
|
|
|
quantity = models.PositiveIntegerField("quantity")
|
|
net_weight = models.DecimalField("net weight",max_digits=7,decimal_places=3, blank=True, null=True)
|
|
price = models.DecimalField("price",max_digits=7,decimal_places=2,default=0)
|
|
inSale = models.BooleanField("in sale",default=False)
|
|
|