Abstrakt klasse for forretningskvitteringer.
Inheritance: Kvittering
        /// <summary>
        ///     Bekreft mottak av <see cref="Forretningskvittering" /> mottatt gjennom
        ///     <see cref="HentKvittering(Kvitteringsforespørsel)" />.
        ///     <list type="bullet">
        ///         <listheader>
        ///             <description>
        ///                 <para>Dette legger opp til følgende arbeidsflyt:</para>
        ///             </description>
        ///         </listheader>
        ///         <item>
        ///             <description>
        ///                 <para>
        ///                     <see cref="HentKvittering(Kvitteringsforespørsel)" />.
        ///                 </para>
        ///             </description>
        ///         </item>
        ///         <item>
        ///             <description>
        ///                 <para>Gjør intern prosessering av <see cref="Kvittering">Kvitteringen</see>.</para>
        ///             </description>
        ///         </item>
        ///         <item>
        ///             <description>
        ///                 <para><see cref="BekreftAsync">Bekreft</see> mottak av <see cref="Forretningskvittering" />.</para>
        ///             </description>
        ///         </item>
        ///     </list>
        /// </summary>
        /// <param name="kvittering"></param>
        /// <remarks>
        ///     <see cref="HentKvittering(Kvitteringsforespørsel)" /> kommer ikke til å returnere en ny kvittering før mottak av
        ///     den forrige er bekreftet.
        /// </remarks>
        public async Task BekreftAsync(Forretningskvittering kvittering)
        {
            var envelopeSettings = new EnvelopeSettings(kvittering, Databehandler, new GuidUtility());
            var bekreftKvitteringEnvelope = new KvitteringsbekreftelseEnvelope(envelopeSettings);

            ValidateEnvelopeAndThrowIfInvalid(bekreftKvitteringEnvelope, bekreftKvitteringEnvelope.GetType().Name);

            await RequestHelper.ConfirmReceipt(bekreftKvitteringEnvelope).ConfigureAwait(false);
            Log.Debug($"Bekreftet kvittering, conversationId '{kvittering.KonversasjonsId}'");
        }
        /// <summary>
        ///     Forespør <see cref="Kvittering" /> for <see cref="Forsendelse">Forsendelser</see>, med mulighet til å samtidig
        ///     <see cref="BekreftAsync">bekrefte</see> på forrige <see cref="Kvittering" /> for å slippe å
        ///     kjøre eget kall for <see cref="BekreftAsync" />. <see cref="Kvittering">Kvitteringer</see> blir tilgjengeliggjort
        ///     etterhvert som de er klare i Meldingsformidler. Det er ikke mulig å etterspørre
        ///     <see cref="Kvittering" /> for en spesifikk forsendelse.
        /// </summary>
        /// <param name="kvitteringsforespørsel"></param>
        /// <param name="forrigeKvittering"></param>
        /// <returns></returns>
        /// <remarks>
        ///     <list type="table">
        ///         <listheader>
        ///             <description>
        ///                 Dersom det ikke er tilgjengelige <see cref="Kvittering">Kvitteringer</see> skal det ventes følgende
        ///                 tidsintervaller før en ny forespørsel gjøres:
        ///             </description>
        ///         </listheader>
        ///         <item>
        ///             <term>normal</term><description>Minimum 10 minutter</description>
        ///         </item>
        ///         <item>
        ///             <term>prioritert</term><description>Minimum 1 minutt</description>
        ///         </item>
        ///     </list>
        /// </remarks>
        public async Task<Kvittering> HentKvitteringOgBekreftForrigeAsync(Kvitteringsforespørsel kvitteringsforespørsel, Forretningskvittering forrigeKvittering)
        {
            if (forrigeKvittering != null)
            {
                await BekreftAsync(forrigeKvittering).ConfigureAwait(false);
            }

            var guidUtility = new GuidUtility();

            Log.Debug($"Utgående kvitteringsforespørsel, messageId '{guidUtility.MessageId}'.");

            var envelopeSettings = new EnvelopeSettings(kvitteringsforespørsel, Databehandler, guidUtility);
            var kvitteringsforespørselEnvelope = new KvitteringsforespørselEnvelope(envelopeSettings);

            ValidateEnvelopeAndThrowIfInvalid(kvitteringsforespørselEnvelope, kvitteringsforespørselEnvelope.GetType().Name);

            var receipt = await RequestHelper.GetReceipt(kvitteringsforespørselEnvelope).ConfigureAwait(false);
            var transportReceiptXml = XmlUtility.TilXmlDokument(receipt.Rådata);

            if (receipt is TomKøKvittering)
            {
                Log.Debug($"{receipt}");
                SecurityValidationOfEmptyQueueReceipt(transportReceiptXml, kvitteringsforespørselEnvelope.Xml());
            }
            else if (receipt is Forretningskvittering)
            {
                Log.Debug($"{receipt}");
                SecurityValidationOfMessageReceipt(transportReceiptXml, kvitteringsforespørselEnvelope);
            }

            return receipt;
        }
 /// <summary>
 ///     Bekreft mottak av <see cref="Forretningskvittering" /> mottatt gjennom
 ///     <see cref="HentKvittering(Kvitteringsforespørsel)" />.
 ///     <list type="bullet">
 ///         <listheader>
 ///             <description>
 ///                 <para>Dette legger opp til følgende arbeidsflyt:</para>
 ///             </description>
 ///         </listheader>
 ///         <item>
 ///             <description>
 ///                 <para>
 ///                     <see cref="HentKvittering(Kvitteringsforespørsel)" />.
 ///                 </para>
 ///             </description>
 ///         </item>
 ///         <item>
 ///             <description>
 ///                 <para>Gjør intern prosessering av <see cref="Kvittering">Kvitteringen</see>.</para>
 ///             </description>
 ///         </item>
 ///         <item>
 ///             <description>
 ///                 <para><see cref="Bekreft">Bekreft</see> mottak av <see cref="Forretningskvittering" />.</para>
 ///             </description>
 ///         </item>
 ///     </list>
 /// </summary>
 /// <param name="kvittering"></param>
 /// <remarks>
 ///     <see cref="HentKvittering(Kvitteringsforespørsel)" /> kommer ikke til å returnere en ny kvittering før mottak av
 ///     den forrige er bekreftet.
 /// </remarks>
 public void Bekreft(Forretningskvittering kvittering)
 {
     BekreftAsync(kvittering).Wait();
 }
 /// <summary>
 ///     Settings for BekreftKvittering
 /// </summary>
 public EnvelopeSettings(Forretningskvittering forrigeKvittering, Databehandler databehandler, GuidUtility guidUtility)
 {
     ForrigeKvittering = forrigeKvittering;
     Databehandler = databehandler;
     GuidUtility = guidUtility;
 }
 /// <summary>
 ///     Forespør <see cref="Kvittering" /> for <see cref="Forsendelse">Forsendelser</see>, med mulighet til å samtidig
 ///     <see cref="Bekreft">bekrefte</see> på forrige <see cref="Kvittering" /> for å slippe å
 ///     kjøre eget kall for <see cref="Bekreft" />. <see cref="Kvittering">Kvitteringer</see> blir tilgjengeliggjort
 ///     etterhvert som de er klare i Meldingsformidler. Det er ikke mulig å etterspørre
 ///     <see cref="Kvittering" /> for en spesifikk forsendelse.
 /// </summary>
 /// <param name="kvitteringsforespørsel"></param>
 /// <param name="forrigeKvittering"></param>
 /// <returns></returns>
 /// <remarks>
 ///     <list type="table">
 ///         <listheader>
 ///             <description>
 ///                 Dersom det ikke er tilgjengelige <see cref="Kvittering">Kvitteringer</see> skal det ventes følgende
 ///                 tidsintervaller før en ny forespørsel gjøres:
 ///             </description>
 ///         </listheader>
 ///         <item>
 ///             <term>normal</term><description>Minimum 10 minutter</description>
 ///         </item>
 ///         <item>
 ///             <term>prioritert</term><description>Minimum 1 minutt</description>
 ///         </item>
 ///     </list>
 /// </remarks>
 public Kvittering HentKvitteringOgBekreftForrige(Kvitteringsforespørsel kvitteringsforespørsel,
     Forretningskvittering forrigeKvittering)
 {
     return HentKvitteringOgBekreftForrigeAsync(kvitteringsforespørsel, forrigeKvittering).Result;
 }
 private void Logg(TraceEventType viktighet, Guid konversasjonsId, Forretningskvittering kvittering, bool datoPrefiks, bool isXml, params string[] filsti)
 {
     var fileSuffix = isXml ? ".xml" : ".txt";
     Logg(viktighet,konversasjonsId,kvittering.Rådata, datoPrefiks, isXml,"Mottatt - " + kvittering.GetType().Name + fileSuffix);
 }
        /// <summary>
        /// Bekreft mottak av forretningskvittering gjennom <see cref="HentKvittering(Kvitteringsforespørsel)"/>.
        /// <list type="bullet">
        /// <listheader><description><para>Dette legger opp til følgende arbeidsflyt</para></description></listheader>
        /// <item><description><para><see cref="HentKvittering(Kvitteringsforespørsel)"/></para></description></item>
        /// <item><description><para>Gjør intern prosessering av kvitteringen (lagre til database, og så videre)</para></description></item>
        /// <item><description><para>Bekreft mottak av kvittering</para></description></item>
        /// </list>
        /// </summary>
        /// <param name="forrigeKvittering"></param>
        /// <remarks>
        /// <see cref="HentKvittering(Kvitteringsforespørsel)"/> kommer ikke til å returnere en ny kvittering før mottak av den forrige er bekreftet.
        /// </remarks>
        public async Task BekreftAsync(Forretningskvittering forrigeKvittering)
        {
            Logging.Log(TraceEventType.Information, forrigeKvittering.KonversasjonsId, "Bekrefter forrige kvittering.");

            var envelopeSettings = new EnvelopeSettings(forrigeKvittering, _databehandler, new GuidUtility());
            var kvitteringMottattEnvelope = new KvitteringsbekreftelseEnvelope(envelopeSettings);

            string filnavn = forrigeKvittering.GetType().Name + ".xml";
            Logg(TraceEventType.Verbose, forrigeKvittering.KonversasjonsId, forrigeKvittering, true, true, filnavn);
            
            try
            {
                var kvitteringMottattEnvelopeValidering = new KvitteringMottattEnvelopeValidator();
                var kvitteringMottattEnvelopeValidert = kvitteringMottattEnvelopeValidering.ValiderDokumentMotXsd(kvitteringMottattEnvelope.Xml().OuterXml);
                if (!kvitteringMottattEnvelopeValidert)
                    throw new Exception(kvitteringMottattEnvelopeValidering.ValideringsVarsler);
            }
            catch (Exception e)
            {
                throw new XmlValidationException("Kvitteringsbekreftelse validerer ikke:" + e.Message);
            }


            var soapContainer = new SoapContainer(kvitteringMottattEnvelope);
            await SendSoapContainer(soapContainer);
        }
 /// <summary>
 /// Bekreft mottak av forretningskvittering gjennom <see cref="HentKvittering(Kvitteringsforespørsel)"/>.
 /// <list type="bullet">
 /// <listheader><description><para>Dette legger opp til følgende arbeidsflyt</para></description></listheader>
 /// <item><description><para><see cref="HentKvittering(Kvitteringsforespørsel)"/></para></description></item>
 /// <item><description><para>Gjør intern prosessering av kvitteringen (lagre til database, og så videre)</para></description></item>
 /// <item><description><para>Bekreft mottak av kvittering</para></description></item>
 /// </list>
 /// </summary>
 /// <param name="forrigeKvittering"></param>
 /// <remarks>
 /// <see cref="HentKvittering(Kvitteringsforespørsel)"/> kommer ikke til å returnere en ny kvittering før mottak av den forrige er bekreftet.
 /// </remarks>
 public void Bekreft(Forretningskvittering forrigeKvittering)
 {
     BekreftAsync(forrigeKvittering);
 }
        /// <summary>
        /// Forespør kvittering for forsendelser med mulighet til å samtidig bekrefte på forrige kvittering for å slippe å kjøre eget kall for bekreft. 
        /// Kvitteringer blir tilgjengeliggjort etterhvert som de er klare i meldingsformidler. Det er ikke mulig å etterspørre kvittering for en 
        /// spesifikk forsendelse. 
        /// </summary>
        /// <param name="kvitteringsforespørsel"></param>
        /// <param name="forrigeKvittering"></param>
        /// <returns></returns>
        /// <remarks>
        /// <list type="table">
        /// <listheader><description>Dersom det ikke er tilgjengelige kvitteringer skal det ventes følgende tidsintervaller før en ny forespørsel gjøres</description></listheader>
        /// <item><term>normal</term><description>Minimum 10 minutter</description></item>
        /// <item><term>prioritert</term><description>Minimum 1 minutt</description></item>
        /// </list>
        /// </remarks>
        public async Task<Kvittering> HentKvitteringOgBekreftForrigeAsync(Kvitteringsforespørsel kvitteringsforespørsel, Forretningskvittering forrigeKvittering)
        {
            if (forrigeKvittering != null)
            {
                Bekreft(forrigeKvittering);
            }

            Logging.Log(TraceEventType.Information, "Henter kvittering for " + kvitteringsforespørsel.Mpc);

            var guidHandler = new GuidUtility();
            var envelopeSettings = new EnvelopeSettings(kvitteringsforespørsel, _databehandler, guidHandler);
            var kvitteringsenvelope = new KvitteringsforespørselEnvelope(envelopeSettings);

            Logging.Log(TraceEventType.Verbose, "Envelope for kvitteringsforespørsel" + Environment.NewLine + kvitteringsenvelope.Xml().OuterXml);

            ValiderKvitteringsEnvelope(kvitteringsenvelope);

            var soapContainer = new SoapContainer(kvitteringsenvelope);
            var kvittering = await SendSoapContainer(soapContainer);

            Logg(TraceEventType.Verbose, Guid.Empty , kvitteringsenvelope.Xml().OuterXml, true, true, "Sendt - Kvitteringsenvelope.xml");

            try
            {
                var valideringAvResponsSignatur = new Responsvalidator(kvittering, kvitteringsenvelope.Xml());
                valideringAvResponsSignatur.ValiderHeaderSignatur();
                valideringAvResponsSignatur.ValiderKvitteringSignatur();
            }
            catch (Exception e)
            {
                return ValiderTransportkvittering(kvittering,kvitteringsenvelope.Xml(),guidHandler);
            }

            return KvitteringFactory.GetForretningskvittering(kvittering);
        }
        public SmokeTestsHelper Fetch_Receipt()
        {
            Assert_state(_transportkvittering);

            const int maxTries = 10;
            var kvitteringReceived = false;
            var numberOfTries = 0;

            while (!kvitteringReceived && (numberOfTries++ <= maxTries))
            {
                var kvittering = GetSingleKvittering();

                if (kvittering is TomKøKvittering)
                {
                    continue;
                }

                kvitteringReceived = true;
                _forretningskvittering = (Forretningskvittering) kvittering;
            }

            Assert.True(kvitteringReceived, "Fikk ikke til å hente kvittering. Var du for rask å hente, eller har noe skjedd galt med hvilken kø du henter fra?");

            return this;
        }