123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- from decimal import Decimal
- from django.contrib.localflavor.us.us_states import STATE_CHOICES
- from django.db import models
- from django.contrib.auth.models import User
- from django_countries.countries import COUNTRIES
- from billing.models import GCNewOrderNotification, AmazonFPSResponse
- from catalog.models import Item
- from pbp_core.models import TimeStampedModel
- from . import constants
- from . import managers
- class BaseOrderInfo(TimeStampedModel):
- """ base class for storing customer order information """
- class Meta:
- abstract = True
- # contact info
- email = models.EmailField(max_length=50, null=True, blank=True)
- phone = models.CharField(max_length=20, null=True, blank=True)
- # shipping information
- shipping_name = models.CharField(max_length=50, null=True, blank=True)
- shipping_address_1 = models.CharField(max_length=50, null=True, blank=True)
- shipping_address_2 = models.CharField(max_length=50, null=True, blank=True)
- shipping_city = models.CharField(max_length=50, null=True, blank=True)
- shipping_state = models.CharField(max_length=2, null=True, blank=True)
- shipping_country = models.CharField(max_length=50, null=True, blank=True)
- shipping_zip = models.CharField(max_length=10, null=True, blank=True)
- # billing information
- billing_name = models.CharField(max_length=50, null=True, blank=True)
- billing_address_1 = models.CharField(max_length=50, null=True, blank=True)
- billing_address_2 = models.CharField(max_length=50, null=True, blank=True)
- billing_city = models.CharField(max_length=50, null=True, blank=True)
- billing_state = models.CharField(max_length=2, null=True, blank=True)
- billing_country = models.CharField(max_length=50, null=True, blank=True)
- billing_zip = models.CharField(max_length=10, null=True, blank=True)
- class Order(BaseOrderInfo):
- """ model class for storing a customer order instance """
- # each individual status
- INIT = 0
- SUBMITTED = 1
- PROCESSED = 2
- SHIPPED = 3
- CANCELLED = 4
- # set of possible order statuses
- ORDER_STATUSES = (
- (INIT, "Initialized"),
- (SUBMITTED, "Submitted"),
- (PROCESSED, "Processed"),
- (SHIPPED, "Shipped"),
- (CANCELLED, "Cancelled"),
- )
- # order info
- date = models.DateTimeField(auto_now_add=True)
- status = models.IntegerField(choices=ORDER_STATUSES, default=INIT)
- ip_address = models.IPAddressField(null=True, blank=True)
- last_updated = models.DateTimeField(auto_now=True)
- user = models.ForeignKey(User, null=True, blank=True)
- transaction_id = models.CharField(max_length=20, null=True, blank=True)
- cart_id = models.CharField(max_length=50, null=True, blank=True)
- objects = managers.OrderManager()
- def __unicode__(self):
- return u"Order #" + str(self.id)
- @property
- def get_status(self):
- for enum, value in self.ORDER_STATUSES:
- if self.status == enum:
- return value
- @property
- def has_items(self):
- return self.item_count > 0
- @property
- def item_count(self):
- return self.items.count()
- @property
- def order_items(self):
- return self.items.all()
- @property
- def subscription_items(self):
- """ return only the subscriptions """
- for item in self.order_items:
- if item.is_subscription:
- yield item
- @property
- def subtotal(self):
- total = Decimal("0.00")
- for item in self.order_items:
- total += item.total
- return total
- @property
- def shipping_total(self):
- ship_cost = Decimal(0.0)
- for item in self.order_items:
- ship_cost = ship_cost + item.shipping_cost
- return ship_cost
- @property
- def total(self):
- return self.subtotal + self.shipping_total
- @models.permalink
- def get_absolute_url(self):
- return "view_order_detail", (), {"order_number": self.pk}
- def delete_items(self):
- """ delete all orderItems for this order """
- OrderItem.objects.filter(order=self).delete()
- class OrderPayment(TimeStampedModel):
- order = models.OneToOneField(Order)
- amazon_payment = models.ForeignKey(
- AmazonFPSResponse, related_name="order_payment", blank=True, null=True
- )
- google_payment = models.ForeignKey(
- GCNewOrderNotification, related_name="order_payment", blank=True, null=True
- )
- @property
- def is_amazon(self):
- if self.amazon_payment:
- return True
- return False
- @property
- def is_google(self):
- if self.google_payment:
- return True
- return False
- @property
- def shipping_state(self):
- if self.is_google:
- return self.google_payment.fulfillment_order_state
- return "N/A"
- @property
- def payment_state(self):
- if self.is_google:
- return self.google_payment.financial_order_state
- return "N/A"
- class OrderItemGiftDetail(TimeStampedModel):
- first_name = models.CharField(max_length=30)
- last_name = models.CharField(max_length=30)
- company = models.CharField(max_length=30, blank=True, null=True)
- address1 = models.CharField(max_length=30)
- address2 = models.CharField(max_length=30, blank=True, null=True)
- city = models.CharField(max_length=30)
- region = models.CharField(max_length=30, choices=STATE_CHOICES)
- phone = models.CharField(max_length=30)
- country = models.CharField(max_length=30, choices=COUNTRIES)
- postal_code = models.CharField(max_length=30)
- plus_four = models.CharField(max_length=4)
- email = models.CharField(max_length=30)
- bill_on_renewal = models.CharField(
- max_length=10, choices=constants.BILL_CHOICES, default=constants.CHOOSE
- )
- gift_card_delivery = models.CharField(
- max_length=10,
- choices=constants.GIFT_CARD_DELIVERY_CHOICES,
- default=constants.GIFT_CARD_NONE,
- )
- message = models.CharField(max_length=72, null=True, blank=True)
- class OrderItem(TimeStampedModel):
- """ store each Product instance purchased in each order """
- product = models.ForeignKey(Item)
- quantity = models.IntegerField(default=1)
- price = models.DecimalField(max_digits=9, decimal_places=2)
- order = models.ForeignKey(Order, related_name="items")
- gift_detail = models.OneToOneField(OrderItemGiftDetail, null=True, blank=True)
- account_number = models.CharField(max_length=7, null=True, blank=True)
- @property
- def is_gift(self):
- if self.gift_detail:
- return True
- return False
- @property
- def is_subscription(self):
- if self.product.is_subscription:
- return True
- return False
- @property
- def total(self):
- return self.quantity * self.price
- @property
- def name(self):
- return self.product.title
- @property
- def long_description(self):
- return self.product.long_description
- @property
- def sku(self):
- return self.product.sku
- def __unicode__(self):
- return self.product.title + " (" + self.product.sku + ")"
- @property
- def shipping_cost(self):
- """ Shipping costs. If there is just one item take the shipping_cost
- from the product, if there is more then one, for each item after the
- first one, the shipping cost is shipping_cost_multiple for each item
- total them together to get the total shipping cost
- """
- initial_cost = self.product.shipping_cost
- if self.quantity == 0:
- return 0.0
- if self.quantity == 1:
- return initial_cost
- elif self.quantity > 1:
- return initial_cost + (
- (self.quantity - 1) * self.product.shipping_cost_multiple
- )
- @property
- def total_plus_shipping(self):
- return self.total + self.shipping_cost
|