Exemplo n.º 1
0
class BaseOrderItem(models.Model):
    """
    A line Item for an order.
    """

    order = models.ForeignKey(get_model_string('Order'),
                              related_name='items',
                              verbose_name=_('Order'))
    product_reference = models.CharField(max_length=255,
                                         verbose_name=_('Product reference'))
    product_name = models.CharField(max_length=255,
                                    null=True,
                                    blank=True,
                                    verbose_name=_('Product name'))
    product = models.ForeignKey(get_model_string('Product'),
                                verbose_name=_('Product'),
                                null=True,
                                blank=True,
                                **f_kwargs)
    unit_price = CurrencyField(verbose_name=_('Unit price'))
    quantity = models.IntegerField(verbose_name=_('Quantity'))
    line_subtotal = CurrencyField(verbose_name=_('Line subtotal'))
    line_total = CurrencyField(verbose_name=_('Line total'))

    class Meta(object):
        abstract = True
        app_label = 'shop'
        verbose_name = _('Order item')
        verbose_name_plural = _('Order items')

    def save(self, *args, **kwargs):
        if not self.product_name and self.product:
            self.product_name = self.product.get_name()
        super(BaseOrderItem, self).save(*args, **kwargs)
Exemplo n.º 2
0
class Confirmation(models.Model):
    """
    Model to store every confirmation for successful or failed payments.
    """
    class Meta:
        verbose_name = _('IPayment Confirmation')

    shopper_id = models.IntegerField(
        verbose_name=_('Unique identifier for submitted payments'))
    vendor_comment = models.TextField(null=True, blank=True,
        verbose_name=_('Additional comments from the vendor'))
    ret_booknr = models.CharField(max_length=63,
        verbose_name=_('IPayments internal booking number'))
    ret_errorcode = models.IntegerField()
    trx_paymentmethod = models.CharField(max_length=63)
    ret_trx_number = models.CharField(max_length=63)
    ret_transdatetime = models.DateTimeField()
    ret_ip = models.IPAddressField(
        verbose_name=_('The clients IP address'))
    trx_typ = models.CharField(max_length=63)
    addr_name = models.CharField(max_length=63, verbose_name=_('Cardholder name'))
    trx_amount = CurrencyField()
    trx_remoteip_country = models.CharField(blank=True, max_length=2)
    trx_currency = models.CharField(max_length=4)
    ret_authcode = models.CharField(blank=True, max_length=63)
    trx_paymenttyp = models.CharField(max_length=63)
    ret_status = models.CharField(max_length=63)
    trxuser_id = models.IntegerField()
Exemplo n.º 3
0
class TextOptionBase(models.Model):
    """
    This part of the option is selected by the merchant - it lets him/her "flag"
    a product as being able to receive some text as an option, and sets its
    price.
    """
    name = models.CharField(
        max_length=255,
        help_text=_(
            'A name for this option - this will be displayed to the user'))
    description = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        help_text=_('A longer description for this option'))
    price = CurrencyField(
        help_text=_('Price per character for this custom text'))
    max_length = models.IntegerField()

    class Meta(object):
        abstract = True
        verbose_name = _('Text Option')
        verbose_name_plural = _('Text Options')

    def __unicode__(self):
        return self.name
Exemplo n.º 4
0
class TextOption(models.Model):
    """
    This part of the option is selected by the merchant - it lets him/her "flag"
    a product as being able to receive some text as an option, and sets its
    price.
    """
    name = models.CharField(
        max_length=255,
        help_text="A name for this option - this will be displayed to the user"
    )
    description = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        help_text='A longer description for this option')
    price = CurrencyField(
        help_text='The price for this custom text')  # The price
    max_length = models.PositiveIntegerField(
        default=0,
        help_text=
        'Limit the amount of text allowed.  A value of 0 means unlimited')
    products = models.ManyToManyField(Product, related_name='text_options')
    required = models.BooleanField(default=True, blank=True)

    def __unicode__(self):
        return self.name
Exemplo n.º 5
0
class TextOption(models.Model):
    """
    This part of the option is selected by the merchant - it lets him/her "flag"
    a product as being able to receive some text as an option, and sets its
    price.
    """
    name = models.CharField(
        max_length=255,
        help_text="A name for this option - this will be displayed to the user"
    )
    description = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        help_text='A longer description for this option')
    price = CurrencyField(
        help_text='The price for this custom text')  # The price
    #length = models.IntegerField() # TODO: make this limiting in the form
    products = models.ManyToManyField(Product, related_name='text_options')

    class Meta:
        app_label = 'shop_simplevariations'

    def __unicode__(self):
        return self.name
Exemplo n.º 6
0
class Vape(Product):
    description = models.TextField(_('Description'), null=True, blank=True)
    image = models.ImageField(upload_to=determine_upload_path, default='',
                              blank=True, null=True, verbose_name='Picture', help_text='Product picture')
    price_usa = CurrencyField(verbose_name=_('Unit price USA'))

    class Meta:
        pass
Exemplo n.º 7
0
class ExtraOrderItemPriceField(models.Model):
    """
    This will make Cart-provided extra price fields persistent since we want
    to "snapshot" their statuses at the time when the order was made
    """
    order_item = models.ForeignKey(OrderItem)
    label = models.CharField(max_length=255)
    value = CurrencyField()

    class Meta:
        app_label = 'shop'
Exemplo n.º 8
0
class OrderPayment(models.Model):
    """ 
    A class to hold basic payment information. Backends should define their own 
    more complex payment types should they need to store more informtion
    """
    order = models.ForeignKey(Order)
    amount = CurrencyField()# How much was payed with this particular transfer
    transaction_id = models.CharField(max_length=255, help_text="The transaction processor's reference")
    payment_method= models.CharField(max_length=255, help_text="The payment backend use to process the purchase")
    
    class Meta:
        app_label = 'shop'
Exemplo n.º 9
0
class OrderItem(models.Model):
    '''
    A line Item for an order.
    '''
    
    order = models.ForeignKey(Order, related_name='items')
    
    product_reference = models.CharField(max_length=255)
    product_name = models.CharField(max_length=255)
    unit_price = CurrencyField()
    quantity = models.IntegerField()
    
    line_subtotal = CurrencyField()
    line_total = CurrencyField()
    
    class Meta:
        app_label = 'shop'
    
    @property
    def product(self):
        return Product.objects.get(pk=self.product_reference)
Exemplo n.º 10
0
class BaseProduct(PolymorphicModel):
    """
    A basic product for the shop.

    Most of the already existing fields here should be generic enough to reside
    on the "base model" and not on an added property.
    """

    name = models.CharField(max_length=255, verbose_name=_('Name'))
    active = models.BooleanField(default=False, verbose_name=_('Active'))
    date_added = models.DateTimeField(auto_now_add=True,
                                      verbose_name=_('Date added'))
    last_modified = models.DateTimeField(auto_now=True,
                                         verbose_name=_('Last modified'))
    unit_price = CurrencyField(verbose_name=_('Unit price'))

    class Meta(object):
        abstract = True
        app_label = 'shop'
        verbose_name = _('Product')
        verbose_name_plural = _('Products')

    def __unicode__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('product_detail', args=[self.slug])

    def get_unit_price(self):
        """
        Returns the price for this item (provided for extensibility).
        """
        return self.unit_price

    def get_price(self):
        return self.get_unit_price()  # backwards compatibility, deprecated

    def get_name(self):
        """
        Returns the name of this Product (provided for extensibility).
        """
        return self.name

    def get_product_reference(self):
        """
        Returns product reference of this Product (provided for extensibility).
        """
        return unicode(self.pk)

    @property
    def can_be_added_to_cart(self):
        return self.active
Exemplo n.º 11
0
class ExtraOrderItemPriceField(models.Model):
    """
    This will make Cart-provided extra price fields persistent since we want
    to "snapshot" their statuses at the time when the order was made
    """
    order_item = models.ForeignKey(OrderItem, verbose_name=_('Order item'))
    label = models.CharField(max_length=255, verbose_name=_('Label'))
    value = CurrencyField(verbose_name=_('Amount'))

    class Meta(object):
        app_label = 'shop'
        verbose_name = _('Extra order item price field')
        verbose_name_plural = _('Extra order item price fields')
Exemplo n.º 12
0
class Option(models.Model):
    '''
    A product option. Examples:

    "Red": 10$
    "Blue": 5$
    ...
    '''
    name = models.CharField(max_length=255)
    price = CurrencyField()  # Can be negative
    group = models.ForeignKey(OptionGroup)

    def __unicode__(self):
        return self.name
Exemplo n.º 13
0
class ExtraOrderPriceField(models.Model):
    '''
    This will make Cart-provided extra price fields persistent since we want
    to "snapshot" their statuses at the time when the order was made
    '''
    order = models.ForeignKey(Order)
    label = models.CharField(max_length=255)
    value = CurrencyField()
    
    # Does this represent shipping costs?
    is_shipping = models.BooleanField(default=False, editable=False)

    class Meta:
        app_label = 'shop'
Exemplo n.º 14
0
class OptionBase(models.Model):
    '''
    A product option. Example: Red, 10.0; Green: 20.0; Blue, 30.0;
    '''
    name = models.CharField(max_length=255)
    price = CurrencyField()  # Can be negative
    group = models.ForeignKey(OptionGroup)

    class Meta:
        abstract = True
        verbose_name = _('Group Option')
        verbose_name_plural = _('Group Options')

    def __unicode__(self):
        return self.name
Exemplo n.º 15
0
class Price(models.Model):
    """
    A class representing a Price. A price is made of a value (the numerical
    part), and a currency. They are tied to a product.
    """
    # Product is polymorphic, so this is actually a key to a Product subclasses
    product = models.ForeignKey(Product)
    value = CurrencyField()  # What a poor naming choice :(
    currency = models.ForeignKey(Currency)

    def __unicode__(self):
        if self.currency.prefix:
            return "%s%s" % (self.currency.symbol, self.value)
        else:
            return "%s%s" % (self.value, self.currency.symbol)
Exemplo n.º 16
0
class ExtraOrderPriceField(models.Model):
    """
    This will make Cart-provided extra price fields persistent since we want
    to "snapshot" their statuses at the time when the order was made
    """
    order = models.ForeignKey(Order, verbose_name=_('Order'))
    label = models.CharField(max_length=255, verbose_name=_('Label'))
    value = CurrencyField(verbose_name=_('Amount'))
    # Does this represent shipping costs?
    is_shipping = models.BooleanField(default=False,
                                      editable=False,
                                      verbose_name=_('Is shipping'))

    class Meta(object):
        app_label = 'shop'
        verbose_name = _('Extra order price field')
        verbose_name_plural = _('Extra order price fields')
Exemplo n.º 17
0
class BaseProduct(PolymorphicModel):
    """
    A basic product for the shop
    Most of the already existing fields here should be generic enough to reside
    on the "base model" and not on an added property
    """

    name = models.CharField(max_length=255, verbose_name=_('Name'))

    # slug = models.SlugField(verbose_name=_('Slug'), unique=True)

    slug = AutoSlugField(verbose_name=_('Slug'),
                         editable=True,
                         populate_from='name')

    active = models.BooleanField(default=False, verbose_name=_('Active'))
    date_added = models.DateTimeField(auto_now_add=True,
                                      verbose_name=_('Date added'))
    last_modified = models.DateTimeField(auto_now=True,
                                         verbose_name=_('Last modified'))
    unit_price = CurrencyField(verbose_name=_('Unit price'))

    class Meta(object):
        abstract = True
        app_label = 'shop'
        verbose_name = _('Product')
        verbose_name_plural = _('Products')

    def __unicode__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('product_detail', args=[self.slug])

    def get_price(self):
        """
        Return the price for this item (provided for extensibility)
        """
        return self.unit_price

    def get_name(self):
        """
        Return the name of this Product (provided for extensibility)
        """
        return self.name
Exemplo n.º 18
0
class Confirmation(models.Model):
    """
    Model to store every confirmation for successful or failed payments.
    """
    class Meta:
        verbose_name = _('Viveum Confirmation')

    order = models.ForeignKey(
        Order, verbose_name=_('Unique identifier for submitted payments'))
    status = models.IntegerField(verbose_name=_('The PSP\'s return status'))
    acceptance = models.CharField(
        max_length=20,
        blank=True,
        verbose_name=_('Acquirer\'s acceptance (authorisation) code.'))
    payid = models.IntegerField(
        verbose_name=_('The PSP\'s unique transaction reference.'))
    merchant_comment = models.TextField(
        null=True,
        blank=True,
        verbose_name=_('Additional comments from the merchant'))
    ncerror = models.IntegerField(verbose_name=_('The PSP\'s error code'))
    cn = models.CharField(max_length=255,
                          verbose_name=_('Card holder (customer) name'))
    amount = CurrencyField()
    ipcty = models.CharField(
        blank=True,
        max_length=2,
        verbose_name=_('Originating country of the IP address'))
    currency = models.CharField(max_length=3,
                                verbose_name=_('Currency of the transaction'))
    cardno = models.CharField(
        max_length=21,
        verbose_name=_(
            'The last 4 digits of the customers credit card number'))
    brand = models.CharField(
        max_length=25,
        verbose_name=_('Brand of a credit/debit/purchasing card'))
    origin = models.CharField(max_length=10,
                              verbose_name=_('Origin for this confirmation'))

    @staticmethod
    def get_meta_fields():
        return Confirmation._meta.fields
Exemplo n.º 19
0
class OrderPayment(models.Model):
    """
    A class to hold basic payment information. Backends should define their own
    more complex payment types should they need to store more informtion
    """
    order = models.ForeignKey(Order, verbose_name=_('Order'))
    # How much was paid with this particular transfer
    amount = CurrencyField(verbose_name=_('Amount'))
    transaction_id = models.CharField(
        max_length=255,
        verbose_name=_('Transaction ID'),
        help_text=_("The transaction processor's reference"))
    payment_method = models.CharField(
        max_length=255,
        verbose_name=_('Payment method'),
        help_text=_("The payment backend used to process the purchase"))

    class Meta(object):
        app_label = 'shop'
        verbose_name = _('Order payment')
        verbose_name_plural = _('Order payments')
Exemplo n.º 20
0
class Product(PolymorphicModel):
    """
    A basic product for the shop
    Most of the already existing fields here should be generic enough to reside
    on the "base model" and not on an added property
    """
    
    name = models.CharField(max_length=255)
    slug = models.SlugField()
    short_description = models.CharField(max_length=255)
    long_description = models.TextField()
    active = models.BooleanField(default=False)
    
    date_added = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    
    unit_price = CurrencyField()
    
    objects = ProductManager()
    
    class Meta:
        app_label = 'shop'
    
    def __unicode__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('product_detail', args=[self.slug])
    
    def get_price(self):
        """
        Return the price for this item (provided for extensibility)
        """
        return self.unit_price
    
    def get_name(self):
        """
        Return the name of this Product (provided for extensibility)
        """
        return self.name
Exemplo n.º 21
0
class Product(BaseProduct):
    """
    A basic product for the shop
    Most of the already existing fields here should be generic enough to reside
    on the "base model" and not on an added property
    """
    name = models.CharField(max_length=255)
    slug = models.SlugField()
    short_description = models.CharField(max_length=255)
    long_description = models.TextField()
    active = models.BooleanField(default=False)

    date_added = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)

    unit_price = CurrencyField()

    # The subtype stores the lowest-level classname in the inheritence tree
    subtype = models.CharField(max_length=255, editable=False)

    class Meta:
        app_label = 'shop'
Exemplo n.º 22
0
class BaseOrder(models.Model):
    """
    A model representing an Order.

    An order is the "in process" counterpart of the shopping cart, which holds
    stuff like the shipping and billing addresses (copied from the User
    profile) when the Order is first created), list of items, and holds stuff
    like the status, shipping costs, taxes, etc...
    """

    PROCESSING = 10  # New order, addresses and shipping/payment methods chosen (user is in the shipping backend)
    CONFIRMING = 20  # The order is pending confirmation (user is on the confirm view)
    CONFIRMED = 30  # The order was confirmed (user is in the payment backend)
    COMPLETED = 40  # Payment backend successfully completed
    SHIPPED = 50  # The order was shipped to client
    CANCELED = 60  # The order was canceled
    CANCELLED = CANCELED  # DEPRECATED SPELLING

    PAYMENT = 30  # DEPRECATED!

    STATUS_CODES = (
        (PROCESSING, _('Processing')),
        (CONFIRMING, _('Confirming')),
        (CONFIRMED, _('Confirmed')),
        (COMPLETED, _('Completed')),
        (SHIPPED, _('Shipped')),
        (CANCELED, _('Canceled')),
    )

    # If the user is null, the order was created with a session
    user = models.ForeignKey(USER_MODEL,
                             blank=True,
                             null=True,
                             verbose_name=_('User'))
    status = models.IntegerField(choices=STATUS_CODES,
                                 default=PROCESSING,
                                 verbose_name=_('Status'))
    order_subtotal = CurrencyField(verbose_name=_('Order subtotal'))
    order_total = CurrencyField(verbose_name=_('Order Total'))
    shipping_address_text = models.TextField(_('Shipping address'),
                                             blank=True,
                                             null=True)
    billing_address_text = models.TextField(_('Billing address'),
                                            blank=True,
                                            null=True)
    created = models.DateTimeField(auto_now_add=True,
                                   verbose_name=_('Created'))
    modified = models.DateTimeField(auto_now=True, verbose_name=_('Updated'))
    cart_pk = models.PositiveIntegerField(_('Cart primary key'),
                                          blank=True,
                                          null=True)

    class Meta(object):
        abstract = True
        app_label = 'shop'
        verbose_name = _('Order')
        verbose_name_plural = _('Orders')

    def __unicode__(self):
        return _('Order ID: %(id)s') % {'id': self.pk}

    def get_absolute_url(self):
        return reverse('order_detail', kwargs={'pk': self.pk})

    def is_paid(self):
        """Has this order been integrally paid for?"""
        return self.amount_paid >= self.order_total

    is_payed = is_paid  #Backward compatability, deprecated spelling

    def is_completed(self):
        return self.status == self.COMPLETED

    def get_status_name(self):
        return dict(self.STATUS_CODES)[self.status]

    @property
    def amount_paid(self):
        """
        The amount paid is the sum of related orderpayments
        """
        from shop.models import OrderPayment
        sum_ = OrderPayment.objects.filter(order=self).aggregate(
            sum=Sum('amount'))
        result = sum_.get('sum')
        if result is None:
            result = Decimal(0)
        return result

    amount_payed = amount_paid  #Backward compatability, deprecated spelling

    @property
    def shipping_costs(self):
        from shop.models import ExtraOrderPriceField
        sum_ = Decimal('0.0')
        cost_list = ExtraOrderPriceField.objects.filter(order=self).filter(
            is_shipping=True)
        for cost in cost_list:
            sum_ += cost.value
        return sum_

    @property
    def short_name(self):
        """
        A short name for the order, to be displayed on the payment processor's
        website. Should be human-readable, as much as possible
        """
        return "%s-%s" % (self.pk, self.order_total)

    def set_billing_address(self, billing_address):
        """
        Process billing_address trying to get as_text method from address
        and copying.
        You can override this method to process address more granulary
        e.g. you can copy address instance and save FK to it in your order
        class.
        """
        if hasattr(billing_address, 'as_text') and callable(
                billing_address.as_text):
            self.billing_address_text = billing_address.as_text()
            self.save()

    def set_shipping_address(self, shipping_address):
        """
        Process shipping_address trying to get as_text method from address
        and copying.
        You can override this method to process address more granulary
        e.g. you can copy address instance and save FK to it in your order
        class.
        """
        if hasattr(shipping_address, 'as_text') and callable(
                shipping_address.as_text):
            self.shipping_address_text = shipping_address.as_text()
            self.save()
Exemplo n.º 23
0
class Product(models.Model):
    """
    A basic product for the shop
    Most of the already existing fields here should be generic enough to reside
    on the "base model" and not on an added property
    """
    
    __metaclass__ = ProductMetaClass
    
    name = models.CharField(max_length=255)
    slug = models.SlugField()
    short_description = models.CharField(max_length=255)
    long_description = models.TextField()
    active = models.BooleanField(default=False)
    
    date_added = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    
    unit_price = CurrencyField()
    
    # The subtype stores the lowest-level classname in the inheritence tree
    subtype = models.CharField(max_length=255, editable=False)
    
    objects = ProductManager()
    
    class Meta:
        app_label = 'shop'
    
    def __unicode__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('product_detail', args=[self.slug])
    
    def get_specific(self):
        """
        This magic method returns this as an instance of the most specific
        decendant in the inheritence tree.
        """
        return getattr(self, self.subtype, self)
    
    def get_price(self):
        """
        Return the price for this item (provided for extensibility)
        """
        return self.unit_price
    
    def get_name(self):
        """
        Return the name of this Product (provided for extensibility)
        """
        return self.name
    
    @classmethod
    def save_subtype_name(cls, instance, **kwargs):
        """
        This is called when a subclass of Product is saved. It sets the 
        relation name to the subclass in the "subtype" field of the Product 
        instance.
        This allows "get_specific()" to always return the specific instance of 
        the subclass, no matter its type.
        
        This method is (and should) only called from the pre_save signal set
        in ProductMetaClass
        """
        instance.subtype = cls.__name__.lower()
Exemplo n.º 24
0
class Order(models.Model):
    """
    A model representing an Order.
    
    An order is the "in process" counterpart of the shopping cart, which holds
    stuff like the shipping and billing addresses (copied from the User profile)
    when the Order is first created), list of items, and holds stuff like the
    status, shipping costs, taxes, etc...
    """

    PROCESSING = 1  # New order, no shipping/payment backend chosen yet
    CONFIRMED = 2  # Chosen shipping/payment backend, processing payment
    COMPLETED = 3  # Successful payment confirmed by payment backend
    SHIPPED = 4  # successful order shipped to client
    CANCELLED = 5  # order has been cancelled

    STATUS_CODES = (
        (PROCESSING, 'Processing'),
        (CONFIRMED, 'Confirmed'),
        (COMPLETED, 'Completed'),
        (SHIPPED, 'Shipped'),
        (CANCELLED, 'Cancelled'),
    )

    # If the user is null, the order was created with a session
    user = models.ForeignKey(User, blank=True, null=True)

    status = models.IntegerField(choices=STATUS_CODES, default=PROCESSING)

    order_subtotal = CurrencyField()
    order_total = CurrencyField()

    payment_method = models.CharField(max_length=255, null=True)

    # Addresses MUST be copied over to the order when it's created, however
    # the fields must be nullable since sometimes we cannot create the address
    # fields right away (for instance when the shopper is a guest)
    shipping_name = models.CharField(max_length=255, null=True)
    shipping_address = models.CharField(max_length=255, null=True)
    shipping_address2 = models.CharField(max_length=255, null=True)
    shipping_city = models.CharField(max_length=255, null=True)
    shipping_zip_code = models.CharField(max_length=20, null=True)
    shipping_state = models.CharField(max_length=255, null=True)
    shipping_country = models.CharField(max_length=255, null=True)

    billing_name = models.CharField(max_length=255, null=True)
    billing_address = models.CharField(max_length=255, null=True)
    billing_address2 = models.CharField(max_length=255, null=True)
    billing_city = models.CharField(max_length=255, null=True)
    billing_zip_code = models.CharField(max_length=20, null=True)
    billing_state = models.CharField(max_length=255, null=True)
    billing_country = models.CharField(max_length=255, null=True)

    created = models.DateTimeField(auto_now_add=True,
                                   verbose_name=_('Created'))
    modified = models.DateTimeField(auto_now=True, verbose_name=_('Updated'))

    objects = OrderManager()

    class Meta:
        app_label = 'shop'

    def is_payed(self):
        """Has this order been integrally payed for?"""
        return self.amount_payed == self.order_total

    def is_completed(self):
        return self.status == self.COMPLETED

    @property
    def amount_payed(self):
        """
        The amount payed is the sum of related orderpayments
        """
        sum = OrderPayment.objects.filter(order=self).aggregate(
            sum=Sum('amount'))
        result = sum.get('sum')
        if not result:
            result = Decimal('0')
        return result

    @property
    def shipping_costs(self):
        sum = Decimal('0.0')
        cost_list = ExtraOrderPriceField.objects.filter(order=self).filter(
            is_shipping=True)
        for cost in cost_list:
            sum = sum + cost.value
        return sum

    def __unicode__(self):
        return _('Order ID: %(id)s') % {'id': self.id}

    def get_absolute_url(self):
        return reverse('order_detail', kwargs={'pk': self.pk})
Exemplo n.º 25
0
class Order(models.Model):
    '''
    A model representing an Order.
    
    An order is the "in process" counterpart of the shopping cart, which holds
    stuff like the shipping and billing addresses (copied from the User profile)
    when the Order is first created), list of items, and holds stuff like the
    status, shipping costs, taxes, etc...
    '''
    
    PROCESSING = 1
    CONFIRMED = 2
    COMPLETED = 3
    
    STATUS_CODES = (
        (PROCESSING, 'Processing'), # User still checking out the contents
        (CONFIRMED, 'Confirmed'), # Contents are valid, now we can handle payment etc...
        (COMPLETED, 'Completed'), # Everything is fine, only need to send the products
    )
    
    # If the user is null, the order was created with a session
    user = models.ForeignKey(User, blank=True, null=True)
    
    status = models.IntegerField(choices=STATUS_CODES, default=PROCESSING)
    
    order_subtotal = CurrencyField()
    order_total = CurrencyField()
    
    amount_payed = CurrencyField()
    payment_method = models.CharField(max_length=255, null=True)
    
    # Addresses MUST be copied over to the order when it's created, however
    # the fields must be nullable since sometimes we cannot create the address 
    # fields right away (for instance when the shopper is a guest)
    shipping_name = models.CharField(max_length=255, null=True)
    shipping_address = models.CharField(max_length=255, null=True)
    shipping_address2 = models.CharField(max_length=255, null=True)
    shipping_zip_code = models.CharField(max_length=20, null=True)
    shipping_state = models.CharField(max_length=255, null=True)
    shipping_country = models.CharField(max_length=255, null=True)
    
    billing_name = models.CharField(max_length=255, null=True)
    billing_address = models.CharField(max_length=255, null=True)
    billing_address2 = models.CharField(max_length=255, null=True)
    billing_zip_code = models.CharField(max_length=20, null=True)
    billing_state = models.CharField(max_length=255, null=True)
    billing_country = models.CharField(max_length=255, null=True)
    
    objects = OrderManager()
    
    class Meta:
        app_label = 'shop'
    
    def is_payed(self):
        '''Has this order been integrally payed for?'''
        return self.amount_payed == self.order_total
    
    def is_completed(self):
        return self.status == self.COMPLETED
    
    @property
    def shipping_costs(self):
        sum = Decimal('0.0')
        cost_list = ExtraOrderPriceField.objects.filter(order=self).filter(is_shipping=True)
        for cost in cost_list:
            sum = sum + cost.value
        return sum
Exemplo n.º 26
0
class BaseOrder(models.Model):
    """
    A model representing an Order.

    An order is the "in process" counterpart of the shopping cart, which holds
    stuff like the shipping and billing addresses (copied from the User
    profile) when the Order is first created), list of items, and holds stuff
    like the status, shipping costs, taxes, etc...
    """

    PROCESSING = 1  # New order, no shipping/payment backend chosen yet
    PAYMENT = 2  # The user is filling in payment information
    CONFIRMED = 3  # Chosen shipping/payment backend, processing payment
    COMPLETED = 4  # Successful payment confirmed by payment backend
    SHIPPED = 5  # successful order shipped to client
    CANCELLED = 6  # order has been cancelled

    STATUS_CODES = (
        (PROCESSING, _('Processing')),
        (PAYMENT, _('Selecting payment')),
        (CONFIRMED, _('Confirmed')),
        (COMPLETED, _('Completed')),
        (SHIPPED, _('Shipped')),
        (CANCELLED, _('Cancelled')),
    )

    # If the user is null, the order was created with a session
    user = models.ForeignKey(User,
                             blank=True,
                             null=True,
                             verbose_name=_('User'))
    status = models.IntegerField(choices=STATUS_CODES,
                                 default=PROCESSING,
                                 verbose_name=_('Status'))
    order_subtotal = CurrencyField(verbose_name=_('Order subtotal'))
    order_total = CurrencyField(verbose_name=_('Order Total'))
    shipping_address_text = models.TextField(_('Shipping address'),
                                             blank=True,
                                             null=True)
    billing_address_text = models.TextField(_('Billing address'),
                                            blank=True,
                                            null=True)
    created = models.DateTimeField(auto_now_add=True,
                                   verbose_name=_('Created'))
    modified = models.DateTimeField(auto_now=True, verbose_name=_('Updated'))

    class Meta(object):
        abstract = True
        app_label = 'shop'
        verbose_name = _('Order')
        verbose_name_plural = _('Orders')

    def __unicode__(self):
        return _('Order ID: %(id)s') % {'id': self.id}

    def get_absolute_url(self):
        return reverse('order_detail', kwargs={'pk': self.pk})

    def is_payed(self):
        """Has this order been integrally payed for?"""
        return self.amount_payed == self.order_total

    def is_completed(self):
        return self.status == self.COMPLETED

    @property
    def amount_payed(self):
        """
        The amount payed is the sum of related orderpayments
        """
        from shop.models import OrderPayment
        sum_ = OrderPayment.objects.filter(order=self).aggregate(
            sum=Sum('amount'))
        result = sum_.get('sum')
        if not result:
            result = Decimal('-1')
        return result

    @property
    def shipping_costs(self):
        from shop.models import ExtraOrderPriceField
        sum_ = Decimal('0.0')
        cost_list = ExtraOrderPriceField.objects.filter(order=self).filter(
            is_shipping=True)
        for cost in cost_list:
            sum_ += cost.value
        return sum_

    def set_billing_address(self, billing_address):
        """
        Process billing_address trying to get as_text method from address
        and copying.
        You can override this method to process address more granulary
        e.g. you can copy address instance and save FK to it in your order
        class.
        """
        if hasattr(billing_address, 'as_text'):
            self.billing_address_text = billing_address.as_text()
            self.save()

    def set_shipping_address(self, shipping_address):
        """
        Process shipping_address trying to get as_text method from address
        and copying.
        You can override this method to process address more granulary
        e.g. you can copy address instance and save FK to it in your order
        class.
        """
        if hasattr(shipping_address, 'as_text'):
            self.shipping_address_text = shipping_address.as_text()
            self.save()
Exemplo n.º 27
0
 def test_03_currencyfield_can_override_default(self):
     cf = CurrencyField(default=Decimal('99.99'))
     default = cf.get_default()
     self.assertNotEqual(default, None)
     self.assertEqual(default, Decimal('99.99'))
Exemplo n.º 28
0
 def test_02_currencyfield_has_default(self):
     cf = CurrencyField()
     default = cf.get_default()
     self.assertNotEqual(default, None)
     self.assertEqual(default, Decimal('0.0'))
Exemplo n.º 29
0
 def test_01_currencyfield_has_fixed_format(self):
     cf = CurrencyField(max_digits=2, decimal_places=1)
     number = cf.format_number(99.99)
     #number should *not* end up having only one decimal place
     self.assertEqual(Decimal(number), Decimal('99.99'))
Exemplo n.º 30
0
class BaseProduct(models.Model):
    unit_price = CurrencyField()