""" Catalog models """ from django.conf import settings from django.db import models from django.core.urlresolvers import reverse from django.utils.text import Truncator from sorl import thumbnail from catalog.constants import ( SHIPPING_TYPES, INSTATE, REGULAR, SHIPPING_METHODS) from catalog.managers import ( ItemManager, PersonManager, SubscriptionManager, ZipCodeManager) from pbp_core.models import OperationalTable from pbp_core.slugify import unique_slugify MEDIA_DIRECTORY = settings.MEDIA_ROOT class Item(OperationalTable): """ Item model """ title = models.CharField(max_length=50) long_description = models.TextField(blank=True, null=True) synopsis = models.CharField(max_length=200, blank=True, null=True) image = thumbnail.ImageField(upload_to='images/sorl', blank=True, null=True) price = models.DecimalField(max_digits=7, decimal_places=2) # shipping cost for one item shipping_cost = models.DecimalField(max_digits=7, decimal_places=2) # shipping cost for each item after 1. shipping_cost_multiple = models.DecimalField(max_digits=7, decimal_places=2) subclass_type = models.CharField(max_length=200, editable=False) sku = models.SlugField(max_length=20, unique=True) # logical delete Might cause confusion if they want to reuse # the SKU again since that is required to be unique. deleted = models.BooleanField(default=False) featured = models.BooleanField(default=False) tax_free = models.BooleanField(default=False) objects = ItemManager() def __unicode__(self): """ unicode repr of class """ return unicode(self.title) def save(self, *args, **kwargs): """ save the model """ # save what kind we are. self.subclass_type = self.__class__.__name__.lower() super(Item, self).save(*args, **kwargs) def child(self): """ get the child """ return getattr(self, self.subclass_type) @property def is_book(self): """ are we a book """ return self.subclass_type == Book.__name__.lower() @property def is_movie(self): """ are we a movie """ return self.subclass_type == Movie.__name__.lower() @property def is_map(self): """ is it a map """ return self.subclass_type == Map.__name__.lower() @property def is_subscription(self): """ is subscription """ return self.subclass_type == Subscription.__name__.lower() @property def category(self): """ Return a string name for the category the item is in.""" if self.is_book(): return "book" elif self.is_movie(): return "movie" elif self.is_map(): return "map" elif self.is_subscription(): return "subscription" else: return None @property def edit_link(self): """ get the edit link """ return self.child().edit_link def get_absolute_url(self): """ get absolute url """ return reverse('item_detail', kwargs={'sku': self.sku}) @property def short_description(self): return Truncator(self.long_description).words(25, truncate=' ...') @property def description(self): return self.long_description class Person(OperationalTable): """ Person Model """ name = models.CharField(max_length=60) slug = models.SlugField(max_length=60, unique=True) title = models.CharField(max_length=60, null=True, blank=True, default='') image = thumbnail.ImageField(upload_to='images/sorl', blank=True, null=True) description = models.TextField(null=True, blank=True, default='') # logical delete Might cause confusion if they want to reuse # the SKU again since that is required to be unique. deleted = models.BooleanField(default=False) objects = PersonManager() def __repr__(self): return u"{0}(name={1}".format(self.__class__, self.name) def __str__(self): return u"{0}".format(self.name) if not self.title \ else u"{0}, {1}".format(self.name, self.title) @property def edit_link(self): """ get the edit link """ try: return reverse('person_edit', kwargs={'person_slug': self.slug}) except Exception, e: print e def save(self, *args, **kwargs): if not self.slug: unique_slugify(self, self.name) super(Person, self).save(*args, **kwargs) class Book(Item): """ Book model """ subtitle = models.CharField(max_length=100, blank=True, null=True) authors = models.ManyToManyField(Person, blank=True, null=True) editors = models.CharField(max_length=200, blank=True, null=True) illustrator = models.CharField(max_length=200, blank=True, null=True) publisher = models.CharField(max_length=200, blank=True, null=True) printer = models.CharField(max_length=200, blank=True, null=True) publish_date = models.CharField(max_length=20, blank=True, null=True) edition = models.CharField(max_length=50, blank=True, null=True) features = models.CharField(max_length=100, blank=True, null=True) dimensions = models.CharField(max_length=20, blank=True, null=True) pages = models.IntegerField(blank=True, null=True) isbn = models.CharField(max_length=20, blank=True, null=True) library_of_congress_number = models.CharField(max_length=20, blank=True, null=True) genre = models.CharField(max_length=100, blank=True, null=True) objects = ItemManager() @property def edit_link(self): """ get the edit link """ return reverse('catalog_edit_book', kwargs={'sku': self.sku}) class Movie(Item): """ Movie model """ producer = models.CharField(max_length=200, blank=True, null=True) music = models.CharField(max_length=200, blank=True, null=True) runtime_minutes = models.IntegerField(blank=True, null=True) format = models.CharField(max_length=20, blank=True, null=True) region = models.CharField(max_length=50, blank=True, null=True) sound = models.CharField(max_length=50, blank=True, null=True) language = models.CharField(max_length=50, blank=True, null=True) captioning = models.CharField(max_length=50, blank=True, null=True) genre = models.CharField(max_length=100, blank=True, null=True) objects = ItemManager() @property def edit_link(self): """ get the edit link """ return reverse('catalog_edit_movie', kwargs={'sku': self.sku}) class Map(Item): """ Map model""" dimensions = models.CharField(max_length=20, blank=True, null=True) objects = ItemManager() @property def edit_link(self): """ get Edit link """ return reverse('catalog_edit_map', kwargs={'sku': self.sku}) class Subscription(Item): """ Subscriptions are items and are operational tables (created by, time, ect). """ shipping_type = models.CharField(max_length=10, choices=SHIPPING_TYPES, default=INSTATE) shipping_method = models.CharField(max_length=20, choices=SHIPPING_METHODS, default=REGULAR) duration = models.IntegerField() renewal = models.BooleanField(default=False) objects = SubscriptionManager() @property def edit_link(self): """ get the edit link""" return reverse('catalog_edit_subscription', kwargs={'sku': self.sku}) class ZipCode(OperationalTable): """ Zip code model """ zipcode = models.CharField(max_length=9, unique=True) city = models.CharField(max_length=64, blank=True, null=True) state = models.CharField(max_length=2, blank=True, null=True) county = models.CharField(max_length=64, blank=True, null=True) deleted = models.BooleanField(default=False) objects = ZipCodeManager() def __unicode__(self): """ unicode repr of class """ return unicode(self.zipcode)