Untitled

 avatar
unknown
plain_text
5 months ago
2.7 kB
2
Indexable
import calendar
from datetime import datetime

def monthly_charge(month, subscription, users):
    """
    Computes the monthly charge for a given subscription.

    @type month: str
    @param month: Always present
                  Has the following structure: "2022-04"  # April 2022 in YYYY-MM format

    @type subscription: dict
    @param subscription: May be None
                         If present, has the following structure:
                         {
                             'id': 763,
                             'customer_id': 328,
                             'monthly_price_in_cents': 359  # Price per active user per month
                         }

    @type users: list
    @param users: May be empty, but not None
                  List of user activity dictionaries with start and end dates:
                  [
                      {'user_id': 1, 'start_date': '2022-04-01', 'end_date': '2022-04-10'},
                      {'user_id': 2, 'start_date': '2022-04-05', 'end_date': None}
                  ]

    @returns: int, total monthly bill in cents, rounded to the nearest cent.
              For example, a bill of $20.00 should return 2000.
              If there are no active users or the subscription is None, returns 0.
    """
    if not subscription or not users:
        return 0

    # Parse the month and year from the input month string
    year, month = map(int, month.split('-'))
    # Get the number of days in the month
    _, days_in_month = calendar.monthrange(year, month)

    # Calculate daily rate in cents for the subscription
    monthly_rate = subscription['monthly_price_in_cents']
    daily_rate = monthly_rate / days_in_month

    # Calculate total charges for all active users for the month
    total_charge = 0

    for user in users:
        # Parse the user's subscription start and end dates
        start_date = datetime.strptime(user['start_date'], '%Y-%m-%d')
        end_date = datetime.strptime(user['end_date'], '%Y-%m-%d') if user['end_date'] else datetime(year, month, days_in_month)

        # Calculate the number of days the user was active in the given month
        # Consider only days within the specified month
        active_start = max(start_date, datetime(year, month, 1))
        active_end = min(end_date, datetime(year, month, days_in_month))
        
        # Calculate number of active days within the given month
        active_days = (active_end - active_start).days + 1  # +1 to include the end day

        # Add the user's contribution to the total charge
        if active_days > 0:
            total_charge += active_days * daily_rate

    # Return the total charge rounded to whole cents
    return int(round(total_charge))
Editor is loading...
Leave a Comment