private static void verifyDispanDd14(IBackgroundContext context, PrevalidatorParams args, IEnumerable<Event> allEvents) { if (context.CancellationPending) return; context.ReportProgress(@"Проверка диспансеризации детей 14 летних"); if (dsServices == null) { loadDdServices(); } var eventCodes = new[] { "ДД14лет" }; var actionComplexPrefix = @"Комплексная услуга на"; var regExAgeList = new Regex(@"\(.*\)"); var ddsEvents = from e in allEvents where eventCodes.Contains(e.EventType.Code) select e; var errors = new List<string>(); foreach (var ddsEvent in ddsEvents) { errors.Clear(); var actComplex = (from a in ddsEvent.Actions where a.ActionType != null && a.ActionType.Name.StartsWith(actionComplexPrefix) select a).ToList(); Action complexService = null; if (!actComplex.Any()) { errors.Add(string.Format(@"Не найдена ""{0}""", actionComplexPrefix)); } else { if (actComplex.Count() > 1) errors.Add(@"Определено более одной комплексной услуги"); else { complexService = actComplex.First(); var emptyIspoln = (from a in ddsEvent.Actions where a.ActionType != null && a.Person_PersonId == null select a).ToList(); errors.AddRange(emptyIspoln.Select(action => string.Format(@"Не задан исполнитель услуги {0}", action.ActionType.Code))); var emptySpec = (from a in ddsEvent.Actions where a.ActionType != null && a.Person_PersonId != null && a.Person_PersonId.RbSpeciality == null select a).ToList(); errors.AddRange(emptySpec.Select(action => string.Format(@"Не задана специальность исполнителя услуги {0}", action.ActionType.Code))); if (complexService.Person_PersonId != null && complexService.Person_PersonId.RbSpeciality != null) { var specCode = complexService.Person_PersonId.RbSpeciality.FederalCode; var validSpecCodes = new List<string> { "1134" }; if (!validSpecCodes.Contains(specCode)) errors.Add( string.Format(@"Неверная специальность исполнителя комплексной услуги {0} {1}", specCode, complexService.Person_PersonId.FIO)); } var serviceName = complexService.ActionType.Name; if (ddsEvent.ExecDate.HasValue) { if (regExAgeList.IsMatch(serviceName)) { var ddYear = ddsEvent.ExecDate.Value.Year - 14; if (ddsEvent.Client.BirthDate.Year != ddYear) { errors.Add(string.Format(@"Год рождения пациента {0} не равен {1}", ddsEvent.Client.BirthDate.Year, ddYear)); } } var longServices = from a in ddsEvent.Actions where a.EndDate != a.BegDate select a; errors.AddRange(longServices.Select(longService => string.Format(@"Услуга {0} имеет дату окончания не равную дате начала", longService.ActionType.Code))); var oldServices = (from a in ddsEvent.Actions where a.BegDate < args.DateBegin select a).ToList(); foreach (var oldService in oldServices) { var maxServiceAgeMonth = oldService.ActionType.Code.EndsWith("61021") ? 12 : 1; if (oldService.BegDate != null && oldService.BegDate.Value < ddsEvent.SetDate.AddMonths(-maxServiceAgeMonth)) { errors.Add(string.Format(@"Анализ просрочен {0}", oldService.ActionType.Code)); } } var dupActions = (from a in ddsEvent.Actions group a by a.ActionType into g where g.Count() > 1 select g); foreach (var dupAction in dupActions) { errors.Add(string.Format(@"Найдено более одного ({0}) мероприятия с кодом {1}", dupAction.Count(), dupAction.Key.Code)); } /* объемы */ var ddrServiceIfo = (from d in dsServices where d.EventCode == ddsEvent.EventType.Code && d.Gender == ddsEvent.Client.Sex select d).FirstOrDefault(); if (ddrServiceIfo != null) { var ageServices = (from c in ddrServiceIfo.AgeServicesList from s in c.ServiceCodes where 14 >= c.AgeBegin && 14 <= c.AgeEnd select s).Distinct().ToList(); if (ageServices.Count > 0) { var minCount = ageServices.Count; var effectiveActions = (from a in ddsEvent.Actions where ageServices.Contains(a.ActionType.Code) select a).ToList(); if (effectiveActions.Count < minCount) { var candidates = string.Join(",", ageServices.Except(effectiveActions.Select(x => x.ActionType.Code))); errors.Add(string.Format(@"Недостаточный объем услуг {0} из {1}. Можно добавить {2}", effectiveActions.Count, minCount, candidates)); } var unavailActions = (from a in ddsEvent.Actions where !ageServices.Contains(a.ActionType.Code) && a != complexService select a).ToList(); if (unavailActions.Count > 0) { errors.Add(string.Format(@"Недопустимые(ое) мероприятия(e) {0} нужно удалить", string.Join(",", unavailActions.Select(x => x.ActionType.Code)))); } } } } } } if (errors.Count > 0) { context.ReportError(@" {0} {1}", ddsEvent.EventType.Code, ddsEvent); if (complexService != null) context.ReportProgress(@" > {0}", complexService); errors.ForEach(x => context.ReportProgress(@" -> {0}", x)); } } }
private static void verifyDispanDdr1(IBackgroundContext context, PrevalidatorParams args, IList<Event> allEvents) { if (context.CancellationPending) return; context.ReportProgress(@"Проверка диспансеризации работающих 2013 (1 этап)"); if(ddServices == null) { loadDdServices(); } var eventCodes = new[] {"dd2013_1"}; const string actionComplexPrefix = @"Комплексная услуга на"; var regExGender = new Regex(@"(мужчины|женщины)"); var regExAgeList = new Regex(@"\(.*\)"); var ddrEvents = from e in allEvents where eventCodes.Contains(e.EventType.Code) select e; var errors = new List<string>(); foreach (var ddrEvent in ddrEvents) { errors.Clear(); var actComplex = (from a in ddrEvent.Actions where a.ActionType != null && a.ActionType.Name.StartsWith(actionComplexPrefix) select a).ToList(); var isDdr2014 = ddrEvent.SetDate < new DateTime(2015, 4, 1); Action complexService = null; if (!actComplex.Any()) { errors.Add(string.Format(@"Не найдена ""{0}""", actionComplexPrefix)); } else { if(actComplex.Count() > 1) errors.Add(@"Определено более одной комплексной услуги"); else { complexService = actComplex.FirstOrDefault(); var emptyIspoln = (from a in ddrEvent.Actions where a.ActionType != null && a.Person_PersonId == null select a).ToList(); errors.AddRange(emptyIspoln.Select(action => string.Format(@"Не задан исполнитель услуги {0}", action.ActionType.Code))); var emptySpec = (from a in ddrEvent.Actions where a.ActionType != null && a.Person_PersonId != null && a.Person_PersonId.RbSpeciality == null select a).ToList(); errors.AddRange(emptySpec.Select(action => string.Format(@"Не задана специальность исполнителя услуги {0}", action.ActionType.Code))); var specCode = "???"; if (complexService != null) { if (complexService.Person_PersonId != null) specCode = complexService.Person_PersonId.RbSpeciality.FederalCode; var validSpecCodes = new List<string> {"27", "16"}; if (!validSpecCodes.Contains(specCode)) errors.Add( string.Format(@"Неверная специальность исполнителя комплексной услуги {0} {1}", specCode, (complexService.Person_PersonId == null ? "???" : complexService.Person_PersonId.FIO))); } var serviceName = complexService == null ? "" : complexService.ActionType.Name; var isNewComplex = regExGender.IsMatch(serviceName); if(string.IsNullOrEmpty(serviceName) || isNewComplex || ddrEvent.ExecDate < new DateTime(2013, 5, 1)) { int gender = ddrEvent.Client.Sex; if (!string.IsNullOrEmpty(serviceName)) { if (isNewComplex) { gender = regExGender.Match(serviceName).Value == @"мужчины" ? 1 : 2; } if (gender > 0 && ddrEvent.Client.Sex != gender) errors.Add(@"Неверный пол пациента"); if (regExAgeList.IsMatch(serviceName)) { var strList = regExAgeList.Match(serviceName).Value; strList = strList.Replace("для возрастов - ", ""); strList = strList.Replace("для возрастов ", ""); strList = strList.Replace(" лет", ""); strList = strList.Substring(1, strList.Length - 2); var clientYear = ddrEvent.Client.BirthDate.Year; if (strList.Contains(",")) { var ageList = strList.Split(',').Select(x => int.Parse(x.Trim())).ToList(); var yearList = ageList.Select(x => complexService.EndDate != null ? complexService.EndDate.Value.Year - x : 0).ToList(); if (!yearList.Contains(clientYear)) { errors.Add( string.Format(@"Год рождения пациента {0} не соответствует допустимым" + @" годам для услуги {1} - {2}", clientYear, complexService.ActionType.Code, string.Join(",", yearList.Select(x => x.ToString())) )); } } else if (strList.Contains("-")) { // 061050 - 061051 strList = strList.Replace(" ", ""); var ageBounds = strList.Split('-').Select(x => int.Parse(x.Trim())).ToList(); for (int i = 0; i < ageBounds.Count; i++) { ageBounds[i] = args.DateEnd.Year - ageBounds[i]; } if (clientYear > ageBounds[0] || clientYear < ageBounds[1]) { errors.Add( string.Format(@"Год рождения пациента {0} не соответствует допустимым" + @" возрастам для услуги {1} - {2}", clientYear, complexService.ActionType.Code, "от " + ageBounds[0] + " до " + ageBounds[1])); } } } } var longServices = from a in ddrEvent.Actions where a.EndDate != a.BegDate && a.ActionType.Code.IsInt() select a; foreach (var longService in longServices) { errors.Add(string.Format(@"Услуга {0} имеет дату окончания не равную дате начала", longService.ActionType.Code)); } var oldServices = (from a in ddrEvent.Actions where a.BegDate < args.DateBegin select a).ToList(); var dupActions = (from a in ddrEvent.Actions group a by a.ActionType into g where g.Count() > 1 select g); foreach (var dupAction in dupActions) { errors.Add(string.Format(@"Найдено более одного ({0}) мероприятия с кодом {1}", dupAction.Count(), dupAction.Key.Code)); } /* объемы */ var theEvent = ddrEvent; var ddrServiceIfo = (from d in (isDdr2014 ? ddServices2014 : ddServices) where d.EventCode == theEvent.EventType.Code && d.Gender == gender select d).FirstOrDefault(); if(ddrServiceIfo != null) { if (theEvent.ExecDate != null) { var age = theEvent.ExecDate.Value.Year - ddrEvent.Client.BirthDate.Year; var ageSrv = ddrServiceIfo.AgeServicesList.FirstOrDefault(x => x.Age == age); if(ageSrv != null) { var minCount = ageSrv.ServiceCodes.Count * 0.85; if ((int)minCount < minCount) minCount = ((int)minCount) + 1; if (ageSrv.MinServicesCount > 0) minCount = ageSrv.MinServicesCount; var effectiveActions = (from a in ddrEvent.Actions where ageSrv.ServiceCodes.Contains(a.ActionType.Code) select a).ToList(); if(effectiveActions.Count < minCount) { var candidates = string.Join(",", ageSrv.ServiceCodes.Except( effectiveActions.Select(x => x.ActionType.Code))); errors.Add(string.Format(@"Недостаточный объем услуг {0} из {1}. Можно добавить {2}", effectiveActions.Count, minCount, candidates)); } var unavailActions = (from a in ddrEvent.Actions where !ageSrv.ServiceCodes.Contains(a.ActionType.Code) && !(!a.ActionType.Code.IsInt() || a == complexService) select a).ToList(); if(unavailActions.Count > 0) { errors.Add(string.Format(@"Недопустимые(ое) мероприятия(e) {0} нужно удалить", string.Join(",", unavailActions.Select(x => x.ActionType.Code)))); } } } } } else errors.Add(string.Format(@"Комплексная услуга {0} более не используется", complexService.ActionType.Code)); } } var reexRes = new Regex(@"(рисвоена|пределена) .* гр.*здоровья"); if(ddrEvent.RbResult == null) errors.Add("Не определен результат обращения"); else if(!reexRes.IsMatch(ddrEvent.RbResult.Name)) errors.Add("Недопустимый результат обращения (в результате нет группы здоровья)"); if(errors.Count>0) { context.ReportError(@" dd2013 {0}", ddrEvent); if(complexService != null) context.ReportProgress(@" > {0}", complexService); errors.ForEach(x => context.ReportProgress(@" -> {0}", x)); } } }
private static void verifyMkb(IBackgroundContext context, PrevalidatorParams args, VistaMedDataContext dataContext) { if (context.CancellationPending) return; context.ReportProgress(@"Проверка на пустые МКБ"); var emptyMkbActions = (from action in dataContext.VistaMed.ActionsNotInAccount where action.EndDate >= args.DateBegin && action.EndDate <= args.DateEnd && action.Event != null && action.Event.EventType != null && action.Event.EventType.Name.ToLower().Contains(@"стоматология") && action.MKB == null select action).ToList(); if (emptyMkbActions.Any()) { context.ReportError(@"Неопределенный МКБ для услуг"); foreach (var action in emptyMkbActions) { context.ReportProgress(@" > {0} {1}", action.Event, action.ToShortString()); if (context.CancellationPending) return; } } if (context.CancellationPending) return; var emptyMkbDs = from d in dataContext.VistaMed.Diagnoses from ds in dataContext.VistaMed.Diagnostics where (d.MKB == null || string.IsNullOrEmpty(d.MKB)) && ds.DiagnosisId == d.Id && ds.Event != null && ds.Event.ExecDate >= args.DateBegin && ds.Event.ExecDate <= args.DateEnd && !dataContext.VistaMed.AccountItems.Any(x => x.EventId == ds.EventId) select ds.Event; if (emptyMkbDs.Any()) { context.ReportError(@"Неопределенный МКБ для диагнозов"); foreach (var dsEvent in emptyMkbDs) { context.ReportProgress(@" > {0}", dsEvent); if (context.CancellationPending) return; } } var unknownMkbActions = (from action in dataContext.VistaMed.ActionsNotInAccount where action.EndDate >= args.DateBegin && action.EndDate <= args.DateEnd && action.Event != null && action.Event.EventType != null && !string.IsNullOrEmpty(action.MKB) && !(from m in dataContext.VistaMed.MKBs where action.MKB == m.DiagID select m).Any() select action).ToList(); if (context.CancellationPending) return; if (unknownMkbActions.Any()) { context.ReportError(@"Несуществующий МКБ"); foreach (var action in unknownMkbActions) { context.ReportProgress(@" > {0} {1}", action.Event, action.ToShortString()); if (context.CancellationPending) return; } } }
private static void verifyContracts(IBackgroundContext context, PrevalidatorParams prevalidatorParams, VistaMedDataContext dataContext) { if (context.CancellationPending) return; var errors = (from a in dataContext.VistaMed.Actions let e = a.Event where e.ExecDate != null && e.Contract != null && e.ExecDate >= prevalidatorParams.DateBegin && e.ExecDate <= prevalidatorParams.DateEnd && !dataContext.VistaMed.AccountItems.Any(x => x.EventId == e.Id) && a.Contract != null && a.Contract != e.Contract select new {Event = e, Action = a}).ToList(); var invalidGroups = (from s in errors group s by s.Event into g select g).ToList(); if (invalidGroups.Any()) { context.ReportError(@"Несовпадение договора в талоне и услугах"); foreach (var invalidGroup in invalidGroups) { context.ReportProgress(@" > {0}", invalidGroup.Key); context.ReportProgress(@" > договор события {0}", invalidGroup.Key.Contract.GetFullName(dataContext.VistaMed)); foreach (var action in invalidGroup.Select(x => x.Action)) { var actionStr = (action.ActionType == null ? "" : action.ActionType.Code); context.ReportProgress(@" > договор мероприятия {0} {1}", actionStr, action.Contract.GetFullName(dataContext.VistaMed)); } } } }
private static void verifyFinance(IBackgroundContext context, PrevalidatorParams args, VistaMedDataContext dataContext) { if (context.CancellationPending) return; var badVisits = from visit in dataContext.VistaMed.VisitsNotInAccount where visit.Date >= args.DateBegin && visit.Date <= args.DateEnd && visit.ServiceId != null && visit.Event != null && visit.Event.Contract != null && visit.Event.Contract.RbFinance != null && visit.Event.Contract.FinanceId != visit.FinanceId && !dataContext.VistaMed.AccountItems.Any(x => x.EventId == visit.EventId) select visit; if(badVisits.Select(x => x.Id).Any()) { context.ReportError(@"Неверный тип финансирования для посещений"); var badGroups = from v in badVisits.ToList() group v by v.Event into g select g; foreach (var badVisit in badGroups) { context.ReportProgress(@" > {0} тип фин.""{1}""", badVisit.Key, badVisit.Key.Contract.RbFinance.Name); foreach (var visit in badVisit) { context.ReportProgress(@" -> {0} тип фин.""{1}""", visit.ToShortString(), visit.RbFinance.Name); } if (context.CancellationPending) break; } } if (context.CancellationPending) return; var badActions = from action in dataContext.VistaMed.ActionsNotInAccount where action.EndDate >= args.DateBegin && action.EndDate <= args.DateEnd && action.ActionType != null && action.FinanceId != null && action.Event != null && action.Event.Contract != null && action.Event.Contract.RbFinance != null && action.Event.Contract.FinanceId != action.FinanceId select action; if (badActions.Any()) { context.ReportError(@"Неверный тип финансирования для мероприятий"); var badGroups = from v in badActions.ToList() group v by v.Event into g select g; foreach (var badGroup in badGroups) { context.ReportProgress(@" > {0} тип фин.""{1}""", badGroup.Key, badGroup.Key.Contract.RbFinance.Name); foreach (var action in badGroup) { context.ReportProgress(@" -> {0} тип фин.""{1}""", action.ToShortString(), action.RbFinance.Name); } if (context.CancellationPending) break; } } if (context.CancellationPending) return; var budOms = (from ev in dataContext.VistaMed.EventsNotInAccount where ev.ExecDate >= args.DateBegin && ev.ExecDate <= args.DateEnd && ev.Client != null && ev.Client.ClientPolicies.Count == 0 && ev.Contract != null && ev.Contract.RbFinance != null && ev.Contract.RbFinance.Code == "2" select ev).ToList(); if (budOms.Any()) { context.ReportError(@"Финансирование ОМС для пациента без полисов ОМС"); foreach (var badEvent in budOms) { context.ReportProgress(@" > {0}", badEvent); if (context.CancellationPending) break; } } }
public static void Prevalidate(IBackgroundContext context, PrevalidatorParams args) { if (context.CancellationPending) return; context.ProgressSeparator(); context.ReportProgress(@"ПРЕДВАРИТЕЛЬНАЯ ПРОВЕРКА ДАННЫХ Виста-Мед за период с {0} по {1}", args.DateBegin.ToShortDateString(), args.DateEnd.ToShortDateString()); context.ReportProgress(""); using (var dataContext = new VistaMedDataContext(context)) { context.ReportProgress(@"Выборка талонов ..."); var allEvents = (from e in dataContext.VistaMed.EventsNotInAccount where e.EventType != null && e.ExecDate != null && e.ExecDate.Value >= args.DateBegin && e.ExecDate.Value <= args.DateEnd && e.Client != null && (args.CreatePersonId ==0 || e.CreatePersonId == args.CreatePersonId) select e).ToList(); context.ReportProgress(@"Выборка мероприятий ..."); var allActions = (from action in dataContext.VistaMed.ActionsNotInAccount where action.EndDate >= args.DateBegin && action.EndDate <= args.DateEnd && action.Event != null && action.Event.EventType != null && !action.ActionType.Code.StartsWith("4-") && (args.CreatePersonId == 0 || action.CreatePersonId == args.CreatePersonId) select action).ToList(); verifyPolicies(context, dataContext, allEvents); if(args.ValidateAll || args.ValidateContracts) verifyContracts(context, args, dataContext); if (args.ValidateAll || args.ValidateFinance) verifyFinance(context, args, dataContext); if (args.ValidateAll || args.ValidateMkb) verifyMkb(context, args, dataContext); if (args.ValidateAll || args.ValidatePodrUsl) verifyPodrUsl(context, allEvents, allActions); if (args.ValidateAll || args.ValidateIspoln) verifyIspoln(context, allActions); if (args.ValidateAll || args.ValidateDdr) { verifyDispanDdr1(context, args, allEvents); // verifyDispanDdr2(context, args, allEvents); } if (args.ValidateAll || args.ValidateDdVet) { verifyDispanVet(context, args, allEvents); } if (args.ValidateAll || args.ValidateDds) verifyDispanDds(context, args, dataContext, allEvents); if (args.ValidateAll || args.ValidateDd14) verifyDispanDd14(context, args, allEvents); if (args.ValidateAll || args.ValidateProfOsm) verifyDispanProfOsm(context, args, allEvents); if (args.ValidateAll || args.ValidateViolet) verifyViolet(context, allEvents); if (args.ValidateAll || args.Validate1013) verify1013(context, allEvents); if (args.ValidateAll || args.ValidateStationar) verifyStationar(context, allEvents, dataContext, allActions); verifyKolUsl(context, allActions, dataContext); //if (args.ValidateAll || args.ValidatePodrUsl) // verifyNotInBill(context, allEvents, allActions, dataContext); } context.ProgressSeparator('-'); }
private static void verifyDispanProfOsm(IBackgroundContext context, PrevalidatorParams args, IList<Event> allEvents) { if (context.CancellationPending) return; context.ReportProgress(@"Проверка профосмотров"); if (dpServices == null) { loadDdServices(); } var eventCodes = new[] { "ПрофОсм" }; const string actionComplexPrefix = @"Комплексная услуга на"; var regExGender = new Regex(@"(мужчин|женщин)"); var regExAgeList = new Regex(@"\(.*\)"); var ddrEvents = from e in allEvents where eventCodes.Contains(e.EventType.Code) select e; var errors = new List<string>(); foreach (var ddrEvent in ddrEvents) { errors.Clear(); var actComplex = (from a in ddrEvent.Actions where a.ActionType != null && a.ActionType.Name.StartsWith(actionComplexPrefix) select a).ToList(); Action complexService = null; if (!actComplex.Any()) { errors.Add(string.Format(@"Не найдена ""{0}""", actionComplexPrefix)); } else { if (actComplex.Count() > 1) errors.Add(@"Определено более одной комплексной услуги"); else { complexService = actComplex.First(); var emptyIspoln = (from a in ddrEvent.Actions where a.ActionType != null && a.Person_PersonId == null select a).ToList(); errors.AddRange(emptyIspoln.Select(action => string.Format(@"Не задан исполнитель услуги {0}", action.ActionType.Code))); var emptySpec = (from a in ddrEvent.Actions where a.ActionType != null && a.Person_PersonId != null && a.Person_PersonId.RbSpeciality == null select a).ToList(); errors.AddRange(emptySpec.Select(action => string.Format(@"Не задана специальность исполнителя услуги {0}", action.ActionType.Code))); var specCode = complexService.Person_PersonId.RbSpeciality.FederalCode; var validSpecCodes = new List<string> { "27", "16" }; if (!validSpecCodes.Contains(specCode)) errors.Add(string.Format(@"Неверная специальность исполнителя комплексной услуги {0} {1}", specCode, complexService.Person_PersonId.FIO)); var serviceName = complexService.ActionType.Name; var isNewComplex = regExGender.IsMatch(serviceName); if (isNewComplex) { int gender = 0; if (isNewComplex) { gender = regExGender.Match(serviceName).Value == @"мужчин" ? 1 : 2; } if (gender > 0 && ddrEvent.Client.Sex != gender) errors.Add(@"Неверный пол пациента"); if (regExAgeList.IsMatch(serviceName)) { var strList = regExAgeList.Match(serviceName).Value; var validChars = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ','}; strList = new string(strList.ToArray().Where(validChars.Contains).Select(y => y).ToArray()); strList = strList.Replace(@"1820", "18,19,20"); var ageList = strList.Split(',').Select(x => int.Parse(x.Trim())).ToList(); var yearList = ageList.Select(x => complexService.EndDate != null ? complexService.EndDate.Value.Year - x : 0).ToList(); var clientYear = ddrEvent.Client.BirthDate.Year; if (!yearList.Contains(clientYear)) { errors.Add(string.Format(@"Год рождения пациента {0} не соответствует допустимым" + @" годам для услуги {1} - {2}", clientYear, complexService.ActionType.Code, string.Join(",", yearList.Select(x => x.ToString())) )); } } var longServices = from a in ddrEvent.Actions where a.EndDate != a.BegDate && a.ActionType.Code.IsInt() select a; foreach (var longService in longServices) { errors.Add(string.Format(@"Услуга {0} имеет дату окончания не равную дате начала", longService.ActionType.Code)); } var oldServices = (from a in ddrEvent.Actions where a.BegDate < args.DateBegin select a).ToList(); //foreach (var oldService in oldServices) //{ // if(oldService.BegDate != null && oldService.BegDate.Value < new DateTime(2013,1,1)) // { // errors.Add(string.Format(@"Анализ просрочен {0}", oldService.ActionType.Code)); // } //} var dupActions = (from a in ddrEvent.Actions group a by a.ActionType into g where g.Count() > 1 select g); foreach (var dupAction in dupActions) { errors.Add(string.Format(@"Найдено более одного ({0}) мероприятия с кодом {1}", dupAction.Count(), dupAction.Key.Code)); } /* объемы */ var theEvent = ddrEvent; var ddrServiceIfo = (from d in dpServices where d.EventCode == theEvent.EventType.Code && d.Gender == gender select d).FirstOrDefault(); if (ddrServiceIfo != null) { if (theEvent.ExecDate != null) { var age = theEvent.ExecDate.Value.Year - ddrEvent.Client.BirthDate.Year; var ageSrv = ddrServiceIfo.AgeServicesList.FirstOrDefault(x => x.Age == age); if (ageSrv != null) { var minCount = ageSrv.ServiceCodes.Count * 0.85; minCount = Math.Round(minCount); //if ((int)minCount < minCount) // minCount = ((int)minCount) + 1; var effectiveActions = (from a in ddrEvent.Actions where ageSrv.ServiceCodes.Contains(a.ActionType.Code) select a).ToList(); if (effectiveActions.Count < minCount) { var candidates = string.Join(",", ageSrv.ServiceCodes.Except( effectiveActions.Select(x => x.ActionType.Code))); errors.Add(string.Format(@"Недостаточный объем услуг {0} из {1}. Можно добавить {2}", effectiveActions.Count, minCount, candidates)); } var unavailActions = (from a in ddrEvent.Actions where !ageSrv.ServiceCodes.Contains(a.ActionType.Code) && !(!a.ActionType.Code.IsInt() || a == complexService) select a).ToList(); if (unavailActions.Count > 0) { errors.Add(string.Format(@"Недопустимые(ое) мероприятия(e) {0} нужно удалить", string.Join(",", unavailActions.Select(x => x.ActionType.Code)))); } } } } } else errors.Add(string.Format(@"Комплексная услуга {0} более не используется", complexService.ActionType.Code)); } } if (errors.Count > 0) { context.ReportError(@" ПрофОсм {0}", ddrEvent); if (complexService != null) context.ReportProgress(@" > {0}", complexService); errors.ForEach(x => context.ReportProgress(@" -> {0}", x)); } } }
private static void verifyDispanDds(IBackgroundContext context, PrevalidatorParams args, VistaMedDataContext dataContext, IEnumerable<Event> allEvents) { if (context.CancellationPending) return; if (args.DateEnd.Year != 2013) return; context.ReportProgress(@"Проверка диспансеризации детей сирот 2013"); if (dsServices == null) { loadDdServices(); } var eventCodes = new[] { "ДДСирот", "ДДСирТЖС" }; var actionComplexPrefix = @"Комплексная услуга на"; var regExAgeList = new Regex(@"\(.*\)"); var ddsEvents = from e in allEvents where eventCodes.Contains(e.EventType.Code) select e; var errors = new List<string>(); foreach (var ddsEvent in ddsEvents) { errors.Clear(); var actComplex = (from a in ddsEvent.Actions where a.ActionType != null && a.ActionType.Name.StartsWith(actionComplexPrefix) select a).ToList(); Action complexService = null; if (ddsEvent.ExecDate != null) { var clientAge = dataContext.VistaMed.Age(ddsEvent.Client.BirthDate, ddsEvent.ExecDate.Value); if (!actComplex.Any()) { errors.Add(string.Format(@"Не найдена ""{0}""", actionComplexPrefix)); } else { if (actComplex.Count() > 1) errors.Add(@"Определено более одной комплексной услуги"); else { complexService = actComplex.First(); var emptyIspoln = (from a in ddsEvent.Actions where a.ActionType != null && a.Person_PersonId == null select a).ToList(); errors.AddRange(emptyIspoln.Select(action => string.Format(@"Не задан исполнитель услуги {0}", action.ActionType.Code))); var emptySpec = (from a in ddsEvent.Actions where a.ActionType != null && a.Person_PersonId != null && a.Person_PersonId.RbSpeciality == null select a).ToList(); errors.AddRange(emptySpec.Select(action => string.Format(@"Не задана специальность исполнителя услуги {0}", action.ActionType.Code))); if (complexService.Person_PersonId != null && complexService.Person_PersonId.RbSpeciality != null) { var specCode = complexService.Person_PersonId.RbSpeciality.FederalCode; var validSpecCodes = new List<string> {"1134"}; if (!validSpecCodes.Contains(specCode)) errors.Add( string.Format(@"Неверная специальность исполнителя комплексной услуги {0} {1}", specCode, complexService.Person_PersonId.FIO)); } var serviceName = complexService.ActionType.Name; if (regExAgeList.IsMatch(serviceName)) { var strList = regExAgeList.Match(serviceName).Value; strList = strList.Substring(1, strList.Length - 2); var arrAge = strList.Split('-').Select(x => int.Parse(x.Trim())).ToArray(); var ageBeg = arrAge[0]; var ageEnd = arrAge[1]; if (clientAge < ageBeg || clientAge > ageEnd) { errors.Add(string.Format(@"Возраст пациента {0} не соответствует диапазону возрастов " + @" для услуги {1}: {2}-{3}", clientAge, complexService.ActionType.Code, ageBeg, ageEnd)); } } var longServices = from a in ddsEvent.Actions where a.EndDate != a.BegDate select a; foreach (var longService in longServices) { errors.Add(string.Format(@"Услуга {0} имеет дату окончания не равную дате начала", longService.ActionType.Code)); } var oldServices = (from a in ddsEvent.Actions where a.BegDate < args.DateBegin select a).ToList(); foreach (var oldService in oldServices) { var aAge = clientAge < 2 ? 1 : 3; var maxServiceAgeMonth = oldService.ActionType.Code.EndsWith("61021") ? 12 : aAge; if (oldService.BegDate != null && oldService.BegDate.Value < ddsEvent.SetDate.AddMonths(-maxServiceAgeMonth)) { errors.Add(string.Format(@"Анализ просрочен {0}", oldService.ActionType.Code)); } } var dupActions = (from a in ddsEvent.Actions group a by a.ActionType into g where g.Count() > 1 select g); foreach (var dupAction in dupActions) { errors.Add(string.Format(@"Найдено более одного ({0}) мероприятия с кодом {1}", dupAction.Count(), dupAction.Key.Code)); } /* объемы */ Event theEvent = ddsEvent; var ddrServiceIfo = (from d in dsServices where d.EventCode == theEvent.EventType.Code && d.Gender == theEvent.Client.Sex select d).FirstOrDefault(); if (ddrServiceIfo != null) { var ageServices = (from c in ddrServiceIfo.AgeServicesList from s in c.ServiceCodes where clientAge >= c.AgeBegin && clientAge <= c.AgeEnd select s).Distinct().ToList(); if (ageServices.Count > 0) { var minCount = ageServices.Count; var effectiveActions = (from a in ddsEvent.Actions where ageServices.Contains(a.ActionType.Code) select a).ToList(); if (effectiveActions.Count < minCount) { var candidates = string.Join(",", ageServices.Except( effectiveActions.Select(x => x.ActionType.Code))); errors.Add(string.Format( @"Недостаточный объем услуг {0} из {1}. Можно добавить {2}", effectiveActions.Count, minCount, candidates)); } var unavailActions = (from a in ddsEvent.Actions where !ageServices.Contains(a.ActionType.Code) && a != complexService select a).ToList(); if (unavailActions.Count > 0) { errors.Add(string.Format(@"Недопустимые(ое) мероприятия(e) {0} нужно удалить", string.Join(",", unavailActions.Select(x => x.ActionType.Code)))); } } } } } if (errors.Count > 0) { context.ReportError(@" {0} {1}", ddsEvent.EventType.Code, ddsEvent); if (complexService != null) context.ReportProgress(@" > {0}", complexService); context.ReportProgress(@" > возраст на дату закрытия талона {0} полных лет", clientAge); errors.ForEach(x => context.ReportProgress(@" -> {0}", x)); } } } }
private static void verifyDispanDdr2(IBackgroundContext context, PrevalidatorParams args, IList<Event> allEvents) { if (context.CancellationPending) return; context.ReportProgress(@"Проверка диспансеризации работающих 2013 (2 этап)"); if (ddServices == null) { loadDdServices(); } var eventCodes = new[] { "dd2013_2" }; const string actionComplexPrefix = @"Осмотр врача-терапевта/врача общей практики"; var ddrEvents = from e in allEvents where eventCodes.Contains(e.EventType.Code) select e; var errors = new List<string>(); foreach (var ddrEvent in ddrEvents) { errors.Clear(); var actComplex = (from a in ddrEvent.Actions where a.ActionType != null && a.ActionType.Name.StartsWith(actionComplexPrefix) select a).ToList(); Action complexService = null; if (!actComplex.Any()) { errors.Add(string.Format(@"Не найдена ""{0}""", actionComplexPrefix)); } else { if (actComplex.Count() > 1) errors.Add(@"Определено более одной комплексной услуги"); else { complexService = actComplex.First(); var emptyIspoln = (from a in ddrEvent.Actions where a.ActionType != null && a.Person_PersonId == null select a).ToList(); errors.AddRange(emptyIspoln.Select(action => string.Format(@"Не задан исполнитель услуги {0}", action.ActionType.Code))); var emptySpec = (from a in ddrEvent.Actions where a.ActionType != null && a.Person_PersonId != null && a.Person_PersonId.RbSpeciality == null select a).ToList(); errors.AddRange(emptySpec.Select(action => string.Format( @"Не задана специальность исполнителя услуги {0}", action.ActionType.Code))); var specCode = "???"; if (complexService.Person_PersonId != null) specCode = complexService.Person_PersonId.RbSpeciality.FederalCode; var validSpecCodes = new List<string> {"27", "16"}; if (!validSpecCodes.Contains(specCode)) errors.Add(string.Format(@"Неверная специальность исполнителя комплексной услуги {0} {1}", specCode, (complexService.Person_PersonId == null ? "???" : complexService.Person_PersonId.FIO))); int gender = ddrEvent.Client.Sex; var longServices = from a in ddrEvent.Actions where a.EndDate != a.BegDate && a.ActionType.Code.IsInt() select a; foreach (var longService in longServices) { errors.Add(string.Format(@"Услуга {0} имеет дату окончания не равную дате начала", longService.ActionType.Code)); } var dupActions = (from a in ddrEvent.Actions group a by a.ActionType into g where g.Count() > 1 select g); foreach (var dupAction in dupActions) { errors.Add(string.Format(@"Найдено более одного ({0}) мероприятия с кодом {1}", dupAction.Count(), dupAction.Key.Code)); } /* объемы */ var theEvent = ddrEvent; var ddrServiceIfo = (from d in ddServices where d.EventCode == theEvent.EventType.Code && d.Gender == gender select d).FirstOrDefault(); if (ddrServiceIfo != null) { if (theEvent.ExecDate != null) { var age = theEvent.ExecDate.Value.Year - ddrEvent.Client.BirthDate.Year; var ageSrv = ddrServiceIfo.AgeServicesList.FirstOrDefault(x => x.Age == age); if (ageSrv != null) { var minCount = ageSrv.ServiceCodes.Count*0.85; if ((int) minCount < minCount) minCount = ((int) minCount) + 1; if (ageSrv.MinServicesCount > 0) minCount = ageSrv.MinServicesCount; var effectiveActions = (from a in ddrEvent.Actions where ageSrv.ServiceCodes.Contains(a.ActionType.Code) select a).ToList(); if (effectiveActions.Count < minCount) { var candidates = string.Join(",", ageSrv.ServiceCodes.Except( effectiveActions.Select(x => x.ActionType.Code))); errors.Add( string.Format(@"Недостаточный объем услуг {0} из {1}. Можно добавить {2}", effectiveActions.Count, minCount, candidates)); } var unavailActions = (from a in ddrEvent.Actions where !ageSrv.ServiceCodes.Contains(a.ActionType.Code) && !(!a.ActionType.Code.IsInt() || a == complexService) select a).ToList(); if (unavailActions.Count > 0) { errors.Add(string.Format(@"Недопустимые(ое) мероприятия(e) {0} нужно удалить", string.Join(",", unavailActions.Select( x => x.ActionType.Code)))); } } } } } } if (errors.Count > 0) { context.ReportError(@" dd2013 {0}", ddrEvent); if (complexService != null) context.ReportProgress(@" > {0}", complexService); errors.ForEach(x => context.ReportProgress(@" -> {0}", x)); } } }