Files
procat2/procat2/models.py
2019-05-14 16:05:55 -07:00

181 lines
5.5 KiB
Python

import datetime
import json
import logging
import os.path
import re
from django.conf import settings
from django.contrib.postgres.fields import JSONField
from django.db import models
from products.models import Product
log = logging.getLogger(__name__)
class Season(models.Model):
id = models.CharField(max_length=30, primary_key=True)
name = models.CharField(max_length=100)
ordering = models.PositiveIntegerField(unique=True, default=1000)
def serialize(self):
return {
'id': self.id,
'name': self.name,
'ordering': self.ordering,
}
class Region(models.Model):
id = models.CharField(max_length=30, primary_key=True)
name = models.CharField(max_length=100)
ordering = models.PositiveIntegerField(unique=True, default=1000)
def serialize(self):
return {
'id': self.id,
'name': self.name,
'ordering': self.ordering,
}
def pretty_datetime(date):
# Oct 16 2018 10:58 am
return "{:%b %-d %Y, %-I:%M %p}".format(date)
def unix_datetime(date):
return date.timestamp()
class Catalog(models.Model):
PDF_DIR = 'catalogs'
PDF_URL = 'export/catalogs'
owner = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
season = models.ForeignKey(Season, on_delete=models.PROTECT)
region = models.ForeignKey(Region, on_delete=models.PROTECT)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True, db_index=True)
name = models.CharField(max_length=300)
public = models.BooleanField(default=False, db_index=True)
pages = models.PositiveIntegerField(default=0)
sections = models.PositiveIntegerField(default=0)
materials = models.PositiveIntegerField(default=0)
data = JSONField(null=True)
master = models.BooleanField(default=False)
show_prices = models.BooleanField(default=False)
build_progress = models.PositiveIntegerField(default=0)
# JSONField docs:
# https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/#jsonfield
def pdf_name(self):
pdf = "{}-{}-{}".format(self.season.id, self.name, self.id)
pdf = re.sub(r'\s+', r'_', pdf)
pdf = re.sub(r'[^\w\-]', r'', pdf)
pdf += '.pdf'
return pdf
def pdf_url(self):
return "http://{}/{}/{}/{}".format(settings.PUBLIC_WEB_HOST,
self.PDF_URL,
self.season.id,
self.pdf_name())
def pdf_file(self):
return os.path.join(settings.ASSET_DIR,
self.PDF_DIR,
self.season.id,
self.pdf_name())
def pdf_exists(self):
return os.path.isfile(self.pdf_file())
def summary(self):
return {
'id': self.id,
'seasonCode': self.season.id,
'regionCode': self.region.id,
'name': self.name,
'ownerName': self.owner.get_full_name(),
'public': self.public,
'updated': unix_datetime(self.updated),
'updatedPretty': pretty_datetime(self.updated),
'created': unix_datetime(self.created),
'createdPretty': pretty_datetime(self.created),
'pages': self.pages,
'sections': self.sections,
'materials': self.materials,
'master': self.master,
'show_prices': self.show_prices,
'build_progress': self.build_progress,
'pdf': self.pdf_url(),
}
def update_metadata(self):
"""Update meta properties from what's in 'data'"""
if not self.data or len(self.data) < 1:
log.warning('no data in update_metadata()')
return
data = self.data
self.name = data.get('name', '(No name)')
self.season = Season.objects.get(id=data.get('season'))
self.region = Region.objects.get(id=data.get('region'))
self.public = data.get('public', False)
self.master = data.get('master', False)
self.show_prices = data.get('show_prices', False)
# NOTE 'is_utility' in the json data is not exposed to the
# django model or placed in a separate postgres column.
# reset until pdf is made
self.build_progress = 0
# calculate some properties
sections = 0
pages = 0
materials = 0
for section in data.get('sections', []):
sections += 1
for page in section.get('pages', []):
pages += 1
for block in page:
materials += len(block.get('ids', []))
self.sections = sections
self.pages = pages
self.materials = materials
def products(self):
"""Return an unordered list of all products in the catalog."""
ids = self.product_ids()
log.info("ids: %s", ids)
# TODO filter on catalog region and season when we
# have that data
return Product.objects.filter(sap__in=ids).distinct('sap')
def product_ids(self):
"""Return an unordered list of all product ids in the catalog."""
materials = set()
if self.data and len(self.data) > 0:
for section in self.data.get('sections', []):
for page in section.get('pages', []):
for block in page:
materials = materials.union(set(block.get('ids', [])))
return materials