Exemple #1
0
    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
Exemple #2
0
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())
Exemple #3
0
 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),
         )
Exemple #4
0
    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)
Exemple #5
0
 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
Exemple #6
0
    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)
            }
        }
Exemple #7
0
    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))
Exemple #8
0
 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),
         )
Exemple #9
0
 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
Exemple #10
0
 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))
Exemple #11
0
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
Exemple #12
0
 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
Exemple #13
0
 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)
Exemple #14
0
    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
Exemple #15
0
    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))
Exemple #16
0
 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)
Exemple #17
0
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)
Exemple #18
0
 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)
Exemple #19
0
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
Exemple #20
0
    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)
Exemple #21
0
 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
Exemple #22
0
    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)
Exemple #23
0
    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)
Exemple #24
0
 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))
Exemple #25
0
    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)
Exemple #26
0
    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)
Exemple #27
0
    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>&nbsp;"
            % {
                "text": escape(text),
                "url": escape(url),
            })
Exemple #28
0
    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))
Exemple #29
0
    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
Exemple #30
0
    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))