public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state        = fiscalPrinterState as FiscalPrinterState;
            var baseDLEValue = (byte)0x70;

            baseDLEValue += state.IsInOnlineMode ? (byte)0x04 : (byte)0x00;
            baseDLEValue += state.IsInOutOfPaperState ? (byte)0x02 : (byte)0x00;
            baseDLEValue += state.IsInInternalErrorState ? (byte)0x01 : (byte)0x00;

            var response = new OneByteFiscalPrinterCommand((byte)(baseDLEValue & 0xFF));

            return(new CommandHandlerResponse(response));
        }
예제 #2
0
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var  state = fiscalPrinterState as FiscalPrinterState;
            bool containsNotSupportedLength     = command.PnArguments.Any(m => m.Length < 1 || m.Length > 2);
            bool containsNoRightParameterLength = command.PnArguments.Count() != 6;

            int[] arguments;

            if (containsNotSupportedLength)
            {
                throw new FP_BadFormatOfArgumentException("Arguments must contains one or two digits.");
            }

            if (containsNoRightParameterLength)
            {
                throw new FP_WrongNumberOfArgumentsException("Required 6 parameters.");
            }

            try
            {
                arguments = command.PnArguments.Select(m => int.Parse(m)).ToArray();
            }
            catch
            {
                throw new FP_BadFormatOfArgumentException("Argument must contain numeric values.");
            }

            var actualDate       = state.TimeDiffrenceInMinutes == int.MinValue ? DateTime.Now : DateTime.Now.AddMinutes(state.TimeDiffrenceInMinutes);
            var passedDate       = new DateTime(2000 + arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
            var minutesDiffrence = Convert.ToInt32(Math.Round(passedDate.Subtract(actualDate).TotalMinutes));

            if ((minutesDiffrence > 60 || minutesDiffrence < -60) && state.IsInFiscalState)
            {
                throw new FP_IllegalOperationException("In Fiscal State change Date and Time is possible only.");
            }

            state.TimeDiffrenceInMinutes = minutesDiffrence;

            StringBuilder reciptBody          = new StringBuilder();
            string        actualDateFormatted = actualDate.ToString("yyyy-MM-dd,HH:mm");
            string        passedDateFormatted = passedDate.ToString("yyyy-MM-dd,HH:mm");

            reciptBody.AppendLine();
            reciptBody.AppendLine("PROGRAMOWANIE ZEGARA".PadCenter(Constants.ReciptWidth));
            reciptBody.AppendLine();
            reciptBody.AppendLine($"Zegar przed zmianą:".PadRight(Constants.ReciptWidth - actualDateFormatted.Length) + actualDateFormatted);
            reciptBody.AppendLine($"Zegar po zmianie:".PadRight(Constants.ReciptWidth - passedDateFormatted.Length) + passedDateFormatted);
            reciptBody.AppendLine();

            return(new CommandHandlerResponse(reciptBody.ToString()));
        }
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state       = fiscalPrinterState as FiscalPrinterState;
            var enqResponse = (byte)0x60;

            enqResponse += state.IsInFiscalState ? (byte)0x08 : (byte)0x00;
            enqResponse += state.LastCommandSuccess ? (byte)0x04 : (byte)0x00;
            enqResponse += state.IsInTransactionState ? (byte)0x02 : (byte)0x00;
            enqResponse += state.LastTransactionSuccess ? (byte)0x01 : (byte)0x00;

            var response = new OneByteFiscalPrinterCommand((byte)(enqResponse & 0xFF));

            return(new CommandHandlerResponse(response));
        }
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state = fiscalPrinterState as FiscalPrinterState;

            if (command.PnArguments.Count() != 1)
            {
                throw new FP_WrongNumberOfArgumentsException("Required one Pn Argument that describes type of error handling");
            }
            var errorHandlingTypeArgument = command.PnArguments.First();

            if (!int.TryParse(errorHandlingTypeArgument, out _) || !Enum.TryParse(errorHandlingTypeArgument, out ErrorHandlingType errorHandlingType))
            {
                throw new FP_IllegalOperationException("Error handling type argument must be numeric and be between 0 and 3");
            }

            state.ErrorHandlingType = errorHandlingType;

            return(new CommandHandlerResponse());
        }
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state = fiscalPrinterState as FiscalPrinterState;

            if (state.TimeDiffrenceInMinutes == int.MinValue)
            {
                throw new FiscalPrinterSimulatorLibraries.Exceptions.FP_IllegalOperationException("RTC not initialized.");
            }
            var actualRTCTime        = DateTime.Now.AddMinutes(state.TimeDiffrenceInMinutes);
            var arrayOfRTCParameters = new List <int> {
                actualRTCTime.Year,
                actualRTCTime.Month,
                actualRTCTime.Day,
                actualRTCTime.Hour,
                actualRTCTime.Minute,
                0
            };

            var commandParameters = string.Join(";", arrayOfRTCParameters);
            var outputCommand     = new ThermalFiscalPrinterCommand(new string[] { "1" }, "#C", commandParameters);

            return(new CommandHandlerResponse(outputCommand));
        }
예제 #6
0
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state = fiscalPrinterState as FiscalPrinterState;

            if (state.TimeDiffrenceInMinutes == int.MinValue)
            {
                throw new FP_IllegalOperationException("RTC clock not initialized.");
            }

            if (state.IsInTransactionState)
            {
                throw new FP_IllegalOperationException("Cannot handle this command in transaction state.");
            }

            var parameters = command.Parameters.Split((char)Constants.ASCICodeCR).Where(m => !string.IsNullOrWhiteSpace(m));

            if (parameters.Count() != 2)
            {
                throw new FP_WrongNumberOfArgumentsException("Expected two parameters to this command.");
            }

            var cashierLogin = parameters.ElementAt(0);

            if (cashierLogin.Length > 32)
            {
                throw new FP_BadFormatOfArgumentException("Cashier login must have maximum 32 characters.");
            }

            var printerCode = parameters.ElementAt(1);

            if (printerCode.Length > 8)
            {
                throw new FP_BadFormatOfArgumentException("Printer code must have maximum 8 characters.");
            }

            state.CashierLogin = cashierLogin;
            state.PrinterCode  = printerCode;

            StringBuilder reciptBuilder = new StringBuilder();

            reciptBuilder.AppendLine(state.FiscalPrinterHeader);
            var leftLineOfDate = DateTime.Now.AddMinutes(state.TimeDiffrenceInMinutes).ToString("yyyy-MM-dd");
            var printoutNumber = state.NextFiscalPrinterReciptId.ToString();

            reciptBuilder.AppendLine(leftLineOfDate.PadRight(Constants.ReciptWidth - printoutNumber.Length) + printoutNumber);
            reciptBuilder.AppendLine("N I E F I S K A L N Y".PadCenter(Constants.ReciptWidth));
            reciptBuilder.AppendLine("Rozpoczęcie pracy kasjera");
            reciptBuilder.AppendLine("Kasjer".PadRight(Constants.ReciptWidth - cashierLogin.Length) + cashierLogin);
            reciptBuilder.AppendLine("Numer kasy".PadRight(Constants.ReciptWidth - printerCode.Length) + printerCode);
            reciptBuilder.AppendLine();
            reciptBuilder.AppendLine("N I E F I S K A L N Y".PadCenter(Constants.ReciptWidth));
            var rightLineOfTime = DateTime.Now.AddMinutes(state.TimeDiffrenceInMinutes).ToString("HH-mm-ss");

            reciptBuilder.AppendLine($"    #{printerCode}     {cashierLogin}".PadRight(Constants.ReciptWidth - rightLineOfTime.Length) + rightLineOfTime);
            reciptBuilder.AppendLine("12345678".PadCenter(Constants.ReciptWidth));
            reciptBuilder.AppendLine();

            state.NextFiscalPrinterReciptId += 1;

            return(new CommandHandlerResponse(reciptBuilder.ToString()));
        }
예제 #7
0
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state = fiscalPrinterState as FiscalPrinterState;

            if (!command.PnArguments.Any())
            {
                throw new FP_WrongNumberOfArgumentsException("There is no arguments");
            }
            var firstArgument = command.PnArguments.ElementAt(0);

            if (firstArgument == "0" || firstArgument == "1")
            {
                if (state.TimeDiffrenceInMinutes == int.MinValue)
                {
                    throw new FP_IllegalOperationException("Timer RTC not initialized.");
                }
                Enum.TryParse(firstArgument, out DiscountCalculationMethod discountType);
                state.DiscountCalculationType = discountType;
                return(new CommandHandlerResponse());
            }
            else if (command.PnArguments.Count() >= 2)
            {
                var secondArgument = command.PnArguments.ElementAt(1);
                if (secondArgument != "0" || secondArgument != "1")
                {
                    throw new FP_BadFormatOfArgumentException("Second argument must be a bit type (0 or 1 value)");
                }
                if (firstArgument == "3")
                {
                    //TODO: Save value to state ?
                    // var papperSaveFunctionIsOn = secondArgument == "1";
                }
                else if (firstArgument == "4")
                {
                    //TODO: Save value to state ?
                    // var showTransactionOnClientDisplay = secondArgument == "1";
                }
                else if (firstArgument == "6")
                {
                    //TODO: Save value to state ?
                    // var KnifeHightUpper = secondArgument == "1";
                }
                else if (command.PnArguments.Count() == 3 && firstArgument == "5")
                {
                    var thirdArgument = command.PnArguments.ElementAt(2);
                    if (secondArgument == "0")
                    {
                        if (!Enum.TryParse <BacklightOption>(thirdArgument, out _))
                        {
                            throw new FP_BadFormatOfArgumentException("Backlight option support only [0,1,2] arguments");
                        }
                        //TODO: Save value to state ?
                    }
                    if (secondArgument == "1")
                    {
                        if (!int.TryParse(thirdArgument, out int backlightBrightness) || backlightBrightness < 0 || backlightBrightness > 15)
                        {
                            throw new FP_BadFormatOfArgumentException("Backlight brightness must have value between 0 and 15");
                        }
                        //TODO: Save value to state ?
                    }
                    if (secondArgument == "2")
                    {
                        if (!int.TryParse(thirdArgument, out int contrastValue) || contrastValue < 0 || contrastValue > 31)
                        {
                            throw new FP_BadFormatOfArgumentException("Contrast must have value between 0 and 31");
                        }
                        //TODO: Save value to state ?
                    }
                }
            }

            throw new FP_BadFormatOfArgumentException("Cannot resolve this command. Bad first command argument");
        }
 public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState) =>
 new CommandHandlerResponse(
     new ThermalFiscalPrinterCommand(new string[] { "1" }, "#v", $"{Constants.ProtocolName}/{Constants.ProtocolVersion}")
     );
예제 #9
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()));
            }
        }
예제 #10
0
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state = fiscalPrinterState as FiscalPrinterState;

            if (command.PnArguments is null || !command.PnArguments.Any())
            {
                throw new FP_WrongNumberOfArgumentsException("Arguments missing");
            }

            if (!int.TryParse(command.PnArguments.First(), out int numberOfRates))
            {
                throw new FP_BadFormatOfArgumentException("First argument is not in numeric format");
            }

            if (numberOfRates > state.PTURates.Count)
            {
                throw new FP_IllegalOperationException("Maximum of PTU Rates is 7.");
            }

            var ptuParameters = command.Parameters.Split('/').Where(m => !string.IsNullOrEmpty(m)).ToArray();

            if (ptuParameters.Length != numberOfRates)
            {
                throw new FP_WrongNumberOfArgumentsException("First argument not contain right number of PTU rates.");
            }



            StringBuilder sb = new StringBuilder();

            sb.AppendLine("N I E F I S K A L N Y".PadCenter(Constants.ReciptWidth));
            sb.AppendLine("Z m i a n a  s t a w e k  P T U".PadCenter(Constants.ReciptWidth));
            sb.AppendLine("Stare PTU:".PadRight(Constants.ReciptWidth));
            state.PTURates.ForEach(key =>
            {
                sb.AppendLine(PrintPTUValuesOnRecipt(key.Type, state));
            });
            sb.AppendLine("-".PadRight(Constants.ReciptWidth, '-'));

            ChangePTURatesByCommand(state, ptuParameters);

            sb.AppendLine("Nowe PTU:".PadRight(Constants.ReciptWidth));
            state.PTURates.ForEach(key =>
            {
                sb.AppendLine(PrintPTUValuesOnRecipt(key.Type, state));
            });
            sb.AppendLine("N I E F I S K A L N Y".PadCenter(Constants.ReciptWidth));

            var lastErrorCode        = "0";
            var fiscalState          = state.IsInFiscalState ? "1" : "0";
            var transactionState     = state.IsInTransactionState ? "1" : "0";
            var lastTransactionState = state.LastTransactionSuccess ? "1" : "0";

            var outputCommandArguments = new string[]
            {
                lastErrorCode,
                fiscalState,
                transactionState,
                lastTransactionState,
                "0",
                "1",
                DateTime.Now.Year.ToString().Substring(2, 2),
                DateTime.Now.Month.ToString(),
                DateTime.Now.Day.ToString()
            };

            var outputCommandParametersString =
                string.Join(";", outputCommandArguments) + "/" +
                string.Join("/", state.PTURates.Select(m => m.ActualPercentageValue)) + (state.NextFiscalPrinterReciptId - 1) + "/" +
                string.Join("/", state.PTURates.Select(m => m.TotalValueOfSalesInType)) + "/" + state.ActualDrawerAmmount + "ABC12345678";

            var outputCommand = new ThermalFiscalPrinterCommand(outputCommandArguments, "#X", outputCommandParametersString);


            return(new CommandHandlerResponse(outputCommand, sb.ToString()));
        }
        public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
        {
            var state = fiscalPrinterState as FiscalPrinterState;

            if (state.TimeDiffrenceInMinutes == int.MinValue)
            {
                throw new FP_IllegalOperationException("RTC clock is not set up. Please do this before any actions.");
            }
            if (!state.IsInTransactionState)
            {
                throw new FP_IllegalOperationException("Fiscal Printer is not in transaction state.");
            }

            var slipLine = new SlipLine();


            DiscountType        discountType        = DiscountType.NO_DISCOUNT;
            DiscountDescription discountDescription = DiscountDescription.NONE;

            string discountDescriptionText = "";
            string productDescription      = "";
            double discountValueAmmount    = 0;



            if (!command.PnArguments.Any())
            {
                throw new FP_WrongNumberOfArgumentsException("This command required at least one argument");
            }

            if (command.PnArguments.Count() >= 1)
            {
                if (!int.TryParse(command.PnArguments.ElementAt(0), out int lineNumber))
                {
                    throw new FP_BadFormatOfArgumentException("first argument must be a number");
                }
            }
            if (command.PnArguments.Count() >= 2)
            {
                if (!Enum.TryParse <DiscountType>(command.PnArguments.ElementAt(1), out discountType))
                {
                    throw new FP_BadFormatOfArgumentException("Unknkown Pr command argument");
                }
            }

            if (command.PnArguments.Count() >= 3)
            {
                if (!Enum.TryParse <DiscountDescription>(command.PnArguments.ElementAt(2), out discountDescription))
                {
                    throw new FP_BadFormatOfArgumentException("Unknkown Po command argument");
                }
            }

            if (command.PnArguments.Count() == 4 && command.PnArguments.ElementAt(3) != "1")
            {
                throw new FP_BadFormatOfArgumentException("Bad command formatting. Check your arguments.");
            }
            if (command.PnArguments.Count() > 4)
            {
                throw new FP_BadFormatOfArgumentException("Bad number of arguments for this command.");
            }

            var commandParameters = command.Parameters.Split('/', (char)Constants.ASCICodeCR).Where(m => !string.IsNullOrEmpty(m)).ToArray();

            if (commandParameters.Length == 0)
            {
                throw new FP_WrongNumberOfArgumentsException("Cannot get any parameters from command.");
            }
            if (commandParameters.Length >= 1)
            {
                if (string.IsNullOrWhiteSpace(commandParameters[0]))
                {
                    throw new FP_BadFormatOfArgumentException("Product name cannot be null");
                }
                else if (commandParameters[0].Length > 40)
                {
                    throw new FP_BadFormatOfArgumentException("Product name cannot have more then 40 characters.");
                }
                else
                {
                    slipLine.ProductName = commandParameters[0];
                }
            }
            if (commandParameters.Length >= 2)
            {
                if (!double.TryParse(commandParameters[1], out double ammount))
                {
                    throw new FP_BadFormatOfArgumentException("Cannot parse ammount of product. Check formatting.");
                }
                else if (ammount == 0)
                {
                    throw new FP_BadFormatOfArgumentException("Ammoutn cannot be 0.");
                }
                else
                {
                    slipLine.Ammount = ammount;
                }
            }
            if (commandParameters.Length >= 3)
            {
                if (!Enum.TryParse <PTU>(commandParameters[2], out PTU ptu))
                {
                    throw new FP_BadFormatOfArgumentException("Cannot parse PTU type. Check if you pass right parameter.");
                }
                else
                {
                    slipLine.PTU = ptu;
                }
            }
            if (commandParameters.Length >= 4)
            {
                if (!double.TryParse(commandParameters[3], out double price))
                {
                    throw new FP_BadFormatOfArgumentException("Cannot parse product price. Check if you pass right parameter.");
                }
                else
                {
                    slipLine.ProductPrice = price;
                }
            }

            if (commandParameters.Length >= 5)
            {
                if (!double.TryParse(commandParameters[4], out double brutto))
                {
                    throw new FP_BadFormatOfArgumentException("Cannot parse product brutto price. Check if you pass right parameter.");
                }
                else
                {
                    slipLine.TotalPrice = brutto;
                }
            }

            if (commandParameters.Length >= 6)
            {
                if (!double.TryParse(commandParameters[5], out double discountAmmount))
                {
                    throw new FP_BadFormatOfArgumentException("Cannot parse product discount ammout. Check if you pass right parameter.");
                }
                else
                {
                    slipLine.DiscountValue = discountAmmount;
                }
            }

            if (commandParameters.Length >= 7)
            {
                if (discountDescription == DiscountDescription.CUSTOM && string.IsNullOrWhiteSpace(commandParameters[6]))
                {
                    throw new FP_BadFormatOfArgumentException("Description cannot be empty in custom type");
                }
                else if (discountDescription == DiscountDescription.CUSTOM && commandParameters[6].Length > 20)
                {
                    throw new FP_BadFormatOfArgumentException("Description cannot have more then 20 characters.");
                }
                else
                {
                    discountDescriptionText = commandParameters[6];
                }
            }

            if (commandParameters.Length == 8)
            {
                productDescription = commandParameters[7];
            }
            if (commandParameters.Length > 8)
            {
                throw new FP_WrongNumberOfArgumentsException("Too many parameters for this command.");
            }

            StringBuilder slipBuilder = new StringBuilder();


            if (!state.SlipLines.Any())
            {
                state.TransactionCounter += 1;

                var fiscalPrinterDate  = DateTime.Now.AddMinutes(state.TimeDiffrenceInMinutes).ToString("yyyy-MM-dd");
                var transactionCounter = state.TransactionCounter.ToString();

                slipBuilder.AppendLine(state.FiscalPrinterHeader);
                slipBuilder.AppendLine(fiscalPrinterDate.PadRight(Constants.ReciptWidth - transactionCounter.Length) + transactionCounter);
                slipBuilder.AppendLine("P A R A G O N  F I S K A L N Y".PadCenter(Constants.ReciptWidth));
                slipBuilder.AppendLine("".PadLeft(Constants.ReciptWidth, '-'));
            }


            if (slipLine.Ammount * slipLine.ProductPrice != slipLine.TotalPrice)
            {
                throw new FP_IllegalOperationException("Ammount x Price is not equal brutto value");
            }
            else
            {
                discountValueAmmount = slipLine.TotalPrice;
            }

            string financialSlipText = $"{slipLine.Ammount}x{slipLine.ProductPrice.ToString("0.00")}    {slipLine.TotalPrice.ToString("0.00")}{slipLine.PTU.ToString()}";

            if (Constants.ReciptWidth - financialSlipText.Length < slipLine.ProductName.Length)
            {
                slipBuilder.AppendLine(slipLine.ProductName.PadRight(Constants.ReciptWidth));
                slipBuilder.AppendLine(financialSlipText.PadLeft(Constants.ReciptWidth));
            }
            else
            {
                var paddingValue = Constants.ReciptWidth - financialSlipText.Length;
                slipBuilder.AppendLine(slipLine.ProductName.PadRight(paddingValue) + financialSlipText);
            }

            if (!string.IsNullOrWhiteSpace(productDescription))
            {
                slipBuilder.AppendLine("Opis: " + productDescription);
            }

            if (slipLine.DiscountValue != 0)
            {
                discountDescriptionText = discountDescription == DiscountDescription.CUSTOM
                                        ? discountDescriptionText
                                        : GetDiscountDescription(discountDescription);


                bool isPercentageDiscount = slipLine.DiscountValue < 1 && slipLine.DiscountValue > 0;


                var discountValueText = isPercentageDiscount
                                        ? (slipLine.DiscountValue * 100).ToString() + " %"
                                        : slipLine.DiscountValue.ToString("0.00");

                discountValueAmmount -= isPercentageDiscount ? slipLine.TotalPrice * slipLine.DiscountValue : slipLine.DiscountValue;


                var discountSlipLineLeftPart  = $"   {discountDescriptionText} {discountValueText} =";
                var discountSlipLineRightPart = $"-{(slipLine.TotalPrice - discountValueAmmount).ToString("0.00")} ";


                slipBuilder.AppendLine(discountSlipLineLeftPart.PadRight(
                                           Constants.ReciptWidth - discountSlipLineRightPart.Length)
                                       + discountSlipLineRightPart);

                slipBuilder.AppendLine($"{discountValueAmmount.ToString("0.00")}{slipLine.PTU.ToString()}".PadLeft(Constants.ReciptWidth));
            }

            state.SlipLines.Add(slipLine);
            return(new CommandHandlerResponse(slipBuilder.ToString()));
        }
예제 #12
0
 public abstract CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState);
 public override CommandHandlerResponse Handle(IFiscalPrinterState fiscalPrinterState)
 {
     throw new TaskCanceledException("CAN command found.Aborting the service process.");
 }