private NotificationApplicationCompletionProgress GetCompletetionProgress(NotificationProgressResult progressResult)
        {
            var progress = new NotificationApplicationCompletionProgress();

            progress.Id = progressResult.Notification.Id;
            progress.NotificationType = progressResult.Notification.NotificationType;
            progress.CompetentAuthority = progressResult.Notification.CompetentAuthority;
            progress.NotificationNumber = progressResult.Notification.NotificationNumber;

            var organisationsInvolvedComplete = MapProgressForOrganisationsInvolved(progress, progressResult);
            var recoveryOperationComplete = MapProgressForRecoveryOperation(progress, progressResult);
            var transportationComplete = MapProgressForTransportation(progress, progressResult);
            var journeyComplete = MapProgressForJourney(progress, progressResult);
            var amountsAndDatesComplete = MapProgressForAmountsAndDates(progress, progressResult);
            var classifyYourWasteComplete = MapProgressForClassifyYourWaste(progress, progressResult);
            var wasteCodesComplete = MapProgressForWasteCodes(progress, progressResult);
            var wasteRecoveryComplete = MapProgressForWasteRecovery(progress, progressResult);

            progress.IsAllComplete = organisationsInvolvedComplete
                && recoveryOperationComplete
                && transportationComplete
                && journeyComplete
                && amountsAndDatesComplete
                && classifyYourWasteComplete
                && wasteCodesComplete
                && (progress.NotificationType == NotificationType.Disposal || wasteRecoveryComplete);

            return progress;
        }
        public NotificationApplicationCompletionProgress GetNotificationProgressInfo(Guid notificationId)
        {
            var command = context.Database.Connection.CreateCommand();
            command.CommandText = "[Notification].[uspNotificationProgress] @NotificationId";
            command.Parameters.Add(new SqlParameter("@NotificationId", notificationId));

            var progressResult = new NotificationProgressResult();

            try
            {
                context.Database.Connection.Open();
                var reader = command.ExecuteReader();
                var objectContext = ((IObjectContextAdapter)context).ObjectContext;

                progressResult.Notification = objectContext.Translate<NotificationProgressNotificationResult>(reader).Single();
                reader.NextResult();

                progressResult.Producers = objectContext.Translate<NotificationProgressProducersResult>(reader).ToArray();
                reader.NextResult();

                progressResult.Facilities = objectContext.Translate<NotificationProgressFacilitiesResult>(reader).ToArray();
                reader.NextResult();

                progressResult.WasteCodes = objectContext.Translate<NotificationProgressWasteCodesResult>(reader).ToArray();
                reader.NextResult();

                progressResult.CustomsOffices = objectContext.Translate<NotificationProgressCustomsOfficesResult>(reader).ToArray();
            }
            finally
            {
                context.Database.Connection.Close();
            }

            return GetCompletetionProgress(progressResult);
        }
        private NotificationApplicationCompletionProgress GetCompletetionProgress(NotificationProgressResult progressResult)
        {
            var progress = new NotificationApplicationCompletionProgress();

            progress.Id = progressResult.Notification.Id;
            progress.NotificationType   = progressResult.Notification.NotificationType;
            progress.CompetentAuthority = progressResult.Notification.CompetentAuthority;
            progress.NotificationNumber = progressResult.Notification.NotificationNumber;

            var organisationsInvolvedComplete = MapProgressForOrganisationsInvolved(progress, progressResult);
            var recoveryOperationComplete     = MapProgressForRecoveryOperation(progress, progressResult);
            var transportationComplete        = MapProgressForTransportation(progress, progressResult);
            var journeyComplete           = MapProgressForJourney(progress, progressResult);
            var amountsAndDatesComplete   = MapProgressForAmountsAndDates(progress, progressResult);
            var classifyYourWasteComplete = MapProgressForClassifyYourWaste(progress, progressResult);
            var wasteCodesComplete        = MapProgressForWasteCodes(progress, progressResult);
            var wasteRecoveryComplete     = MapProgressForWasteRecovery(progress, progressResult);

            progress.IsAllComplete = organisationsInvolvedComplete &&
                                     recoveryOperationComplete &&
                                     transportationComplete &&
                                     journeyComplete &&
                                     amountsAndDatesComplete &&
                                     classifyYourWasteComplete &&
                                     wasteCodesComplete &&
                                     (progress.NotificationType == NotificationType.Disposal || wasteRecoveryComplete);

            return(progress);
        }
        public NotificationApplicationCompletionProgress GetNotificationProgressInfo(Guid notificationId)
        {
            var command = context.Database.Connection.CreateCommand();

            command.CommandText = "[Notification].[uspNotificationProgress] @NotificationId";
            command.Parameters.Add(new SqlParameter("@NotificationId", notificationId));

            var progressResult = new NotificationProgressResult();

            try
            {
                context.Database.Connection.Open();
                var reader        = command.ExecuteReader();
                var objectContext = ((IObjectContextAdapter)context).ObjectContext;

                progressResult.Notification = objectContext.Translate <NotificationProgressNotificationResult>(reader).Single();
                reader.NextResult();

                progressResult.Producers = objectContext.Translate <NotificationProgressProducersResult>(reader).ToArray();
                reader.NextResult();

                progressResult.Facilities = objectContext.Translate <NotificationProgressFacilitiesResult>(reader).ToArray();
                reader.NextResult();

                progressResult.WasteCodes = objectContext.Translate <NotificationProgressWasteCodesResult>(reader).ToArray();
                reader.NextResult();

                progressResult.CustomsOffices = objectContext.Translate <NotificationProgressCustomsOfficesResult>(reader).ToArray();
            }
            finally
            {
                context.Database.Connection.Close();
            }

            return(GetCompletetionProgress(progressResult));
        }
        private bool MapProgressForWasteCodes(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasBaselOecdCode = progressResult.WasteCodes.Any(wc =>
                wc.CodeType == CodeType.Basel
                || wc.CodeType == CodeType.Oecd);
            progress.HasEwcCodes = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.Ewc);
            progress.HasYCodes = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.Y);
            progress.HasHCodes = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.H);
            progress.HasUnClasses = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.Un);
            progress.HasUnNumbers = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.UnNumber);

            var otherCodes = new[] { CodeType.CustomsCode, CodeType.ImportCode, CodeType.ExportCode, CodeType.OtherCode };
            progress.HasOtherCodes = otherCodes.All(oc =>
                progressResult.WasteCodes.Select(wc => wc.CodeType).Contains(oc));

            return progress.HasBaselOecdCode
                && progress.HasEwcCodes
                && progress.HasYCodes
                && progress.HasHCodes
                && progress.HasUnClasses
                && progress.HasUnNumbers
                && progress.HasOtherCodes;
        }
        private bool MapProgressForClassifyYourWaste(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasWasteType = progressResult.Notification.WasteTypeId.HasValue
                && (!string.IsNullOrWhiteSpace(progressResult.Notification.OtherWasteTypeDescription)
                    || progressResult.Notification.WasteTypeHasAnnex.GetValueOrDefault()
                    || progressResult.Notification.WasteAdditionalInformationId.HasValue);
            progress.HasWasteGenerationProcess = progressResult.Notification.IsWasteGenerationProcessAttached.GetValueOrDefault()
                || !string.IsNullOrWhiteSpace(progressResult.Notification.WasteGenerationProcess);
            progress.HasPhysicalCharacteristics = progressResult.Notification.PhysicalCharacteristicsId.HasValue;

            return progress.HasWasteType
                && progress.HasWasteGenerationProcess
                && progress.HasPhysicalCharacteristics;
        }
        private bool MapProgressForAmountsAndDates(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasShipmentInfo = progressResult.Notification.ShipmentInfoId.HasValue;

            return progress.HasShipmentInfo;
        }
        private bool MapProgressForJourney(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasStateOfExport = progressResult.Notification.StateOfExportId.HasValue;
            progress.HasStateOfImport = progressResult.Notification.StateOfImportId.HasValue;
            progress.HasTransitState = progressResult.Notification.TransitStateId.HasValue;

            if (progressResult.CustomsOffices.Any(co => co.ImportIsEuMember.HasValue && co.ExportIsEuMember.HasValue))
            {
                bool importIsEuMember = progressResult.CustomsOffices.First().ImportIsEuMember.GetValueOrDefault();
                bool exportIsEuMember = progressResult.CustomsOffices.First().ExportIsEuMember.GetValueOrDefault();
                bool allTransitStatsAreEu = progressResult.CustomsOffices.All(co => co.TransitIsEuMember.GetValueOrDefault(true));
                bool hasEntryOffice = progressResult.CustomsOffices.First().EntryCustomsOfficeId.HasValue;
                bool hasExitOffice = progressResult.CustomsOffices.First().ExitCustomsOfficeId.HasValue;

                bool allInEu = importIsEuMember && exportIsEuMember && allTransitStatsAreEu;
                bool importOutsideEu = !importIsEuMember && exportIsEuMember && allTransitStatsAreEu;
                bool importAndTransitsOutsideEu = !importIsEuMember && exportIsEuMember && !allTransitStatsAreEu;
                bool transitsOutsideEu = importIsEuMember && exportIsEuMember && !allTransitStatsAreEu;

                progress.HasCustomsOffice = allInEu
                    || (importOutsideEu && hasExitOffice)
                    || (importAndTransitsOutsideEu && hasEntryOffice)
                    || (transitsOutsideEu && hasExitOffice && hasEntryOffice);
            }
            else
            {
                progress.HasCustomsOffice = false;
            }

            return progress.HasStateOfExport
                && progress.HasStateOfImport;
        }
        private bool MapProgressForTransportation(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasCarrier = progressResult.Notification.CarrierId.HasValue;
            progress.HasMeansOfTransport = !string.IsNullOrWhiteSpace(progressResult.Notification.MeansOfTransport);
            progress.HasPackagingInfo = progressResult.Notification.PackagingInfoId.HasValue;
            progress.HasSpecialHandlingRequirements = progressResult.Notification.HasSpecialHandlingRequirements.HasValue;

            return progress.HasCarrier
                && progress.HasMeansOfTransport
                && progress.HasPackagingInfo
                && progress.HasSpecialHandlingRequirements;
        }
        private bool MapProgressForTransportation(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasCarrier                     = progressResult.Notification.CarrierId.HasValue;
            progress.HasMeansOfTransport            = !string.IsNullOrWhiteSpace(progressResult.Notification.MeansOfTransport);
            progress.HasPackagingInfo               = progressResult.Notification.PackagingInfoId.HasValue;
            progress.HasSpecialHandlingRequirements = progressResult.Notification.HasSpecialHandlingRequirements.HasValue;

            return(progress.HasCarrier &&
                   progress.HasMeansOfTransport &&
                   progress.HasPackagingInfo &&
                   progress.HasSpecialHandlingRequirements);
        }
        private bool MapProgressForWasteRecovery(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasRecoveryData = progressResult.Notification.IsRecoveryPercentageDataProvidedByImporter.HasValue &&
                                       (progressResult.Notification.IsRecoveryPercentageDataProvidedByImporter.Value ||
                                        (progressResult.Notification.RecoveryInfoId.HasValue &&
                                         (progressResult.Notification.PercentageRecoverable == 100 || progressResult.Notification.DisposalInfoId.HasValue)));

            return(progress.HasRecoveryData);
        }
        private bool MapProgressForWasteCodes(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasBaselOecdCode = progressResult.WasteCodes.Any(wc =>
                                                                      wc.CodeType == CodeType.Basel ||
                                                                      wc.CodeType == CodeType.Oecd);
            progress.HasEwcCodes  = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.Ewc);
            progress.HasYCodes    = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.Y);
            progress.HasHCodes    = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.H);
            progress.HasUnClasses = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.Un);
            progress.HasUnNumbers = progressResult.WasteCodes.Any(wc => wc.CodeType == CodeType.UnNumber);

            var otherCodes = new[] { CodeType.CustomsCode, CodeType.ImportCode, CodeType.ExportCode, CodeType.OtherCode };

            progress.HasOtherCodes = otherCodes.All(oc =>
                                                    progressResult.WasteCodes.Select(wc => wc.CodeType).Contains(oc));

            return(progress.HasBaselOecdCode &&
                   progress.HasEwcCodes &&
                   progress.HasYCodes &&
                   progress.HasHCodes &&
                   progress.HasUnClasses &&
                   progress.HasUnNumbers &&
                   progress.HasOtherCodes);
        }
        private bool MapProgressForClassifyYourWaste(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasWasteType = progressResult.Notification.WasteTypeId.HasValue &&
                                    (!string.IsNullOrWhiteSpace(progressResult.Notification.OtherWasteTypeDescription) ||
                                     progressResult.Notification.WasteTypeHasAnnex.GetValueOrDefault() ||
                                     progressResult.Notification.WasteAdditionalInformationId.HasValue);
            progress.HasWasteGenerationProcess = progressResult.Notification.IsWasteGenerationProcessAttached.GetValueOrDefault() ||
                                                 !string.IsNullOrWhiteSpace(progressResult.Notification.WasteGenerationProcess);
            progress.HasPhysicalCharacteristics = progressResult.Notification.PhysicalCharacteristicsId.HasValue;

            return(progress.HasWasteType &&
                   progress.HasWasteGenerationProcess &&
                   progress.HasPhysicalCharacteristics);
        }
        private bool MapProgressForAmountsAndDates(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasShipmentInfo = progressResult.Notification.ShipmentInfoId.HasValue;

            return(progress.HasShipmentInfo);
        }
        private bool MapProgressForJourney(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasStateOfExport = progressResult.Notification.StateOfExportId.HasValue;
            progress.HasStateOfImport = progressResult.Notification.StateOfImportId.HasValue;
            progress.HasTransitState  = progressResult.Notification.TransitStateId.HasValue;

            if (progressResult.CustomsOffices.Any(co => co.ImportIsEuMember.HasValue && co.ExportIsEuMember.HasValue))
            {
                bool importIsEuMember     = progressResult.CustomsOffices.First().ImportIsEuMember.GetValueOrDefault();
                bool exportIsEuMember     = progressResult.CustomsOffices.First().ExportIsEuMember.GetValueOrDefault();
                bool allTransitStatsAreEu = progressResult.CustomsOffices.All(co => co.TransitIsEuMember.GetValueOrDefault(true));
                bool hasEntryOffice       = progressResult.CustomsOffices.First().EntryCustomsOfficeId.HasValue;
                bool hasExitOffice        = progressResult.CustomsOffices.First().ExitCustomsOfficeId.HasValue;

                bool allInEu           = importIsEuMember && exportIsEuMember && allTransitStatsAreEu;
                bool importOutsideEu   = !importIsEuMember && exportIsEuMember;
                bool transitsOutsideEu = importIsEuMember && exportIsEuMember && !allTransitStatsAreEu;

                progress.HasCustomsOffice = allInEu ||
                                            (importOutsideEu && hasExitOffice) ||
                                            (transitsOutsideEu && hasExitOffice && hasEntryOffice);
            }
            else
            {
                progress.HasCustomsOffice = false;
            }

            var exemptStatusList = new List <NotificationStatus>()
            {
                NotificationStatus.Transmitted,
                NotificationStatus.Withdrawn,
                NotificationStatus.Objected,
                NotificationStatus.Consented,
                NotificationStatus.ConsentWithdrawn,
                NotificationStatus.FileClosed
            };

            // Identify whether the notification is exempt from the customs office selections check
            // This is necessary as historic data does not have data present in the EntryExitCustomsSelection table
            bool exemptFromCheck = exemptStatusList.Contains(progressResult.Notification.NotificationStatus);

            progress.HasCustomsOfficeSelections = exemptFromCheck || (progressResult.CustomsOffices.Any() &&
                                                                      (progressResult.CustomsOffices.First().IsEntryCustomsOfficeRequired !=
                                                                       null &&
                                                                       progressResult.CustomsOffices.First().IsExitCustomsOfficeRequired !=
                                                                       null));

            return(progress.HasStateOfExport &&
                   progress.HasStateOfImport &&
                   progress.HasCustomsOfficeSelections);
        }
        private bool MapProgressForWasteRecovery(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasRecoveryData = progressResult.Notification.IsRecoveryPercentageDataProvidedByImporter.HasValue
                && (progressResult.Notification.IsRecoveryPercentageDataProvidedByImporter.Value
                || (progressResult.Notification.RecoveryInfoId.HasValue 
                    && (progressResult.Notification.PercentageRecoverable == 100 || progressResult.Notification.DisposalInfoId.HasValue)));

            return progress.HasRecoveryData;
        }
        private bool MapProgressForOrganisationsInvolved(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasExporter              = progressResult.Notification.ExporterId.HasValue;
            progress.HasProducer              = progressResult.Producers.Any(p => p.Id.HasValue);
            progress.HasSiteOfExport          = progressResult.Producers.Any(p => p.IsSiteOfExport.GetValueOrDefault());
            progress.HasImporter              = progressResult.Notification.ImporterId.HasValue;
            progress.HasFacility              = progressResult.Facilities.Any(f => f.Id.HasValue);
            progress.HasActualSiteOfTreatment = progressResult.Facilities.Any(f => f.IsActualSiteOfTreatment.GetValueOrDefault());

            return(progress.HasExporter &&
                   progress.HasProducer &&
                   progress.HasSiteOfExport &&
                   progress.HasImporter &&
                   progress.HasFacility &&
                   progress.HasActualSiteOfTreatment);
        }
        private bool MapProgressForRecoveryOperation(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasPreconsentedInformation = progressResult.Notification.NotificationType == NotificationType.Disposal
                || progressResult.Notification.IsPreconsentedRecoveryFacility.HasValue;
            progress.HasOperationCodes = progressResult.Notification.OperationCodesId.HasValue;
            progress.HasTechnologyEmployed = progressResult.Notification.TechnologyEmployedId.HasValue;
            progress.HasReasonForExport = !string.IsNullOrWhiteSpace(progressResult.Notification.ReasonForExport);

            return progress.HasPreconsentedInformation
                && progress.HasOperationCodes
                && progress.HasTechnologyEmployed
                && progress.HasReasonForExport;
        }
        private bool MapProgressForOrganisationsInvolved(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasExporter = progressResult.Notification.ExporterId.HasValue;
            progress.HasProducer = progressResult.Producers.Any(p => p.Id.HasValue);
            progress.HasSiteOfExport = progressResult.Producers.Any(p => p.IsSiteOfExport.GetValueOrDefault());
            progress.HasImporter = progressResult.Notification.ImporterId.HasValue;
            progress.HasFacility = progressResult.Facilities.Any(f => f.Id.HasValue);
            progress.HasActualSiteOfTreatment = progressResult.Facilities.Any(f => f.IsActualSiteOfTreatment.GetValueOrDefault());

            return progress.HasExporter
                && progress.HasProducer
                && progress.HasSiteOfExport
                && progress.HasImporter
                && progress.HasFacility
                && progress.HasActualSiteOfTreatment;
        }
        private bool MapProgressForRecoveryOperation(NotificationApplicationCompletionProgress progress, NotificationProgressResult progressResult)
        {
            progress.HasPreconsentedInformation = progressResult.Notification.NotificationType == NotificationType.Disposal ||
                                                  progressResult.Notification.IsPreconsentedRecoveryFacility.HasValue;
            progress.HasOperationCodes     = progressResult.Notification.OperationCodesId.HasValue;
            progress.HasTechnologyEmployed = progressResult.Notification.TechnologyEmployedId.HasValue;
            progress.HasReasonForExport    = !string.IsNullOrWhiteSpace(progressResult.Notification.ReasonForExport);

            return(progress.HasPreconsentedInformation &&
                   progress.HasOperationCodes &&
                   progress.HasTechnologyEmployed &&
                   progress.HasReasonForExport);
        }