public BudgetModel CloneBudgetModel(BudgetModel sourceBudget, DateTime newBudgetEffectiveFrom) { if (sourceBudget == null) { throw new ArgumentNullException(nameof(sourceBudget)); } if (newBudgetEffectiveFrom <= sourceBudget.EffectiveFrom) { throw new ArgumentException("The effective date of the new budget must be later than the other budget.", nameof(newBudgetEffectiveFrom)); } if (newBudgetEffectiveFrom <= DateTime.Today) { throw new ArgumentException("The effective date of the new budget must be a future date.", nameof(newBudgetEffectiveFrom)); } var validationMessages = new StringBuilder(); if (!sourceBudget.Validate(validationMessages)) { throw new ValidationWarningException(string.Format(CultureInfo.CurrentCulture, "The source budget is currently in an invalid state, unable to clone it at this time.\n{0}", validationMessages)); } var newBudget = new BudgetModel { EffectiveFrom = newBudgetEffectiveFrom, Name = string.Format(CultureInfo.CurrentCulture, "Copy of {0}", sourceBudget.Name) }; newBudget.Update(CloneBudgetIncomes(sourceBudget), CloneBudgetExpenses(sourceBudget)); if (!newBudget.Validate(validationMessages)) { throw new InvalidOperationException("New cloned budget is invalid but the source budget is ok. Code Error.\n" + validationMessages); } Budgets.Add(newBudget); this.budgetRepository.SaveAsync(); UpdateServiceMonitor(); return(newBudget); }