def get_success_url(self): if self.request.GET.get("mode", "") == "iframe": quick_add_target = self.request.GET.get("quick_add_target") return "%s?mode=iframe&quick_add_target=%s&iframe_close=yes" % ( get_model_url(self.object, shop=self.request.shop), quick_add_target) next = self.request.POST.get("__next") try: if next == "return": return self.get_return_url() elif next == "new": return self.get_new_url() except NoModelUrl: pass try: return super(CreateOrUpdateView, self).get_success_url() except ImproperlyConfigured: pass try: return get_model_url(self.object, shop=self.request.shop) except NoModelUrl: pass
def test_model_url(): with admin_only_urls(): with pytest.raises(NoModelUrl): get_model_url(Counter) # That's silly! p = get_default_product() assert get_model_url(p, shop=get_default_shop())
def _get_parent_and_sibling_items(self, parent, siblings): yield DropdownItem( text=_("Parent: %s") % parent, icon="fa fa-eye", url=get_model_url(parent, shop=self.request.shop), ) for sib in siblings: yield DropdownItem( text=_("Sibling: %s") % sib, icon="fa fa-eye", url=get_model_url(sib, shop=self.request.shop), )
def save_form_parts(self, form): is_new = (not self.object.pk) form_parts = self.get_form_parts(self.object) for form_part in form_parts: retval = form_part.form_valid(form) if retval is not None: # Allow a form part to change the identity of the object self.object = retval for form_part in form_parts: form_part.object = self.object if is_new: object_created.send(sender=type(self.object), object=self.object) add_create_or_change_message(self.request, self.object, is_new) if self.request.GET.get( "redirect") and not self.request.POST.get("__next"): return HttpResponseRedirect(self.request.GET.get("redirect")) if hasattr(self, "get_success_url"): return HttpResponseRedirect(self.get_success_url()) if is_new: return HttpResponseRedirect( get_model_url(self.object, shop=self.request.shop)) else: return HttpResponseRedirect(self.request.path)
def get_toolbar(self): toolbar = get_default_edit_toolbar(self, "change_password_form", discard_url=get_model_url( self.object), with_split_save=False) return toolbar
def handle_product_data(self, request): product_id = request.GET["id"] shop_id = request.GET["shop_id"] customer_id = request.GET.get("customer_id") supplier_id = request.GET.get("supplier_id") quantity = decimal.Decimal(request.GET.get("quantity", 1)) product = Product.objects.filter(pk=product_id).first() if not product: return {"errorText": _("Product %s does not exist.") % product_id} shop = Shop.objects.get(pk=shop_id) try: shop_product = product.get_shop_instance(shop) except ShopProduct.DoesNotExist: return { "errorText": _("Product %(product)s is not available in the %(shop)s shop.") % {"product": product.name, "shop": shop.name} } min_quantity = shop_product.minimum_purchase_quantity # Make quantity to be at least minimum quantity quantity = (min_quantity if quantity < min_quantity else quantity) customer = Contact.objects.filter(pk=customer_id).first() if customer_id else None price_info = get_price_info(shop, customer, product, quantity) supplier = None if supplier_id: supplier = shop_product.suppliers.filter(id=supplier_id).first() if not supplier: supplier = shop_product.get_supplier(customer, quantity) stock_status = supplier.get_stock_status(product.pk) if supplier else None return { "id": product.id, "sku": product.sku, "name": product.name, "quantity": quantity, "logicalCount": stock_status.logical_count if stock_status else 0, "physicalCount": stock_status.physical_count if stock_status else 0, "salesDecimals": product.sales_unit.decimals if product.sales_unit else 0, "salesUnit": product.sales_unit.symbol if product.sales_unit else "", "purchaseMultiple": shop_product.purchase_multiple, "taxClass": { "id": product.tax_class.id, "name": force_text(product.tax_class), }, "baseUnitPrice": { "value": price_info.base_unit_price.value, "includesTax": price_info.base_unit_price.includes_tax }, "unitPrice": { "value": price_info.discounted_unit_price.value, "includesTax": price_info.base_unit_price.includes_tax }, "product": { "text": product.name, "id": product.id, "url": get_model_url(product, shop=request.shop) } }
def form_valid(self, form): order = self.get_object() for key, field_title in [("billing_address", _("Billing Address")), ("shipping_address", _("Shipping Address"))]: if not form[key].has_changed(): continue new_mutable_address = form[key].save() new_immutable_address = new_mutable_address.to_immutable() new_immutable_address.save() old_address = getattr(order, key) setattr(order, key, new_immutable_address) new_mutable_address.delete() order.save(update_fields=[key]) log_entry_message = _( "%(field)s updated from: %(old_address)s") % { "field": field_title, "old_address": old_address } order.add_log_entry(log_entry_message[:256], identifier=ADDRESS_EDITED_LOG_IDENTIFIER, kind=LogEntryKind.EDIT) messages.success( self.request, _("%(field)s saved successfully.") % {"field": field_title}) return HttpResponseRedirect(get_model_url(order))
def _get_children_items(self, children): for child in children: yield DropdownItem( text=_("Child: %s") % child, icon="fa fa-eye", url=get_model_url(child, shop=self.request.shop), )
def get_toolbar(self): toolbar = get_default_edit_toolbar(self, "permissions_form", discard_url=get_model_url( self.object), with_split_save=False) return toolbar
def get_toolbar(self): save_form_id = self.get_save_form_id() object = self.get_object() delete_url = get_model_url(object, "delete") if object.pk else None return get_default_edit_toolbar( self, save_form_id, delete_url=(delete_url if object.can_delete() else None))
def check_for_delete(view, request, object): can_delete = object.can_delete() delete_url = get_model_url(object, "delete") response = view(request, pk=object.pk) if hasattr(response, "render"): response.render() assert response.status_code in [200, 302] assert bool(delete_url in force_text(response.content)) == can_delete
def get_object_url(self, instance): try: return get_model_url(instance, user=self.request.user, shop=self.request.shop) except NoModelUrl: pass return None
def get_search_results(self, request, query): minimum_query_length = 3 if len(query) >= minimum_query_length: users = get_user_model().objects.filter( Q(username__icontains=query) | Q(email=query)) for i, user in enumerate(users[:10]): relevance = 100 - i yield SearchResult(text=six.text_type(user), url=get_model_url(user), category=_("Contacts"), relevance=relevance)
def get_toolbar(self): toolbar = get_default_edit_toolbar( self, self.get_save_form_id(), discard_url=(get_model_url(self.object) if self.object.pk else None)) for button in get_provide_objects("admin_contact_edit_toolbar_button"): toolbar.append(button(self.object)) return toolbar
def form_valid(self, form): order = self.object restock_products = bool(form.cleaned_data.get("restock_products")) try: order.create_full_refund(restock_products) except NoRefundToCreateException: messages.error(self.request, _("Could not create full refund.")) return self.form_invalid(form) messages.success(self.request, _("Full refund created.")) return HttpResponseRedirect(get_model_url(order))
def get_help_blocks(self, request, kind): yield SimpleHelpBlock( text=_("Add a product category to organize your products"), actions=[{ "text": _("New category"), "url": get_model_url(Category, "new") }], icon_url="wshop_admin/img/category.png", category=HelpBlockCategory.PRODUCTS, priority=1, done=Category.objects.filter( shops=request.shop).exists() if kind == "setup" else False)
def test_model_url_with_permissions(): permissions = set( ["wshop.add_product", "wshop.delete_product", "wshop.change_product"]) shop = get_default_shop() p = get_default_product() # If no user is given, don't check for permissions assert get_model_url(p, shop=shop) # If a user is given and no permissions are provided, check for default model permissions user = StaffUser() with pytest.raises(NoModelUrl): assert get_model_url(p, user=user, shop=shop) # If a user is given and permissions are provided, check for those permissions assert get_model_url(p, user=user, required_permissions=(), shop=shop) with pytest.raises(NoModelUrl): assert get_model_url(p, user=user, required_permissions=["wshop.add_product"], shop=shop) # Confirm that url is returned with correct permissions user.permissions = permissions assert get_model_url(p, user=user, shop=shop) assert get_model_url(p, user=user, required_permissions=permissions, shop=shop)
def get_search_results(self, request, query): minimum_query_length = 3 if len(query) >= minimum_query_length: categories = Category.objects.filter( Q(translations__name__icontains=query) | Q(identifier__icontains=query)).distinct().order_by( "tree_id", "lft") for i, category in enumerate(categories[:10]): relevance = 100 - i yield SearchResult(text=six.text_type(category), url=get_model_url(category), category=self.category, relevance=relevance)
def test_product_module_search(rf, admin_user): get_default_shop() request = apply_request_middleware(rf.get("/"), user=admin_user) with replace_modules([CategoryModule, ImportAdminModule, ProductModule, ProductTypeModule, ManufacturerModule, PaymentMethodModule, ShippingMethodModule]): with admin_only_urls(): default_product = get_default_product() model_url = get_model_url(default_product, shop=get_shop(request)) sku = default_product.sku assert any(sr.url == model_url for sr in get_search_results(request, query=sku)) # Queries work assert any(sr.is_action for sr in get_search_results(request, query=sku[:5])) # Actions work assert empty_iterable(get_search_results(request, query=sku[:2])) # Short queries don't
def get_search_results(self, request, query): minimum_query_length = 3 if len(query) >= minimum_query_length: orders = Order.objects.filter( Q(identifier__istartswith=query) | Q(reference_number__istartswith=query) | Q(email__icontains=query) | Q(phone__icontains=query)).order_by("-id")[:15] for i, order in enumerate(orders): relevance = 100 - i yield SearchResult(text=six.text_type(order), url=get_model_url(order), category=_("Orders"), relevance=relevance)
def get_context_data(self, **kwargs): context = super(EditScriptContentView, self).get_context_data(**kwargs) context["title"] = get_create_or_change_title(self.request, self.object) context["action_infos"] = Action.get_ui_info_map() context["condition_infos"] = Condition.get_ui_info_map() context["cond_op_names"] = get_enum_choices_dict(StepConditionOperator) context["step_next_names"] = get_enum_choices_dict(StepNext) context["toolbar"] = Toolbar([ JavaScriptActionButton( text="Save", icon="fa fa-save", extra_css_class="btn-success", onclick="ScriptEditor.save();return false" ), get_discard_button(get_model_url(self.object, "edit")) ]) return context
def get_search_results(self, request, query): minimum_query_length = 3 if len(query) >= minimum_query_length: filters = Q(Q(name__icontains=query) | Q(email=query)) # show only contacts which the shop has access if settings.WSHOP_ENABLE_MULTIPLE_SHOPS and settings.WSHOP_MANAGE_CONTACTS_PER_SHOP: filters &= Q(shops=request.shop) contacts = Contact.objects.filter(filters) for i, contact in enumerate(contacts[:10]): relevance = 100 - i yield SearchResult(text=six.text_type(contact), url=get_model_url(contact), category=_("Contacts"), relevance=relevance)
def get_search_results(self, request, query): if not settings.WSHOP_ENABLE_MULTIPLE_SHOPS: return minimum_query_length = 3 if len(query) >= minimum_query_length: shops = Shop.objects.get_for_user( request.user).filter(translations__name__icontains=query) for i, shop in enumerate(shops[:10]): relevance = 100 - i yield SearchResult( text=(_('Set "{}" as the active shop')).format(shop.name), url=get_model_url(shop, "select"), category=( _("Available Shops [currently active: {}]")).format( request.shop.name), relevance=relevance)
def form_valid(self, form): order = self.object amount = Money(form.cleaned_data["amount"], order.currency) if amount.value == 0: messages.error(self.request, _("Payment amount cannot be 0")) return self.form_invalid(form) try: payment = order.create_payment(amount, description="Manual payment") messages.success( self.request, _("Payment %s created.") % payment.payment_identifier) except NoPaymentToCreateException: messages.error(self.request, _("Order has already been paid")) return self.form_invalid(form) else: return HttpResponseRedirect(get_model_url(order))
def for_model(cls, model, **kwargs): """ Generate a NewActionButton for a model, auto-wiring the URL. :param model: Model class :rtype: wshop.admin.toolbar.NewActionButton|None """ if "url" not in kwargs: try: url = get_model_url(model, kind="new") except NoModelUrl: return None kwargs["url"] = url kwargs.setdefault( "text", _("New %(model)s") % {"model": model._meta.verbose_name}) return cls(**kwargs)
def for_model(cls, model, **kwargs): """ Generate a SettingsActionButton for a model, auto-wiring the URL. :param model: Model class :rtype: wshop.admin.toolbar.SettingsActionButton|None """ if "url" not in kwargs: try: url = get_model_url(model, kind="list_settings") except NoModelUrl: return None return_url = kwargs.get("return_url") if not return_url: return_url = camelcase_to_snakecase(model.__name__) kwargs["url"] = url + "?module=%s&model=%s&return_url=%s" % ( model.__module__, model.__name__, return_url) return cls(**kwargs)
def render_text(self, obj): url = getattr(obj, "url", None) text = self.empty_text if obj: text = force_text(obj) if not url: try: url = get_model_url(obj) except NoModelUrl: pass if not url: url = "#" return mark_safe( "<a class=\"browse-text\" href=\"%(url)s\" target=\"_blank\">%(text)s</a> " % { "text": escape(text), "url": escape(url), })
def form_valid(self, form): order = self.object refund_lines = [] for refund in form.cleaned_data: line = self._get_refund_line_info(order, refund) if line: refund_lines.append(line) try: order.create_refund(refund_lines, created_by=self.request.user) except RefundExceedsAmountException: messages.error(self.request, _("Refund amount exceeds order amount.")) return self.form_invalid(form) except InvalidRefundAmountException: messages.error(self.request, _("Refund amounts should match sign on parent line.")) return self.form_invalid(form) messages.success(self.request, _("Refund created.")) return HttpResponseRedirect(get_model_url(order))
def get_toolbar(self): save_form_id = self.get_save_form_id() object = self.get_object() delete_url = reverse_lazy("wshop_admin:service_provider.delete", kwargs={"pk": object.pk}) toolbar = get_default_edit_toolbar(self, save_form_id, delete_url=delete_url) if self.object.pk: toolbar.append( URLActionButton(text=_("Create {service_name}").format( service_name=self.object.service_model._meta.verbose_name), icon="fa fa-plus", url="{model_url}?provider={id}".format( model_url=get_model_url( self.object.service_model, "new"), id=self.object.id), extra_css_class="btn-info")) return toolbar
def form_valid(self, form): product_ids_to_quantities = dict( (int(key.replace("q_", "")), value) for (key, value) in six.iteritems(form.cleaned_data) if key.startswith("q_") and (value > 0 if value else False)) order = self.object product_map = Product.objects.in_bulk( set(product_ids_to_quantities.keys())) products_to_quantities = dict( (product_map[product_id], quantity) for (product_id, quantity) in six.iteritems(product_ids_to_quantities)) unsaved_shipment = Shipment( order=order, supplier=form.cleaned_data["supplier"], tracking_code=form.cleaned_data.get("tracking_code"), description=form.cleaned_data.get("description"), ) has_extension_errors = self.form_valid_hook(form, unsaved_shipment) if has_extension_errors: return self.form_invalid(form) try: shipment = self.create_shipment( order=order, product_quantities=products_to_quantities, shipment=unsaved_shipment) except Problem as problem: messages.error(self.request, problem) return self.form_invalid(form) except NoProductsToShipException: messages.error(self.request, _("No products to ship.")) return self.form_invalid(form) except NoShippingAddressException: messages.error(self.request, _("Shipping address is not set.")) else: messages.success(self.request, _("Shipment %s created.") % shipment.id) return HttpResponseRedirect(get_model_url(order))