Esempio n. 1
0
        public static void Stats(string[] args)
        {
            // Load the file
            var parms = new ParameterParser <InstallParameters>().Parse(args);

            ApplicationContext.Current.Start();
            var ds = DatasetInstall.Load(parms.DatasetFile);

            Console.WriteLine("Statistics for {0} ({1} objects)...", ds.Action.Count, ds.Id);
            foreach (var gc in ds.Action?.GroupBy(o => o.Element?.GetType()))
            {
                Console.WriteLine("{0} - {1} items", gc.Key, gc.Count());
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Will layout the object in a referentially proper way
        /// </summary>
        private static void LayoutObject(IdentifiedData obj, DatasetInstall dsOutput, bool insert = false)
        {
            // Add myself
            if (!insert)
            {
                dsOutput.Action.Add(new DataUpdate()
                {
                    Element           = obj,
                    InsertIfNotExists = true
                });
            }
            else
            {
                dsOutput.Action.Insert(0, new DataUpdate()
                {
                    Element           = obj,
                    InsertIfNotExists = true
                });
            }

            // Iterate properties
            foreach (var prop in obj.GetType().GetRuntimeProperties())
            {
                var sra   = prop.GetCustomAttribute <SerializationReferenceAttribute>();
                var value = prop.GetValue(obj);

                // Value is list
                if (value is IList && prop.GetCustomAttribute <XmlElementAttribute>() != null)
                {
                    foreach (var v in (value as IList))
                    {
                        LayoutObject(v as IdentifiedData, dsOutput, true);
                    }
                }
                else if (value == null && sra != null)                 // No XmlElement .. hmm we might have to insert this stuff
                {
                    value = OpenIZ.Core.Model.ExtensionMethods.LoadProperty(obj, prop.Name);
                }

                if (value is IdentifiedData)
                {
                    dsOutput.Action.Insert(0, new DataUpdate()
                    {
                        Element           = value as IdentifiedData,
                        InsertIfNotExists = true
                    });
                }
            }
        }
Esempio n. 3
0
        public static void Install(string[] args)
        {
            // Load the file
            var parms = new ParameterParser <InstallParameters>().Parse(args);

            ApplicationContext.Current.Start();
            var dsi = new DataInitializationService();
            var ds  = DatasetInstall.Load(parms.DatasetFile);

            Console.WriteLine("Will install dataset {0} ({1} objects)...", ds.Action.Count, ds.Id);

            dsi.ProgressChanged += (o, e) =>
            {
                Console.CursorLeft = 4;
                Console.Write("{0} ({1:0%})", e.State, e.Progress);
            };

            dsi.InstallDataset(ds);
        }
Esempio n. 4
0
        public static void TsvToDataset(String[] args)
        {
            var            options        = new ParameterParser <CvxOptions>().Parse(args);
            DatasetInstall conceptDataset = new DatasetInstall()
            {
                Id = "TSV File"
            };

            using (var codeReader = File.OpenText(options.Input))
            {
                var sourceLine = codeReader.ReadLine();
                var components = sourceLine.Split('\t').Select(o => o.Trim()).ToArray();

                // Create vaccine code concept set
                var conceptSet = new DataUpdate()
                {
                    InsertIfNotExists = true,
                    Element           = new ConceptSet()
                    {
                        Key      = Guid.NewGuid(),
                        Mnemonic = options.ConceptSetName ?? "TsvConceptSet",
                        Name     = components[5],
                        Oid      = components[6],
                        Url      = "http://openiz.org/conceptset/imported/" + (options.ConceptSetName ?? "TsvConceptSet")
                    },
                    Association = new List <DataAssociation>()
                };
                var codeSystem = new DataUpdate()
                {
                    InsertIfNotExists = true,
                    Element           = new CodeSystem(components[5], components[6], (options.ConceptSetName ?? "TsvConceptSet"))
                    {
                        Key = Guid.NewGuid(),

                        Url = "http://openiz.org/conceptset/imported/" + (options.ConceptSetName ?? "TsvConceptSet"),
                    }
                };
                conceptDataset.Action.Add(codeSystem);

                // Now import the concepts from CVX to their OpenIZ Concepts
                while (!codeReader.EndOfStream)
                {
                    ReferenceTerm refTerm = new ReferenceTerm()
                    {
                        CodeSystemKey = codeSystem.Element.Key,
                        Mnemonic      = components[1],
                        DisplayNames  = new List <ReferenceTermName>()
                        {
                            new ReferenceTermName()
                            {
                                Language = "en", Name = components[2]
                            }
                        },
                        Key = Guid.NewGuid()
                    };

                    var mnemonic = String.Format("{0}-{1}", options.ConceptSetName ?? "Tsv", components[1].Replace(" ", "").Replace(".", "").Replace("(", "").Replace(")", ""));
                    if (mnemonic.Length > 64)
                    {
                        mnemonic = mnemonic.Substring(0, 64);
                    }
                    Concept concept = new Concept()
                    {
                        Key          = Guid.Parse(components[0]),
                        Mnemonic     = mnemonic,
                        ClassKey     = ConceptClassKeys.Material,
                        ConceptNames = new List <ConceptName>()
                        {
                            new ConceptName()
                            {
                                Language = "en", Name = components[2]
                            }
                        },
                        ReferenceTerms = new List <ConceptReferenceTerm>()
                        {
                            new ConceptReferenceTerm()
                            {
                                ReferenceTermKey    = refTerm.Key,
                                RelationshipTypeKey = ConceptRelationshipTypeKeys.SameAs
                            }
                        },
                        StatusConceptKey = StatusKeys.Active
                    };

                    conceptDataset.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true,
                        Element           = refTerm
                    });
                    conceptDataset.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true,
                        Element           = concept
                    });
                    (conceptSet.Element as ConceptSet).ConceptsXml.Add(concept.Key.Value);

                    sourceLine = codeReader.ReadLine();
                    components = sourceLine.Split('\t').Select(o => o.Trim()).ToArray();
                }

                conceptDataset.Action.Add(conceptSet);
            }

            XmlSerializer xsz = new XmlSerializer(typeof(DatasetInstall));

            using (FileStream fs = File.Create(options.Output))
                xsz.Serialize(fs, conceptDataset);
        }
Esempio n. 5
0
        public static void CvxToDataset(String[] args)
        {
            var            options        = new ParameterParser <CvxOptions>().Parse(args);
            DatasetInstall conceptDataset = new DatasetInstall()
            {
                Id = "CDC CVX Codes"
            };
            // Create vaccine code concept set
            var conceptSet = new DataUpdate()
            {
                InsertIfNotExists = true,
                Element           = new ConceptSet()
                {
                    Key      = Guid.NewGuid(),
                    Mnemonic = "VaccineTypeCodes",
                    Name     = "Vaccines",
                    Oid      = "1.3.6.1.4.1.33349.3.1.5.9.1.25",
                    Url      = "http://openiz.org/conceptset/VaccineTypeCodes"
                },
                Association = new List <DataAssociation>()
            };
            var codeSystem = new DataUpdate()
            {
                InsertIfNotExists = true,
                Element           = new CodeSystem("HL7 CVX Codes", "2.16.840.1.113883.3.88.12.80.22", "CVX")
                {
                    Url = "http://hl7.org/fhir/sid/cvx",
                    Key = Guid.Parse("EBA4F94A-2CAD-4BB3-ACA7-F4E54EAAC4BD")
                }
            };

            conceptDataset.Action.Add(codeSystem);

            using (var codeReader = File.OpenText(options.Input))
            {
                // Now import the concepts from CVX to their OpenIZ Concepts
                while (!codeReader.EndOfStream)
                {
                    var sourceLine = codeReader.ReadLine();
                    var components = sourceLine.Split('|').Select(o => o.Trim()).ToArray();

                    ReferenceTerm refTerm = new ReferenceTerm()
                    {
                        CodeSystemKey = codeSystem.Element.Key,
                        Mnemonic      = components[0],
                        DisplayNames  = new List <ReferenceTermName>()
                        {
                            new ReferenceTermName()
                            {
                                Language = "en", Name = components[1]
                            }
                        },
                        Key = Guid.NewGuid()
                    };

                    var mnemonic = String.Format("VaccineType-{0}", components[1].Replace(" ", "").Replace(".", "").Replace("(", "").Replace(")", ""));
                    if (mnemonic.Length > 64)
                    {
                        mnemonic = mnemonic.Substring(0, 64);
                    }
                    Concept concept = new Concept()
                    {
                        Key          = Guid.NewGuid(),
                        Mnemonic     = mnemonic,
                        ClassKey     = ConceptClassKeys.Material,
                        ConceptNames = new List <ConceptName>()
                        {
                            new ConceptName()
                            {
                                Language = "en", Name = components[2]
                            },
                            new ConceptName()
                            {
                                Language = "en", Name = components[1]
                            }
                        },
                        ReferenceTerms = new List <ConceptReferenceTerm>()
                        {
                            new ConceptReferenceTerm()
                            {
                                ReferenceTermKey    = refTerm.Key,
                                RelationshipTypeKey = ConceptRelationshipTypeKeys.SameAs
                            }
                        },
                        StatusConceptKey = components[3] == "Inactive" ? StatusKeys.Obsolete : StatusKeys.Active,
                        CreationTime     = DateTime.Parse(components[6])
                    };

                    conceptDataset.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true,
                        Element           = refTerm
                    });
                    conceptDataset.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true,
                        Element           = concept
                    });
                    (conceptSet.Element as ConceptSet).ConceptsXml.Add(concept.Key.Value);
                }
            }

            conceptDataset.Action.Add(conceptSet);
            XmlSerializer xsz = new XmlSerializer(typeof(DatasetInstall));

            using (FileStream fs = File.Create(options.Output))
                xsz.Serialize(fs, conceptDataset);
        }
Esempio n. 6
0
        public static void PhinVadsToDataset(String[] args)
        {
            var            options        = new ParameterParser <CvxOptions>().Parse(args);
            DatasetInstall conceptDataset = new DatasetInstall();

            using (var sr = File.OpenText(options.Input))
            {
                // Consume the first line
                sr.ReadLine();
                var components = sr.ReadLine().Split('\t');
                // Next line is the value set information
                // Create  code concept set
                var conceptSet = new ConceptSet()
                {
                    Key          = Guid.NewGuid(),
                    Mnemonic     = options.ConceptSetName ?? components[1],
                    Name         = options.ConceptSetDescription ?? components[0],
                    Oid          = options.ConceptSetOid ?? components[2],
                    CreationTime = DateTime.Parse(String.IsNullOrEmpty(components[6]) ? DateTime.Now.ToString() : components[6]),
                    Url          = !String.IsNullOrEmpty(options.ConceptSetName) ? "http://openiz.org/conceptset/" + options.ConceptSetName :
                                   "http://openiz.org/conceptsets/contrib/" + components[1]
                };

                Dictionary <String, CodeSystem> codeSystems = new Dictionary <string, CodeSystem>();

                // Consume the next set of lines
                while (!sr.ReadLine().StartsWith("Concept Code"))
                {
                    ;
                }

                while (!sr.EndOfStream)
                {
                    components = sr.ReadLine().Split('\t');

                    // Try to get the code system
                    CodeSystem codeSys = null;
                    if (!codeSystems.TryGetValue(components[4], out codeSys))
                    {
                        codeSys = new CodeSystem()
                        {
                            Key          = Guid.NewGuid(),
                            Authority    = components[8],
                            Name         = components[6],
                            Oid          = components[4],
                            Description  = components[5],
                            CreationTime = conceptSet.CreationTime
                        };
                        codeSystems.Add(codeSys.Oid, codeSys);
                        conceptDataset.Action.Add(new DataUpdate()
                        {
                            InsertIfNotExists = true,
                            Element           = codeSys
                        });
                    }

                    // Insert the code
                    var refTerm = new ReferenceTerm()
                    {
                        Key           = Guid.NewGuid(),
                        CodeSystemKey = codeSys.Key,
                        CreationTime  = conceptSet.CreationTime,
                        DisplayNames  = new List <ReferenceTermName>()
                        {
                            new ReferenceTermName()
                            {
                                Name     = components[1],
                                Language = "en"
                            }
                        },
                        Mnemonic = components[0]
                    };
                    var concept = new Concept()
                    {
                        Key              = Guid.NewGuid(),
                        Mnemonic         = components[6] + "-" + components[1].Replace("[", "").Replace("]", "").Replace("-", "").Replace(" ", ""),
                        CreationTime     = conceptSet.CreationTime,
                        StatusConceptKey = StatusKeys.Active,
                        ClassKey         = ConceptClassKeys.Other,
                        ConceptNames     = new List <ConceptName>()
                        {
                            new ConceptName()
                            {
                                Name     = components[1],
                                Language = "en"
                            }
                        },
                        ReferenceTerms = new List <ConceptReferenceTerm>()
                        {
                            new ConceptReferenceTerm()
                            {
                                ReferenceTermKey    = refTerm.Key,
                                RelationshipTypeKey = ConceptRelationshipTypeKeys.SameAs
                            }
                        }
                    };
                    conceptDataset.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true, Element = refTerm
                    });
                    conceptDataset.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true, Element = concept
                    });
                    conceptSet.ConceptsXml.Add(concept.Key.Value);
                }
                conceptDataset.Action.Add(new DataUpdate()
                {
                    InsertIfNotExists = true, Element = conceptSet
                });
            }

            XmlSerializer xsz = new XmlSerializer(typeof(DatasetInstall));

            using (FileStream fs = File.Create(options.Output))
                xsz.Serialize(fs, conceptDataset);
        }
Esempio n. 7
0
        public static void Extract(string[] args)
        {
            var parms = new ParameterParser <ExtractionParameters>().Parse(args);

            // Is there any type specified, or no
            List <Type> targetTypes = new List <Type>();

            if (parms.Type.Count == 0)             // All types
            {
                targetTypes = typeof(DataInstallAction).GetRuntimeProperty("Element").GetCustomAttributes <XmlElementAttribute>().Select(o => o.Type).ToList();
            }
            else
            {
                targetTypes = typeof(DataInstallAction).GetRuntimeProperty("Element").GetCustomAttributes <XmlElementAttribute>().Where(o => parms.Type.Contains(o.ElementName)).Select(o => o.Type).ToList();
            }

            // Now time to get the DPE and extract
            IEnumerable <IdentifiedData> objects = new List <IdentifiedData>();

            foreach (var itm in targetTypes)
            {
                Console.Write("Extracting {0}.", itm.Name);
                try
                {
                    // Load persister
                    var idt = typeof(IDataPersistenceService <>).MakeGenericType(itm);
                    var idp = ApplicationContext.Current.GetService(idt) as IDataPersistenceService;
                    if (idp == null)
                    {
                        throw new InvalidOperationException("Cannot find data persistence service");
                    }

                    // Convert query
                    var mi = typeof(QueryExpressionParser).GetGenericMethod("BuildLinqExpression", new Type[] { itm }, new Type[] { typeof(OpenIZ.Core.Model.Query.NameValueCollection) });
                    var qd = mi.Invoke(null, new object[] { OpenIZ.Core.Model.Query.NameValueCollection.ParseQueryString(parms.Filter) }) as Expression;

                    // Exec query
                    int tr = 1, ofs = 0;
                    while (ofs < tr)
                    {
                        ofs += 100;
                        (objects as List <IdentifiedData>).AddRange(idp.Query(qd, ofs, 100, out tr).OfType <IdentifiedData>());
                        Console.Write(".");
                    }

                    Console.WriteLine("ok");
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.ToString());
                    Console.WriteLine("fail");
                }
            }

            // Now we want to organize the file properly
            Console.WriteLine("Preliminary remove duplicates...");
            objects = objects.Distinct(new IdentifiedEntityComparer());

            // Now we flatten the objects and re-organize them
            DatasetInstall dsOutput = new DatasetInstall();

            Console.Write("Flattening objects: ( 0 / {0} )", objects.Count());
            int i = 0;

            foreach (var obj in objects)
            {
                Console.CursorLeft = 0;
                Console.Write("Flattening objects: ( {0} / {1} )", i++, objects.Count());

                if (!parms.IncludeRelated)
                {
                    dsOutput.Action.Add(new DataUpdate()
                    {
                        Element           = obj,
                        InsertIfNotExists = true
                    });
                }
                else
                {
                    LayoutObject(obj, dsOutput);
                }
            }

            // Now we want to organize the file properly
            Console.WriteLine("Secondary remove duplicates...");
            objects = objects.Distinct(new IdentifiedEntityComparer());
        }
Esempio n. 8
0
        public static void EnumToDataset(String[] args)
        {
            var parms = new ParameterParser <ConsoleParameters>().Parse(args);

            var asm = Assembly.LoadFile(parms.AssemblyFile);

            foreach (var en in asm.ExportedTypes.Where(o => o.IsEnum && o.GetCustomAttribute <StructureAttribute>() != null))
            {
                StructureAttribute sta = en.GetCustomAttribute <StructureAttribute>();

                DatasetInstall conceptDataset = new DatasetInstall()
                {
                    Id = String.Format("HL7v3 {0} Concept Set", sta.Name)
                };

                // Create vaccine code concept set
                var conceptSet = new DataUpdate()
                {
                    InsertIfNotExists = true,
                    Element           = new ConceptSet()
                    {
                        Key      = Guid.NewGuid(),
                        Mnemonic = en.Name,
                        Name     = sta.Name,
                        Oid      = sta.CodeSystem,
                        Url      = String.Format("http://openiz.org/valuset/v3-{0}", en.Name)
                    },
                    Association = new List <DataAssociation>()
                };

                var codeSystem = new DataUpdate()
                {
                    InsertIfNotExists = true,
                    Element           = new CodeSystem(sta.Name, sta.CodeSystem, en.Name)
                    {
                        Url = String.Format("http://hl7.org/fhir/v3-{0}", en.Name),
                        Key = Guid.NewGuid(),
                    }
                };
                conceptDataset.Action.Add(codeSystem);

                foreach (var enm in en.GetFields())
                {
                    var ena = enm.GetCustomAttribute <EnumerationAttribute>();

                    if (ena == null)
                    {
                        continue;
                    }

                    var dsa = enm.GetCustomAttribute <DescriptionAttribute>();

                    ReferenceTerm refTerm = new ReferenceTerm()
                    {
                        CodeSystemKey = codeSystem.Element.Key,
                        Mnemonic      = ena.Value,
                        DisplayNames  = new List <ReferenceTermName>()
                        {
                            new ReferenceTermName()
                            {
                                Language = "en", Name = dsa?.Description ?? enm.Name
                            }
                        },
                        Key = Guid.NewGuid()
                    };

                    var mnemonic = String.Format("{0}-{1}", en.Name, enm.Name);
                    if (mnemonic.Length > 64)
                    {
                        mnemonic = mnemonic.Substring(0, 64);
                    }
                    Concept concept = new Concept()
                    {
                        Key          = Guid.NewGuid(),
                        Mnemonic     = mnemonic,
                        ClassKey     = ConceptClassKeys.Other,
                        ConceptNames = new List <ConceptName>()
                        {
                            new ConceptName()
                            {
                                Language = "en", Name = dsa?.Description
                            }
                        },
                        ReferenceTerms = new List <ConceptReferenceTerm>()
                        {
                            new ConceptReferenceTerm()
                            {
                                ReferenceTermKey    = refTerm.Key,
                                RelationshipTypeKey = ConceptRelationshipTypeKeys.SameAs
                            }
                        },
                        StatusConceptKey = StatusKeys.Active,
                        CreationTime     = DateTime.Now
                    };

                    conceptDataset.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true,
                        Element           = refTerm
                    });
                    conceptDataset.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true,
                        Element           = concept
                    });
                    (conceptSet.Element as ConceptSet).ConceptsXml.Add(concept.Key.Value);
                }

                conceptDataset.Action.Add(conceptSet);
                XmlSerializer xsz = new XmlSerializer(typeof(DatasetInstall));
                using (FileStream fs = File.Create(en.Name + ".dataset"))
                    xsz.Serialize(fs, conceptDataset);
            }
        }
Esempio n. 9
0
        public static void ImportSvs(string[] args)
        {
            var parameters = new ParameterParser <SvsOptions>().Parse(args);

            var svsDatasetInstall = new DatasetInstall
            {
                Action = new List <DataInstallAction>()
            };

            var fileInfo = new FileInfo(parameters.File);

            var serializer = new XmlSerializer(typeof(RetrieveValueSetResponseType));

            var svs = (RetrieveValueSetResponseType)serializer.Deserialize(new StreamReader(parameters.File));

            svsDatasetInstall.Id = svs.ValueSet.displayName;

            foreach (var conceptListType in svs.ValueSet.ConceptList)
            {
                var codeSystem = new CodeSystem
                {
                    Key         = Guid.NewGuid(),
                    Name        = svs.ValueSet.displayName,
                    Oid         = svs.ValueSet.id,
                    VersionText = svs.ValueSet.version
                };

                svsDatasetInstall.Action.Add(new DataUpdate
                {
                    Element           = codeSystem,
                    InsertIfNotExists = true
                });

                foreach (var cpt in conceptListType.Concept)
                {
                    var referenceTerm = new ReferenceTerm
                    {
                        CodeSystemKey = codeSystem.Key,
                        DisplayNames  = new List <ReferenceTermName>
                        {
                            new ReferenceTermName(conceptListType.lang?.Length > 2 ? conceptListType.lang?.Substring(0, 2) : "en", cpt.displayName)
                        },
                        Key      = Guid.NewGuid(),
                        Mnemonic = cpt.code
                    };

                    svsDatasetInstall.Action.Add(new DataUpdate
                    {
                        Element           = referenceTerm,
                        InsertIfNotExists = true
                    });

                    var concept = new Concept
                    {
                        ClassKey     = ConceptClassKeys.Other,
                        ConceptNames = new List <ConceptName>
                        {
                            new ConceptName(conceptListType.lang?.Length > 2 ? conceptListType.lang?.Substring(0, 2) : "en", cpt.displayName)
                        },
                        CreationTime   = DateTimeOffset.Now,
                        Key            = Guid.NewGuid(),
                        Mnemonic       = cpt.code,
                        ReferenceTerms = new List <ConceptReferenceTerm>
                        {
                            new ConceptReferenceTerm(referenceTerm.Key, ConceptRelationshipTypeKeys.SameAs)
                        },
                        StatusConceptKey = StatusKeys.Active
                    };

                    svsDatasetInstall.Action.Add(new DataUpdate
                    {
                        Element           = concept,
                        InsertIfNotExists = true
                    });
                }
            }

            serializer = new XmlSerializer(typeof(DatasetInstall));

            using (var fileStream = File.Create($"999-SVS-import-{fileInfo.Name}.dataset"))
            {
                serializer.Serialize(fileStream, svsDatasetInstall);
            }
        }
Esempio n. 10
0
        public static void ImportCsd(string[] args)
        {
            ApplicationContext.Current.Start();

            ShowInfoMessage("Adding service providers...");

            ApplicationContext.Current.AddServiceProvider(typeof(LocalEntityRepositoryService));
            ApplicationContext.Current.AddServiceProvider(typeof(LocalMetadataRepositoryService));
            ApplicationContext.Current.AddServiceProvider(typeof(LocalConceptRepositoryService));

            AuthenticationContext.Current = new AuthenticationContext(AuthenticationContext.SystemPrincipal);

            ApplicationContext.Current.Started += (o, e) =>
            {
                emergencyMessage = ApplicationContext.Current.GetLocaleString("01189998819991197253");
            };

            var parameters = new ParameterParser <CsdOptions>().Parse(args);

            var csdDatasetInstall = new DatasetInstall("HFR via CSD, Organizations, Places, Providers, Services");

            var actions = new List <DataInstallAction>();

            var serializer = new XmlSerializer(typeof(CSD));

            var fileInfo = new FileInfo(parameters.File);

            ShowInfoMessage($"Loading file: {fileInfo.Name}...");

            var csd = (CSD)serializer.Deserialize(new StreamReader(parameters.File));

            ShowInfoMessage($"File: {fileInfo.Name} loaded successfully, starting mapping process...");

            int limit = Int32.MaxValue;

            if (!String.IsNullOrEmpty(parameters.Limit))
            {
                limit = Int32.Parse(parameters.Limit);
            }

            if (parameters.RelationshipsOnly)
            {
                int idx = 0;
                foreach (var fac in csd.facilityDirectory.Take(limit))
                {
                    var place = GetOrCreateEntity <Place>(fac.entityID, parameters.EntityUidAuthority, parameters);
                    var rels  = CreateEntityRelationships(place, fac, csd.organizationDirectory, parameters);
                    actions.AddRange(rels.Select(o => new DataUpdate()
                    {
                        Element           = o,
                        InsertIfNotExists = true,
                        IgnoreErrors      = true
                    }));

                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.WriteLine($"Mapped place: ({idx++}/{csd.facilityDirectory.Take(limit).Count()}) {place.Key.Value} {string.Join(" ", place.Names.SelectMany(n => n.Component).Select(c => c.Value))}");
                    Console.ResetColor();
                }
            }
            else
            {
                var stopwatch = new Stopwatch();

                stopwatch.Start();

                // map organizations
                var organizations = !parameters.SkipOrganizations ? MapOrganizations(csd.organizationDirectory.Take(limit), parameters).Select(o => new DataUpdate
                {
                    InsertIfNotExists = true,
                    Element           = o
                }) : new List <DataUpdate>();

                actions.AddRange(organizations);

                // map places
                var places = !parameters.SkipFacilties ? MapPlaces(csd.facilityDirectory.Take(limit), csd.organizationDirectory, parameters).Select(p => new DataUpdate
                {
                    InsertIfNotExists = true,
                    Element           = p
                }) : new List <DataUpdate>();

                actions.AddRange(places);


                // map providers
                var providers = MapProviders(csd.providerDirectory.Take(limit), parameters).Select(p => new DataUpdate
                {
                    InsertIfNotExists = true,
                    Element           = p
                });

                actions.AddRange(providers);

                // map services
                var services = MapServices(csd.serviceDirectory.Take(limit)).Select(s => new DataUpdate
                {
                    InsertIfNotExists = true,
                    Element           = s
                });

                actions.AddRange(services);

                stopwatch.Stop();

                ShowPerformanceMessage($"Mapped {places.Count()} Places, {providers.Count()} Providers, {organizations.Count()} Organizations, and {services.Count()} Services in {stopwatch.Elapsed.Minutes} minutes and {stopwatch.Elapsed.Seconds} seconds");
            }


            if (parameters.RelationshipsOnly)
            {
                csdDatasetInstall.Action = actions;
            }
            else
            {
                var entities      = new List <Entity>();
                var relationships = new List <EntityRelationship>();
                foreach (var entity in actions.Where(a => a.Element is Entity).Select(c => c.Element as Entity))
                {
                    entity.Relationships.ForEach(o => o.SourceEntityKey = entity.Key);
                    relationships.AddRange(entity.Relationships);

                    // HACK: clear the entity relationships because we are going to import them separately
                    entity.Relationships.Clear();

                    entities.Add(entity);
                }

                // add entities to the list of items to import
                csdDatasetInstall.Action.AddRange(entities.Select(e => new DataUpdate
                {
                    InsertIfNotExists = true,
                    Element           = e
                }).ToList());

                // add relationships to the list of items to import
                csdDatasetInstall.Action.AddRange(relationships.Select(e => new DataUpdate
                {
                    InsertIfNotExists = true,
                    Element           = e
                }).ToList());
            }

            csdDatasetInstall.Action = csdDatasetInstall.Action.Distinct(new EntityComparison()).ToList();

            if (parameters.RelationshipsOnly)
            {
                csdDatasetInstall.Action.RemoveAll(o => !(o.Element is EntityRelationship) || (o.Element as EntityRelationship).RelationshipTypeKey == EntityRelationshipTypeKeys.Parent);
            }

            serializer = new XmlSerializer(typeof(DatasetInstall));

            var filename = $"999-CSD-import-{fileInfo.Name}.dataset";

            using (var fileStream = File.Create(filename))
            {
                serializer.Serialize(fileStream, csdDatasetInstall);
            }

            ShowInfoMessage($"Dataset file created: {filename}");

            if (parameters.Live)
            {
                ShowWarningMessage("Warning, the live flag is set to true, data will be imported directly into the database");

                ShowInfoMessage("Starting live import");

                var stopwatch = new Stopwatch();
                stopwatch.Start();

                var bundle = new Bundle
                {
                    Item = actions.Select(a => a.Element).ToList()
                };

                var bundlePersistenceService = ApplicationContext.Current.GetService <IDataPersistenceService <Bundle> >();

                ShowInfoMessage("Importing data directly into the database...");

                bundlePersistenceService.Insert(bundle, AuthenticationContext.SystemPrincipal, TransactionMode.Commit);

                ShowInfoMessage("The CSD live import is now complete");

                stopwatch.Stop();

                ShowPerformanceMessage($"Imported {bundle.Item.OfType<Place>().Count()} Places, {bundle.Item.OfType<Provider>().Count()} Providers, {bundle.Item.OfType<Organization>().Count()} Organizations, and {bundle.Item.OfType<PlaceService>().Count()} Services in {stopwatch.Elapsed.Minutes} minutes and {stopwatch.Elapsed.Seconds} seconds");
            }
        }
Esempio n. 11
0
        static void Main(string[] args)
        {
            // Concepts
            Console.WriteLine("Generating OpenIZ Concepts to support GIIS data");
            DatasetInstall conceptDataset = new DatasetInstall()
            {
                Id = "Concepts to support TIIS data", Action = new List <DataInstallAction>()
            };
            DataInsert healthFacilityTypes = new DataInsert()
            {
                Element = new ConceptSet()
                {
                    Key      = Guid.NewGuid(),
                    Mnemonic = "HealthFacilityTypes",
                    Oid      = "1.3.6.1.4.1.45219.1.3.5.99.1",
                    Name     = "Health Facility Types",
                    Url      = "http://ivd.moh.go.tz/valueset/timr/HealthFacilityTypes"
                },
                Association = new List <DataAssociation>()
            },
                       placeTypes = new DataInsert()
            {
                Element = new ConceptSet()
                {
                    Key      = Guid.NewGuid(),
                    Mnemonic = "PlaceTypes",
                    Oid      = "1.3.6.1.4.1.45219.1.3.5.99.2",
                    Name     = "Place Sub-Classifications",
                    Url      = "http://openiz.org/valueset/timr/PlaceTypes"
                },
                Association = new List <DataAssociation>()
                {
                    new DataAssociation()
                    {
                        PropertyName = "Concepts",
                        Element      = new Concept()
                        {
                            Key = PT_DISTRICT,
                            StatusConceptKey = StatusKeys.Active,
                            IsSystemConcept  = false,
                            ClassKey         = ConceptClassKeys.Other,
                            Mnemonic         = "PlaceType-District",
                            ConceptNames     = new List <ConceptName>()
                            {
                                new ConceptName()
                                {
                                    Language = "en",
                                    Name     = "District"
                                }
                            }
                        }
                    },
                    new DataAssociation()
                    {
                        PropertyName = "Concepts",
                        Element      = new Concept()
                        {
                            Key = PT_DISTRICT_COUNCIL,
                            StatusConceptKey = StatusKeys.Active,
                            IsSystemConcept  = false,
                            ClassKey         = ConceptClassKeys.Other,
                            Mnemonic         = "PlaceType-DistrictCouncil",
                            ConceptNames     = new List <ConceptName>()
                            {
                                new ConceptName()
                                {
                                    Language = "en",
                                    Name     = "District Council"
                                }
                            }
                        }
                    },
                    new DataAssociation()
                    {
                        PropertyName = "Concepts",
                        Element      = new Concept()
                        {
                            Key = PT_REGION,
                            StatusConceptKey = StatusKeys.Active,
                            IsSystemConcept  = false,
                            ClassKey         = ConceptClassKeys.Other,
                            Mnemonic         = "PlaceType-Region",
                            ConceptNames     = new List <ConceptName>()
                            {
                                new ConceptName()
                                {
                                    Language = "en",
                                    Name     = "Region"
                                }
                            }
                        }
                    },
                    new DataAssociation()
                    {
                        PropertyName = "Concepts",
                        Element      = new Concept()
                        {
                            Key = PT_TERRITORY,
                            StatusConceptKey = StatusKeys.Active,
                            IsSystemConcept  = false,
                            ClassKey         = ConceptClassKeys.Other,
                            Mnemonic         = "PlaceType-Territory",
                            ConceptNames     = new List <ConceptName>()
                            {
                                new ConceptName()
                                {
                                    Language = "en",
                                    Name     = "Territory"
                                }
                            }
                        }
                    },
                    new DataAssociation()
                    {
                        PropertyName = "Concepts",
                        Element      = new Concept()
                        {
                            Key = PT_VILLAGE,
                            StatusConceptKey = StatusKeys.Active,
                            IsSystemConcept  = false,
                            ClassKey         = ConceptClassKeys.Other,
                            Mnemonic         = "PlaceType-Village",
                            ConceptNames     = new List <ConceptName>()
                            {
                                new ConceptName()
                                {
                                    Language = "en",
                                    Name     = "Village"
                                }
                            }
                        }
                    }
                }
            };


            foreach (var itm in HealthFacilityType.GetHealthFacilityTypeList().OrderBy(o => o.Id))
            {
                facilityTypeId.Add(itm.Id, Guid.NewGuid());

                healthFacilityTypes.Association.Add(
                    new DataAssociation()
                {
                    PropertyName = "Concepts",
                    Element      = new Concept()
                    {
                        Key = facilityTypeId[itm.Id],
                        StatusConceptKey = StatusKeys.Active,
                        IsSystemConcept  = false,
                        ClassKey         = ConceptClassKeys.Other,
                        Mnemonic         = "Facility-" + itm.Name.Replace(" ", ""),
                        ConceptNames     = new List <ConceptName>()
                        {
                            new ConceptName()
                            {
                                Language = "en",
                                Name     = itm.Name
                            }
                        }
                    }
                }
                    );
            }


            (healthFacilityTypes.Element as ConceptSet).ConceptsXml = healthFacilityTypes.Association.Select(o => o.Element.Key.Value).ToList();
            (placeTypes.Element as ConceptSet).ConceptsXml          = placeTypes.Association.Select(o => o.Element.Key.Value).ToList();
            conceptDataset.Action.AddRange(healthFacilityTypes.Association.Select(o => new DataInsert()
            {
                Element = o.Element
            }));
            conceptDataset.Action.AddRange(placeTypes.Association.Select(o => new DataInsert()
            {
                Element = o.Element
            }));
            conceptDataset.Action.AddRange(new DataInstallAction[]
            {
                new DataInsert()
                {
                    Element = new Concept()
                    {
                        Key = industryManufacturer, Mnemonic = "Industry-Manufacturing", ClassKey = ConceptClassKeys.Other, IsSystemConcept = false, StatusConceptKey = StatusKeys.Active, ConceptNames = new List <ConceptName>()
                        {
                            new ConceptName()
                            {
                                Language = "en", Name = "Manufacturing"
                            }
                        }, ConceptSetsXml = new List <Guid>()
                        {
                            Guid.Parse("d1597e50-845a-46e1-b9ae-6f99ff93d9db")
                        }
                    }
                },
                new DataInsert()
                {
                    Element = new Concept()
                    {
                        Key = industryOther, Mnemonic = "Industry-OtherUnknown", ClassKey = ConceptClassKeys.Other, IsSystemConcept = false, StatusConceptKey = StatusKeys.Active, ConceptNames = new List <ConceptName>()
                        {
                            new ConceptName()
                            {
                                Language = "en", Name = "Other/Unknown"
                            }
                        }, ConceptSetsXml = new List <Guid>()
                        {
                            Guid.Parse("d1597e50-845a-46e1-b9ae-6f99ff93d9db")
                        }
                    }
                },
                new DataInsert()
                {
                    Element = new Concept()
                    {
                        Key = industryHealthDelivery, Mnemonic = "Industry-HealthDelivery", ClassKey = ConceptClassKeys.Other, IsSystemConcept = false, StatusConceptKey = StatusKeys.Active, ConceptNames = new List <ConceptName>()
                        {
                            new ConceptName()
                            {
                                Language = "en", Name = "Healthcare"
                            }
                        }, ConceptSetsXml = new List <Guid>()
                        {
                            Guid.Parse("d1597e50-845a-46e1-b9ae-6f99ff93d9db")
                        }
                    }
                }
            });
            healthFacilityTypes.Association.Clear();
            placeTypes.Association.Clear();
            conceptDataset.Action.Add(healthFacilityTypes);
            conceptDataset.Action.Add(placeTypes);

            // Facilities
            Console.WriteLine("Exporting GIIS Facilities to OpenIZ IMS Format");
            DatasetInstall facilityDataset = new DatasetInstall()
            {
                Action = new List <DataInstallAction>()
            };

            facilityDataset.Id = "Facilities from GIIS";
            foreach (var itm in HealthFacility.GetHealthFacilityList().OrderBy(o => o.Id))
            {
                facilityDataset.Action.Add(new DataInsert()
                {
                    Element = MapFacility(itm)
                });
            }

            // Places
            Console.WriteLine("Exporting GIIS Places to OpenIZ IMS Format");
            DatasetInstall placeDataset = new DatasetInstall()
            {
                Action = new List <DataInstallAction>()
            };

            placeDataset.Id = "Places from GIIS";
            foreach (var itm in GIIS.DataLayer.Place.GetPlaceList().OrderBy(o => o.ParentId))
            {
                placeDataset.Action.Add(new DataInsert()
                {
                    Element = MapPlace(itm)
                });
            }

            // Users
            Console.WriteLine("Exporting GIIS Users to OpenIZ IMS Format");
            DatasetInstall userDataset = new DatasetInstall()
            {
                Action = new List <DataInstallAction>()
            };

            userDataset.Id = "Users from TIIS";
            foreach (var itm in User.GetUserList())
            {
                if (userDataset.Action.Any(o => (o.Element as SecurityUser)?.UserName.Trim().ToLower() == itm.Username.Trim().ToLower()) ||
                    itm.Username.ToLower() == "administrator")
                {
                    continue; /// Apparently user names are distinct based on case?
                }
                Guid userId = Guid.NewGuid(), entityId = Guid.NewGuid();
                userMap.Add(itm.Id, userId);

                if (!userEntityMap.TryGetValue(itm.Id, out entityId))
                {
                    entityId = Guid.NewGuid();
                    userEntityMap.Add(itm.Id, entityId);
                }
                var securityUser = new SecurityUser()
                {
                    Key              = userId,
                    UserName         = itm.Username,
                    Email            = itm.Email,
                    EmailConfirmed   = !String.IsNullOrEmpty(itm.Email),
                    LastLoginTime    = itm.Lastlogin,
                    SecurityHash     = Guid.Empty.ToString(),
                    Lockout          = itm.IsActive ? null : (DateTime?)DateTime.MaxValue,
                    PasswordHash     = BitConverter.ToString(Convert.FromBase64String(itm.Password)).Replace("-", ""),
                    UserClass        = UserClassKeys.HumanUser,
                    TwoFactorEnabled = false,
                    ObsoletionTime   = itm.Deleted ? (DateTime?)DateTime.Now : null,
                    ObsoletedByKey   = itm.Deleted ? (Guid?)Guid.Parse(AuthenticationContext.SystemUserSid) : null,
                };
                var userEntity = new UserEntity()
                {
                    Key   = entityId,
                    Names = new List <EntityName>()
                    {
                        new EntityName(NameUseKeys.OfficialRecord, itm.Lastname, itm.Firstname)
                    },

                    SecurityUserKey = userId,
                    Identifiers     = new List <EntityIdentifier>()
                    {
                        new EntityIdentifier(new AssigningAuthority("TIIS_USER_ID", "TIIS User Identifiers", "1.3.6.1.4.1.45219.1.3.5.2"), itm.Id.ToString())
                    },
                    Tags = new List <EntityTag>()
                    {
                        new EntityTag("http://openiz.org/tags/contrib/importedData", "true")
                    },
                    StatusConceptKey = itm.IsActive ? StatusKeys.Active : StatusKeys.Obsolete
                };
                if (!String.IsNullOrEmpty(itm.Email))
                {
                    userEntity.Telecoms = new List <EntityTelecomAddress>()
                    {
                        new EntityTelecomAddress(TelecomAddressUseKeys.WorkPlace, itm.Email)
                    }
                }
                ;

                Guid facilityId = Guid.Empty;
                if (facilityMap.TryGetValue(itm.HealthFacilityId, out facilityId))
                {
                    userEntity.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.Employee, new Entity()
                    {
                        Key = facilityId
                    }));
                }

                // data element
                var securityUserData = new DataInsert()
                {
                    Element     = securityUser,
                    Association = new List <DataAssociation>()
                };

                // Role
                foreach (var r in Role.GetRolesOfUser(itm.Id))
                {
                    Guid roleId = Guid.Empty;
                    if (!roleMap.TryGetValue(r.Id, out roleId))
                    {
                        roleId = Guid.NewGuid();
                        roleMap.Add(r.Id, roleId);
                    }

                    var role = new SecurityRole()
                    {
                        Key            = roleId,
                        Name           = r.Name,
                        ObsoletionTime = r.IsActive ? null : (DateTime?)DateTime.Now,
                        ObsoletedByKey = r.IsActive ? null : (Guid?)Guid.Parse(AuthenticationContext.SystemUserSid)
                    };

                    // Add roles to the user
                    securityUserData.Association.Add(new DataAssociation()
                    {
                        PropertyName = "Roles",
                        Element      = new SecurityRole()
                        {
                            Key = role.Key
                        }
                    });

                    // Add role
                    userDataset.Action.Add(new DataInsert()
                    {
                        Element = role
                    });

                    // Vaccinator?
                    if (r.Name == "Vaccinator")
                    {
                        // Provider entity
                        var providerEntity = new Provider()
                        {
                            Key         = Guid.NewGuid(),
                            Names       = userEntity.Names,
                            Telecoms    = userEntity.Telecoms,
                            Identifiers = userEntity.Identifiers.Select(o => new EntityIdentifier(new AssigningAuthority("PROVIDER_ID", "TImR Assigned Provider ID", "1.3.6.1.4.1.45219.1.3.5.80"), o.Value)).ToList(),
                            Tags        = new List <EntityTag>()
                            {
                                new EntityTag("http://openiz.org/tags/contrib/importedData", "true")
                            },
                            StatusConceptKey = itm.IsActive ? StatusKeys.Active : StatusKeys.Obsolete
                        };
                        userDataset.Action.Add(new DataInsert()
                        {
                            Element = providerEntity
                        });

                        // Create a heath care provider
                        userEntity.Relationships.Add(new EntityRelationship()
                        {
                            RelationshipTypeKey = EntityRelationshipTypeKeys.AssignedEntity,
                            TargetEntityKey     = providerEntity.Key
                        });
                    }
                }


                userDataset.Action.Add(securityUserData);
                userDataset.Action.Add(new DataInsert()
                {
                    Element = userEntity
                });
            }

            var materialDataset = new DatasetInstall()
            {
                Id = "Manufactured Materials from GIIS"
            };

            foreach (var il in ItemLot.GetItemLotList())
            {
                var itm = MapMaterial(il, materialDataset);
                materialDataset.Action.Add(new DataUpdate()
                {
                    InsertIfNotExists = true, Element = itm
                });
            }


            // Write datasets
            XmlSerializer xsz = new XmlSerializer(typeof(DatasetInstall));

            using (var fs = File.Create("990-tiis.concepts.dataset"))
                xsz.Serialize(fs, conceptDataset);
            using (var fs = File.Create("991-tiis.facilities.dataset"))
                xsz.Serialize(fs, facilityDataset);
            using (var fs = File.Create("992-tiis.places.dataset"))
                xsz.Serialize(fs, placeDataset);
            using (var fs = File.Create("993-tiis.users.dataset"))
                xsz.Serialize(fs, userDataset);
            using (var fs = File.Create("994-tiis.materials.dataset"))
                xsz.Serialize(fs, materialDataset);
        }
    }
Esempio n. 12
0
        /// <summary>
        /// Map a facility
        /// </summary>
        static OpenIZ.Core.Model.Entities.ManufacturedMaterial MapMaterial(ItemLot item, DatasetInstall context)
        {
            Guid id = Guid.NewGuid();

            manufacturedMaterialMap.Add(item.Id, id);
            EntitySource.Current = new EntitySource(new DummyEntitySource());

            Guid materialId = Guid.Empty;

            if (!materialMap.TryGetValue(item.ItemId, out materialId))
            {
                materialId = Guid.NewGuid();
                Material material = new Material()
                {
                    Key                  = materialId,
                    ExpiryDate           = item.ItemObject.ExitDate,
                    FormConceptKey       = Guid.Parse(item.ItemObject.Name == "OPV" ? "66CBCE3A-2E77-401D-95D8-EE0361F4F076" : "9902267C-8F77-4233-BFD3-E6B068AB326A"),
                    DeterminerConceptKey = DeterminerKeys.Described,
                    Identifiers          = new List <EntityIdentifier>()
                    {
                        new EntityIdentifier(new AssigningAuthority("TIIS_ITEM", "TIIS Item Identifiers", "1.3.6.1.4.1.33349.3.1.5.102.3.5.12"), item.ItemId.ToString())
                    },
                    Names = new List <EntityName>()
                    {
                        new EntityName(NameUseKeys.OfficialRecord, item.ItemObject.Name)
                    },
                    StatusConceptKey = item.ItemObject.IsActive ? StatusKeys.Active : StatusKeys.Obsolete
                };
                context.Action.Add(new DataUpdate()
                {
                    InsertIfNotExists = true, Element = material
                });
                materialMap.Add(item.ItemId, materialId);
            }

            // Organization map?
            Guid organizationId = Guid.Empty;
            var  gtinObject     = ItemManufacturer.GetItemManufacturerByGtin(item.Gtin);

            if (gtinObject != null && !manufacturerMap.TryGetValue(gtinObject.ManufacturerId, out organizationId))
            {
                organizationId = Guid.NewGuid();
                Organization organization = new Organization()
                {
                    Key         = organizationId,
                    Identifiers = new List <EntityIdentifier>()
                    {
                        new EntityIdentifier(new AssigningAuthority("MANUFACTURER_CODE", "Manufacturer Codes", "1.3.6.1.4.1.33349.3.1.5.102.3.5.14"), gtinObject.ManufacturerObject.Code),
                        new EntityIdentifier(new AssigningAuthority("TIIS_MANUFACTURER", "TIIS Manufacturer Identifiers", "1.3.6.1.4.1.33349.3.1.5.102.3.5.13"), gtinObject.ManufacturerId.ToString())
                    },
                    Names = new List <EntityName>()
                    {
                        new EntityName(NameUseKeys.OfficialRecord, gtinObject.ManufacturerObject.Name)
                    },
                    StatusConceptKey   = gtinObject.ManufacturerObject.IsActive ? StatusKeys.Active : StatusKeys.Obsolete,
                    IndustryConceptKey = industryManufacturer
                };
                context.Action.Add(new DataUpdate()
                {
                    InsertIfNotExists = true, Element = organization
                });
                manufacturerMap.Add(gtinObject.ManufacturerId, organizationId);
            }

            Guid typeConceptKey = Guid.Empty;

            materialTypeMap.TryGetValue(item.ItemId, out typeConceptKey);

            // TODO: Migrate over kit items
            // TODO: Link boxes/vials/doses
            // Core construction of place
            ManufacturedMaterial retVal = new ManufacturedMaterial()
            {
                Key            = id,
                TypeConceptKey = typeConceptKey == Guid.Empty ? (Guid?)null : typeConceptKey,
                Relationships  = new List <EntityRelationship>()
                {
                    new EntityRelationship(EntityRelationshipTypeKeys.ManufacturedProduct, id)
                    {
                        SourceEntityKey = materialId
                    },
                },
                Names = new List <EntityName>()
                {
                    new EntityName(NameUseKeys.Assigned, String.Format("{0} ({1})", item.ItemObject.Name, gtinObject?.ManufacturerObject.Name))
                },
                ExpiryDate  = item.ExpireDate,
                LotNumber   = item.LotNumber,
                Identifiers = new List <EntityIdentifier>()
                {
                    new EntityIdentifier(new AssigningAuthority("GTIN", "GS1 Global Trade Identification Number (GTIN)", "1.3.160"), item.Gtin),
                    new EntityIdentifier(new AssigningAuthority("GIIS_ITEM_ID", "GIIS Item Identifiers", "1.3.6.1.4.1.33349.3.1.5.102.3.5.15"), item.Id.ToString())
                },
                IsAdministrative = false,
                StatusConceptKey = StatusKeys.Active
            };

            if (organizationId != Guid.Empty)
            {
                retVal.Relationships.Add(new EntityRelationship(EntityRelationshipTypeKeys.WarrantedProduct, id)
                {
                    SourceEntityKey = organizationId
                });
            }

            return(retVal);
        }