| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- from django.db import models
- from django.utils.html import format_html
- from django.contrib.postgres.fields import HStoreField, ArrayField
- from taggit.managers import TaggableManager
- from django.contrib.auth.models import User
- from django.db.models.signals import post_save
- from django.dispatch import receiver
- from mptt.models import MPTTModel, TreeForeignKey, TreeManyToManyField
- from djrichtextfield.models import RichTextField
- from django_editorjs_fields import EditorJsJSONField # Django >= 3.1
- from django_editorjs_fields import EditorJsTextField
- from filebrowser.fields import FileBrowseField
- import qrcode
- import base64
- import uuid
- from django.conf import settings
- from django_google_maps.fields import AddressField, GeoLocationField
- from phonenumber_field.modelfields import PhoneNumberField
- # Create your models here.
- PROCESS = "process"
- STATUS_CHOICES = [
- ('process', 'Process'),
- ('fn', 'Finished'),
- ('purchase', 'Purchase')
- ]
- GENDER_CHOICES = [
- ('na', 'N/A'),
- ('lgbt', 'LGBT'),
- ('male', 'Male'),
- ('female', 'Female'),
- ]
- MENU_GROUP_CHOICES = [
- ('primary', 'Primary'),
- ('footer', 'Footer'),
- ('secondary', 'Secondary'),
- ]
- class Profile(models.Model):
- STORE_OWNER = 1
- CHEF = 2
- EMPLOYEE = 3
- ROLE_CHOICES = (
- (STORE_OWNER, 'Store Owner'),
- (CHEF, 'Chef'),
- (EMPLOYEE, 'Employee'),
- )
- user = models.OneToOneField(User, on_delete=models.CASCADE)
- location = models.CharField(max_length=30, blank=True)
- birthdate = models.DateField(null=True, blank=True)
- role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
- store = models.ForeignKey('Store', on_delete=models.CASCADE, null=True, blank=False)
- def __str__(self): # __unicode__ for Python 2
- return self.user.username
- @receiver(post_save, sender=User)
- def create_or_update_user_profile(sender, instance, created, **kwargs):
- if created:
- Profile.objects.create(user=instance)
- else:
- try:
- instance.profile.save()
- except:
- Profile.objects.create(user=instance)
- class GeneralField(models.Model):
- created_at = models.DateTimeField(auto_now_add=True)
- updated_at = models.DateTimeField(auto_now=True)
- owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
- class Meta:
- abstract = True
- class ProcesslField(models.Model):
- inProcess = models.CharField(max_length=100, blank=True, null=True)
- status = models.CharField(max_length=100,choices=STATUS_CHOICES,default=PROCESS)
- class Meta:
- abstract = True
- class MenuItem(GeneralField, models.Model):
- name = models.CharField(max_length=100)
- tagline = models.TextField(blank=True, null=True)
- store = models.ForeignKey('Store', on_delete=models.CASCADE)
- qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
- featureImage = models.ImageField(upload_to='uploads/%Y/%m/%d/', blank=True, null=True)
- description = models.TextField(blank=True, null=True)
- '''
- photos = ArrayField(
- models.FileField(upload_to='uploads/%Y/%m/%d/'),
- size=8,blank=True,null=True)
- '''
- def __str__(self):
- return self.name
- def save(self, *args, **kwargs):
- self.qrCode.name = self.genCode()
- super(MenuItem, self).save(*args, **kwargs)
- @property
- def qrImage(self):
- if self.qrCode:
- return format_html('<img src="{}" width="100%">', self.qrCode.url)
- else:
- return "-"
- def genCode(self):
- img = qrcode.make(f"{self.store.name}#{self.name}#{self.id}")
- rid = uuid.uuid4().hex
- path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
- rpath = f"qr/{rid}.png"
- img.save(path)
- return rpath
- class Ingredient(GeneralField, models.Model):
- name = models.CharField(max_length=200)
- qty = models.DecimalField(decimal_places=2, max_digits=5)
- unit = models.CharField(max_length=10)
- comment = models.TextField(blank=True, null=True)
- menu = models.ForeignKey('MenuItem', on_delete=models.CASCADE)
- class Store(GeneralField, models.Model):
- name = models.CharField(max_length=100, blank=False, null=False, default="Unititled")
- addressText = models.TextField(blank=True, null=True)
- province = models.CharField(max_length=100, blank=True, null=True)
- storeType = models.CharField("Store Type", max_length=100, blank=True, null=True)
- qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
- description = models.TextField(blank=True, null=True)
- address = AddressField(max_length=100, null=True, blank=True)
- geolocation = GeoLocationField(blank=True, null=True)
- logo = models.ImageField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
- phone_number = PhoneNumberField(blank=True, null=True)
- fax_number = PhoneNumberField(blank=True, null=True)
- lineId = models.CharField(max_length=100, blank=True, null=True)
- email = models.EmailField(max_length=200, blank=True, null=True)
- '''
- photos = ArrayField(
- models.FileField(upload_to='uploads/%Y/%m/%d/'),
- size=8,blank=True,null=True)
- '''
- def __str__(self):
- return f"{self.name}"
- def save(self, *args, **kwargs):
- self.qrCode.name = self.genCode()
- super(Store, self).save(*args, **kwargs)
- @property
- def qrImage(self):
- if self.qrCode:
- return format_html('<img src="{}" width="100%">', self.qrCode.url)
- else:
- return "-"
- def genCode(self):
- img = qrcode.make(f"{self.name}#{self.id}")
- rid = uuid.uuid4().hex
- path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
- rpath = f"qr/{rid}.png"
- img.save(path)
- return rpath
- class Table(GeneralField, models.Model):
- store = models.ForeignKey('Store', on_delete=models.CASCADE)
- code = models.CharField(max_length=100, default="N\A")
- nSeats = models.IntegerField(default=1)
- occupy = models.BooleanField(default=False)
- qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
- def __str__(self):
- return f"{self.code}"
- def save(self, *args, **kwargs):
- self.qrCode.name = self.genCode()
- super(Table, self).save(*args, **kwargs)
- @property
- def qrImage(self):
- if self.qrCode:
- return format_html('<img src="{}" width="100%">', self.qrCode.url)
- else:
- return "-"
- def genCode(self):
- img = qrcode.make(f"{self.store.name}#{self.code}")
- rid = uuid.uuid4().hex
- path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
- rpath = f"qr/{rid}.png"
- img.save(path)
- return rpath
- class BookingTable(GeneralField, models.Model):
- table = models.ForeignKey(Table, on_delete=models.CASCADE)
- onDate = models.DateField(null=True)
- onTime = models.TimeField(null=True)
- note = models.TextField(blank=True, null=True)
- store = models.ForeignKey('Store', on_delete=models.CASCADE, null=True)
- qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
- def __str__(self):
- return f"{self.table}@{self.onDate}({self.note})"
- def save(self, *args, **kwargs):
- self.qrCode.name = self.genCode()
- super(BookingTable, self).save(*args, **kwargs)
- @property
- def qrImage(self):
- if self.qrCode:
- return format_html('<img src="{}" width="100%">', self.qrCode.url)
- else:
- return "-"
- def genCode(self):
- img = qrcode.make(f"{self.store.name}#{self.table.code}#{self.onDate}@{self.onTime}")
- rid = uuid.uuid4().hex
- path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
- rpath = f"qr/{rid}.png"
- img.save(path)
- return rpath
- class Order(GeneralField, models.Model):
- PURCHASE = 'purchase'
- table = models.ForeignKey(Table, null=True, on_delete=models.SET_NULL)
- note = models.TextField(blank=True, null=True)
- store = models.ForeignKey('Store', on_delete=models.SET_NULL, default=None, null=True)
- #items = models.ManyToManyField(MenuItem)
- qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
- def save(self, *args, **kwargs):
- self.qrCode.name = self.genCode()
- super(Order, self).save(*args, **kwargs)
- @property
- def qrImage(self):
- if self.qrCode:
- return format_html('<img src="{}" width="100%">', self.qrCode.url)
- else:
- return "-"
- def genCode(self):
- img = qrcode.make(f"{self.store.name}#{self.table.code}#{self.id}")
- rid = uuid.uuid4().hex
- path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
- rpath = f"qr/{rid}.png"
- img.save(path)
- return rpath
- class OrderItem(GeneralField, models.Model):
- item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
- qty = models.IntegerField(default=1)
- order = models.ForeignKey(Order, on_delete=models.CASCADE)
- note = models.TextField(blank=True, null=True)
- store = models.ForeignKey('Store', on_delete=models.SET_NULL, default=None, null=True)
- @property
- def store_items(self):
- return MenuItem.objects.filter(store = order.store)
- class StoreFile(GeneralField, models.Model):
- store = models.ForeignKey('Store', on_delete=models.CASCADE)
- storeFile = models.FileField(upload_to='uploads/%Y/%m/%d/')
- tags = TaggableManager(blank=True)
- class MenuFile(GeneralField, models.Model):
- menuItem = models.ForeignKey('MenuItem', on_delete=models.CASCADE, null=True)
- menuFile = models.FileField(upload_to='uploads/%Y/%m/%d/')
- tags = TaggableManager(blank=True)
- class Setting(GeneralField, models.Model):
- store = models.OneToOneField(Store, on_delete=models.CASCADE, primary_key=True)
- data = HStoreField(blank=True, null=True)
- note = models.CharField(max_length=200, blank=True, null=True)
- class UIMenu(GeneralField,MPTTModel, models.Model):
- name = models.CharField(max_length=200)
- parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
- group = models.CharField(choices=MENU_GROUP_CHOICES, max_length=200, default='primary')
- url = models.CharField(max_length=200)
- icon = models.CharField(max_length=100, blank=True, null=True, default='file')
- store = models.ForeignKey('Store', on_delete=models.CASCADE, default=None, null=True)
- nOrder = models.IntegerField(default=1)
- class MPTTMeta:
- order_insertion_by = ['-nOrder']
- def __str__(self):
- return f"{self.name}"
- class PostCategory(MPTTModel, models.Model):
- name = models.CharField(max_length=200)
- parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
- class MPTTMeta:
- order_insertion_by = ['name']
- def __str__(self):
- return f"{self.name}"
- class Post(GeneralField, models.Model):
- title = models.CharField(max_length=200)
- content = RichTextField(blank=True)
- description = models.TextField(blank=True, null=True)
- store = models.ForeignKey('Store', on_delete=models.CASCADE, default=None, null=True)
- category = TreeManyToManyField(PostCategory, blank=True, null=True)
- featureImage = models.ImageField(upload_to='uploads/%Y/%m/%d/', blank=True, null=True)
- tags = TaggableManager(blank=True)
- relateMenus = models.ManyToManyField('MenuItem', blank=True, null=True)
- #photos = ArrayField(models.ImageField(upload_to='uploads/%Y/%m/%d/'), blank=True, null=True)
- @property
- def cats(self):
- return ",".join([ c.name for c in self.category.all()])
- def __str__(self):
- return f"{self.title}"
- class PostFile(GeneralField, models.Model):
- post = models.ForeignKey('Post', on_delete=models.CASCADE)
- file = models.FileField(upload_to='uploads/%Y/%m/%d/')
- tags = TaggableManager(blank=True)
- class Customer(GeneralField, models.Model):
- fullName = models.CharField(max_length=200)
- email = models.EmailField(blank=True, null=True)
- lineId = models.CharField(max_length=100, blank=True, null=True)
- gender = models.CharField(choices=GENDER_CHOICES, default='na', max_length=40)
- store = models.ForeignKey('Store', on_delete=models.CASCADE, default=None, null=True)
- qrCode = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
- def save(self, *args, **kwargs):
- self.qrCode.name = self.genCode()
- super(Customer, self).save(*args, **kwargs)
- @property
- def qrImage(self):
- if self.qrCode:
- return format_html('<img src="{}" width="100%">', self.qrCode.url)
- else:
- return "-"
- def genCode(self):
- img = qrcode.make(f"{self.fullName}#{self.email}#{self.lineId}#{self.store.name}")
- rid = uuid.uuid4().hex
- path = settings.MEDIA_ROOT+f"/qr/{rid}.png"
- rpath = f"qr/{rid}.png"
- img.save(path)
- return rpath
- class Message(GeneralField, MPTTModel, models.Model):
- subject = models.CharField(max_length=255)
- email = models.EmailField()
- lineId = models.CharField(max_length=200, blank=True, null=True)
- body = models.TextField()
- reply = models.TextField(blank=True, null=True)
- store = models.ForeignKey("Store", on_delete=models.CASCADE)
- parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
- tel = PhoneNumberField(blank=True, null=True)
- messageFile = models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/')
- def __str__(self):
- return f"{self.subject} {self.created_at}"
- class Code(GeneralField, models.Model):
- store = models.OneToOneField('Store', on_delete=models.CASCADE, default=None, null=True)
- jsCode = models.TextField(blank=True)
- cssCode = models.TextField(blank=True)
- pluginCode = models.TextField(blank=True)
- # body_default = models.TextField()
- # body_editorjs = EditorJsJSONField(
- # plugins=[
- # "@editorjs/image",
- # "@editorjs/header",
- # "editorjs-github-gist-plugin",
- # "@editorjs/code@2.6.0", # version allowed :)
- # "@editorjs/list@latest",
- # "@editorjs/inline-code",
- # "@editorjs/table",
- # '@editorjs/raw',
- # '@editorjs/embed',
- # ],
- # ) # Django >= 3.1
- # body_editorjs_text = EditorJsTextField()
- # image = FileBrowseField("Image", max_length=200, directory="images/", extensions=[".jpg"], blank=True)
- # document = FileBrowseField("PDF", max_length=200, directory="documents/", extensions=[".pdf",".doc"], blank=True)
- # code = models.TextField(blank=True)
|