public ActionResult EditCRepOrderStatus(EditCRepOrderStatus_VM model)
        {
            model.Order = repairRepository.CRepOrders.SingleOrDefault(o => o.CRO_ID == model.OrderID); //обязательно надо связать с заявкой до валидации
            ValidateEditCRepOrderStatus_VM(model, ModelState);

            if (ModelState.IsValid)
            {
                //валидация успешна, пробуем изменить заявку в БД
                //отдельно рассматриваются каждый новый статус в части изменяемых полей заявки
                switch (model.NewStatus)
                {
                    case "sended":
                        model.Order.CRO_sendedDate = DateTime.Parse(model.SendedDate);
                        model.Order.CRO_No = model.No;
                        break;
                    case "billed":
                        model.Order.CRO_billedDate = DateTime.Parse(model.BilledDate);
                        model.RepairCost = model.RepairCost.Replace('.', ',');
                        model.Order.CRO_repairCost = float.Parse(model.RepairCost);
                        model.Order.CRO_repairContractor = model.Contractor;
                        break;
                    case "examined":
                        model.Order.CRO_examinedDate = DateTime.Parse(model.ExaminedDate);
                        model.Order.CRO_comment = model.Comment;
                        break;
                    case "notexamined":
                        model.Order.CRO_examinedDate = null;
                        model.Order.CRO_closedDate = null;
                        model.Order.CRO_repairResult = null;
                        model.Order.CRO_verdict = null;
                        model.Order.CRO_comment = model.Comment;
                        break;
                    case "closed":
                        model.Order.CRO_closedDate = DateTime.Parse(model.ClosedDate);
                        model.Order.CRO_repairResult = model.RepairResult;
                        model.Order.CRO_verdict = model.Verdict;
                        break;
                    case "examinednotclosed":
                        model.Order.CRO_examinedDate = DateTime.Parse(model.ExaminedDate);
                        model.Order.CRO_closedDate = null;
                        model.Order.CRO_repairResult = null;
                        model.Order.CRO_verdict = null;
                        model.Order.CRO_comment = model.Comment;
                        break;
                    case "notbilled":
                        model.Order.CRO_billedDate = null;
                        model.Order.CRO_repairCost = null;
                        model.Order.CRO_repairContractor = null;
                        break;
                }//switch
                //объект поменяли, сохраняем
                try
                {
                    repairRepository.SaveCRepOrder(model.Order);
                }
                catch (Exception e)
                {
                    //сохранение неудачно
                    repairRepository.ResetCRepOrders();
                    ModelState.AddModelError("", e.Message);
                }

            }

            if(ModelState.IsValid)
            {
                //валидация и изменения БД успешны: перепрыгнем на ReturnURL
                return Redirect(model.ReturnURL);
            }
            else
            {
                //есть ошибки валидации перегрузим окно вместе с ошибками
                //Добавим в модель недостающие данные
                // model.Order уже привязали ранее, но надо привязать повторно, иначе на окне с ошибками неправильно отражается стстус заявки

                model.Contractors = repairRepository.Contractors;
                return View(model);
            }
        }
        void ValidateEditCRepOrderStatus_VM(EditCRepOrderStatus_VM model, ModelStateDictionary state)
        {
            state.Clear();
            DateTime tempDate;
            float tempFloat;
            string tempString;
            //валидация проходит отдельно для каждого варианта нового статуса
            //1.sended
            if (model.NewStatus=="sended")
            {
                //дата отправки
                //должна быть введена, должна иметь правильный формат, должна быть в интервале дата обнаружения -- текущая дата
                try
                {
                    if (model.SendedDate != null)
                    {
                        tempDate = DateTime.Parse(model.SendedDate); //если ввели некоректные данные, то не распарсит
                        if (tempDate > DateTime.Now)
                        {
                            state.AddModelError("", "Дата направления заявки позже текущей даты!");
                        }
                        else if (tempDate < model.Order.CRO_revealedDate)
                        {
                            //state.AddModelError("", "Заявка не может быть направлена раньше обнаружения неисправности!");
                        }
                    }
                    else
                    {
                        state.AddModelError("", "Пожалуйста введите дату направления заявки!");
                    }
                }
                catch
                {
                    //нераспарсил
                    state.AddModelError("DateError", "Пожалуйста введить дату направления заявки в формате ДД.ММ.ГГГГ");
                }
                //номер заявки - должен быть присвоен, должен быть не более 10 символов
                if (model.No== null)
                    state.AddModelError("NoError", "Пожалуйста укажите номер, присвоенный заявке!");
                else if (model.No.Length>10)
                    state.AddModelError("NoError", "Ошибка: номер заявки должен быть в пределах 10 символов");

            } //sended

            //2. billed
            if (model.NewStatus == "billed")
            {
                //дата предъявления
                //должна быть введена, должна иметь правильный формат, должна быть в интервале дата восстановления -- текущая дата
                //перед приемкой к оплате работ заявка должна быть закрыта
                try
                {
                    if (model.BilledDate != null)
                    {
                        tempDate = DateTime.Parse(model.BilledDate); //если ввели некоректные данные, то не распарсит
                        if (tempDate > DateTime.Now)
                        {
                            state.AddModelError("", "Дата предъявления работ к оплате позже текущей даты!");
                        }

                        if(model.Order.CRO_closedDate==null)
                        {
                            state.AddModelError("", "Ошибка: попытка внесения информации об оплате заявки, которая не закрыта!");
                        }
                        else if (tempDate < model.Order.CRO_closedDate)
                        {
                            state.AddModelError("", "Ошибка. Дата предъявления работ к оплате раньше даты закрытия заявки!");
                        }
                    }
                    else
                    {
                        state.AddModelError("", "Пожалуйста введите дату предъявления работ к оплате!");
                    }
                }
                catch
                {
                    //нераспарсил
                    state.AddModelError("DateError", "Пожалуйста введить дату предъявления работ к оплате в формате ДД.ММ.ГГГГ");
                }

                //подрядная организация
                //должна быть выбрана
                if(model.Contractor==null)
                {
                    state.AddModelError("", "Пожалуйста выберите подрядную организацию!");
                }

                //стоимость ремонта
                // должна быть введена, должна быть в интервале 150 - 150 000,00
                if (model.RepairCost!=null)
                {
                    //на
                    tempString = model.RepairCost.Replace('.', ',');//для того, чтобы пользователь имел возможность вводить и через точку и через запятую
                    try
                    {
                        tempFloat = float.Parse(tempString);
                        //распарсил, продолжаем
                        if (tempFloat<150.00 || tempFloat>150000.00)
                        {
                            state.AddModelError("", "Ошибка: введена недостоверная сумма!");
                        }
                    }
                    catch
                    {
                        state.AddModelError("","Пожалуйста введите сумму в формате XXXX,XX!");
                    }
                }
                else
                {
                    //сумма не введена
                    state.AddModelError("", "Пожалуйста введите сумму!");
                }

            } //billed

            //3. examined
            if (model.NewStatus == "examined")
            {
                //дата обследования
                //должна быть введена, должна иметь правильный формат, должна быть в интервале дата отправки заявки -- текущая дата
                //перед обследованием заявка должна быть направлена Подрядчику
                try
                {
                    if (model.ExaminedDate != null)
                    {
                        tempDate = DateTime.Parse(model.ExaminedDate); //если ввели некоректные данные, то не распарсит
                        if (tempDate > DateTime.Now)
                        {
                            state.AddModelError("", "Дата обследования позже текущей даты!");
                        }

                        if (model.Order.CRO_sendedDate==null)
                        {
                            state.AddModelError("", "Ошибка: обследование невозможно, заявка не была направлена подрядчику!");
                        }
                        else if (tempDate < model.Order.CRO_revealedDate)
                        {
                            //state.AddModelError("", "Ошибка: обследования объекта раньше даты обнаружения неисправности!");
                        }
                    }
                    else
                    {
                        state.AddModelError("", "Пожалуйста введите дату обследования!");
                    }
                }
                catch
                {
                    //нераспарсил
                    state.AddModelError("DateError", "Пожалуйста введить дату обследования в формате ДД.ММ.ГГГГ");
                }
                // Примечание должно быть не более 1000 символов
                if (model.Comment!=null&&model.Comment.Length>1000)
                {
                    state.AddModelError("CommentError", "Ошибка: примечание слишком длинное!");
                }

            } //examined

            //4. notexamined
            if (model.NewStatus == "notexamined")
            {
                //запрещено удаление информации об обследовании и итогах работы, если работы предъявлены к оплате
                if (model.Order.CRO_billedDate != null)
                {
                    state.AddModelError("", "Ошибка удаления информации: выполнение работ по заявке предъявлено к оплате");
                }
                // Примечание должно быть не более 1000 символов
                if (model.Comment != null && model.Comment.Length > 1000)
                {
                    state.AddModelError("CommentError", "Ошибка: примечание слишком длинное!");
                }
            }//notexamined

            //5. closed
            if (model.NewStatus == "closed")
            {
                //результат ремонта
                //должен быть указан, должен быть либо repeared, cancelled, decommited
                if (model.RepairResult==null)
                {
                    state.AddModelError("", "Пожалуйста укажите результат выполнения заявки");
                }
                else if (model.RepairResult != "repeared" && model.RepairResult != "decommited" && model.RepairResult != "cancelled")
                {
                    state.AddModelError("", "Ошибка: указан неизвестный результат выполнения заявки");
                }

                //дата закрытия заявки
                //должна быть введена, должна иметь правильный формат, должна быть в интервале дата отправки заявки -- текущая дата
                //если результат ремонта : выполнен или извещение, то заявка должна быть направлена

                try
                {
                    if (model.ClosedDate != null)
                    {
                        tempDate = DateTime.Parse(model.ClosedDate); //если ввели некоректные данные, то не распарсит
                        if (tempDate > DateTime.Now)
                        {
                            state.AddModelError("", "Ошибка: дата закрытия заявки позже текущей даты!");
                        }

                        if (model.Order.CRO_sendedDate == null)
                        {
                            if(model.RepairResult!= "cancelled")
                            {
                                //результат ремонта : выполнен или извещение
                                //state.AddModelError("", "Ошибка закрытия заявки: заявка не была направлена подрядчику!");
                            }
                        }
                        else if (tempDate < model.Order.CRO_sendedDate)
                        {
                            //state.AddModelError("", "Ошибка: дата закрытия заявки раньше, чем дата направления ее подрядчику!");
                        }
                    }
                    else
                    {
                        switch (model.RepairResult)
                        {
                            case ("repeared"):
                                state.AddModelError("", "Пожалуйста введите дату выполнения ремонта!");
                                break;
                            case ("decommited"):
                                state.AddModelError("", "Пожалуйста введите дату выдачи извещения!");
                                break;
                            case ("cancelled"):
                                state.AddModelError("", "Пожалуйста введите дату отмены заявки!");
                                break;
                        }
                    }
                }
                catch
                {
                    //нераспарсил
                    state.AddModelError("DateError", "Пожалуйста введить дату в формате ДД.ММ.ГГГГ");
                }

                //Вердикт
                // Должен быть указан, долен быть не более 1000 символов
                //описание неисправности: обязательно, не более 1000 символов
                if (model.Verdict == null)
                {
                    switch (model.RepairResult)
                    {
                        case ("repeared"):
                            state.AddModelError("", "Пожалуйста опишите выявленные дефекты!");
                            break;
                        case ("decommited"):
                            state.AddModelError("", "Пожалуйста укажите заключение подрядчика!");
                            break;
                        case ("cancelled"):
                            state.AddModelError("", "Пожалуйста укажите причины отмены заявки!");
                            break;
                    }
                }
                else if (model.Verdict.Length > 1000)
                {
                    switch (model.RepairResult)
                    {
                        case ("repeared"):
                            state.AddModelError("", "Ошибка: слишком длинное описание дефектов!");
                            break;
                        case ("decommited"):
                            state.AddModelError("", "Ошибка: слишком длинное заключение подрядчика!");
                            break;
                        case ("cancelled"):
                            state.AddModelError("", "Ошибка: слишком длинное описание причин отмены заявки!");
                            break;
                    }
                }
            } //closed

            //6. examinednotclosed
            //запрещено удаление информации об обследовании и итогах работы, если работы предъявлены к оплате
            if (model.NewStatus == "examinednotclosed")
            {
                if (model.Order.CRO_billedDate != null)
                {
                    state.AddModelError("", "Ошибка удаления информации: выполнение работ по заявке предъявлено к оплате");
                }
                // Примечание должно быть не более 1000 символов
                if (model.Comment != null && model.Comment.Length > 1000)
                {
                    state.AddModelError("CommentError", "Ошибка: примечание слишком длинное!");
                }
            }//examinednotclosed
        }
        public ActionResult EditCRepOrderStatus(int ID, string returnURL)
        {
            CRepOrder order = repairRepository.CRepOrders.SingleOrDefault(o=>o.CRO_ID==ID);
            EditCRepOrderStatus_VM model = new EditCRepOrderStatus_VM
            {
                SendedDate = order.CRO_sendedDate != null?
                    order.CRO_sendedDate.Value.ToShortDateString() :
                    DateTime.Now.ToShortDateString(),
                BilledDate = order.CRO_billedDate != null ?
                    order.CRO_billedDate.Value.ToShortDateString() :
                    DateTime.Now.ToShortDateString(),
                ExaminedDate = order.CRO_examinedDate != null ?
                    order.CRO_examinedDate.Value.ToShortDateString() :
                    DateTime.Now.ToShortDateString(),
                ClosedDate = order.CRO_closedDate != null ?
                    order.CRO_closedDate.Value.ToShortDateString() :
                    DateTime.Now.ToShortDateString(),
                OrderID = ID,
                ReturnURL = returnURL,
                Order = order,
                Contractors = repairRepository.Contractors,
                Contractor = order.CRO_repairContractor,
                RepairCost = order.CRO_repairCost!=null? order.CRO_repairCost.ToString() : null,
                RepairResult = order.CRO_repairResult,
                Verdict = order.CRO_verdict,
                Comment = order.CRO_comment,
                No = order.CRO_No

            };
            return View(model);
        }