Beispiel #1
0
    def _render_report(self, report):
        if not report.rendered:
            report_data = report.get_data()
            self.write_heading(
                "{title} {start} - {end}".format(
                    title=report.title,
                    start=format_date(report_data["start"], format="short", locale=get_current_babel_locale()),
                    end=format_date(report_data["end"], format="short", locale=get_current_babel_locale()))
            )
            report.ensure_texts()
            self.write_data_table(report, report_data["data"], has_totals=report_data["has_totals"])

        return self.get_rendered_output()
Beispiel #2
0
 def get_dashboard_blocks(self, request):
     if not self.check_demo_optin(request):
         return
     locale = get_current_babel_locale()
     n = now()
     weekday = format_date(n, "EEEE", locale=locale)
     today = format_date(n, locale=locale)
     yield DashboardValueBlock(
         id="test-x", color="blue", title="Happy %s!" % weekday, value=today, icon="fa fa-calendar"
     )
     yield DashboardNumberBlock(
         id="test-x", color="red", title="Visitors Yesterday", value=random.randint(2200, 10000), icon="fa fa-globe"
     )
     yield DashboardNumberBlock(id="test-x", color="gray", title="Registered Users", value=1240, icon="fa fa-user")
     yield DashboardNumberBlock(id="test-x", color="orange", title="Orders", value=32, icon="fa fa-inbox")
     yield DashboardMoneyBlock(
         id="test-x", color="green", title="Open Orders Value", value=32000, currency="USD", icon="fa fa-line-chart"
     )
     yield DashboardNumberBlock(id="test-x", color="yellow", title="Current Visitors", value=6, icon="fa fa-users")
     yield DashboardMoneyBlock(
         id="test-x", color="none", title="Sales this week", value=430.30, currency="USD", icon="fa fa-dollar"
     )
     yield DashboardValueBlock(
         id="test-1", value="\u03C0", title="The most delicious number", color="purple", icon="fa fa-smile-o"
     )
Beispiel #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)
    }
Beispiel #4
0
 def __init__(self, id, value, title, currency, **kwargs):
     self.currency = currency
     value = parse_decimal_string(value)
     value = format_currency(value,
                             currency=self.currency,
                             locale=get_current_babel_locale())
     super(DashboardMoneyBlock, self).__init__(id, value, title, **kwargs)
Beispiel #5
0
    def __init__(self, title, data_type=ChartDataType.NUMBER, locale=None, currency=None, options=None):
        """
        :param str title: the title of the chart

        :param ChartDataType data_type: the data type of values
            The chart will format the output labels according to this parameter

        :param str locale: the locale to render values
            If not set, the locale will be fetched from Babel

        :param str currency: the ISO-4217 code for the currency
            This is necessary when the data_type is CURRENCY

        :param dict options: a dicionaty with options for Chartjs
        """
        self.title = title
        self.datasets = []
        self.options = options
        self.data_type = data_type
        self.currency = currency

        if locale:
            self.locale = locale
        else:
            self.locale = get_current_babel_locale()

        if data_type == ChartDataType.CURRENCY and not currency:
            raise AttributeError("You should also set currency for this data type")
Beispiel #6
0
    def __init__(self,
                 title,
                 data_type=ChartDataType.NUMBER,
                 locale=None,
                 currency=None,
                 options=None):
        """
        :param str title: the title of the chart

        :param ChartDataType data_type: the data type of values
            The chart will format the output labels according to this parameter

        :param str locale: the locale to render values
            If not set, the locale will be fetched from Babel

        :param str currency: the ISO-4217 code for the currency
            This is necessary when the data_type is CURRENCY

        :param dict options: a dicionaty with options for Chartjs
        """
        self.title = title
        self.datasets = []
        self.options = options
        self.data_type = data_type
        self.currency = currency

        if locale:
            self.locale = locale
        else:
            self.locale = get_current_babel_locale()

        if data_type == ChartDataType.CURRENCY and not currency:
            raise AttributeError(
                "You should also set currency for this data type")
Beispiel #7
0
    def get_data(self):
        orders = self.get_objects().order_by("-order_date")
        data = []
        for order_date, orders_group in itertools.groupby(
                orders, key=self.extract_date):
            taxless_total = TaxlessPrice(0, currency=self.shop.currency)
            taxful_total = TaxfulPrice(0, currency=self.shop.currency)
            paid_total = TaxfulPrice(0, currency=self.shop.currency)
            product_count = 0
            order_count = 0
            for order in orders_group:
                taxless_total += order.taxless_total_price
                taxful_total += order.taxful_total_price
                product_count += sum(
                    order.get_product_ids_and_quantities().values())
                order_count += 1
                if order.payment_date:
                    paid_total += order.taxful_total_price

            data.append({
                "date":
                format_date(order_date,
                            format="short",
                            locale=get_current_babel_locale()),
                "order_count":
                order_count,
                "product_count":
                int(product_count),
                "taxless_total":
                taxless_total,
                "taxful_total":
                taxful_total,
            })

        return self.get_return_data(data)
Beispiel #8
0
    def get_data(self):
        orders = self.get_objects().order_by("-order_date")
        data = []
        for order_date, orders_group in itertools.groupby(orders, key=self.extract_date):
            taxless_total = TaxlessPrice(0, currency=self.shop.currency)
            taxful_total = TaxfulPrice(0, currency=self.shop.currency)
            paid_total = TaxfulPrice(0, currency=self.shop.currency)
            product_count = 0
            order_count = 0
            for order in orders_group:
                taxless_total += order.taxless_total_price
                taxful_total += order.taxful_total_price
                product_count += sum(order.get_product_ids_and_quantities().values())
                order_count += 1
                if order.payment_date:
                    paid_total += order.taxful_total_price

            data.append({
                "date": format_date(order_date, format="short", locale=get_current_babel_locale()),
                "order_count": order_count,
                "product_count": int(product_count),
                "taxless_total": taxless_total,
                "taxful_total": taxful_total,
            })

        return self.get_return_data(data)
Beispiel #9
0
    def get_data(self):
        orders = self.get_objects().order_by("-order_date")
        data = []
        # TODO: maybe make raw sql query in future
        for order_date, orders_group in itertools.groupby(
                orders, key=self.extract_date):
            taxless_total = TaxlessPrice(0, currency=self.shop.currency)
            taxful_total = TaxfulPrice(0, currency=self.shop.currency)
            product_count = 0
            order_count = 0
            for order in orders_group:
                taxless_total += order.taxless_total_price
                taxful_total += order.taxful_total_price
                product_count += sum(
                    order.get_product_ids_and_quantities().values())
                order_count += 1

            data.append({
                "date":
                format_date(order_date, locale=get_current_babel_locale()),
                "order_count":
                order_count,
                "product_count":
                int(product_count),
                "taxless_total":
                taxless_total.as_rounded().value,
                "taxful_total":
                taxful_total.as_rounded().value,
            })

        return self.get_return_data(data)
Beispiel #10
0
    def get_data(self, **kwargs):
        data = []
        coupons_usages = self.get_objects()

        for coupon_usage in coupons_usages:
            total_discount = self.shop.create_price(0)
            for discount in coupon_usage.order.lines.discounts():
                total_discount += discount.taxful_price

            data.append({
                "date":
                format_date(coupon_usage.order.order_date,
                            locale=get_current_babel_locale()),
                "coupon":
                coupon_usage.coupon.code,
                "order":
                coupon_usage.order,
                "taxful_total":
                coupon_usage.order.taxful_total_price.as_rounded().value,
                "taxful_subtotal": (coupon_usage.order.taxful_total_price -
                                    total_discount).as_rounded().value,
                "total_discount":
                total_discount.as_rounded().value
            })

        return self.get_return_data(data)
Beispiel #11
0
 def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
     locale = get_current_babel_locale()
     translated_choices = [(code, locale.languages.get(code, code))
                           for code in sorted(self.LANGUAGE_CODES)]
     translated_choices.sort(key=lambda pair: pair[1].lower())
     if include_blank:
         translated_choices = blank_choice + translated_choices
     return translated_choices
Beispiel #12
0
    def _render_report(self, report):
        if not report.rendered:
            report_data = report.get_data()
            self.write_heading("{title} {start} - {end}".format(
                title=report.title,
                start=format_date(report_data["start"],
                                  format="short",
                                  locale=get_current_babel_locale()),
                end=format_date(report_data["end"],
                                format="short",
                                locale=get_current_babel_locale())))
            report.ensure_texts()
            self.write_data_table(report,
                                  report_data["data"],
                                  has_totals=report_data["has_totals"])

        return self.get_rendered_output()
Beispiel #13
0
 def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
     locale = get_current_babel_locale()
     translated_choices = [
         (code, locale.languages.get(code, code)) for (code, _) in super(
             LanguageField, self).get_choices(include_blank, blank_choice)
     ]
     translated_choices.sort(key=lambda pair: pair[1].lower())
     return translated_choices
Beispiel #14
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]
        }
Beispiel #15
0
 def get_gettings(cls, request, **kwargs):
     return {
         "minSearchInputLength": settings.SHUUP_ADMIN_MINIMUM_INPUT_LENGTH_SEARCH or 1,
         "dateInputFormat": settings.SHUUP_ADMIN_DATE_INPUT_FORMAT,
         "datetimeInputFormat": settings.SHUUP_ADMIN_DATETIME_INPUT_FORMAT,
         "timeInputFormat": settings.SHUUP_ADMIN_TIME_INPUT_FORMAT,
         "datetimeInputStep": settings.SHUUP_ADMIN_DATETIME_INPUT_STEP,
         "dateInputLocale": get_current_babel_locale().language
     }
Beispiel #16
0
 def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
     locale = get_current_babel_locale()
     translated_choices = [
         (code, locale.languages.get(code, code))
         for (code, _)
         in super(LanguageField, self).get_choices(include_blank, blank_choice)
     ]
     translated_choices.sort(key=lambda pair: pair[1].lower())
     return translated_choices
Beispiel #17
0
 def __init__(self, **kwargs):
     super(ShopBaseForm, self).__init__(**kwargs)
     self.fields["logo"].widget = MediaChoiceWidget(clearable=True)
     locale = get_current_babel_locale()
     self.fields["currency"] = forms.ChoiceField(choices=sorted(
         locale.currencies.items()),
                                                 required=True,
                                                 label=_("Currency"))
     self.disable_protected_fields()
Beispiel #18
0
 def __init__(self, **kwargs):
     super(ShopBaseForm, self).__init__(**kwargs)
     self.fields["logo"].widget = MediaChoiceWidget(clearable=True)
     locale = get_current_babel_locale()
     self.fields["currency"] = forms.ChoiceField(
         choices=sorted(locale.currencies.items()),
         required=True,
         label=_("Currency")
     )
     self.disable_protected_fields()
Beispiel #19
0
 def __init__(self, **kwargs):
     super(ShopWizardForm, self).__init__(**kwargs)
     locale = get_current_babel_locale()
     self.fields["prices_include_tax"].help_text = _(
         "Show storefront products with tax pre-calculated into the price. "
         "Note this behavior can be overridden for customer groups.")
     self.fields["currency"] = forms.ChoiceField(choices=sorted(
         locale.currencies.items()),
                                                 required=True,
                                                 label=_("Currency"))
Beispiel #20
0
def get_first_day_of_the_current_week(today_start):
    locale = i18n.get_current_babel_locale()
    first_day_of_the_week = today_start
    if today_start.weekday() == locale.first_week_day:
        return first_day_of_the_week

    def get_prospect(i):
        return (today_start - datetime.timedelta(days=i))

    return iterables.first([get_prospect(i) for i in range(1, 7) if get_prospect(i).weekday() == locale.first_week_day])
Beispiel #21
0
def get_first_day_of_the_current_week(today_start):
    locale = i18n.get_current_babel_locale()
    first_day_of_the_week = today_start
    if today_start.weekday() == locale.first_week_day:
        return first_day_of_the_week

    def get_prospect(i):
        return today_start - datetime.timedelta(days=i)

    return iterables.first([get_prospect(i) for i in range(1, 7) if get_prospect(i).weekday() == locale.first_week_day])
def test_parse_date_range_presets():
    locale = i18n.get_current_babel_locale()

    def local_now():
        return datetime.datetime(2017, 12, 4, 17, 1, tzinfo=pytz.UTC)

    with mock.patch("shuup.utils.dates.local_now", side_effect=local_now):
        start, end = parse_date_range_preset(DateRangeChoices.TODAY)
        assert start == local_now().replace(hour=0, minute=0, second=0)
        assert end == local_now()

        start, end = parse_date_range_preset(DateRangeChoices.RUNNING_WEEK)
        assert start == local_now().replace(month=11,
                                            day=27,
                                            hour=0,
                                            minute=0,
                                            second=0)
        assert end == local_now()

        start, end = parse_date_range_preset(DateRangeChoices.RUNNING_MONTH)
        assert start == local_now().replace(month=11,
                                            day=4,
                                            hour=0,
                                            minute=0,
                                            second=0)
        assert end == local_now()

        assert local_now().weekday() == locale.first_week_day
        start, end = parse_date_range_preset(DateRangeChoices.THIS_WEEK)
        assert start == local_now().replace(hour=0, minute=0, second=0)
        assert end == local_now()

        start, end = parse_date_range_preset(DateRangeChoices.THIS_MONTH)
        assert start == local_now().replace(month=12,
                                            day=1,
                                            hour=0,
                                            minute=0,
                                            second=0)
        assert end == local_now()

        start, end = parse_date_range_preset(DateRangeChoices.THIS_YEAR)
        assert start == local_now().replace(month=1,
                                            day=1,
                                            hour=0,
                                            minute=0,
                                            second=0)
        assert end == local_now()

        start, end = parse_date_range_preset(DateRangeChoices.ALL_TIME)
        assert start == local_now().replace(year=2000,
                                            hour=0,
                                            minute=0,
                                            second=0)
        assert end == local_now()
Beispiel #23
0
 def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
     locale = get_current_babel_locale()
     translated_choices = [
         (code, locale.languages.get(code, code))
         for code
         in sorted(self.LANGUAGE_CODES)
     ]
     translated_choices.sort(key=lambda pair: pair[1].lower())
     if include_blank:
         translated_choices = blank_choice + translated_choices
     return translated_choices
Beispiel #24
0
def encode_line(line):
    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),
        "discountAmount": format_money(line.discount_amount.amount),
        "taxlessTotal": format_money(line.taxless_price.amount),
        "taxPercentage": format_percent(line.tax_rate, 2),
        "taxfulTotal": format_money(line.taxful_price.amount)
    }
Beispiel #25
0
def datetime(value, kind="datetime", format="medium", tz=True):
    """
    Format a `datetime` for human consumption.

    The currently active locale's formatting rules are used. The output
    of this function is probably not machine-parseable.

    :param value: datetime object to format
    :type value: datetime.datetime

    :param kind: Format as 'datetime', 'date' or 'time'.
    :type kind: str

    :param format:
      Format specifier or one of 'full', 'long', 'medium' or 'short'.
    :type format: str

    :param tz:
      Convert to current or given timezone. Accepted values are:

         True (default)
             convert to the currently active timezone (as reported by
             :func:`django.utils.timezone.get_current_timezone`)
         False (or other false value like empty string)
             do no convert to any timezone (use UTC)
         Other values (as str)
             convert to a given timezone (e.g. ``"US/Hawaii"``)
    :type tz: bool|str
    """

    locale = get_current_babel_locale()

    if type(
            value
    ) is date:  # Not using isinstance, since `datetime`s are `date` too.
        # We can't do any TZ manipulation for dates, so just always use `format_date`
        return format_date(value, format=format, locale=locale)

    if tz:
        value = localtime(value, (None if tz is True else tz))

    if kind == "datetime":
        return format_datetime(value, format=format, locale=locale)
    elif kind == "date":
        return format_date(value, format=format, locale=locale)
    elif kind == "time":
        return format_time(value, format=format, locale=locale)
    else:
        raise ValueError("Error! Unknown `datetime` kind: %r." % kind)
Beispiel #26
0
 def get_chart(self):
     orders = get_orders_by_currency(self.currency)
     aggregate_data = group_by_period(
         orders.valid().since(days=365), "order_date", "month", sum=Sum("taxful_total_price_value")
     )
     locale = get_current_babel_locale()
     bar_chart = BarChart(
         title=_("Sales per Month (last year)"),
         labels=[format_date(k, format=get_year_and_month_format(locale), locale=locale) for k in aggregate_data],
     )
     bar_chart.add_data(
         _("Sales (%(currency)s)") % {"currency": self.currency},
         [bankers_round(v["sum"], 2) for v in aggregate_data.values()],  # TODO: To be fixed in SHUUP-1912
     )
     return bar_chart
Beispiel #27
0
 def __init__(self, **kwargs):
     initial_languages = [i[0] for i in kwargs.get("languages", [])]
     super(ShopBaseForm, self).__init__(**kwargs)
     self.fields["logo"].widget = MediaChoiceWidget(clearable=True)
     locale = get_current_babel_locale()
     self.fields["currency"] = forms.ChoiceField(choices=sorted(
         locale.currencies.items()),
                                                 required=True,
                                                 label=_("Currency"))
     self.fields["languages"] = forms.MultipleChoiceField(
         choices=settings.LANGUAGES,
         initial=initial_languages,
         required=True,
         label=_("Languages"))
     self.disable_protected_fields()
Beispiel #28
0
def datetime(value, kind="datetime", format="medium", tz=True):
    """
    Format a datetime for human consumption.

    The currently active locale's formatting rules are used.  The output
    of this function is probably not machine-parseable.

    :param value: datetime object to format
    :type value: datetime.datetime

    :param kind: Format as 'datetime', 'date' or 'time'
    :type kind: str

    :param format:
      Format specifier or one of 'full', 'long', 'medium' or 'short'
    :type format: str

    :param tz:
      Convert to current or given timezone. Accepted values are:

         True (default)
             convert to currently active timezone (as reported by
             :func:`django.utils.timezone.get_current_timezone`)
         False (or other false value like empty string)
             do no convert to any timezone (use UTC)
         Other values (as str)
             convert to given timezone (e.g. ``"US/Hawaii"``)
    :type tz: bool|str
    """

    locale = get_current_babel_locale()

    if type(value) is date:  # Not using isinstance, since `datetime`s are `date` too.
        # We can't do any TZ manipulation for dates, so just use `format_date` always
        return format_date(value, format=format, locale=locale)

    if tz:
        value = localtime(value, (None if tz is True else tz))

    if kind == "datetime":
        return format_datetime(value, format=format, locale=locale)
    elif kind == "date":
        return format_date(value, format=format, locale=locale)
    elif kind == "time":
        return format_time(value, format=format, locale=locale)
    else:
        raise ValueError("Unknown `datetime` kind: %r" % kind)
Beispiel #29
0
    def as_string_list(self, locale=None):
        locale = locale or get_current_babel_locale()
        country = self.country.code.upper()

        base_lines = [
            self.company_name, self.full_name, self.name_ext, self.street,
            self.street2, self.street3,
            "%s %s %s" % (self.region_code, self.postal_code, self.city),
            self.region,
            locale.territories.get(country, country)
            if not self.is_home else None
        ]

        stripped_lines = [
            force_text(line).strip() for line in base_lines if line
        ]
        return [s for s in stripped_lines if (s and len(s) > 1)]
Beispiel #30
0
 def __init__(self, **kwargs):
     initial_languages = [i[0] for i in kwargs.get("languages", [])]
     super(ShopBaseForm, self).__init__(**kwargs)
     self.fields["logo"].widget = MediaChoiceWidget(clearable=True)
     locale = get_current_babel_locale()
     self.fields["currency"] = forms.ChoiceField(
         choices=sorted(locale.currencies.items()),
         required=True,
         label=_("Currency")
     )
     self.fields["languages"] = forms.MultipleChoiceField(
         choices=settings.LANGUAGES,
         initial=initial_languages,
         required=True,
         label=_("Languages")
     )
     self.disable_protected_fields()
Beispiel #31
0
 def get_chart(self):
     orders = get_orders_by_currency(self.currency)
     aggregate_data = group_by_period(orders.valid().since(days=365),
                                      "order_date",
                                      "month",
                                      sum=Sum("taxful_total_price_value"))
     locale = get_current_babel_locale()
     bar_chart = BarChart(title=_("Sales per Month (last year)"),
                          labels=[
                              format_date(
                                  k,
                                  format=get_year_and_month_format(locale),
                                  locale=locale) for k in aggregate_data
                          ])
     bar_chart.add_data(
         _("Sales (%(currency)s)") % {"currency": self.currency},
         [v["sum"] for v in aggregate_data.values()])
     return bar_chart
Beispiel #32
0
    def as_string_list(self, locale=None):
        locale = locale or get_current_babel_locale()
        country = self.country.code.upper()

        base_lines = [
            self.company_name,
            self.full_name,
            self.name_ext,
            self.street,
            self.street2,
            self.street3,
            "%s %s %s" % (self.region_code, self.postal_code, self.city),
            self.region,
            locale.territories.get(country, country) if not self.is_home else None
        ]

        stripped_lines = [force_text(line).strip() for line in base_lines if line]
        return [s for s in stripped_lines if (s and len(s) > 1)]
Beispiel #33
0
    def get_data(self, **kwargs):
        data = []
        coupons_usages = self.get_objects()

        for coupon_usage in coupons_usages:
            total_discount = self.shop.create_price(0)
            for discount in coupon_usage.order.lines.discounts():
                total_discount += discount.taxful_price

            data.append({
                "date": format_date(coupon_usage.order.order_date, locale=get_current_babel_locale()),
                "coupon": coupon_usage.coupon.code,
                "order": coupon_usage.order,
                "taxful_total": coupon_usage.order.taxful_total_price.as_rounded().value,
                "taxful_subtotal": (coupon_usage.order.taxful_total_price - total_discount).as_rounded().value,
                "total_discount": total_discount.as_rounded().value
            })

        return self.get_return_data(data)
Beispiel #34
0
    def address_as_string_list(self, address, locale=None):
        assert issubclass(type(address), Address)

        locale = locale or get_current_babel_locale()
        country = address.country.code.upper()

        base_lines = [
            address.company_name, address.full_name, address.name_ext,
            address.street, address.street2, address.street3,
            "%s %s %s" % (address.postal_code, address.city,
                          address.region_code or address.region),
            locale.territories.get(country, country)
            if not address.is_home else None
        ]

        stripped_lines = [
            force_text(line).strip() for line in base_lines if line
        ]
        return [s for s in stripped_lines if (s and len(s) > 1)]
Beispiel #35
0
    def address_as_string_list(self, address, locale=None):
        assert issubclass(type(address), Address)

        locale = locale or get_current_babel_locale()
        country = address.country.code.upper()

        base_lines = [
            address.company_name,
            address.full_name,
            address.name_ext,
            address.street,
            address.street2,
            address.street3,
            "%s %s %s" % (address.postal_code, address.city, address.region_code or address.region),
            locale.territories.get(country, country) if not address.is_home else None
        ]

        stripped_lines = [force_text(line).strip() for line in base_lines if line]
        return [s for s in stripped_lines if (s and len(s) > 1)]
Beispiel #36
0
    def address_as_string_list(self, address, locale=None):
        assert issubclass(type(address), Address)

        locale = locale or get_current_babel_locale()
        country = address.country.code.upper()

        base_lines = [
            address.full_name, "{0}, {1}".format(address.street,
                                                 address.extra.numero),
            address.street2, address.extra.ponto_ref, address.postal_code,
            "{0} {1}".format(address.city, address.region
                             or address.region_code),
            locale.territories.get(country, country)
            if not address.is_home else None
        ]

        stripped_lines = [
            force_text(line).strip() for line in base_lines if line
        ]
        return [s for s in stripped_lines if (s and len(s) > 1)]
Beispiel #37
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
            ]
        }
Beispiel #38
0
    def get_data(self):
        orders = self.get_objects().order_by("-order_date")
        data = []
        # TODO: maybe make raw sql query in future
        for order_date, orders_group in itertools.groupby(orders, key=self.extract_date):
            taxless_total = TaxlessPrice(0, currency=self.shop.currency)
            taxful_total = TaxfulPrice(0, currency=self.shop.currency)
            product_count = 0
            order_count = 0
            for order in orders_group:
                taxless_total += order.taxless_total_price
                taxful_total += order.taxful_total_price
                product_count += sum(order.get_product_ids_and_quantities().values())
                order_count += 1

            data.append({
                "date": format_date(order_date, locale=get_current_babel_locale()),
                "order_count": order_count,
                "product_count": int(product_count),
                "taxless_total": taxless_total.as_rounded().value,
                "taxful_total": taxful_total.as_rounded().value,
            })

        return self.get_return_data(data)
Beispiel #39
0
    def get_chart(self):
        if self.cached_chart is not None:
            return self.cached_chart

        chart_options = {
            "scales": {
                "yAxes": [{
                    "ticks": {
                        "beginAtZero": True
                    }
                }]
            }
        }

        today = date.today()
        chart_start_date = today - timedelta(days=365)

        orders = get_orders_by_currency(self.currency)
        sum_sales_data = group_by_period(
            orders.valid().since((today - chart_start_date).days),
            "order_date",
            "month",
            sum=Sum("taxful_total_price_value")
        )

        for (month, year) in month_iter(chart_start_date, today):
            sales_date = date(year, month, 1)
            if sales_date not in sum_sales_data:
                sum_sales_data[sales_date] = {"sum": Decimal(0)}

        # sort and recreated the ordered dict since we've put new items into
        sum_sales_data = OrderedDict(sorted(six.iteritems(sum_sales_data), key=lambda x: x[0]))

        locale = get_current_babel_locale()
        labels = [
            format_date(k, format=get_year_and_month_format(locale), locale=locale)
            for k in sum_sales_data
        ]
        mixed_chart = MixedChart(title=_("Sales per Month (past 12 months)"),
                                 labels=labels,
                                 data_type=ChartDataType.CURRENCY,
                                 options=chart_options,
                                 currency=self.currency,
                                 locale=locale)

        cumulative_sales = []
        average_sales = []

        # only calculate cumulative and average if there are at least 3 months
        if len(sum_sales_data) >= 3:
            count = 0
            total = Decimal()

            for month_sale in sum_sales_data.values():
                total = total + month_sale["sum"]
                cumulative_sales.append(total)
                average_sales.append(total / (count+1))
                count = count + 1

        # this will be on top of all bars
        if average_sales:
            mixed_chart.add_data(_("Average Sales"), [v for v in average_sales], ChartType.LINE)

        # this will be under the cummulative bars
        mixed_chart.add_data(_("Sales"), [v["sum"] for v in sum_sales_data.values()], ChartType.BAR)

        # this will be under all others charts
        if cumulative_sales:
            mixed_chart.add_data(_("Cumulative Total Sales"), [v for v in cumulative_sales], ChartType.BAR)

        self.cached_chart = mixed_chart
        return mixed_chart
Beispiel #40
0
 def get_currency_display(self, instance):
     locale = get_current_babel_locale()
     return locale.currencies.get(instance.code, instance.code)
def test_sales_report_timezone(server_timezone):
    with override_settings(TIME_ZONE=server_timezone):
        # Timezone needs to be activated to current one because some old timezone can still be active
        activate(pytz.timezone(server_timezone))
        """
        TIME TABLE

        | identifier  | ISO 8859-1                | UTC                 | America/Los_Angeles | America/Sao_Paulo   |
        | first_date  | 2017-10-01T23:50:00+03:00 | 2017-10-01 20:50:00 | 2017-10-01 13:50:00 | 2017-10-01 17:50:00 |
        | second_date | 2017-10-02T17:13:00+10:00 | 2017-10-02 07:13:00 | 2017-10-02 00:13:00 | 2017-10-02 04:13:00 |
        | third_date  | 2017-10-02T22:04:44-01:00 | 2017-10-02 23:04:44 | 2017-10-02 16:04:44 | 2017-10-02 20:04:44 |
        | forth_date  | 2017-10-02T23:04:44-05:00 | 2017-10-03 04:04:44 | 2017-10-02 21:04:44 | 2017-10-03 01:04:44 |
        """

        first_date = parse_datetime("2017-10-01T23:50:00+03:00")
        second_date = parse_datetime("2017-10-02T17:13:00+10:00")
        third_date = parse_datetime("2017-10-02T22:04:44-01:00")
        forth_date = parse_datetime("2017-10-02T23:04:44-05:00")

        inited_data = create_orders_for_dates(
            [first_date, second_date, third_date, forth_date], as_paid=True)
        assert Order.objects.count() == 4

        first_date_local = first_date.astimezone(timezone(server_timezone))
        second_date_local = second_date.astimezone(timezone(server_timezone))
        third_date_local = third_date.astimezone(timezone(server_timezone))
        forth_date_local = forth_date.astimezone(timezone(server_timezone))

        data = {
            "report": SalesReport.get_name(),
            "shop": inited_data["shop"].pk,
            "start_date": first_date_local,
            "end_date": second_date_local,
        }
        report = SalesReport(**data)
        report_data = report.get_data()["data"]
        assert len(report_data) == 2

        # the orders should be rendered as localtime
        assert report_data[0]["date"] == format_date(
            second_date_local, locale=get_current_babel_locale())
        assert report_data[1]["date"] == format_date(
            first_date_local, locale=get_current_babel_locale())

        # includes the 3rd order
        data.update({
            "start_date": first_date_local,
            "end_date": third_date_local
        })
        report = SalesReport(**data)
        report_data = report.get_data()["data"]
        assert len(report_data) == 2

        assert report_data[0]["date"] == format_date(
            second_date_local, locale=get_current_babel_locale())
        assert report_data[1]["date"] == format_date(
            first_date_local, locale=get_current_babel_locale())

        # includes the 4th order - here the result is different for Los_Angeles and Sao_Paulo
        data.update({
            "start_date": first_date_local,
            "end_date": forth_date_local
        })
        report = SalesReport(**data)
        report_data = report.get_data()["data"]

        if server_timezone == "America/Los_Angeles":
            assert len(report_data) == 2
            assert report_data[0]["date"] == format_date(
                second_date_local, locale=get_current_babel_locale())
            assert report_data[1]["date"] == format_date(
                first_date_local, locale=get_current_babel_locale())
        else:
            assert len(report_data) == 3
            assert report_data[0]["date"] == format_date(
                forth_date_local, locale=get_current_babel_locale())
            assert report_data[1]["date"] == format_date(
                second_date_local, locale=get_current_babel_locale())
            assert report_data[2]["date"] == format_date(
                first_date_local, locale=get_current_babel_locale())

        # Using strings as start or end date should raise TypeError.
        # Only date or datetime objects should be accepted.
        data.update({
            "start_date": first_date_local.isoformat(),
            "end_date": forth_date_local.isoformat()
        })
        with pytest.raises(TypeError):
            report = SalesReport(**data)
            report_data = report.get_data()["data"]

        # Using different date types in start and end date should raise TypeError.
        data.update({
            "start_date": first_date_local,
            "end_date": forth_date_local.date()
        })
        with pytest.raises(TypeError):
            report = SalesReport(**data)
            report_data = report.get_data()["data"]
Beispiel #42
0
def get_currency_choices():
    locale = get_current_babel_locale()
    currencies = Currency.objects.all().order_by("code")
    return [(currency.code, locale.currencies.get(currency.code, currency))
            for currency in currencies]
Beispiel #43
0
 def __init__(self, id, value, title, **kwargs):
     value = parse_decimal_string(value)
     if int(value) == value:
         value = int(value)
     value = format_number(value, locale=get_current_babel_locale())
     super(DashboardNumberBlock, self).__init__(id, value, title, **kwargs)
Beispiel #44
0
def number(value):
    return format_decimal(value, locale=get_current_babel_locale())
Beispiel #45
0
 def get_symbol(self, currency):
     return babel.numbers.get_currency_symbol(currency.code,
                                              get_current_babel_locale())
Beispiel #46
0
def test_shop_api(admin_user, currency, currency_decimals):
    activate("en")
    default_shop = get_default_shop()
    client = APIClient()
    client.force_authenticate(user=admin_user)
    Currency.objects.get_or_create(code=currency,
                                   decimal_places=currency_decimals)

    shop_data = {
        "domain": "shuup.com",
        "status": ShopStatus.ENABLED.value,
        "owner": create_random_person().pk,
        "currency": currency,
        "prices_include_tax": True,
        "maintenance_mode": False,
        "translations": {
            "en": {
                "name": "Store 1",
                "public_name": "Public Store 1"
            }
        }
    }
    response = client.post("/api/shuup/shop/",
                           content_type="application/json",
                           data=json.dumps(shop_data))
    assert response.status_code == status.HTTP_201_CREATED
    shop = Shop.objects.exclude(pk=default_shop.pk).first()
    assert shop.domain == shop_data["domain"]
    assert shop.status.value == shop_data["status"]
    assert shop.owner.pk == shop_data["owner"]
    assert shop.currency == shop_data["currency"]
    assert shop.maintenance_mode == shop_data["maintenance_mode"]
    assert shop.prices_include_tax == shop_data["prices_include_tax"]
    assert shop.name == shop_data["translations"]["en"]["name"]
    assert shop.public_name == shop_data["translations"]["en"]["public_name"]

    shop_data["domain"] = "cloud.shuup.com"
    response = client.put("/api/shuup/shop/%d/" % shop.id,
                          content_type="application/json",
                          data=json.dumps(shop_data))
    assert response.status_code == status.HTTP_200_OK
    shop = Shop.objects.exclude(pk=default_shop.pk).first()
    assert shop.domain == shop_data["domain"]

    response = client.get("/api/shuup/shop/%d/" % shop.id)
    assert response.status_code == status.HTTP_200_OK
    data = json.loads(response.content.decode("utf-8"))
    assert shop.domain == data["domain"]
    assert shop.status.value == data["status"]
    assert shop.owner.pk == data["owner"]
    assert shop.currency == data["currency"]["code"]
    assert data["currency"]["symbol"] == babel.numbers.get_currency_symbol(
        shop.currency, get_current_babel_locale())
    assert data["currency"]["decimal_places"] == currency_decimals
    assert shop.maintenance_mode == data["maintenance_mode"]
    assert shop.prices_include_tax == data["prices_include_tax"]
    assert shop.name == data["translations"]["en"]["name"]
    assert shop.public_name == data["translations"]["en"]["public_name"]

    response = client.get("/api/shuup/shop/")
    assert response.status_code == status.HTTP_200_OK
    data = json.loads(response.content.decode("utf-8"))
    assert shop.domain == data[1]["domain"]

    response = client.delete("/api/shuup/shop/%d/" % shop.id)
    assert response.status_code == status.HTTP_204_NO_CONTENT
    assert Shop.objects.count() == 1

    # shouldn't be possible to delete a shop with a related order
    product = create_product("product1",
                             shop=default_shop,
                             supplier=get_default_supplier())
    create_random_order(create_random_person(), [product],
                        completion_probability=1,
                        shop=default_shop)
    response = client.delete("/api/shuup/shop/%d/" % default_shop.id)
    assert response.status_code == status.HTTP_400_BAD_REQUEST
    assert "This object can not be deleted because it is referenced by" in response.content.decode(
        "utf-8")
    assert Shop.objects.count() == 1
Beispiel #47
0
 def _formatted_datetime(self, dt):
     return format_datetime(localtime(dt), locale=get_current_babel_locale())
Beispiel #48
0
def test_coupons_usage_report(rf):
    shop = get_default_shop()
    tax_class = get_default_tax_class()
    creator = OrderCreator()

    coupon1 = Coupon.objects.create(code="coupon1", active=True)
    coupon2 = Coupon.objects.create(code="coupon2", active=True)

    campaign1 = get_default_campaign(coupon1, "10")
    campaign2 = get_default_campaign(coupon2, "25")

    source1 = seed_source(coupon1)
    source2 = seed_source(coupon1)
    source3 = seed_source(coupon1)
    source4 = seed_source(coupon2)

    creator.create_order(source1)
    creator.create_order(source2)
    creator.create_order(source3)
    creator.create_order(source4)

    # pay orders
    [o.create_payment(o.taxful_total_price) for o in Order.objects.all()]

    data = {
        "report": CouponsUsageReport.get_name(),
        "shop": shop.pk,
        "date_range": DateRangeChoices.ALL_TIME,
        "writer": "json",
        "force_download": 1,
    }
    report = CouponsUsageReport(**data)
    writer = get_writer_instance(data["writer"])
    response = writer.get_response(report=report)
    if hasattr(response, "render"):
        response.render()
    json_data = json.loads(response.content.decode("utf-8"))
    assert force_text(CouponsUsageReport.title) in json_data.get("heading")
    data = json_data.get("tables")[0].get("data")
    assert len(data) == Order.objects.count()

    expected_data = []

    orders = Order.objects.all().order_by("order_date")
    for order in orders:
        discount = order.shop.create_price(0)
        for dt in order.lines.discounts():
            discount += dt.taxful_price

        expected_data.append({
            "date":
            format_date(order.order_date, locale=get_current_babel_locale()),
            "coupon":
            order.codes[0],
            "order":
            str(order),
            "taxful_total":
            str(order.taxful_total_price.as_rounded().value),
            "taxful_subtotal":
            str((order.taxful_total_price - discount).as_rounded().value),
            "total_discount":
            str(discount.as_rounded().value)
        })

    assert len(expected_data) == len(data)

    for ix, d in enumerate(data):
        for k, v in d.items():
            assert expected_data[ix][k] == v
Beispiel #49
0
def test_coupons_usage_report(rf):
    shop = get_default_shop()
    tax_class = get_default_tax_class()
    creator = OrderCreator()

    coupon1 = Coupon.objects.create(code="coupon1", active=True)
    coupon2 = Coupon.objects.create(code="coupon2", active=True)

    campaign1 = get_default_campaign(coupon1, "10")
    campaign2 = get_default_campaign(coupon2, "25")

    source1 = seed_source(coupon1)
    source2 = seed_source(coupon1)
    source3 = seed_source(coupon1)
    source4 = seed_source(coupon2)

    creator.create_order(source1)
    creator.create_order(source2)
    creator.create_order(source3)
    creator.create_order(source4)

    # pay orders
    [o.create_payment(o.taxful_total_price) for o in Order.objects.all()]

    data = {
        "report": CouponsUsageReport.get_name(),
        "shop": shop.pk,
        "date_range": DateRangeChoices.ALL_TIME,
        "writer": "json",
        "force_download": 1,
    }
    report = CouponsUsageReport(**data)
    writer = get_writer_instance(data["writer"])
    response = writer.get_response(report=report)
    if hasattr(response, "render"):
        response.render()
    json_data = json.loads(response.content.decode("utf-8"))
    assert force_text(CouponsUsageReport.title) in json_data.get("heading")
    data = json_data.get("tables")[0].get("data")
    assert len(data) == Order.objects.count()

    expected_data = []

    orders = Order.objects.all().order_by("order_date")
    for order in orders:
        discount = order.shop.create_price(0)
        for dt in order.lines.discounts():
            discount += dt.taxful_price

        expected_data.append({
            "date": format_date(order.order_date, locale=get_current_babel_locale()),
            "coupon": order.codes[0],
            "order": str(order),
            "taxful_total": str(order.taxful_total_price.as_rounded().value),
            "taxful_subtotal": str((order.taxful_total_price - discount).as_rounded().value),
            "total_discount": str(discount.as_rounded().value)
        })

    assert len(expected_data) == len(data)

    for ix, d in enumerate(data):
        for k, v in d.items():
            assert expected_data[ix][k] == v
Beispiel #50
0
def get_currency_choices():
    locale = get_current_babel_locale()
    currencies = Currency.objects.all().order_by("code")
    return [(currency.code, locale.currencies.get(currency.code, currency)) for currency in currencies]
Beispiel #51
0
 def _formatted_datetime(self, dt):
     return format_datetime(localtime(dt), locale=get_current_babel_locale())
Beispiel #52
0
    def get_chart(self):
        if self.cached_chart is not None:
            return self.cached_chart

        chart_options = {
            "scales": {
                "yAxes": [{
                    "ticks": {
                        "beginAtZero": True
                    }
                }]
            }
        }

        today = date.today()
        chart_start_date = today - timedelta(days=365)

        orders = get_orders_for_shop(self.request)
        sum_sales_data = group_by_period(orders.valid().since(
            (today - chart_start_date).days),
                                         "order_date",
                                         "month",
                                         sum=Sum("taxful_total_price_value"))

        for (month, year) in month_iter(chart_start_date, today):
            sales_date = date(year, month, 1)
            if sales_date not in sum_sales_data:
                sum_sales_data[sales_date] = {"sum": Decimal(0)}

        # sort and recreated the ordered dict since we've put new items into
        sum_sales_data = OrderedDict(
            sorted(six.iteritems(sum_sales_data), key=lambda x: x[0]))

        locale = get_current_babel_locale()
        labels = [
            format_date(k,
                        format=get_year_and_month_format(locale),
                        locale=locale) for k in sum_sales_data
        ]
        mixed_chart = MixedChart(title=_("Sales per Month (past 12 months)"),
                                 labels=labels,
                                 data_type=ChartDataType.CURRENCY,
                                 options=chart_options,
                                 currency=self.currency,
                                 locale=locale)

        cumulative_sales = []
        average_sales = []

        # only calculate cumulative and average if there are at least 3 months
        if len(sum_sales_data) >= 3:
            count = 0
            total = Decimal()

            for month_sale in sum_sales_data.values():
                total = total + month_sale["sum"]
                cumulative_sales.append(total)
                average_sales.append(total / (count + 1))
                count = count + 1

        # this will be on top of all bars
        if average_sales:
            mixed_chart.add_data(_("Average Sales"),
                                 [v for v in average_sales], ChartType.LINE)

        # this will be under the cummulative bars
        mixed_chart.add_data(_("Sales"),
                             [v["sum"] for v in sum_sales_data.values()],
                             ChartType.BAR)

        # this will be under all others charts
        if cumulative_sales:
            mixed_chart.add_data(_("Cumulative Total Sales"),
                                 [v for v in cumulative_sales], ChartType.BAR)

        self.cached_chart = mixed_chart
        return mixed_chart
Beispiel #53
0
 def __init__(self, id, value, title, **kwargs):
     value = parse_decimal_string(value)
     if int(value) == value:
         value = int(value)
     value = format_number(value, locale=get_current_babel_locale())
     super(DashboardNumberBlock, self).__init__(id, value, title, **kwargs)
Beispiel #54
0
 def get_symbol(self, currency):
     return babel.numbers.get_currency_symbol(currency.code, get_current_babel_locale())
Beispiel #55
0
 def __init__(self, id, value, title, currency, **kwargs):
     self.currency = currency
     value = parse_decimal_string(value)
     value = format_currency(value, currency=self.currency, locale=get_current_babel_locale())
     super(DashboardMoneyBlock, self).__init__(id, value, title, **kwargs)
Beispiel #56
0
def test_sales_report_timezone(server_timezone):
    with override_settings(TIME_ZONE = server_timezone):
        """
        TIME TABLE

        | identifier  | ISO 8859-1                | UTC                 | America/Los_Angeles | America/Sao_Paulo   |
        | first_date  | 2017-10-01T23:50:00+03:00 | 2017-10-01 20:50:00 | 2017-10-01 13:50:00 | 2017-10-01 17:50:00 |
        | second_date | 2017-10-02T17:13:00+10:00 | 2017-10-02 07:13:00 | 2017-10-02 00:13:00 | 2017-10-02 04:13:00 |
        | third_date  | 2017-10-02T22:04:44-01:00 | 2017-10-02 23:04:44 | 2017-10-02 16:04:44 | 2017-10-02 20:04:44 |
        | forth_date  | 2017-10-02T23:04:44-05:00 | 2017-10-03 04:04:44 | 2017-10-02 21:04:44 | 2017-10-03 01:04:44 |
        """

        first_date = parse_datetime("2017-10-01T23:50:00+03:00")
        second_date = parse_datetime("2017-10-02T17:13:00+10:00")
        third_date = parse_datetime("2017-10-02T22:04:44-01:00")
        forth_date = parse_datetime("2017-10-02T23:04:44-05:00")

        inited_data = create_orders_for_dates([first_date, second_date, third_date, forth_date], as_paid=True)
        assert Order.objects.count() == 4

        first_date_local = first_date.astimezone(timezone(server_timezone))
        second_date_local = second_date.astimezone(timezone(server_timezone))
        third_date_local = third_date.astimezone(timezone(server_timezone))
        forth_date_local = forth_date.astimezone(timezone(server_timezone))

        data = {
            "report": SalesReport.get_name(),
            "shop": inited_data["shop"].pk,
            "start_date": first_date_local,
            "end_date": second_date_local,
        }
        report = SalesReport(**data)
        report_data = report.get_data()["data"]
        assert len(report_data) == 2

        # the orders should be rendered as localtime
        assert report_data[0]["date"] == format_date(second_date_local, locale=get_current_babel_locale())
        assert report_data[1]["date"] == format_date(first_date_local, locale=get_current_babel_locale())

        # includes the 3rd order
        data.update({
            "start_date": first_date_local,
            "end_date": third_date_local
        })
        report = SalesReport(**data)
        report_data = report.get_data()["data"]
        assert len(report_data) == 2

        assert report_data[0]["date"] == format_date(second_date_local, locale=get_current_babel_locale())
        assert report_data[1]["date"] == format_date(first_date_local, locale=get_current_babel_locale())

        # includes the 4th order - here the result is different for Los_Angeles and Sao_Paulo
        data.update({
            "start_date": first_date_local,
            "end_date": forth_date_local
        })
        report = SalesReport(**data)
        report_data = report.get_data()["data"]

        if server_timezone == "America/Los_Angeles":
            assert len(report_data) == 2
            assert report_data[0]["date"] == format_date(second_date_local, locale=get_current_babel_locale())
            assert report_data[1]["date"] == format_date(first_date_local, locale=get_current_babel_locale())
        else:
            assert len(report_data) == 3
            assert report_data[0]["date"] == format_date(forth_date_local, locale=get_current_babel_locale())
            assert report_data[1]["date"] == format_date(second_date_local, locale=get_current_babel_locale())
            assert report_data[2]["date"] == format_date(first_date_local, locale=get_current_babel_locale())

        # Using strings as start or end date should raise TypeError.
        # Only date or datetime objects should be accepted.
        data.update({
            "start_date": first_date_local.isoformat(),
            "end_date": forth_date_local.isoformat()
        })
        with pytest.raises(TypeError):
            report = SalesReport(**data)
            report_data = report.get_data()["data"]

        # Using different date types in start and end date should raise TypeError.
        data.update({
            "start_date": first_date_local,
            "end_date": forth_date_local.date()
        })
        with pytest.raises(TypeError):
            report = SalesReport(**data)
            report_data = report.get_data()["data"]
Beispiel #57
0
def test_shop_api(admin_user, currency, currency_decimals):
    activate("en")
    default_shop = get_default_shop()
    client = APIClient()
    client.force_authenticate(user=admin_user)
    Currency.objects.get_or_create(code=currency, decimal_places=currency_decimals)

    shop_data = {
        "domain": "shuup.com",
        "status": ShopStatus.ENABLED.value,
        "owner": create_random_person().pk,
        "currency": currency,
        "prices_include_tax": True,
        "maintenance_mode": False,
        "translations":{
            "en": {
                "name": "Store 1",
                "public_name": "Public Store 1"
            }
        }
    }
    response = client.post("/api/shuup/shop/",
                           content_type="application/json",
                           data=json.dumps(shop_data))
    assert response.status_code == status.HTTP_201_CREATED
    shop = Shop.objects.exclude(pk=default_shop.pk).first()
    assert shop.domain == shop_data["domain"]
    assert shop.status.value == shop_data["status"]
    assert shop.owner.pk == shop_data["owner"]
    assert shop.currency == shop_data["currency"]
    assert shop.maintenance_mode == shop_data["maintenance_mode"]
    assert shop.prices_include_tax == shop_data["prices_include_tax"]
    assert shop.name == shop_data["translations"]["en"]["name"]
    assert shop.public_name == shop_data["translations"]["en"]["public_name"]

    shop_data["domain"] = "cloud.shuup.com"
    response = client.put("/api/shuup/shop/%d/" % shop.id,
                          content_type="application/json",
                          data=json.dumps(shop_data))
    assert response.status_code == status.HTTP_200_OK
    shop = Shop.objects.exclude(pk=default_shop.pk).first()
    assert shop.domain == shop_data["domain"]

    response = client.get("/api/shuup/shop/%d/" % shop.id)
    assert response.status_code == status.HTTP_200_OK
    data = json.loads(response.content.decode("utf-8"))
    assert shop.domain == data["domain"]
    assert shop.status.value == data["status"]
    assert shop.owner.pk == data["owner"]
    assert shop.currency == data["currency"]["code"]
    assert data["currency"]["symbol"] == babel.numbers.get_currency_symbol(shop.currency, get_current_babel_locale())
    assert data["currency"]["decimal_places"] == currency_decimals
    assert shop.maintenance_mode == data["maintenance_mode"]
    assert shop.prices_include_tax == data["prices_include_tax"]
    assert shop.name == data["translations"]["en"]["name"]
    assert shop.public_name == data["translations"]["en"]["public_name"]

    response = client.get("/api/shuup/shop/")
    assert response.status_code == status.HTTP_200_OK
    data = json.loads(response.content.decode("utf-8"))
    assert shop.domain == data[1]["domain"]

    response = client.delete("/api/shuup/shop/%d/" % shop.id)
    assert response.status_code == status.HTTP_204_NO_CONTENT
    assert Shop.objects.count() == 1

    # shouldn't be possible to delete a shop with a related order
    product = create_product("product1", shop=default_shop, supplier=get_default_supplier())
    create_random_order(create_random_person(), [product], completion_probability=1, shop=default_shop)
    response = client.delete("/api/shuup/shop/%d/" % default_shop.id)
    assert response.status_code == status.HTTP_400_BAD_REQUEST
    assert "This object can not be deleted because it is referenced by" in response.content.decode("utf-8")
    assert Shop.objects.count() == 1