static async Task ComposePatientBlock(TextWriter writer, Func<int> lineNumberGetter, Action<int> lineNumberSetter, Patient patient, bool lab)
        {
            var lineNumber = lineNumberGetter();

            //Lijn 1: aanduiding begin van een aanvraag formaat: #A (eventueel gevolgd het rijksregisternummer van de patient of bij gebrek hieraan het Medidoc dossiernummer van de patiënt   zie appendix A voor de vorming van het Medidoc dossiernummer)
            lineNumber++;
            await writer.WriteLineAsync(string.Concat("#A", patient.Id));

            //Lijn 2:	naam en voornaam van de patiënt
            lineNumber++;
            await writer.WriteLineAsync(string.Concat(patient.LastName?.TrimToMaxSize(24).PadRight(24) ?? string.Empty, patient.FirstName).TrimToMaxSize(40));

            //Lijn 3: geboortedatum patiënt
            //formaat: JJJJMMDD
            lineNumber++;
            await writer.WriteLineAsync(patient.BirthDate?.ToString("yyyyMMdd"));

            //Lijn 4: geslacht patiënt
            //formaat: X, of Y, of Z
            lineNumber++;
            switch (patient.Sex)
            {
                case Sex.male:
                    await writer.WriteLineAsync("Y");
                    break;
                case Sex.female:
                    await writer.WriteLineAsync("X");
                    break;
                default:
                    await writer.WriteLineAsync("Z");
                    break;
            }

            //Lijn 5:	datum van de aanvraag
            //formaat: JJJJMMDD
            lineNumber++;
            await writer.WriteLineAsync(patient.RequestDate?.ToString("yyyyMMdd"));

            //(Lijn 6:	referentienummer aanvraag 
            //formaat: max 14 karakters.
            lineNumber++;
            await writer.WriteLineAsync(patient.ReferenceNumber?.TrimToMaxSize(14));

            if (lab)
            {
                //Lijn 7:	protocol code
                //formaat: 1 karakter, zijnde: P indien partieel protocol; C indien volledig protocol; S indien aanvulling van een partieel; L indien het de laatste aanvulling is
                lineNumber++;
                switch (patient.ProtocolCode)
                {
                    case ProtocolCode.Partial:
                        await writer.WriteLineAsync("P");
                        break;
                    case ProtocolCode.Full:
                        await writer.WriteLineAsync("C");
                        break;
                    case ProtocolCode.Adition:
                        await writer.WriteLineAsync("S");
                        break;
                    case ProtocolCode.LastAdition:
                        await writer.WriteLineAsync("L");
                        break;
                    default:
                        await writer.WriteLineAsync();
                        break;
                }
            }
            else
            {
                //(lijn 7:)Episodenummer (positie 1-14); legt verband tussen meerdere onderzoeken
                //mag blanco gelaten worden
                lineNumber++;
                await writer.WriteLineAsync(patient.EpisodeNumber?.TrimToMaxSize(14));
            }

            //(lijn 1-7 zijn obligaat, de volgende lijnen mogen weggelaten worden)
            //(lijn 8:)Straat (positie 1-24) + nr (positie 25-31)
            if (!string.IsNullOrEmpty(patient.Address?.Street))
            {
                lineNumber++;
                await writer.WriteLineAsync(string.Concat(patient.Address?.Street?.TrimToMaxSize(24).PadRight(24) ?? string.Empty, patient.Address?.HouseNr).TrimToMaxSize(31));
            }

            //(lijn 9:)Postcode (positie 1-7)
            if (!string.IsNullOrEmpty(patient.Address?.PostalCode))
            {
                lineNumber++;
                await writer.WriteLineAsync(patient.Address?.PostalCode?.TrimToMaxSize(7));
            }

            //(lijn 10:)Gemeente (positie 1-24)
            if (!string.IsNullOrEmpty(patient.Address?.Town))
            {
                lineNumber++;
                await writer.WriteLineAsync(patient.Address?.Town?.TrimToMaxSize(24));
            }

            foreach (var result in patient.Results)
               await  ComposeResultBlock(writer, () => lineNumber, (ln) => lineNumber = ln, result);

            lineNumber++;
            await writer.WriteLineAsync("#A/");

            lineNumberSetter(lineNumber);
        }
Exemple #2
0
        static async Task<Patient> ParsePatientBlock(TextReader reader, Func<int> lineNumberGetter, Action<int> lineNumberSetter, IDictionary<int, IList<string>> parserErrors, string firstLine, bool lab)
        {
            var patient = new Patient();
            var lineNumber = lineNumberGetter();

            //Lijn 1: aanduiding begin van een aanvraag formaat: #A (eventueel gevolgd het rijksregisternummer van de patient of bij gebrek hieraan het Medidoc dossiernummer van de patiënt   zie appendix A voor de vorming van het Medidoc dossiernummer)
            if (firstLine.Length > 2)
            {
                var id = firstLine.Substring(2);
                if (id.Length == 11)
                {
                    if (!id.IsValidSocialSecurityNumber())
                        parserErrors.AddItem(lineNumber, $"Not a valid SSN: '{id}'");
                }
                else if (id.Length == 13)
                {
                    if (id == null || !Regex.Match(id.Trim(), @"\d{6}[XYZ][A-Z.]{6}", RegexOptions.IgnoreCase).Success)
                        parserErrors.AddItem(lineNumber, $"Not a valid Medidoc dossiernummer: '{id}'");
                }
                else
                {
                    parserErrors.AddItem(lineNumber, $"Invalid patient id '{firstLine}'");
                }

                patient.Id = id?.Trim();
            }

            //Lijn 2:	naam en voornaam van de patiënt
            lineNumber++;
            var name = (await reader.ReadLineAsync())?.CheckMaxSize(40, parserErrors, lineNumber);
            patient.LastName = name?.Substring(0, name.Length > 24 ? 24 : name.Length).Trim();
            if (name?.Length > 24)
                patient.FirstName = name?.Substring(24).Trim();

            //Lijn 3: geboortedatum patiënt
            //formaat: JJJJMMDD
            lineNumber++;
            patient.BirthDate = (await reader.ReadLineAsync())?.CheckMaxSize(8, parserErrors, lineNumber).ToNullableDatetime("yyyyMMdd", "yyMMdd");

            //Lijn 4: geslacht patiënt
            //formaat: X, of Y, of Z
            lineNumber++;
            switch ((await reader.ReadLineAsync())?.CheckMaxSize(1, parserErrors, lineNumber))
            {
                case "X":
                    patient.Sex = Sex.female;
                    break;
                case "Y":
                    patient.Sex = Sex.male;
                    break;
                default:
                    patient.Sex = Sex.unknown;
                    break;
            }

            //Lijn 5:	datum van de aanvraag
            //formaat: JJJJMMDD
            lineNumber++;
            patient.RequestDate = (await reader.ReadLineAsync())?.CheckMaxSize(8, parserErrors, lineNumber).ToNullableDatetime("yyyyMMdd", "yyMMdd");

            //(Lijn 6:	referentienummer aanvraag 
            //formaat: max 14 karakters.
            lineNumber++;
            patient.ReferenceNumber = (await reader.ReadLineAsync())?.CheckMaxSize(14, parserErrors, lineNumber).Trim();

            if (lab)
            {
                //Lijn 7:	protocol code
                //formaat: 1 karakter, zijnde: P indien partieel protocol; C indien volledig protocol; S indien aanvulling van een partieel; L indien het de laatste aanvulling is
                lineNumber++;
                var protocolCode = (await reader.ReadLineAsync())?.CheckMaxSize(1, parserErrors, lineNumber);
                switch (protocolCode)
                {
                    case "P":
                        patient.ProtocolCode = ProtocolCode.Partial;
                        break;
                    case "C":
                        patient.ProtocolCode = ProtocolCode.Full;
                        break;
                    case "S":
                        patient.ProtocolCode = ProtocolCode.Adition;
                        break;
                    case "L":
                        patient.ProtocolCode = ProtocolCode.LastAdition;
                        break;
                    default:
                        parserErrors.AddItem(lineNumber, string.Format($"'{protocolCode}' is not a valid protocol code (only P,C,S and L) are allowed."));
                        break;
                }
            }
            else
            {
                //(lijn 7:)Episodenummer (positie 1-14); legt verband tussen meerdere onderzoeken
                //mag blanco gelaten worden
                lineNumber++;
                patient.EpisodeNumber = (await reader.ReadLineAsync())?.CheckMaxSize(14, parserErrors, lineNumber).Trim();
            }

            //(lijn 1-7 zijn obligaat, de volgende lijnen mogen weggelaten worden)
            lineNumber++;
            var line = await reader.ReadLineAsync();
            if (line != null && !line.StartsWith(@"#R"))
            {
                //(lijn 8:)Straat (positie 1-24) + nr (positie 25-31)
                var address = line?.CheckMaxSize(31, parserErrors, lineNumber);
                patient.Address.Street = address?.Substring(0, address.Length > 24 ? 24 : address.Length).Trim();
                if (address?.Length > 24)
                    patient.Address.HouseNr = address?.Substring(24).Trim();

                lineNumber++;
                line = await reader.ReadLineAsync();
                if (line != null && !line.StartsWith(@"#R"))
                {
                    //(lijn 9:)Postcode (positie 1-7)
                    patient.Address.PostalCode = line?.CheckMaxSize(7, parserErrors, lineNumber).Trim();

                    lineNumber++;
                    line = await reader.ReadLineAsync();
                    if (line != null && !line.StartsWith(@"#R"))
                    {
                        //(lijn 10:)Gemeente (positie 1-24)
                        patient.Address.Town = line?.CheckMaxSize(24, parserErrors, lineNumber).Trim();
                    }
                }
            }
            if (line != null && !line.StartsWith(@"#R"))
            {
                //(lijn 11 en volgende: in voorbereiding voor mut-gegevens, enz)
                lineNumber++;
                while ((line = (await reader.ReadLineAsync())) != null && !line.StartsWith(@"#R"))
                {
                    lineNumber++;
                }
            }

            do
            {
                if (line == null || !line.StartsWith("#R"))
                    parserErrors.AddItem(lineNumber, $"Not valid start of result block expected '#R' but got '{line}'");

                if (line != null)
                    patient.Results.Add(await ParseResultBlock(reader, () => lineNumber, (ln) => lineNumber = ln, parserErrors, line));
                lineNumber++;
            }
            while ((line = (await reader.ReadLineAsync())) != null && !line.StartsWith(@"#A/"));

            lineNumberSetter(lineNumber);
            return patient;
        }