Beispiel #1
0
        public CalculateResponse Calculate(CalculateRequest request)
        {
            JavaScriptSerializer serializer      = new JavaScriptSerializer();
            LogEntry             requestLogEntry = new LogEntry();

            requestLogEntry.Category = LogCategory.Information;
            requestLogEntry.Message  = serializer.Serialize(request);

            logUtility.Write(requestLogEntry);

            CalculateResponse response = new CalculateResponse();

            // Verifica se o request recebido é valido.
            if (request.IsValid == false)
            {
                response.ErrorReportCollection = request.ErrorReportCollection;
                return(response);
            }

            // Armazena o troco a ser retornado.
            ulong changeAmount = request.PaidAmount - request.ProductAmount;

            // Armazena o troco ainda não processado.
            ulong remainingAmount = changeAmount;

            List <ChangeData> changeDataCollection = new List <ChangeData>();

            while (remainingAmount > 0)
            {
                // Selecionar o processador adequado para o troco restante.
                IProcessor processor = ProcessorFactory.Create(remainingAmount);

                // Verifica se foi encontrado um processador para realizar o cálculo.
                if (processor == null)
                {
                    ErrorReport errorReport = new ErrorReport();
                    errorReport.FieldName = "ChangeAmount";
                    errorReport.Message   = "Unable to calculate the change amount.";

                    response.ErrorReportCollection.Add(errorReport);

                    break;
                }

                // Calcula o troco para o valor especificado.
                List <KeyValuePair <uint, ulong> > changeCollection = processor.Calculate(remainingAmount);

                ChangeData changeData = new ChangeData();
                changeData.MoneyDescription = processor.GetName();
                changeData.ChangeCollection = changeCollection;
                changeDataCollection.Add(changeData);

                ProcessorCompletedEventArgs eventArgs = new ProcessorCompletedEventArgs();
                eventArgs.CurrentChange = changeData;

                // Caso exista alguém escutando o evento, dispara a notificação.
                if (this.OnProcessorCompleted != null)
                {
                    this.OnProcessorCompleted(this, eventArgs);
                }

                IEnumerable <ulong> processedAmountCollection = changeCollection.Select(p => p.Key * p.Value);
                ulong processedAmount = 0;
                foreach (ulong amount in processedAmountCollection)
                {
                    processedAmount += amount;
                }

                remainingAmount -= processedAmount;
            }

            // Caso nenhum erro tenha sido encontrado, define success como true e informa o troco
            if (response.ErrorReportCollection.Any() == false)
            {
                response.Success = true;
                response.Change  = changeDataCollection;
            }


            LogEntry responseLogEntry = new LogEntry();

            responseLogEntry.Category = LogCategory.Information;
            responseLogEntry.Message  = serializer.Serialize(response);

            logUtility.Write(responseLogEntry);
            return(response);
        }