using System.Collections.Generic;
public class Subscription {
public Subscription(int id, int customerId, int monthlyPriceInDollars) {
this.CustomerId = customerId;
this.MonthlyPriceInDollars = monthlyPriceInDollars;
public int MonthlyPriceInDollars;
public User(int id, string name, DateTime activatedOn, DateTime deactivatedOn, int customerId) {
this.ActivatedOn = activatedOn;
this.DeactivatedOn = deactivatedOn;
this.CustomerId = customerId;
public DateTime ActivatedOn;
public DateTime DeactivatedOn;
public static Decimal BillFor(string month, Subscription activeSubscription, User[] users) {
if(string.IsNullOrEmpty(month)){
if(activeSubscription?.MonthlyPriceInDollars == null){
var currentMonthDate = DateTime.Parse(month);
var numberOfDays = DateTime.DaysInMonth(currentMonthDate.Year, currentMonthDate.Month);
decimal dailyRate = activeSubscription.MonthlyPriceInDollars / numberOfDays;
var roundedDailyRate = Math.Round(dailyRate, 9);
Console.WriteLine($"Daily rate is {activeSubscription.MonthlyPriceInDollars} / {numberOfDays} days => {dailyRate} / day");
for(int i=0; i < numberOfDays; i++){
currentMonthDate = currentMonthDate.AddDays(i);
var activeUsers = users.Where(x => x.ActivatedOn <= currentMonthDate && x.DeactivatedOn > currentMonthDate && x.CustomerId == activeSubscription.CustomerId).ToList();
var dailyTotal = Math.Round(dailyRate * activeUsers.Count, 9);
Console.WriteLine($"{currentMonthDate} {activeUsers.Count} active users * ${dailyRate} = ${dailyTotal} (subtotal: ${subTotal})");
Console.WriteLine($"Total = ${subTotal} (round subtotal to nearest cent)");
return Math.Round(subTotal, 2);
private static DateTime FirstDayOfMonth(DateTime date) {
return new DateTime(date.Year, date.Month, 1);
private static DateTime LastDayOfMonth(DateTime date) {
return new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
private static DateTime NextDay(DateTime date) {