public ShoppingListResult UpdateShoppingList(AuthIdentity identity, Guid? listId, Guid[] toRemove, ShoppingListModification[] toModify, IShoppingListSource[] toAdd, string newName = null) { using (var session = GetSession()) { using (var transaction = session.BeginTransaction()) { // Deletes if (toRemove.Any()) { var dbDeletes = session.QueryOver<ShoppingListItems>() .Where(p => p.UserId == identity.UserId) .Where(listId.HasValue ? Expression.Eq("ShoppingList", listId.Value) : Expression.IsNull("ShoppingList") ).AndRestrictionOn(p => p.ItemId).IsInG(toRemove) .List(); dbDeletes.ForEach(session.Delete); } // Updates Models.ShoppingLists dbList = null; IList<ShoppingListItems> dbItems = null; if (listId.HasValue) { dbList = session.QueryOver<Models.ShoppingLists>() .Fetch(prop => prop.Items).Eager .Where(p => p.UserId == identity.UserId) .Where(p => p.ShoppingListId == listId.Value) .SingleOrDefault(); if (dbList == null) throw new ShoppingListNotFoundException(); if (!String.IsNullOrWhiteSpace(newName)) dbList.Title = newName; dbItems = dbList.Items; } else { dbItems = session.QueryOver<ShoppingListItems>() .Where(p => p.UserId == identity.UserId) .Where(p => p.ShoppingList == null) .List(); } toModify.ForEach(item => { var dbItem = dbItems.FirstOrDefault(i => i.ItemId == item.ModifiedItemId); if (dbItem == null) return; if (item.CrossOut.HasValue) dbItem.CrossedOut = item.CrossOut.Value; if (item.NewAmount != null) dbItem.Amount = item.NewAmount; }); toAdd.ForEach(item => { var source = item.GetItem(); if (source.Ingredient == null && !String.IsNullOrWhiteSpace(source.Raw)) // Raw shopping list item { if (!dbItems.Any(i => source.Raw.Equals(i.Raw, StringComparison.OrdinalIgnoreCase))) // Add it { var newItem = new ShoppingListItems { ShoppingList = dbList, UserId = identity.UserId, Raw = source.Raw }; session.Save(newItem); dbItems.Add(newItem); } return; } if (source.Ingredient != null && source.Amount == null) // Raw ingredient without any amount { var existingItem = dbItems.FirstOrDefault(i => i.Ingredient != null && i.Ingredient.IngredientId == source.Ingredient.Id); if (existingItem == null) // Add it { var newItem = new ShoppingListItems { ShoppingList = dbList, UserId = identity.UserId, Ingredient = Models.Ingredients.FromId(source.Ingredient.Id) }; session.Save(newItem); dbItems.Add(newItem); } else // Clear out existing amount { existingItem.Amount = null; } } if (source.Ingredient != null && source.Amount != null) // Ingredient with amount, aggregate if necessary { var existingItem = dbItems.FirstOrDefault(i => i.Ingredient != null && i.Ingredient.IngredientId == source.Ingredient.Id); if (existingItem == null) // Add it { var newItem = new ShoppingListItems { ShoppingList = dbList, UserId = identity.UserId, Ingredient = Models.Ingredients.FromId(source.Ingredient.Id), Amount = source.Amount }; session.Save(newItem); dbItems.Add(newItem); } else if (existingItem.Amount != null) // Add to total { existingItem.Amount += source.Amount; } } }); transaction.Commit(); return new ShoppingListResult { List = new ShoppingList( dbList != null ? (Guid?) dbList.ShoppingListId : null, dbList != null ? dbList.Title : null, dbItems.Select(i => i.AsShoppingListItem())) }; } } }
private static void ModifyShopingListItems( ShoppingListModification[] toModify, IList<ShoppingListItems> databaseItems) { toModify.ForEach( item => { var dbItem = databaseItems.FirstOrDefault(i => i.ItemId == item.ModifiedItemId); if (dbItem == null) { return; } if (item.CrossOut.HasValue) { dbItem.CrossedOut = item.CrossOut.Value; } if (item.NewAmount != null) { dbItem.Amount = item.NewAmount; } }); }