def _create_order(self, request): """ Create new order. """ # determine form class order_model = get_order_model() formclass = order_model.get_form() # create form if request.method == 'POST': form = formclass(request.POST) else: form = formclass() form.configure(request, None, False) # validate form if request.method == 'POST' and form.is_valid(): d = form.cleaned_data # create new order order = order_model.create_empty_customer_not_present(request) # redirect to edit page return self._redirect(request, 'edit', order) return {'form': form, 'edit': False}
def generate_order_id(self, order): """ Generate a unique order id. """ order_model = get_order_model() found = False i = 0 while not found: # generate random ref. number for the given order if self._request.settings.order_id == 'numeric': order_id = self.generate_numeric_order_id(order) elif self._request.settings.order_id == 'seq': order_id = self.generate_seq_order_id(order) else: order_id = self.generate_alpha_order_id(order) # add prefix/suffix if self._request.settings.order_id_prefix: order_id = '%s%s' % (self._request.settings.order_id_prefix, order_id) if self._request.settings.order_id_suffix: order_id = '%s%s' % (order_id, self._request.settings.order_id_suffix) # make sure it is unqiue found = (order_model.objects.filter( order_id=order_id).count() == 0) i += 1 if i > 100: raise UserWarning( 'Fatal: Unable to find another unique order id after %d iterations!' % i) return order_id
def shipping_notes(request, secret_id): """ Display for PDF creation of the shipping note/status """ basket = Basket(request) order = get_object_or_404(get_order_model(), secret_id=secret_id) return {'order': order}
def generate_seq_order_id(self, order): """ Generate unique order id based on what looks like a sequential number. """ rnd = self.get_random() n = get_order_model().objects.all().count() oid = rnd.randint(1234, n + (2 * 1234)) return '%d' % oid
def cancel(self, request): order_id = request.GET.get('pk') edit_order = request.GET.get('edit_order', 'false') == 'true' order = get_object_or_404(get_order_model(), pk=order_id) def _do_redirect(): if edit_order: return self._redirect(request, 'edit', order) else: return self._redirect(request, 'index') # cannot cancel if we are awaiting payment approval/rejection if order.approval_status == OrderBase.APPROVAL_STATUS_WAITING: messages.add_message( request, messages.ERROR, 'Order <em>%s</em> is awaiting approval. Please accept or reject this order.' % order.order_id) return _do_redirect() # cannot cancel if the order has already been cancelled if order.cancelled: messages.add_message( request, messages.ERROR, 'Order <em>%s</em> has already been cancelled.' % order.order_id) return _do_redirect() # process cancellation form if request.method == 'POST': form = CancelOrderForm(request.POST) else: form = CancelOrderForm() if request.method == 'POST': if request.POST.get('cubane_form_cancel', '0') == '1': _do_redirect() if form.is_valid(): (success, msg) = order.cancel(request, form.cleaned_data.get('cancel_msg')) if success: messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been cancelled.' % order.order_id) else: messages.add_message( request, messages.ERROR, 'We were unable to cancel the order <em>%s</em>: %s' % (order.order_id, msg)) _do_redirect() return {'order': order, 'form': form}
def account_orders(self, request, status): order_model = get_order_model() if status == 'processing': orders = order_model.objects.get_processing_orders(user=request.user) else: orders = order_model.objects.get_complete_orders(user=request.user) return { 'account_section': True, 'orders': orders, 'status': status, }
def account_index(self, request): profile = get_customer_model().objects.get(user=request.user) orders = get_order_model().objects.get_processing_orders(user=request.user)[:3] try: address = request.user.delivery_addresses.all()[0] except IndexError: address = None return { 'account_section': True, 'profile': profile, 'orders': orders, 'address': address }
def status(request, secret_id): """ View current status of the given order. This page is publicly available on the internet without any user authentification. """ order = get_object_or_404(get_order_model(), secret_id=secret_id) if order.is_placed() and not order.ga_sent: order.ga_sent = True order.save() # convince the template that ga has not been notified yet order.ga_sent = False return {'order': order, 'basket': order.basket, 'order_status_page': True}
def reject(self, request): order_id = request.GET.get('pk') edit_order = request.GET.get('edit_order', 'false') == 'true' order = get_object_or_404(get_order_model(), pk=order_id) if request.method == 'POST': form = RejectOrderForm(request.POST) else: form = RejectOrderForm() if request.method == 'POST': if request.POST.get('cubane_form_cancel', '0') == '1': if edit_order: return self._redirect(request, 'edit', order) else: return self._redirect(request, 'index') if form.is_valid(): (success, msg) = order.reject(request, form.cleaned_data.get('reject_msg')) if success and order.approval_status == OrderBase.APPROVAL_STATUS_REJECTED: messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been rejected.' % order.order_id) else: messages.add_message( request, messages.ERROR, 'We were unable to reject the order <em>%s</em>: %s' % (order.order_id, msg)) if edit_order: return self._redirect(request, 'edit', order) else: return self._redirect(request, 'index') return {'order': order, 'form': form}
def test_payment(request, secret_id): """ If the payment gateway is configured to use the innershed test payment gateway, the user will ultimatly redirected to this page, where a test payment can be confimed or declined. """ # get order order = get_object_or_404(get_order_model(), secret_id=secret_id) # get payment gateway gateway = order.get_payment_gateway() # make sure that the payment gateway is the testing gateway if not isinstance(gateway, TestPaymentGateway): raise Http404( 'The system is not configured to use the test payment gateway.') return { 'order': order, 'details': order.payment_details, 'post_url': gateway.get_response_url(request) }
def view(self, request): """ View existing order and make some minor amendments to it (previous order screen). """ pk = request.GET.get('pk') order = get_object_or_404(get_order_model(), pk=pk) if request.method == 'POST': form = ChangeOrderStatusForm(request.POST) else: form = ChangeOrderStatusForm( initial={ 'status': order.status, 'tracking_provider': order.tracking_provider, 'tracking_code': order.tracking_code, 'delivery_type': order.delivery_type, 'delivery_name': order.delivery_name, 'delivery_company': order.delivery_company, 'delivery_address1': order.delivery_address1, 'delivery_address2': order.delivery_address2, 'delivery_address3': order.delivery_address3, 'delivery_city': order.delivery_city, 'delivery_county': order.delivery_county, 'delivery_postcode': order.delivery_postcode, 'delivery_country': order.delivery_country, 'special_requirements': order.special_requirements, }) form.configure(request, order) if request.method == 'POST': # from cancellation if request.POST.get('cubane_form_cancel', '0') == '1': return self._redirect(request, 'index') # valid? if form.is_valid(): d = form.cleaned_data # update status new_status = int(d.get('status')) status_changed = order.status != new_status order.status = new_status order.special_requirements = d.get('special_requirements') # update tracking code tracking_changed = ( order.tracking_provider != d.get('tracking_provider') or \ order.tracking_code != d.get('tracking_code') ) order.tracking_provider = d.get('tracking_provider') order.tracking_code = d.get('tracking_code') # update delivery type new_delivery_type = int(d.get('delivery_type')) delivery_type_changed = order.delivery_type != new_delivery_type order.delivery_type = new_delivery_type # update delivery address, if this is a delivery order delivery_address_changed = False if not order.is_click_and_collect: delivery_address_changed = ( order.delivery_name != d.get('delivery_name') or \ order.delivery_company != d.get('delivery_company') or \ order.delivery_address1 != d.get('delivery_address1') or \ order.delivery_address2 != d.get('delivery_address2') or \ order.delivery_address3 != d.get('delivery_address3') or \ order.delivery_city != d.get('delivery_city') or \ order.delivery_county != d.get('delivery_county') or \ order.delivery_postcode != d.get('delivery_postcode') or \ order.delivery_country != d.get('delivery_country') ) order.delivery_name = d.get('delivery_name') order.delivery_company = d.get('delivery_company') order.delivery_address1 = d.get('delivery_address1') order.delivery_address2 = d.get('delivery_address2') order.delivery_address3 = d.get('delivery_address3') order.delivery_city = d.get('delivery_city') order.delivery_county = d.get('delivery_county') order.delivery_postcode = d.get('delivery_postcode') order.delivery_country = d.get('delivery_country') # update processing state for all line items order.reset_processed_state() indexes = request_int_list(request.POST, 'processed') for index in indexes: order.mark_item_as_processed(index, True) # update shipped state for all line items order.reset_shipped_state() indexes = request_int_list(request.POST, 'shipped') for index in indexes: order.mark_item_as_shipped(index, True) # save order order.save() # fulfillment if order.status in OrderBase.FULFILLED_STATUS and not order.fulfilled: (success, msg) = order.fulfill(request) if success: messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been fulfilled successfully.' % order.order_id) else: messages.add_message( request, messages.ERROR, 'Error while fulfilling order <em>%s</em>: %s' % (order.order_id, msg)) # send email if something of importance changed if status_changed or tracking_changed or delivery_type_changed or delivery_address_changed: if int(order.status) in [ OrderBase.STATUS_PARTIALLY_SHIPPED, OrderBase.STATUS_SHIPPED, OrderBase.STATUS_READY_TO_COLLECT, OrderBase.STATUS_COLLECTED ]: if mail_customer_order_status(request, order): messages.add_message( request, messages.SUCCESS, 'Email sent to customer: %s' % order.email) messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been updated.' % order.order_id) active_tab = request.POST.get('cubane_save_and_continue', '0') if not active_tab == '0': return HttpResponseRedirect( reverse('cubane.ishop.orders.edit') + '?pk=%d' % order.pk) else: return self._redirect(request, 'index') return {'order': order, 'form': form, 'edit': True}
def payment_update(self, request): cr_id = request.POST.get('CreditRequestID', None) status = request.POST.get('Status', None) api_key = request.POST.get('Identification[api_key]', None) ref = request.POST.get('Identification[RetailerUniqueRef]', None) is_valid_request = True # check if api key is matching our api KEY if api_key != self._get_api_key(): is_valid_request = False if status: status = status.lower() else: is_valid_request = False # credit id should be provided if not cr_id: is_valid_request = False # some requests are with [] some without if ref: ref = ref.split('[')[0] # get order by ref order = get_order_model().objects.filter(secret_id=ref) if order.count() != 1: is_valid_request = False if is_valid_request: order = order[0] if status == 'initialise': order.loan_status = OrderBase.LOAN_STATUS_NONE elif status == 'predecline': order.loan_status = OrderBase.LOAN_STATUS_PREDECLINE elif status == 'accept': order.loan_status = OrderBase.LOAN_STATUS_ACCEPT elif status == 'decline': order.loan_status = OrderBase.LOAN_STATUS_DECLINE order.status = OrderBase.STATUS_PAYMENT_DECLINED elif status == 'refer': order.loan_status = OrderBase.LOAN_STATUS_REFER elif status == 'verified': order.loan_status = OrderBase.LOAN_STATUS_VERIFIED order.status = OrderBase.STATUS_PAYMENT_CONFIRMED order.payment_confirmed_at = datetime.datetime.now() generate_emails_and_notes(request, order) elif status == 'amended': order.loan_status = OrderBase.LOAN_STATUS_AMENDED elif status == 'fulfilled': order.loan_status = OrderBase.LOAN_STATUS_FULFILLED elif status == 'complete': order.loan_status = OrderBase.LOAN_STATUS_COMPLETE elif status == 'cancelled': order.loan_status = OrderBase.LOAN_STATUS_CANCELLED order.status = OrderBase.STATUS_PAYMENT_DECLINED elif status == 'info needed': order.loan_status = OrderBase.LOAN_STATUS_INFO_NEEDED elif status == 'action customer': order.loan_status = OrderBase.LOAN_STATUS_ACTION_CUSTOMER elif status == 'action retailer': order.loan_status = OrderBase.LOAN_STATUS_ACTION_RETAILER else: order.loan_status = OrderBase.LOAN_STATUS_NONE order.transaction_id = cr_id order.save() # Omni didn't define what kind of response they are expecting. Assuming 200... return HttpResponse('Status: OK') else: raise Exception( '[Omni]: Payment Update couldn\'t update given order.')
class Meta: model = get_order_model() fields = '__all__'
class Meta: model = get_order_model() fields = [ # status 'status', # tracking 'tracking_provider', 'tracking_code', # customer 'customer', 'email', 'telephone', # details 'special_requirements', # billing 'billing_postcode_lookup', 'full_name', 'billing_company', 'billing_address1', 'billing_address2', 'billing_address3', 'billing_city', 'billing_county', 'billing_postcode', 'billing_country', # delivery 'delivery_postcode_lookup', 'delivery_name', 'delivery_company', 'delivery_address1', 'delivery_address2', 'delivery_address3', 'delivery_city', 'delivery_county', 'delivery_postcode', 'delivery_country' ] tabs = [ { 'title': 'Line Items', 'fields': ['_basket'] }, { 'title': 'Status and Tracking', 'fields': [ # status 'status', # tracking 'tracking_provider', 'tracking_code' ] }, { 'title': 'Details', 'fields': [ # customer 'customer', 'email', 'telephone', # details 'special_requirements', # billing 'billing_postcode_lookup', 'full_name', 'billing_company', 'billing_address1', 'billing_address2', 'billing_address3', 'billing_city', 'billing_county', 'billing_postcode', 'billing_country', # delivery 'delivery_postcode_lookup', 'delivery_name', 'delivery_company', 'delivery_address1', 'delivery_address2', 'delivery_address3', 'delivery_city', 'delivery_county', 'delivery_postcode', 'delivery_country' ] } ] sections = { 'status': 'Order Status', 'tracking_provider': 'Order Delivery Tracking', 'customer': 'Customer Information', 'special_requirements': 'Customer Details', 'billing_postcode_lookup': 'Billing Address', 'delivery_postcode_lookup': 'Delivery Address', }
class OrderView(ModelView): template_path = 'cubane/ishop/merchant/orders/' model = get_order_model() namespace = 'cubane.ishop.orders' def __init__(self, *args, **kwargs): self.patterns = [] self.listing_actions = [] self.shortcut_actions = [] # view order (previous order screen) self.patterns.append(view_url(r'view/$', 'view', name='view')) self.listing_actions.append(('View', 'view', 'single')) self.shortcut_actions.append('view') # support for pre-auth payments (approval) if settings.SHOP_PREAUTH: self.patterns.extend([ view_url(r'approve/$', 'approve', name='approve'), view_url(r'reject/$', 'reject', name='reject'), view_url(r'cancel/$', 'cancel', name='cancel') ]) self.listing_actions.extend([('[Approve]', 'approve', 'single'), ('[Reject]', 'reject', 'single'), ('[Cancel]', 'cancel', 'single')]) self.shortcut_actions.extend([ 'approve', 'reject', 'cancel', ]) else: self.exclude_columns = ['approval_status'] self.patterns.extend([ view_url(r'basket-editor/', 'basket_editor', name='basket_editor'), view_url(r'basket-editor-search/', 'basket_editor_search', name='basket_editor_search'), view_url(r'basket-editor-add-to-basket/', 'basket_editor_add_to_basket', name='basket_editor_add_to_basket'), ]) super(OrderView, self).__init__(*args, **kwargs) def _get_objects(self, request): return self.model.objects.select_related('customer', 'voucher').all() def _get_objects_or_404(self, request): return self.model.objects.select_related('customer', 'voucher').all() def before_save(self, request, cleaned_data, instance, edit): # default values if not edit: from cubane.ishop.views import get_shop shop = get_shop() instance.customer_not_present = True instance.payment_gateway = shop.get_default_payment_gateway() # save basket. basket = Basket(request, prefix=instance.backend_basket_prefix) if not basket.is_empty(): instance.save_basket(basket) # change status if request.POST.get('next-status'): cleaned_data['status'] = int(request.POST.get('next-status')) def after_save(self, request, cleaned_data, instance, edit): # generate identifiers if not edit: instance.generate_identifiers(request) def after_save_changes(self, request, cleaned_data, instance, changes, edit): """ Called after the given model instance is saved. """ # determine changes status_changed = 'status' in changes tracking_changed = 'tracking_provider' in changes or 'tracking_code' in changes click_and_collect_changed = 'click_and_collect' in changes delivery_option_changed = ('delivery_option_id' in changes or 'delivery_quote' in changes) delivery_address_changed = ('delivery_name' in changes or 'delivery_company' in changes or 'delivery_address1' in changes or 'delivery_address2' in changes or 'delivery_address3' in changes or 'delivery_city' in changes or 'delivery_county' in changes or 'delivery_postcode' in changes or 'delivery_country_id' in changes) changed = (status_changed or tracking_changed or click_and_collect_changed or delivery_option_changed or delivery_address_changed) # fulfillment if instance.status in OrderBase.FULFILLED_STATUS and not instance.fulfilled: (success, msg) = instance.fulfill(request) if success: messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been fulfilled successfully.' % instance.order_id) else: messages.add_message( request, messages.ERROR, 'Error while fulfilling order <em>%s</em>: %s' % (instance.order_id, msg)) # send email if something of importance changed if changed: if int(instance.status) in [ OrderBase.STATUS_PARTIALLY_SHIPPED, OrderBase.STATUS_SHIPPED, OrderBase.STATUS_READY_TO_COLLECT, OrderBase.STATUS_COLLECTED ]: if mail_customer_order_status(request, instance): messages.add_message( request, messages.SUCCESS, 'Email sent to customer: %s' % instance.email) # redirect to payment if request.POST.get('autosubmit'): return HttpResponseRedirect( '%s%s' % (instance.get_absolute_url(), '?autosubmit=true')) def _create_edit(self, request, pk=None, edit=False, duplicate=False): context = super(OrderView, self)._create_edit(request, pk, edit, duplicate) if edit: context['order'] = context.get('object') return context def view(self, request): """ View existing order and make some minor amendments to it (previous order screen). """ pk = request.GET.get('pk') order = get_object_or_404(get_order_model(), pk=pk) if request.method == 'POST': form = ChangeOrderStatusForm(request.POST) else: form = ChangeOrderStatusForm( initial={ 'status': order.status, 'tracking_provider': order.tracking_provider, 'tracking_code': order.tracking_code, 'delivery_type': order.delivery_type, 'delivery_name': order.delivery_name, 'delivery_company': order.delivery_company, 'delivery_address1': order.delivery_address1, 'delivery_address2': order.delivery_address2, 'delivery_address3': order.delivery_address3, 'delivery_city': order.delivery_city, 'delivery_county': order.delivery_county, 'delivery_postcode': order.delivery_postcode, 'delivery_country': order.delivery_country, 'special_requirements': order.special_requirements, }) form.configure(request, order) if request.method == 'POST': # from cancellation if request.POST.get('cubane_form_cancel', '0') == '1': return self._redirect(request, 'index') # valid? if form.is_valid(): d = form.cleaned_data # update status new_status = int(d.get('status')) status_changed = order.status != new_status order.status = new_status order.special_requirements = d.get('special_requirements') # update tracking code tracking_changed = ( order.tracking_provider != d.get('tracking_provider') or \ order.tracking_code != d.get('tracking_code') ) order.tracking_provider = d.get('tracking_provider') order.tracking_code = d.get('tracking_code') # update delivery type new_delivery_type = int(d.get('delivery_type')) delivery_type_changed = order.delivery_type != new_delivery_type order.delivery_type = new_delivery_type # update delivery address, if this is a delivery order delivery_address_changed = False if not order.is_click_and_collect: delivery_address_changed = ( order.delivery_name != d.get('delivery_name') or \ order.delivery_company != d.get('delivery_company') or \ order.delivery_address1 != d.get('delivery_address1') or \ order.delivery_address2 != d.get('delivery_address2') or \ order.delivery_address3 != d.get('delivery_address3') or \ order.delivery_city != d.get('delivery_city') or \ order.delivery_county != d.get('delivery_county') or \ order.delivery_postcode != d.get('delivery_postcode') or \ order.delivery_country != d.get('delivery_country') ) order.delivery_name = d.get('delivery_name') order.delivery_company = d.get('delivery_company') order.delivery_address1 = d.get('delivery_address1') order.delivery_address2 = d.get('delivery_address2') order.delivery_address3 = d.get('delivery_address3') order.delivery_city = d.get('delivery_city') order.delivery_county = d.get('delivery_county') order.delivery_postcode = d.get('delivery_postcode') order.delivery_country = d.get('delivery_country') # update processing state for all line items order.reset_processed_state() indexes = request_int_list(request.POST, 'processed') for index in indexes: order.mark_item_as_processed(index, True) # update shipped state for all line items order.reset_shipped_state() indexes = request_int_list(request.POST, 'shipped') for index in indexes: order.mark_item_as_shipped(index, True) # save order order.save() # fulfillment if order.status in OrderBase.FULFILLED_STATUS and not order.fulfilled: (success, msg) = order.fulfill(request) if success: messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been fulfilled successfully.' % order.order_id) else: messages.add_message( request, messages.ERROR, 'Error while fulfilling order <em>%s</em>: %s' % (order.order_id, msg)) # send email if something of importance changed if status_changed or tracking_changed or delivery_type_changed or delivery_address_changed: if int(order.status) in [ OrderBase.STATUS_PARTIALLY_SHIPPED, OrderBase.STATUS_SHIPPED, OrderBase.STATUS_READY_TO_COLLECT, OrderBase.STATUS_COLLECTED ]: if mail_customer_order_status(request, order): messages.add_message( request, messages.SUCCESS, 'Email sent to customer: %s' % order.email) messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been updated.' % order.order_id) active_tab = request.POST.get('cubane_save_and_continue', '0') if not active_tab == '0': return HttpResponseRedirect( reverse('cubane.ishop.orders.edit') + '?pk=%d' % order.pk) else: return self._redirect(request, 'index') return {'order': order, 'form': form, 'edit': True} def _create_order(self, request): """ Create new order. """ # determine form class order_model = get_order_model() formclass = order_model.get_form() # create form if request.method == 'POST': form = formclass(request.POST) else: form = formclass() form.configure(request, None, False) # validate form if request.method == 'POST' and form.is_valid(): d = form.cleaned_data # create new order order = order_model.create_empty_customer_not_present(request) # redirect to edit page return self._redirect(request, 'edit', order) return {'form': form, 'edit': False} def approve(self, request): order_id = request.GET.get('pk') edit_order = request.GET.get('edit_order', 'false') == 'true' order = get_object_or_404(get_order_model(), pk=order_id) if request.method == 'POST': form = ApproveOrderForm(request.POST) else: form = ApproveOrderForm() if request.method == 'POST': if request.POST.get('cubane_form_cancel', '0') == '1': if edit_order: return self._redirect(request, 'edit', order) else: return self._redirect(request, 'index') if form.is_valid(): (success, msg) = order.approve(request) if success and order.approval_status == OrderBase.APPROVAL_STATUS_APPROVED: messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been approved.' % order.order_id) else: messages.add_message( request, messages.ERROR, 'We were unable to approve the order <em>%s</em>: %s' % (order.order_id, msg)) if edit_order: return self._redirect(request, 'edit', order) else: return self._redirect(request, 'index') return {'order': order, 'form': form} def reject(self, request): order_id = request.GET.get('pk') edit_order = request.GET.get('edit_order', 'false') == 'true' order = get_object_or_404(get_order_model(), pk=order_id) if request.method == 'POST': form = RejectOrderForm(request.POST) else: form = RejectOrderForm() if request.method == 'POST': if request.POST.get('cubane_form_cancel', '0') == '1': if edit_order: return self._redirect(request, 'edit', order) else: return self._redirect(request, 'index') if form.is_valid(): (success, msg) = order.reject(request, form.cleaned_data.get('reject_msg')) if success and order.approval_status == OrderBase.APPROVAL_STATUS_REJECTED: messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been rejected.' % order.order_id) else: messages.add_message( request, messages.ERROR, 'We were unable to reject the order <em>%s</em>: %s' % (order.order_id, msg)) if edit_order: return self._redirect(request, 'edit', order) else: return self._redirect(request, 'index') return {'order': order, 'form': form} def cancel(self, request): order_id = request.GET.get('pk') edit_order = request.GET.get('edit_order', 'false') == 'true' order = get_object_or_404(get_order_model(), pk=order_id) def _do_redirect(): if edit_order: return self._redirect(request, 'edit', order) else: return self._redirect(request, 'index') # cannot cancel if we are awaiting payment approval/rejection if order.approval_status == OrderBase.APPROVAL_STATUS_WAITING: messages.add_message( request, messages.ERROR, 'Order <em>%s</em> is awaiting approval. Please accept or reject this order.' % order.order_id) return _do_redirect() # cannot cancel if the order has already been cancelled if order.cancelled: messages.add_message( request, messages.ERROR, 'Order <em>%s</em> has already been cancelled.' % order.order_id) return _do_redirect() # process cancellation form if request.method == 'POST': form = CancelOrderForm(request.POST) else: form = CancelOrderForm() if request.method == 'POST': if request.POST.get('cubane_form_cancel', '0') == '1': _do_redirect() if form.is_valid(): (success, msg) = order.cancel(request, form.cleaned_data.get('cancel_msg')) if success: messages.add_message( request, messages.SUCCESS, 'Order <em>%s</em> has been cancelled.' % order.order_id) else: messages.add_message( request, messages.ERROR, 'We were unable to cancel the order <em>%s</em>: %s' % (order.order_id, msg)) _do_redirect() return {'order': order, 'form': form} def basket_editor(self, request): prefix = request.GET.get('prefix') basket = Basket(request, prefix=prefix) return {'basket': basket} def basket_editor_search(self, request): from cubane.ishop.views import get_shop q = request.POST.get('q') shop = get_shop() products = shop.get_products().filter( Q(title__icontains=q) | Q(barcode__startswith=q) | Q(part_number__startswith=q) | Q(sku_enabled=True, sku__startswith=q), draft=False) return {'products': products[:100]} def basket_editor_add_to_basket(self, request): from cubane.ishop.views import get_shop pk = request.POST.get('pk') prefix = request.POST.get('prefix') shop = get_shop() product = shop.get_products().get(pk=pk) return {'product': product, 'prefix': prefix, 'settings': settings}
def process_payment(request, gateway, transaction_id): """ Process payment information for the order with the given transaction id. """ # if the payment gateway returns no transaction id, # we consider this as an error. if transaction_id == None: mail_error( 'Payment gateway %s was unable to identify transaction id based on the payment response %s.' % (gateway, request)) return gateway.payment_response(request, PaymentGateway.RESPONSE_ERROR, None, None) # get order based on transaction id order_model = get_order_model() try: order = order_model.objects.get(transaction_id=transaction_id) registration_context = RegistrationContext(order.transaction_id, order.payment_details) except order_model.DoesNotExist: # unable to identify correct order. return HttpResponse('', content_type='text/plain') # let the payment gateway determine the success of the payment # based on the response... payment_status = gateway.payment_accept(request, order, registration_context) # translate payment gateway payment status to system state if payment_status == PaymentGateway.STATUS_PAYMENT_CONFIRMED: if order.preauth: order.approval_status = OrderBase.APPROVAL_STATUS_WAITING else: order.approval_status = OrderBase.APPROVAL_STATUS_NONE order.status = OrderBase.STATUS_PAYMENT_CONFIRMED order.payment_confirmed_at = datetime.datetime.now() order.save() elif payment_status == PaymentGateway.STATUS_PAYMENT_DECLINED: order.status = OrderBase.STATUS_PAYMENT_DECLINED order.save() elif payment_status == PaymentGateway.STATUS_PENDING: order.status = OrderBase.STATUS_PENDING order.save() elif payment_status == PaymentGateway.STATUS_PAYMENT_ERROR: order.status = OrderBase.STATUS_PAYMENT_ERROR order.save() mail_error('Payment error (gateway %s): %s' % (gateway.__class__.__name__, gateway.message)) else: order.status = OrderBase.STATUS_PAYMENT_ERROR order.save() mail_error( 'Received unknown payment response for order %s from gateway %s. Gateway message = %s' % (order.id, gateway.__class__.__name__, gateway.message)) # send out emails and order/shipping notes generate_emails_and_notes(request, order) # send success back to payment gateway (this does not neccessarily # mean that the actual payment was successful)... if order.is_backend_payment: next_url = '%s?pk=%s' % (get_absolute_url('cubane.ishop.orders.edit'), order.pk) else: next_url = get_absolute_url('shop.order.status', args=[order.secret_id]) return gateway.payment_response(request, PaymentGateway.RESPONSE_SUCCESS, order, registration_context, next_url)
def pay(request): """ Start payment based on particular payment provided. At this point in time, the basket is destroyed. """ # get order secret_id = request.POST.get('secret_id', None) if secret_id == None: raise Http404('Missing argument: secret_id.') if not re.match(r'^[a-fA-F0-9]+$', secret_id): raise Http404('Invalid format for argument: secret_id.') order = get_object_or_404(get_order_model(), secret_id=secret_id) # if the order is via invoice, accept order instantly without going through # online payment if order.is_invoice: # verify that the order can be placed if not order.can_be_placed_via_invoice(): raise Http404( 'Unable to place the given order because of its status.') order.status = OrderBase.STATUS_PLACED_INVOICE order.save() generate_emails_and_notes(request, order) _destroy_basket(request) return HttpResponseRedirect( reverse('shop.order.status', args=[secret_id])) # if the total amount payable is zero, then skip the payment process # but the order is not an invoice as such. if order.is_zero_amount_checkout: order.status = OrderBase.STATUS_PLACED_ZERO_AMOUNT order.save() generate_emails_and_notes(request, order) _destroy_basket(request) return HttpResponseRedirect( reverse('shop.order.status', args=[secret_id])) # get gateway gateway = order.get_payment_gateway() # if we retry an existing order, clone the order first, which implicitly # generates a new order id... retry = request.POST.get('retry', '0') == '1' if retry == True and order.is_retry(): order = order.clone(request) # verify that the order has not already been confirmed if not order.can_be_registered_for_payment(): raise Http404( 'Unable to register the given order because of its status.') # if order can be moto order.is_backend_payment = False if order.can_moto and request.user.is_staff: order.is_backend_payment = True # register a new transaction for payment if order.is_backend_payment: preauth = False else: preauth = settings.SHOP_PREAUTH registration_context = gateway.register_payment(request, order, preauth=preauth) # if we do not get a valid registration content, # consider this payment attempt to be failed if registration_context == None: mail_error( 'Payment gateway %s was unable to register payment transaction. Message: %s' % (gateway.name, gateway.message)) order.status = OrderBase.STATUS_PAYMENT_ERROR order.save() return HttpResponseRedirect( reverse('shop.order.status', args=[order.secret_id])) # save transcation details within order order.transaction_id = registration_context.transaction_id order.payment_details = registration_context.payment_details order.status = OrderBase.STATUS_PAYMENT_AWAITING order.save() _destroy_basket(request) if gateway.is_redirect(): # let the payment gateway render the response, which might be a redirect # or a custom submit form... return gateway.payment_redirect(request, order, registration_context) else: # handle payment directly return process_payment(request, gateway, order.transaction_id)
def complete(request): """ (3) Final checkout step, where the order is actually created from the basket. """ basket = Basket(request) # redirect back to a previous step if we missed anything... next = get_next_checkout_step(request, basket, CurrentPage.COMPLETE()) if next: return HttpResponseRedirect(next) # state or county if 'state' in basket.billing_address: county = basket.billing_address.get('state') else: county = basket.billing_address.get('county') # create account if requested if basket.signup: # create user account md5 = hashlib.md5() md5.update(basket.signup.get('email')) email = basket.signup.get('email') if User.objects.filter(email=email).count() > 0: messages.warning( request, 'There is already an account with this email: %s.' % email) return HttpResponseRedirect(reverse('shop.account.login')) user = User.objects.create(username=md5.hexdigest()[:30], first_name=basket.signup.get('first_name'), last_name=basket.signup.get('last_name'), email=email) # replace username with user id and set password user.username = unicode(user.id) user.set_password(basket.signup.get('password')) user.save() # create profile get_customer_model().objects.create( user=user, first_name=user.first_name, last_name=user.last_name, email=user.email, title=basket.billing_address.get('title'), address1=basket.billing_address.get('address1'), address2=basket.billing_address.get('address2'), address3=basket.billing_address.get('address3'), city=basket.billing_address.get('city'), county=county, postcode=basket.billing_address.get('postcode'), country=basket.billing_address.get('country'), telephone=basket.billing_address.get('telephone'), newsletter=basket.newsletter) # log user in login_user_without_password(request, user) basket.signup = None else: if request.user.is_anonymous(): user = None else: user = request.user # if specified, copy relevant information to customer's profile if user != None and basket.update_profile: user.first_name = basket.billing_address.get('first_name') user.last_name = basket.billing_address.get('last_name') user.save() customer = get_customer_model().objects.get(user=user) customer.address1 = basket.billing_address.get('address1') customer.address2 = basket.billing_address.get('address2') customer.address3 = basket.billing_address.get('address3') customer.city = basket.billing_address.get('city') customer.county = county customer.postcode = basket.billing_address.get('postcode') customer.country = basket.billing_address.get('country') customer.telephone = basket.billing_address.get('telephone') customer.save() # create single order order = get_order_model().create_from_basket(request, basket, user) # mailchimp if request.settings.mailchimp_enabled and basket.newsletter: email = basket.billing_address.get('email') first_name = basket.billing_address.get('first_name') last_name = basket.billing_address.get('last_name') person_name = (first_name, last_name) merge_vars = {'FNAME': " ".join(person_name)} ms = MailSnake(request.settings.mailchimp_api) try: ms.listSubscribe(id=request.settings.mailchimp_list_id, email_address=email, merge_vars=merge_vars) except: pass # redirect to order status page (payment from there...) basket.save() return HttpResponseRedirect( reverse('shop.order.status', args=[order.secret_id]))