Exemplo n.º 1
0
    def create(self, request):
        """
        Add an item to the basket
        """
        variant_id = request.data.get("variant_id", None)

        if variant_id is not None:
            variant = ProductVariant.objects.get(id=variant_id)

            quantity = int(request.data.get("quantity", 1))
            items, bid = utils.get_basket_items(request)

            # Check if the variant is already in the basket
            in_basket = False
            for item in items:
                if item.variant.id == variant.id:
                    item.increase_quantity(quantity)
                    in_basket = True
                    break
            if not in_basket:
                item = BasketItem(variant=variant,
                                  quantity=quantity,
                                  basket_id=bid)
                item.save()

            serializer = BasketItemSerializer(self.get_queryset(request),
                                              many=True)
            response = Response(data=serializer.data,
                                status=status.HTTP_201_CREATED)

        else:
            response = Response({"message": "Missing 'variant_id'"},
                                status=status.HTTP_400_BAD_REQUEST)

        return response
Exemplo n.º 2
0
 def get_context_data(self, **kwargs):
     context = super(CheckoutView, self).get_context_data(**kwargs)
     items, _ = get_basket_items(self.request)
     total_price = sum(item.total() for item in items)
     site = getattr(self.request, 'site', None)
     context['checkout_form'] = self.checkout_form(self.request.POST
                                                   or None)
     context['shipping_form'] = self.shipping_address_form(
         self.request.POST or None, prefix='shipping', site=site)
     context['basket'] = items
     context['total_price'] = total_price
     return context
Exemplo n.º 3
0
    def get_context_data(self, **kwargs):
        context = super(CheckoutView, self).get_context_data(**kwargs)
        items, _ = get_basket_items(self.request)
        total_price = sum(item.total() for item in items)
        discount = Discount.objects.filter(basket_id=basket_id(self.request),
                                           order=None).last()
        discount_total_price, discount_total_saved = discount_total(
            total_price, discount)
        site = getattr(self.request, 'site', None)
        context['checkout_form'] = self.checkout_form(self.request.POST
                                                      or None)
        context['shipping_form'] = self.shipping_address_form(
            self.request.POST or None, prefix='shipping', site=site)
        context['billing_form'] = self.billing_address_form(self.request.POST
                                                            or None,
                                                            prefix='billing',
                                                            site=site)
        context['basket'] = items

        default_shipping_rate = ShippingRate.objects.first().rate
        total_price = sum(item.total() for item in items)
        discount = Discount.objects.filter(basket_id=basket_id(self.request),
                                           order=None).last()
        discount_total_price, discount_total_saved = discount_total(
            total_price + default_shipping_rate, discount)
        context['total_price'] = total_price
        context['discount'] = discount
        context['discount_total_price'] = round(discount_total_price, 2)
        context['discount_total_saved'] = round(discount_total_saved, 2)

        context['default_shipping_rate'] = round(default_shipping_rate, 2)

        context['discount_plus_shipping'] = round(
            discount_total_price + default_shipping_rate, 2)
        context['total_plus_shipping'] = round(
            total_price + default_shipping_rate, 2)
        return context
Exemplo n.º 4
0
 def get_queryset(self, request=None):
     items, _ = utils.get_basket_items(request or self.request)
     return items
Exemplo n.º 5
0
def verify_discount_code(request):

    # check that we got the 'code' from the request
    if code := request.POST.get('code'):

        # check if the discount code exists
        try:
            coupon = Coupon.objects.get(code=code)
        except Exception as e:
            return JsonResponse({
                'success':
                False,
                'code':
                'DOES_NOT_EXIST',
                'reason':
                'There is no existing match for the submitted code',
            })
        else:

            # check if the coupon has expired
            if coupon.expiry_date < timezone.now(
            ) and not coupon.infinite_redemptions:
                return JsonResponse({
                    'success': False,
                    'code': 'EXPIRED',
                    'reason': 'This discount code has past its expiry date',
                    'coupon': {
                        'type': coupon.discount_type,
                        'value': coupon.discount_value,
                        'description': coupon.description,
                        'expiry_date': coupon.expiry_date,
                    }
                })

            # check if the coupons amount of times the coupon has been redeemed exceeds
            # the max amount of times it can be redeemed
            if coupon.depleted:
                return JsonResponse({
                    'success': False,
                    'code': 'DEPLETED',
                    'reason': 'This discount code has no more uses available',
                    'coupon': {
                        'type': coupon.discount_type,
                        'value': coupon.discount_value,
                        'description': coupon.description,
                        'max_redemptions': coupon.max_redemptions,
                        'redemptions': coupon.redemptions,
                        'expiry_date': coupon.expiry_date,
                    }
                })

            items, bid = get_basket_items(request)

            # check if the current basket id already has a discount associated with it
            # get (or create) the Discount object
            # is the object that tracks the transaction of actually using the code form the coupon
            # the order will be attached later when the order is completed
            try:
                discount = Discount.objects.get(
                    basket_id=bid,
                    # coupon=coupon,
                    order=None,
                )
                discount.coupon = coupon
                discount.save()
            except Discount.DoesNotExist:
                discount = Discount(
                    basket_id=bid,
                    coupon=coupon,
                    order=None,
                )
                discount.save()

            # get the total price from the items in the basket and run them through the discount
            total_price = sum(item.total() for item in items)

            if shipping_rate_id := request.POST.get('shipping'):
                try:
                    shipping_rate = ShippingRate.objects.get(
                        id=shipping_rate_id)
                except ShippingRate.DoesNotExist:
                    # don't worry that it doesn't exist, just move along
                    print('couldn\'t find a shipping rate')
                    pass
                else:
                    total_price += shipping_rate.rate

            discount_total_price, discount_total_saved = discount_total(
                total_price, discount)

            return JsonResponse({
                'success': True,
                'code': 'VALID',
                'reason': 'This discount code is valid',
                'coupon': {
                    'type': coupon.discount_type,
                    'value': coupon.discount_value,
                    'description': coupon.description,
                    'max_redemptions': coupon.max_redemptions,
                    'redemptions': coupon.redemptions,
                    'expiry_date': coupon.expiry_date,
                    'discount_total_price': discount_total_price,
                    'discount_total_saved': discount_total_saved,
                }
            })
Exemplo n.º 6
0
def basket(context):
    """
    Return the BasketItems in the current basket
    """
    items, _ = get_basket_items(context["request"])
    return items
Exemplo n.º 7
0
def basket_count(context):
    items, _ = get_basket_items(context["request"])
    return len(list(items))
Exemplo n.º 8
0
def create_order(email,
                 request,
                 addresses=None,
                 shipping_address=None,
                 billing_address=None,
                 shipping_option=None,
                 capture_payment=False):
    """
    Create an order from a basket and customer infomation
    """
    basket_items, _ = get_basket_items(request)
    if addresses:
        # Longclaw < 0.2 used 'shipping_name', longclaw > 0.2 uses a consistent
        # prefix (shipping_address_xxxx)
        try:
            shipping_name = addresses['shipping_name']
        except KeyError:
            shipping_name = addresses['shipping_address_name']

        shipping_country = addresses['shipping_address_country']
        if not shipping_country:
            shipping_country = None
        shipping_address, _ = Address.objects.get_or_create(
            name=shipping_name,
            line_1=addresses['shipping_address_line1'],
            city=addresses['shipping_address_city'],
            postcode=addresses['shipping_address_zip'],
            country=shipping_country)
        shipping_address.save()
        try:
            billing_name = addresses['billing_name']
        except KeyError:
            billing_name = addresses['billing_address_name']
        billing_country = addresses['shipping_address_country']
        if not billing_country:
            billing_country = None
        billing_address, _ = Address.objects.get_or_create(
            name=billing_name,
            line_1=addresses['billing_address_line1'],
            city=addresses['billing_address_city'],
            postcode=addresses['billing_address_zip'],
            country=billing_country)
        billing_address.save()
    else:
        shipping_country = shipping_address.country

    ip_address = get_real_ip(request)
    if shipping_country and shipping_option:
        site_settings = Configuration.for_site(request.site)
        shipping_rate = get_shipping_cost(site_settings,
                                          shipping_address.country.pk,
                                          shipping_option)['rate']
    else:
        shipping_rate = Decimal(0)

    order = Order(email=email,
                  ip_address=ip_address,
                  shipping_address=shipping_address,
                  billing_address=billing_address,
                  shipping_rate=shipping_rate)
    order.save()

    # Create the order items & compute total
    total = 0
    for item in basket_items:
        total += item.total()
        order_item = OrderItem(product=item.variant,
                               quantity=item.quantity,
                               order=order)
        order_item.save()

    if capture_payment:
        desc = 'Payment from {} for order id #{}'.format(email, order.id)
        try:
            transaction_id = GATEWAY.create_payment(request,
                                                    total + shipping_rate,
                                                    description=desc)
            order.payment_date = timezone.now()
            order.transaction_id = transaction_id
            # Once the order has been successfully taken, we can empty the basket
            destroy_basket(request)
        except PaymentError:
            order.status = order.FAILURE

        order.save()

    return order
Exemplo n.º 9
0
 def get_context_data(self, **kwargs):
     items, _ = utils.get_basket_items(self.request)
     total_price = sum(item.total() for item in items)
     return {"basket": items, "total_price": total_price}