Exemple #1
0
        private double CalculateTOTALSumWithDiscount(TotalDiscountType DiscountType,
                                                     double DiscountValue,
                                                     double TotalPrice,
                                                     int OptionalPercentageDiscountValue)
        {
            switch (DiscountType)
            {
            case TotalDiscountType.NO_DISCOUNT:
                break;

            case TotalDiscountType.VALUE_DISCOUNT:
                return(TotalPrice - DiscountValue);

            case TotalDiscountType.PERCENTAGE_DISCOUNT:
                return(TotalPrice * (DiscountValue / 100));

            case TotalDiscountType.VALUE_COAT:
                return(TotalPrice + DiscountValue);

            case TotalDiscountType.PERCENTAGE_COAT:
                return(TotalPrice * (1 + (DiscountValue / 100)));

            default:
                break;
            }
            return(OptionalPercentageDiscountValue == 0 ? TotalPrice : TotalPrice *(100 / OptionalPercentageDiscountValue));
        }
Exemple #2
0
        private double ConvertDiscountToPercentage(TotalDiscountType DiscountType,
                                                   double DiscountValue,
                                                   double TotalPrice,
                                                   int OptionalPercentageDiscountValue)
        {
            var discountPercentageValue = CalculateTOTALSumWithDiscount(DiscountType, DiscountValue, TotalPrice, OptionalPercentageDiscountValue) / TotalPrice;

            return(Math.Round(discountPercentageValue, 2));
        }
Exemple #3
0
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state = fiscalPrinterState as FiscalPrinterState;

            if (!state.IsInTransactionState)
            {
                throw new FP_IllegalOperationException("Fiscal Printer is not in transaction state.");
            }

            if (!command.PnArguments.Any())
            {
                throw new FP_WrongNumberOfArgumentsException("This command required at least one argument.");
            }
            else if (command.PnArguments.ElementAt(0) == "0")
            {
                return(CancelTransactionHandle(state));
            }

            int               optionalTotalDiscountPercentage = 0;
            int               ammountOfAdditionalLines        = 0;
            double            passedTotalAmmount          = 0;
            double            passedPaidValue             = 0;
            double            discountValueForTransaction = 0;
            TotalDiscountType discountType = TotalDiscountType.NO_DISCOUNT;
            double            totalAmmountWithoutDiscounts = state.SlipLines.Sum(m => m.TotalWithDiscount);

            if (command.PnArguments.Count() < 2 || command.PnArguments.Count() == 3 || command.PnArguments.Count() == 5 || command.PnArguments.Count() > 6)
            {
                throw new FP_WrongNumberOfArgumentsException("Transaction approval requires at least 2 arguments.");
            }
            else
            {
                if (!int.TryParse(command.PnArguments.ElementAt(1), out optionalTotalDiscountPercentage))
                {
                    throw new FP_BadFormatOfArgumentException("Percent of total discount must be a number between 0 and 99");
                }

                if (command.PnArguments.Count() >= 4)
                {
                    if (!int.TryParse(command.PnArguments.ElementAt(2), out ammountOfAdditionalLines) ||
                        ammountOfAdditionalLines < 0 || ammountOfAdditionalLines > 3)
                    {
                        throw new FP_BadFormatOfArgumentException("Number of additional lines must be a number between 0 and 3.");
                    }

                    if (command.PnArguments.Count() == 6)
                    {
                        if (!Enum.TryParse <TotalDiscountType>(command.PnArguments.ElementAt(4), out discountType))
                        {
                            throw new FP_BadFormatOfArgumentException("Invaild type of discount declared.");
                        }
                    }
                }

                var parametersMatch = new Regex(@"(\w{3})\r((.*\r){0,3})(([\d\.\,]+)\/)(([\d\.\,]+)\/)(([\d\.\,]+)\/)*").Match(command.Parameters);
                if (!parametersMatch.Success)
                {
                    throw new FP_WrongNumberOfArgumentsException("Command code is not ok. Please check it out and try again.");
                }
                if (!parametersMatch.Groups[1].Success)
                {
                    throw new FP_BadFormatOfArgumentException("Parameter \"code\" is in wrong formatting. It must have 3 characters.");
                }
                else if (string.IsNullOrWhiteSpace(state.CashierLogin) || string.IsNullOrWhiteSpace(state.PrinterCode))
                {
                    var passedParameterCode = parametersMatch.Groups[1].Value;
                    state.PrinterCode  = passedParameterCode.Substring(0, 1);
                    state.CashierLogin = passedParameterCode.Substring(1);
                }

                var additionalLines = !parametersMatch.Groups[2].Success ?
                                      new string[0]
                                        : parametersMatch.Groups[2].Value
                                      .Split((char)Constants.ASCICodeCR)
                                      .Where(m => !string.IsNullOrWhiteSpace(m))
                                      .ToArray();
                if (ammountOfAdditionalLines != additionalLines.Length)
                {
                    throw new FP_IllegalOperationException("Passed additional lines argument and passed lines are not equal.");
                }

                if (!double.TryParse(parametersMatch.Groups[5].Value, out passedPaidValue))
                {
                    throw new FP_BadFormatOfArgumentException("Bad formatting of PAID value.");
                }
                else
                {
                    passedTotalAmmount = Math.Round(passedPaidValue, 2);
                }

                if (!double.TryParse(parametersMatch.Groups[7].Value, out passedTotalAmmount))
                {
                    throw new FP_BadFormatOfArgumentException("Bad formatting of TOTAL value.");
                }
                else
                {
                    passedTotalAmmount = Math.Round(passedTotalAmmount, 2);
                }


                if ((discountType != TotalDiscountType.NO_DISCOUNT && discountValueForTransaction != 0) || optionalTotalDiscountPercentage != 0)
                {
                    var totalPriceWithDiscount = CalculateTOTALSumWithDiscount(discountType,
                                                                               discountValueForTransaction,
                                                                               totalAmmountWithoutDiscounts,
                                                                               optionalTotalDiscountPercentage);

                    if (Math.Round(totalPriceWithDiscount, 2) != passedTotalAmmount)
                    {
                        throw new FP_IllegalOperationException("Wrong passed TOTAL value. It not equals with passed fiscal printer line and total discount.");
                    }
                }



                if (command.PnArguments.Count() == 6 &&
                    discountType != TotalDiscountType.NO_DISCOUNT &&
                    !double.TryParse(parametersMatch.Groups[9].Value, out discountValueForTransaction))
                {
                    throw new FP_BadFormatOfArgumentException("Bad formatting of DISCOUNT value.");
                }


                StringBuilder approveTransactionBuilder = new StringBuilder();
                approveTransactionBuilder.AppendLine("".PadRight(Constants.ReciptWidth, '-'));
                if (discountType != TotalDiscountType.NO_DISCOUNT)
                {
                    var subTotalLineRight       = $"{totalAmmountWithoutDiscounts.ToString("0.00")} ";
                    var totalDiscountValueInPLN = Math.Round(totalAmmountWithoutDiscounts - passedTotalAmmount, 2);
                    var discountDescriptionText = totalDiscountValueInPLN < 0 ? "narzut" : "rabat";

                    var discountValue = Math.Abs(totalDiscountValueInPLN).ToString("0.00") + " ";

                    approveTransactionBuilder.AppendLine("Podsuma".PadRight(Constants.ReciptWidth - subTotalLineRight.Length) + subTotalLineRight);
                    approveTransactionBuilder.AppendLine($"    {discountDescriptionText}".PadRight(Constants.ReciptWidth - discountValue.Length) + discountValue);
                }

                var discountPercentage = ConvertDiscountToPercentage(discountType, discountValueForTransaction, totalAmmountWithoutDiscounts, optionalTotalDiscountPercentage);

                var ptuActualValues = state.PTURates
                                      .Where(m => m.ActualPercentageValue < 100)
                                      .ToDictionary(m => m.Type, m => m.ActualPercentageValue);

                var PTUsOverview = state.SlipLines
                                   .GroupBy(m => m.PTU)
                                   .Select(m => new
                {
                    type          = m.Key,
                    sum           = m.Sum(slip => slip.TotalWithDiscount) * discountPercentage,
                    ptuPercentage = ptuActualValues[m.Key],
                    ptuVal        =
                        ((m.Sum(slip => slip.TotalWithDiscount) * discountPercentage) * (ptuActualValues[m.Key] / 100))
                        /
                        (1 + (ptuActualValues[m.Key] / 100))
                });

                foreach (var ptuOVerview in PTUsOverview)
                {
                    var totalInPTU         = ptuOVerview.sum.ToString("0.00") + " ";
                    var totalInPTULeftLine = $"Sprzed. opodatk. {ptuOVerview.type.ToString()}"
                                             .PadRight(Constants.ReciptWidth - totalInPTU.Length);
                    var totalPTUVal         = ptuOVerview.ptuVal.ToString("0.00") + " ";
                    var totalPTUValLeftLine = $"Kwota PTU {ptuOVerview.type.ToString()} {ptuOVerview.ptuPercentage} %"
                                              .PadRight(Constants.ReciptWidth - totalPTUVal.Length);


                    approveTransactionBuilder.AppendLine(totalInPTULeftLine + totalInPTU);
                    approveTransactionBuilder.AppendLine(totalPTUValLeftLine + totalPTUVal);
                }
                var totalPTUsValue = PTUsOverview.Sum(m => m.ptuVal).ToString("0.00") + " ";
                approveTransactionBuilder.AppendLine("ŁĄCZNA KWOTA PTU".PadRight(Constants.ReciptWidth - totalPTUsValue.Length) + totalPTUsValue);

                var totalSumArray = passedTotalAmmount.ToString("0.00").ToArray();
                var totalSum      = string.Join(" ", totalSumArray) + " ";
                approveTransactionBuilder.AppendLine("S U M A".PadRight(Constants.ReciptWidth - totalSum.Length) + totalSum);

                approveTransactionBuilder.AppendLine("".PadRight(Constants.ReciptWidth, '-'));

                if (passedPaidValue > passedTotalAmmount)
                {
                    var paidValue = passedPaidValue.ToString("0.00");
                    approveTransactionBuilder.AppendLine("Gotówka".PadRight(Constants.ReciptWidth - totalSum.Length) + totalSum);

                    var changeValue = (passedPaidValue - passedTotalAmmount).ToString("0.00");
                    approveTransactionBuilder.AppendLine("Reszta".PadRight(Constants.ReciptWidth - changeValue.Length) + changeValue);
                }

                var printId         = new Random().Next(0, 9999).ToString("0000");
                var footerLeftLine  = $"{printId} #Kasa: {state.PrinterCode}  Kasjer: {state.CashierLogin}";
                var transactionTime = DateTime.Now.AddMinutes(state.TimeDiffrenceInMinutes).ToString("HH:mm");
                approveTransactionBuilder.AppendLine(footerLeftLine.PadRight(Constants.ReciptWidth - transactionTime.Length) + transactionTime);

                var fiscalIdAndLogo = "{PL} ABC " + new Random().Next(10000000, 99999999);
                approveTransactionBuilder.AppendLine(fiscalIdAndLogo.PadCenter(Constants.ReciptWidth));
                approveTransactionBuilder.AppendLine();

                foreach (var additionalLine in additionalLines)
                {
                    approveTransactionBuilder.AppendLine(additionalLine.PadCenter(Constants.ReciptWidth));
                }

                state.IsInTransactionState = false;

                return(new CommandHandlerResponse(approveTransactionBuilder.ToString()));
            }
        }