Example #1
0
 def __str__(self):
     text = super(Tax, self).__str__()
     if self.rate is not None:
         text += " ({})".format(format_percent(self.rate, digits=3))
     if self.amount is not None:
         text += " ({})".format(format_money(self.amount))
     return text
def get_price_ranges(shop, min_price, max_price, range_step):
    if range_step == 0:
        return

    ranges = []
    min_price_value = format_money(shop.create_price(min_price))
    ranges.append(("-%s" % min_price, _("Under %(min_limit)s") % {"min_limit": min_price_value}))

    for range_min in range(min_price, max_price, range_step):
        range_min_price = format_money(shop.create_price(range_min))
        range_max = range_min + range_step
        if range_max < max_price:
            range_max_price = format_money(shop.create_price(range_max))
            ranges.append(
                ("%s-%s" % (range_min, range_max), "%s to %s" % (range_min_price, range_max_price)))

    max_price_value = format_money(shop.create_price(max_price))
    ranges.append(("%s-" % max_price, _("%(max_limit)s & Above") % {"max_limit": max_price_value}))
    return ranges
Example #3
0
def encode_line(line):
    if line.base_unit_price.amount.value != 0:
        discount_percent = (
            line.discount_amount.amount.value / (line.base_unit_price.amount.value * line.quantity)
        )
    else:
        discount_percent = 0
    return {
        "sku": line.sku,
        "text": line.text,
        "quantity": format_decimal(line.quantity, locale=get_current_babel_locale()),
        "unitPrice": format_money(line.base_unit_price.amount),
        "discountedUnitPrice": format_money(line.discounted_unit_price.amount),
        "discountAmount": format_money(line.discount_amount.amount),
        "discountPercent": format_percent(discount_percent, 2),
        "taxlessTotal": format_money(line.taxless_price.amount),
        "taxPercentage": format_percent(line.tax_rate, 2),
        "taxfulTotal": format_money(line.taxful_price.amount)
    }
Example #4
0
 def _handle_source_data(self, request):
     self.object = self.get_object()
     state = json.loads(self.get_request_body(request))["state"]
     source = create_source_from_state(
         state,
         creator=request.user,
         ip_address=request.META.get("REMOTE_ADDR"),
         order_to_update=self.object if self.object.pk else None
     )
     # Calculate final lines for confirmation
     source.calculate_taxes(force_recalculate=True)
     return {
         "taxfulTotal": format_money(source.taxful_total_price.amount),
         "taxlessTotal": format_money(source.taxless_total_price.amount),
         "totalDiscountAmount": format_money(source.total_discount.amount),
         "orderLines": [encode_line(line) for line in source.get_final_lines(with_taxes=True)],
         "billingAddress": source.billing_address.as_string_list() if source.billing_address else None,
         "shippingAddress": source.shipping_address.as_string_list() if source.shipping_address else None,
     }
Example #5
0
def test_order_creator_customer_details(rf, admin_user):
    shop = get_default_shop()
    contact = create_random_person(locale="en_US", minimum_name_comp_len=5)
    company = create_random_company()
    group = get_default_customer_group()
    contact.groups.add(group)
    contact.company_memberships.add(company)
    contact.save()
    product = create_product(sku=printable_gibberish(),
                             supplier=get_default_supplier(),
                             shop=shop)
    order = create_random_order(contact, products=[product])
    request = apply_request_middleware(rf.get(
        "/", {
            "command": "customer_details",
            "id": contact.id
        }),
                                       user=admin_user)
    response = OrderEditView.as_view()(request)
    data = json.loads(response.content.decode("utf8"))

    assert "customer_info" in data
    assert "order_summary" in data
    assert "recent_orders" in data
    assert data["customer_info"]["name"] == contact.full_name
    assert data["customer_info"]["phone_no"] == contact.phone
    assert data["customer_info"]["email"] == contact.email
    assert company.full_name in data["customer_info"]["companies"]
    assert group.name in data["customer_info"]["groups"]
    assert data["customer_info"]["merchant_notes"] == contact.merchant_notes
    assert len(data["order_summary"]) == 1
    assert data["order_summary"][0]["year"] == order.order_date.year
    assert data["order_summary"][0]["total"] == format_money(
        order.taxful_total_price)
    assert len(data["recent_orders"]) == 1
    assert data["recent_orders"][0]["status"] == order.get_status_display()
    assert data["recent_orders"][0]["total"] == format_money(
        order.taxful_total_price)
    assert data["recent_orders"][0]["payment_status"] == force_text(
        order.payment_status.label)
    assert data["recent_orders"][0]["shipment_status"] == force_text(
        order.shipping_status.label)
Example #6
0
def _test_create_full_refund(browser, live_server, order):
    url = reverse("wshop_admin:order.create-refund", kwargs={"pk": order.pk})
    browser.visit("%s%s" % (live_server, url))
    wait_until_condition(
        browser, lambda x: x.is_text_present("Refunded: %s" % format_money(
            order.shop.create_price("0.00"))))
    wait_until_condition(
        browser, lambda x: x.is_text_present("Remaining: %s" % format_money(
            order.taxful_total_price)))
    url = reverse("wshop_admin:order.create-full-refund",
                  kwargs={"pk": order.pk})
    click_element(browser, "a[href='%s']" % url)
    wait_until_condition(
        browser, lambda x: x.is_text_present(
            "Refund Amount: %s" % format_money(order.taxful_total_price)))
    click_element(browser, "#create-full-refund")
    _check_create_refund_link(browser, order, False)
    _check_order_details_visible(browser)
    order.refresh_from_db()
    assert not order.taxful_total_price
    assert order.is_paid()
    assert order.is_fully_shipped()
Example #7
0
def money(amount, digits=None, widen=0):
    """
    Format money amount according to current locale settings.

    :param amount: Money or Price object to format
    :type amount: wshop.utils.money.Money
    :param digits: Number of digits to use, by default use locale's default
    :type digits: int|None
    :param widen:
      Number of extra digits to add; for formatting with additional
      precision, e.g. ``widen=3`` will use 5 digits instead of 2
    :type widen: int
    :return: Formatted string representing the given amount
    :rtype: str
    """
    return format_money(amount, digits, widen)
Example #8
0
def test_mixed_chart():
    labels = ["One", "Two", "Three"]
    locale = "pt_br"
    currency = "BRL"
    chart = MixedChart("ma biultiful xart",
                       labels,
                       data_type=ChartDataType.CURRENCY,
                       locale=locale,
                       currency=currency)

    dataset1 = OrderedDict({
        "type": ChartType.BAR,
        "label": "some bars #1",
        "data": [1, 2, 3]
    })
    dataset2 = OrderedDict({
        "type": ChartType.BAR,
        "label": "some bars #2",
        "data": [2, 3, 4]
    })
    dataset3 = OrderedDict({
        "type": ChartType.LINE,
        "label": "some lines #1",
        "data": [5, 6, 7]
    })
    dataset4 = OrderedDict({
        "type": ChartType.LINE,
        "label": "some lines #2",
        "data": [8, 9, 10]
    })
    datasets = [dataset1, dataset2, dataset3, dataset4]

    for dataset in datasets:
        chart.add_data(dataset["label"], dataset["data"], dataset["type"])

    chart_config = chart.get_config()
    assert chart_config["type"] == "mixed"
    assert chart_config["labels"] == labels

    for i in range(len(chart_config["data"])):
        for j in range(len(chart_config["data"][i]["data"])):
            assert chart_config["data"][i]["data"][j] == datasets[i]["data"][j]

            formatted_data = chart_config["data"][i]["formatted_data"][j]
            assert formatted_data == format_money(
                Money(datasets[i]["data"][j], currency=currency).as_rounded())
Example #9
0
    def get_validation_errors(self):  # noqa (C901)
        # check for the minimum sum of order total
        min_total = configuration.get(self.shop, ORDER_MIN_TOTAL_CONFIG_KEY,
                                      Decimal(0))
        total = (self.taxful_total_price.value if self.shop.prices_include_tax
                 else self.taxless_total_price.value)
        if total < min_total:
            min_total_price = format_money(self.shop.create_price(min_total))
            yield ValidationError(
                _("The total should be greater than {} to be ordered.").format(
                    min_total_price),
                code="order_total_too_low")

        shipping_method = self.shipping_method
        payment_method = self.payment_method

        if shipping_method:
            for error in shipping_method.get_unavailability_reasons(
                    source=self):
                yield error

        if payment_method:
            for error in payment_method.get_unavailability_reasons(
                    source=self):
                yield error

        for supplier in self._get_suppliers():
            for product, quantity in iteritems(
                    self._get_products_and_quantities(supplier)):
                try:
                    shop_product = product.get_shop_instance(shop=self.shop)
                except ShopProduct.DoesNotExist:
                    yield ValidationError(_("%s not available in this shop") %
                                          product.name,
                                          code="product_not_available_in_shop")
                    continue
                for error in shop_product.get_orderability_errors(
                        supplier=supplier,
                        quantity=quantity,
                        customer=self.customer):
                    error.message = "%s: %s" % (product.name, error.message)
                    yield error
Example #10
0
    def handle_customer_details(self, request):
        customer_id = request.GET["id"]
        customer = Contact.objects.get(pk=customer_id)
        companies = []
        if isinstance(customer, PersonContact):
            companies = sorted(customer.company_memberships.all(), key=(lambda x: force_text(x)))
        recent_orders = customer.customer_orders.valid().order_by('-id')[:10]

        order_summary = []
        for dt in customer.customer_orders.valid().datetimes('order_date', 'year'):
            summary = customer.customer_orders.filter(order_date__year=dt.year).aggregate(
                total=Sum('taxful_total_price_value')
            )
            order_summary.append({
                'year': dt.year,
                'total': format_currency(
                    summary['total'], currency=recent_orders[0].currency, locale=get_current_babel_locale()
                )
            })

        return {
            "customer_info": {
                "name": customer.full_name,
                "phone_no": customer.phone,
                "email": customer.email,
                "tax_number": getattr(customer, "tax_number", ""),
                "companies": [force_text(company) for company in companies] if len(companies) else None,
                "groups": [force_text(group) for group in customer.groups.all()],
                "merchant_notes": customer.merchant_notes
            },
            "order_summary": order_summary,
            "recent_orders": [
                {
                    "order_date": get_locally_formatted_datetime(order.order_date),
                    "total": format_money(order.taxful_total_price),
                    "status": order.get_status_display(),
                    "payment_status": force_text(order.payment_status.label),
                    "shipment_status": force_text(order.shipping_status.label)
                } for order in recent_orders
            ]
        }
Example #11
0
    def check_different_types(self, value):
        if isinstance(value, ProductMedia):
            return "<img src='/media/%s'>" % value.get_thumbnail()

        if isinstance(value, Image):
            thumbnailer = get_thumbnailer(value)
            options = {"size": (64, 64)}
            thumbnail = thumbnailer.get_thumbnail(options, generate=True)
            return "<img src='%s'>" % thumbnail.url

        if isinstance(value, bool):
            value = yesno(value)

        if isinstance(value, Manager):
            value = ", ".join("%s" % x for x in value.all())

        if isinstance(value, datetime.datetime):
            return get_locally_formatted_datetime(value)

        if isinstance(value, Money):
            return escape(format_money(value))
Example #12
0
def _test_refund_view(browser, live_server, order):
    url = reverse("wshop_admin:order.create-refund", kwargs={"pk": order.pk})
    browser.visit("%s%s" % (live_server, url))
    wait_until_condition(
        browser, lambda x: x.is_text_present("Refunded: %s" % format_money(
            order.shop.create_price("0.00"))))
    assert len(browser.find_by_css("#id_form-0-line_number option")
               ) == 12  # blank + arbitrary amount + num lines
    click_element(browser, "#select2-id_form-0-line_number-container")
    wait_until_appeared(browser, "input.select2-search__field")
    browser.execute_script(
        '$($(".select2-results__option")[1]).trigger({type: "mouseup"})'
    )  # select arbitrary amount
    wait_until_condition(browser,
                         lambda x: len(x.find_by_css("#id_form-0-text")))
    wait_until_condition(browser,
                         lambda x: len(x.find_by_css("#id_form-0-amount")))
    browser.find_by_css("#id_form-0-text").first.value = "test"
    browser.find_by_css("#id_form-0-amount").first.value = "900"
    click_element(browser, "#add-refund")
    click_element(browser, "#select2-id_form-1-line_number-container")
    wait_until_appeared(browser, "input.select2-search__field")
    browser.execute_script(
        '$($(".select2-results__option")[2]).trigger({type: "mouseup"})'
    )  # select first line
    assert decimal.Decimal(
        browser.find_by_css(
            "#id_form-1-amount").first.value) == decimal.Decimal("100.00")
    assert int(
        decimal.Decimal(
            browser.find_by_css("#id_form-1-quantity").first.value)) == 10
    click_element(browser, "button[form='create_refund']")
    _check_create_refund_link(browser, order,
                              True)  # can still refund quantity
    _check_order_details_visible(browser)
    order.refresh_from_db()
    assert not order.taxful_total_price
    assert order.is_paid()
    assert not order.is_fully_shipped()
Example #13
0
    def add_data(self, name, data, chart_type):
        """
        Add data to this chart
        :param name: the name of the dataset
        :type name: str
        :param data: the list of data
        :type data: list[int|float|Decimal]
        :param chart_type: the chart type - tells how data should be rendered.
            This data type must be available in the `supported_chart_type` attribute of this instance
        :type chart_type: ChartType
        """
        assert chart_type in self.supported_chart_types
        formatted_data = []

        # format value for each data point
        if self.data_type == ChartDataType.CURRENCY:
            for value in data:
                formatted_data.append(
                    format_money(
                        Money(value, currency=self.currency).as_rounded()))

        elif self.data_type == ChartDataType.PERCENT:
            for value in data:
                formatted_data.append(format_percent(value,
                                                     locale=self.locale))

        # self.data_type == ChartDataType.NUMBER
        else:
            for value in data:
                formatted_data.append(format_decimal(value,
                                                     locale=self.locale))

        self.datasets.append({
            "type": chart_type,
            "label": name,
            "data": data,
            "formatted_data": formatted_data
        })
Example #14
0
def test_format_money():
    assert format_money(Money("3.6", "EUR"), locale="fi") == "3,60\xa0\u20ac"
    assert format_money(Money("3.6", "EUR"), widen=2,
                        locale="fi") == "3,6000\xa0\u20ac"
    assert format_money(Money("3.6", "EUR"), digits=0,
                        locale="fi") == "4\xa0\u20ac"
Example #15
0
 def format_taxful_total_price(self, instance, *args, **kwargs):
     return escape(format_money(instance.taxful_total_price))