Esempio n. 1
0
        private async Task <FundsResponseResult> DigestResponseItemAsync(
            FundsResponseFile file,
            FundsResponseFileItem item,
            FundsTransferRequest fundsTransferRequest,
            FundsTransferBatchMessage responseBatchMessage,
            SO statefulObject,
            State stateAfterRequest)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }
            if (fundsTransferRequest == null)
            {
                throw new ArgumentNullException(nameof(fundsTransferRequest));
            }

            var line = new FundsResponseLine(file, item, responseBatchMessage.ID);

            return(await DigestResponseLineAsync(fundsTransferRequest, line, statefulObject, stateAfterRequest));
        }
        /// <summary>
        /// Digest a funds response file by feeding it to all <see cref="FundsTransferManagers"/>
        /// for digestion and combining results.
        /// The existence of the credit system and
        /// the collation specified in <paramref name="file"/> is assumed.
        /// </summary>
        /// <param name="file">The file to digest.</param>
        /// <param name="responseBatchMessage">The batch message where the generated funds transfer events will be assigned.</param>
        /// <returns>
        /// Returns a collection of results describing the execution outcome of the
        /// contents of the <paramref name="file"/> or an empty collection if the file is not relevant to this manager.
        /// </returns>
        protected internal override async Task <IReadOnlyCollection <FundsResponseResult> > DigestResponseFileAsync(
            FundsResponseFile file,
            FundsTransferBatchMessage responseBatchMessage)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }
            if (responseBatchMessage == null)
            {
                throw new ArgumentNullException(nameof(responseBatchMessage));
            }

            var fundsResponseResults = Enumerable.Empty <FundsResponseResult>();

            foreach (var manager in this.FundsTransferManagers)
            {
                var managerResults = await manager.DigestResponseFileAsync(file, responseBatchMessage);

                await manager.PostProcessLinesAsync(file.BatchID, managerResults, responseBatchMessage.ID);

                fundsResponseResults = fundsResponseResults.Concat(managerResults);
            }

            return(fundsResponseResults.ToArray());
        }
Esempio n. 3
0
        /// <summary>
        /// Digest a funds transfer response file from a credit system
        /// and execute the appropriate state paths
        /// as specified by the <see cref="TrySpecifyNextStatePath(SO, State, FundsResponseLine)"/> method
        /// on the corresponding stateful objects.
        /// The existence of the credit system and
        /// the collation specified in <paramref name="file"/> is assumed.
        /// </summary>
        /// <param name="file">The file to digest.</param>
        /// <param name="responseBatchMessage">The batch message where the generated funds transfer events will be assigned.</param>
        /// <returns>
        /// Returns a collection of results describing the execution outcome of the
        /// contents of the <paramref name="file"/> or an empty collection if the file is not relevant to this manager.
        /// </returns>
        /// <remarks>
        /// Each action in paths being executed will receive an arguments dictionary
        /// containing at least the key <see cref="StandardArgumentKeys.BillingItem"/> set with value
        /// of type <see cref="FundsResponseLine"/>.
        /// </remarks>
        protected internal override async Task <IReadOnlyCollection <FundsResponseResult> > DigestResponseFileAsync(
            FundsResponseFile file,
            FundsTransferBatchMessage responseBatchMessage)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            long[] lineIDs = file.Items.Select(i => i.LineID).ToArray();

            var fundsTransferEventAssociations = this.FundsTransferEventAssociations;

            var stateHolders = from a in fundsTransferEventAssociations
                               where a != null
                               select a.StateHolder;

            await EagerFetchStateHoldersAsync(stateHolders);

            var associationsQuery = from a in fundsTransferEventAssociations
                                    where a.Event.Type == FundsTransferEventType.Pending
                                    let ftr = a.Event.Request
                                              where lineIDs.Contains(ftr.GroupID) && ftr.BatchID == file.BatchID
                                              select new
            {
                Request = ftr,
                ftr.Events,
                ftr.MainAccount,
                ftr.TransferAccount,
                a.StateHolder,
                a.CurrentState,
                StateAfterRequest = a.StateTransition != null ? a.StateTransition.Path.NextState : null
            };

            var associations = await associationsQuery.ToArrayAsync();

            if (associations.Length == 0)
            {
                return(emptyFundsResponseResults);
            }

            var responseResults = new List <FundsResponseResult>(associations.Length);

            var itemsByLineID =
                file.Items
                .OrderBy(i => i.Time)
                .ToSequentialReadOnlyMultiDictionary(i => i.LineID);

            foreach (var association in associations)
            {
                foreach (var item in itemsByLineID[association.Request.GroupID])
                {
                    var statefulObject = GetStatefulObject(association.StateHolder);

                    var fundsResponseResult =
                        await DigestResponseItemAsync(
                            file,
                            item,
                            association.Request,
                            responseBatchMessage,
                            statefulObject,
                            association.StateAfterRequest);

                    responseResults.Add(fundsResponseResult);
                }
            }

            return(responseResults);
        }