public ActionResult Create(MedicineViewModel viewModel)
 {
     return this.Edit(viewModel);
 }
        public ActionResult Edit(MedicineViewModel formModel)
        {
            if (formModel.IsImporting)
            {
                // in this case it's importing the medicine from Anvisa

                // remove model state errors
                this.ModelState.Remove(() => formModel.Name);
                this.ModelState.Remove(() => formModel.LaboratoryName);

                // validating the existence of the sys medicine
                var sysMedicine = this.db.SYS_Medicine.FirstOrDefault(sm => sm.Id == formModel.AnvisaId);
                if (sysMedicine == null && formModel.AnvisaId.HasValue) // I verify formModel.AnvisaId.HasValue here to prevent double errors
                    this.ModelState.AddModelError<AnvisaImportViewModel>(model => model.AnvisaId, "O medicamento informado não foi encontrado");

                // validating the name is unique
                if (sysMedicine != null && this.db.Medicines.Any(m => m.DoctorId == this.Doctor.Id && m.Name == formModel.AnvisaCustomText))
                    this.ModelState.AddModelError<AnvisaImportViewModel>(
                        model => model.AnvisaId, "Já existe um medicamento com o mesmo nome do medicamento informado");

                if (this.ModelState.IsValid)
                {
                    Debug.Assert(sysMedicine != null, "sysMedicine != null");
                    var medicine = new Medicine()
                    {
                        Name = formModel.AnvisaCustomText,
                        PracticeId = this.DbPractice.Id,
                        DoctorId = this.Doctor.Id,
                        CreatedOn = this.GetUtcNow(),
                    };

                    // verify the need to create a new laboratory
                    var laboratory = this.db.Laboratories.FirstOrDefault(l => l.DoctorId == this.Doctor.Id && l.Name == sysMedicine.Laboratory.Name) ??
                                     new Laboratory()
                                     {
                                         Name = sysMedicine.Laboratory.Name,
                                         PracticeId = this.DbPractice.Id,
                                         DoctorId = this.Doctor.Id,
                                         CreatedOn = this.GetUtcNow(),
                                     };
                    medicine.Laboratory = laboratory;

                    // verify the need to create new active ingredients
                    foreach (var ai in sysMedicine.ActiveIngredients)
                    {
                        medicine.ActiveIngredients.Add(new MedicineActiveIngredient()
                        {
                            Name = ai.Name,
                            PracticeId = this.DbPractice.Id,
                        });
                    }

                    // create the leaflets
                    foreach (var l in sysMedicine.Leaflets)
                        medicine.Leaflets.Add(
                            new Leaflet()
                            {
                                Description = l.Description,
                                Url = l.Url,
                                PracticeId = this.DbPractice.Id
                            });

                    this.db.Medicines.AddObject(medicine);

                    this.db.SaveChanges();

                    // depending on whether or not this is an Ajax request,
                    // this should return an AutocompleteNewJsonResult or the view
                    if (this.Request.IsAjaxRequest())
                        return this.Json(
                            new AutocompleteNewJsonResult()
                            {
                                Id = medicine.Id,
                                Value = medicine.Name
                            });

                    return this.RedirectToAction("Details", new { id = medicine.Id });
                }

            }

            else
            {
                // In this case the medicine is being edited manually

                // remove model state errors
                this.ModelState.Remove(() => formModel.AnvisaId);
                this.ModelState.Remove(() => formModel.AnvisaText);
                this.ModelState.Remove(() => formModel.AnvisaCustomText);

                // if a medicine exists with the same name, a model state error must be placed
                var existingMedicine = this.db.Medicines.FirstOrDefault(m => m.Name == formModel.Name);
                if (existingMedicine != null && existingMedicine.Id != formModel.Id)
                    this.ModelState.AddModelError<MedicineViewModel>(
                        model => model.Name, "Já existe um medicamento cadastrado com o mesmo nome");

                // add validation error when Laboratory Id is invalid
                Laboratory laboratory = null;
                if (formModel.LaboratoryId != null)
                {
                    laboratory = this.db.Laboratories.FirstOrDefault(lab => lab.Id == formModel.LaboratoryId && lab.DoctorId == this.Doctor.Id);
                    if (laboratory == null)
                        this.ModelState.AddModelError<MedicineViewModel>((model) => model.LaboratoryId, "O laboratório informado é inválido");
                }

                if (this.ModelState.IsValid)
                {
                    Medicine medicine = null;

                    if (formModel.Id.HasValue)
                    {
                        medicine = this.db.Medicines.FirstOrDefault(m => m.Id == formModel.Id);
                        if (medicine == null)
                            return this.ObjectNotFound();
                    }
                    else
                    {
                        medicine = new Medicine
                        {
                            PracticeId = this.DbUser.PracticeId,
                            DoctorId = this.Doctor.Id,
                            CreatedOn = this.GetUtcNow(),
                        };
                        this.db.Medicines.AddObject(medicine);
                    }

                    medicine.Name = formModel.Name;
                    medicine.Observations = formModel.Observations;
                    medicine.Usage = (short)formModel.Usage;

                    if (formModel.LaboratoryId != null)
                        medicine.Laboratory = laboratory;

                    // Active ingredients
                    {
                        // Verify whether any existing active ingredient should be REMOVED.
                        var activeIngredientsDeathQueue = new Queue<MedicineActiveIngredient>();
                        foreach (var existingActiveIngredient in medicine.ActiveIngredients)
                            if (formModel.ActiveIngredients.All(a => a.Id != existingActiveIngredient.Id))
                                activeIngredientsDeathQueue.Enqueue(existingActiveIngredient);
                        while (activeIngredientsDeathQueue.Any())
                            this.db.ActiveIngredients.DeleteObject(activeIngredientsDeathQueue.Dequeue());

                        // Verify whether any new active ingredient should be UPDATED or ADDED
                        foreach (var activeIngredientViewModel in formModel.ActiveIngredients)
                        {
                            var existingActiveIngredient = medicine.ActiveIngredients.SingleOrDefault(l => l.Id == activeIngredientViewModel.Id);
                            if (existingActiveIngredient == null)
                            {
                                // ADD when not existing
                                medicine.ActiveIngredients.Add(
                                    new MedicineActiveIngredient()
                                    {
                                        Name = activeIngredientViewModel.Name,
                                        PracticeId = this.DbPractice.Id
                                    });
                            }
                            else
                            {
                                // UPDATE when existing
                                existingActiveIngredient.Name = activeIngredientViewModel.Name;
                            }
                        }
                    }

                    // Leaflets
                    {
                        // Verify whether any existing leaflet must be REMOVED
                        var leafletsDeathQueue = new Queue<Leaflet>();
                        foreach (var existingLeaflet in medicine.Leaflets)
                            if (formModel.Leaflets.All(l => l.Id != existingLeaflet.Id))
                                leafletsDeathQueue.Enqueue(existingLeaflet);
                        while (leafletsDeathQueue.Any())
                            this.db.Leaflets.DeleteObject(leafletsDeathQueue.Dequeue());

                        // Verify whether any leaflet should be UPDATED or ADDED
                        foreach (var leafletViewModel in formModel.Leaflets)
                        {
                            var existingLeaftlet = medicine.Leaflets.SingleOrDefault(l => l.Id == leafletViewModel.Id);
                            if (existingLeaftlet == null)
                            {
                                // ADD when not existing
                                medicine.Leaflets.Add(
                                    new Leaflet()
                                    {
                                        PracticeId = this.DbPractice.Id,
                                        Url = leafletViewModel.Url,
                                        Description = leafletViewModel.Description
                                    });
                            }
                            else
                            {
                                // UPDATE when existing
                                existingLeaftlet.Url = leafletViewModel.Url;
                                existingLeaftlet.Description = leafletViewModel.Description;
                            }
                        }
                    }

                    this.db.SaveChanges();

                    // depending on whether or not this is an Ajax request,
                    // this should return an AutocompleteNewJsonResult or the view
                    if (this.Request.IsAjaxRequest())
                        return this.Json(
                            new AutocompleteNewJsonResult()
                            {
                                Id = medicine.Id,
                                Value = medicine.Name
                            });

                    return Redirect(Url.Action("details", new { id = medicine.Id }));
                }
            }

            return this.Request.IsAjaxRequest() ? View("EditModal", formModel) : View("Edit", formModel);
        }
        public ActionResult Edit(int? id, string text)
        {
            var viewModel = new MedicineViewModel()
                {
                    Name = text
                };

            if (id != null)
            {
                var medicine = this.db.Medicines.First(m => m.Id == id);
                viewModel = this.GetViewModelFromModel(medicine);
            }

            return this.Request.IsAjaxRequest() ? View("EditModal", viewModel) : View("Edit", viewModel);
        }
        public void Edit_AddingNewActiveIngredient()
        {
            MedicinesController controller;

            try
            {
                var mr = new MockRepository(true);
                controller = mr.CreateController<MedicinesController>();
            }
            catch
            {
                Assert.Inconclusive("Test initialization has failed.");
                return;
            }

            var medicineName = "My Medicine";

            // all these active ingredients have already been created.
            // now we have to associate them with the original active ingredients

            var formModel = new MedicineViewModel()
            {
                Name = medicineName,
                ActiveIngredients = new List<MedicineActiveIngredientViewModel>()
                        {
                            new MedicineActiveIngredientViewModel()
                                {
                                    Name = "AI1"
                                },
                            new MedicineActiveIngredientViewModel()
                                {
                                    Name = "AI2"
                                }
                        }
            };
            controller.Create(formModel);

            var medicine = this.db.Medicines.FirstOrDefault(m => m.Name == medicineName);
            Assert.IsNotNull(medicine);
            Assert.AreEqual(2, medicine.ActiveIngredients.Count);

            // verify that all the active ingredients inside the medicine are those that
            // we've created here
            Assert.AreEqual(formModel.ActiveIngredients[0].Name, medicine.ActiveIngredients.ElementAt(0).Name);
            Assert.AreEqual(formModel.ActiveIngredients[1].Name, medicine.ActiveIngredients.ElementAt(1).Name);
        }
        public void Edit_UpdatingExistingLeaflets()
        {
            MedicinesController controller;

            try
            {
                var mr = new MockRepository(true);
                controller = mr.CreateController<MedicinesController>();
            }
            catch
            {
                Assert.Inconclusive("Test initialization has failed.");
                return;
            }

            var medicineName = "My Medicine";

            // all these active ingredients have already been created.
            // now we have to associate them with the original active ingredients

            var formModel = new MedicineViewModel()
            {
                Name = medicineName,
                Leaflets = new List<MedicineLeafletViewModel>()
                        {
                            new MedicineLeafletViewModel()
                                {
                                    Url = "http://www.google.com",
                                    Description = "desc 1"
                                }
                        }
            };
            controller.Create(formModel);

            var medicine = this.db.Medicines.FirstOrDefault(m => m.Name == medicineName);
            Assert.IsNotNull(medicine);
            Assert.AreEqual(1, medicine.Leaflets.Count);

            formModel.Id = medicine.Id;
            formModel.Leaflets[0].Id = medicine.Leaflets.ElementAt(0).Id;
            formModel.Leaflets[0].Url = "http://www.facebook.com";
            formModel.Leaflets[0].Description = "desc 2";

            // Let's edit now and change some properties
            controller.Edit(formModel);

            // we need to refresh since the DB inside the controller is different from this
            this.db.Refresh(RefreshMode.StoreWins, medicine.Leaflets);

            // verify that all the active ingredients inside the medicine are those that
            // we've EDITED here
            Assert.AreEqual(formModel.Leaflets[0].Url, medicine.Leaflets.ElementAt(0).Url);
            Assert.AreEqual(formModel.Leaflets[0].Description, medicine.Leaflets.ElementAt(0).Description);
        }
        public void Edit_RemovingExistingActiveIngredient()
        {
            MedicinesController controller;

            try
            {
                var mr = new MockRepository(true);
                controller = mr.CreateController<MedicinesController>();
            }
            catch
            {
                Assert.Inconclusive("Test initialization has failed.");
                return;
            }

            var medicineName = "My Medicine";

            // all these active ingredients have already been created.
            // now we have to associate them with the original active ingredients

            var formModel = new MedicineViewModel()
            {
                Name = medicineName,
                ActiveIngredients = new List<MedicineActiveIngredientViewModel>()
                        {
                            new MedicineActiveIngredientViewModel()
                                {
                                    Name = "AI1",
                                },
                            new MedicineActiveIngredientViewModel()
                                {
                                    Name = "AI2",
                                }
                        }
            };
            controller.Create(formModel);

            var medicine = this.db.Medicines.FirstOrDefault(m => m.Name == medicineName);
            Assert.IsNotNull(medicine);
            Assert.AreEqual(2, medicine.ActiveIngredients.Count);

            // let's put the formModel in edit mode and remove the second leaflet
            formModel.Id = medicine.Id;
            formModel.ActiveIngredients[0].Id = medicine.ActiveIngredients.ElementAt(0).Id;
            formModel.ActiveIngredients.RemoveAt(1);

            // Let's edit
            controller.Edit(formModel);

            // we need to refresh since the DB inside the controller is different from this
            this.db.Refresh(RefreshMode.StoreWins, medicine.ActiveIngredients);

            Assert.AreEqual(1, medicine.ActiveIngredients.Count);

            // verify that all the active ingredients inside the medicine are those that
            // we've created here
            Assert.AreEqual(formModel.ActiveIngredients[0].Name, medicine.ActiveIngredients.ElementAt(0).Name);
        }