Example #1
0
def calculate_weekly_sales(item_collection_ids, user_tz, year):
    """
    Calculates sales per week for items in the given set of item_collection_ids in a given year,
    in the user's timezone.
    """
    ordered_week_sales = OrderedDict()
    for year_week in Week.weeks_of_year(year):
        ordered_week_sales[year_week.week] = 0
    start_at = isoweek_datetime(year, 1, user_tz)
    end_at = isoweek_datetime(year + 1, 1, user_tz)

    week_sales = db.session.query('sales_week', 'sum').from_statement(db.text('''
        SELECT EXTRACT(WEEK FROM ordered_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone)
        AS sales_week, SUM(final_amount) AS sum
        FROM line_item INNER JOIN item on line_item.item_id = item.id
        WHERE status IN :statuses AND item_collection_id IN :item_collection_ids
        AND ordered_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone >= :start_at
        AND ordered_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone < :end_at
        GROUP BY sales_week ORDER BY sales_week;
        ''')).params(timezone=user_tz, statuses=tuple([LINE_ITEM_STATUS.CONFIRMED, LINE_ITEM_STATUS.CANCELLED]),
        start_at=start_at, end_at=end_at, item_collection_ids=tuple(item_collection_ids)).all()

    for week_sale in week_sales:
        ordered_week_sales[int(week_sale.sales_week)] = week_sale.sum

    return ordered_week_sales
Example #2
0
def calculate_weekly_refunds(item_collection_ids, user_tz, year):
    """
    Calculates refunds per week for a given set of item_collection_ids in a given year,
    in the user's timezone.
    """
    ordered_week_refunds = OrderedDict()
    for year_week in Week.weeks_of_year(year):
        ordered_week_refunds[year_week.week] = 0
    start_at = isoweek_datetime(year, 1, user_tz)
    end_at = isoweek_datetime(year + 1, 1, user_tz)

    week_refunds = db.session.query('sales_week', 'sum').from_statement(
        db.text('''
        SELECT EXTRACT(WEEK FROM payment_transaction.created_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone)
        AS sales_week, SUM(payment_transaction.amount) AS sum
        FROM customer_order INNER JOIN payment_transaction on payment_transaction.customer_order_id = customer_order.id
        WHERE customer_order.status IN :statuses AND customer_order.item_collection_id IN :item_collection_ids
        AND payment_transaction.transaction_type = :transaction_type
        AND payment_transaction.created_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone
            >= :start_at
        AND payment_transaction.created_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone
            < :end_at
        GROUP BY sales_week ORDER BY sales_week;
        ''')).params(timezone=user_tz,
                     statuses=tuple(ORDER_STATUS.TRANSACTION),
                     transaction_type=TRANSACTION_TYPE.REFUND,
                     start_at=start_at,
                     end_at=end_at,
                     item_collection_ids=tuple(item_collection_ids)).all()

    for week_refund in week_refunds:
        ordered_week_refunds[int(week_refund.sales_week)] = week_refund.sum

    return ordered_week_refunds
Example #3
0
def calculate_weekly_sales(item_collection_ids, user_tz, year):
    """
    Calculates sales per week for items in the given set of item_collection_ids in a given year,
    in the user's timezone.
    """
    ordered_week_sales = OrderedDict()
    for year_week in Week.weeks_of_year(year):
        ordered_week_sales[year_week.week] = 0
    start_at = isoweek_datetime(year, 1, user_tz)
    end_at = isoweek_datetime(year + 1, 1, user_tz)

    week_sales = (db.session.query('sales_week', 'sum').from_statement(
        db.text('''
        SELECT EXTRACT(WEEK FROM ordered_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone)
        AS sales_week, SUM(final_amount) AS sum
        FROM line_item INNER JOIN item on line_item.item_id = item.id
        WHERE status IN :statuses AND item_collection_id IN :item_collection_ids
        AND ordered_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone >= :start_at
        AND ordered_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone < :end_at
        GROUP BY sales_week ORDER BY sales_week;
        ''')).params(
            timezone=user_tz,
            statuses=tuple(
                [LINE_ITEM_STATUS.CONFIRMED, LINE_ITEM_STATUS.CANCELLED]),
            start_at=start_at,
            end_at=end_at,
            item_collection_ids=tuple(item_collection_ids),
        ).all())

    for week_sale in week_sales:
        ordered_week_sales[int(week_sale.sales_week)] = week_sale.sum

    return ordered_week_sales
Example #4
0
def sales_by_date(sales_datetime, item_ids, user_tz):
    """Return the sales amount accrued during the given day for given items."""
    if not item_ids:
        return None

    start_at = midnight_to_utc(sales_datetime, timezone=user_tz)
    end_at = midnight_to_utc(
        sales_datetime + datetime.timedelta(days=1), timezone=user_tz
    )
    sales_on_date = (
        db.session.query(db.column('sum'))
        .from_statement(
            db.text(
                '''SELECT SUM(final_amount) FROM line_item
        WHERE status=:status AND ordered_at >= :start_at AND ordered_at < :end_at
        AND line_item.item_id IN :item_ids
        '''
            )
        )
        .params(
            status=LINE_ITEM_STATUS.CONFIRMED,
            start_at=start_at,
            end_at=end_at,
            item_ids=tuple(item_ids),
        )
        .scalar()
    )
    return sales_on_date if sales_on_date else Decimal(0)
Example #5
0
def sales_by_date(sales_datetime, item_ids, user_tz):
    """
    Returns the sales amount accrued during the day for a given date/datetime,
    list of item_ids and timezone.
    """
    if not item_ids:
        return None

    start_at = midnight_to_utc(sales_datetime, timezone=user_tz)
    end_at = midnight_to_utc(sales_datetime + datetime.timedelta(days=1), timezone=user_tz)
    sales_on_date = db.session.query('sum').from_statement(db.text('''SELECT SUM(final_amount) FROM line_item
        WHERE status=:status AND ordered_at >= :start_at AND ordered_at < :end_at
        AND line_item.item_id IN :item_ids
        ''')).params(status=LINE_ITEM_STATUS.CONFIRMED, start_at=start_at, end_at=end_at, item_ids=tuple(item_ids)).scalar()
    return sales_on_date if sales_on_date else Decimal(0)
Example #6
0
def item_collection_net_sales(self):
    """Returns the net revenue for an item collection"""
    total_paid = db.session.query('sum').from_statement(
        db.text('''SELECT SUM(amount) FROM payment_transaction
        INNER JOIN customer_order ON payment_transaction.customer_order_id = customer_order.id
        WHERE transaction_type=:transaction_type
        AND customer_order.item_collection_id = :item_collection_id
        ''')).params(transaction_type=TRANSACTION_TYPE.PAYMENT,
                     item_collection_id=self.id).scalar()

    total_refunded = db.session.query('sum').from_statement(
        db.text('''SELECT SUM(amount) FROM payment_transaction
        INNER JOIN customer_order ON payment_transaction.customer_order_id = customer_order.id
        WHERE transaction_type=:transaction_type
        AND customer_order.item_collection_id = :item_collection_id
        ''')).params(transaction_type=TRANSACTION_TYPE.REFUND,
                     item_collection_id=self.id).scalar()

    if total_paid and total_refunded:
        return total_paid - total_refunded
    elif total_paid:
        return total_paid
    else:
        return Decimal('0')
Example #7
0
def counts_per_date_per_item(item_collection, user_tz):
    """
    Returns number of line items sold per date per item.
    Eg: {'2016-01-01': {'item-xxx': 20}}
    """
    date_item_counts = {}
    for item in item_collection.items:
        item_id = unicode(item.id)
        item_results = db.session.query('date', 'count').from_statement(
            db.text('''SELECT DATE_TRUNC('day', line_item.ordered_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone)::date as date, count(line_item.id) AS count
            FROM line_item WHERE item_id = :item_id AND status = :status
            GROUP BY date ORDER BY date ASC''')).params(timezone=user_tz, status=LINE_ITEM_STATUS.CONFIRMED, item_id=item.id).all()
        for date_count in item_results:
            if not date_item_counts.get(date_count.date):
                # if this date hasn't been been mapped in date_item_counts yet
                date_item_counts[date_count.date] = {item_id: date_count.count}
            else:
                # if it has been mapped, assign the count
                date_item_counts[date_count.date][item_id] = date_count.count
    return date_item_counts
Example #8
0
def counts_per_date_per_item(item_collection, user_tz):
    """
    Returns number of line items sold per date per item.
    Eg: {'2016-01-01': {'item-xxx': 20}}
    """
    date_item_counts = {}
    for item in item_collection.items:
        item_id = unicode(item.id)
        item_results = db.session.query('date', 'count').from_statement(
            db.text(
                '''SELECT DATE_TRUNC('day', line_item.ordered_at AT TIME ZONE 'UTC' AT TIME ZONE :timezone)::date as date, count(line_item.id) AS count
            FROM line_item WHERE item_id = :item_id AND status = :status
            GROUP BY date ORDER BY date ASC''')).params(
                    timezone=user_tz,
                    status=LINE_ITEM_STATUS.CONFIRMED,
                    item_id=item.id).all()
        for date_count in item_results:
            if not date_item_counts.get(date_count.date):
                # if this date hasn't been been mapped in date_item_counts yet
                date_item_counts[date_count.date] = {item_id: date_count.count}
            else:
                # if it has been mapped, assign the count
                date_item_counts[date_count.date][item_id] = date_count.count
    return date_item_counts