public byte[] Serialize(LeveledFileLogger LeveledLog) { TLVWriter ArticleWriter = new TLVWriter(); // анализ флагов перед сериализацией if (Quantity.Value != Quantity.Initial || PriceWithoutDiscount.Value != PriceWithoutDiscount.Initial) // количество товара или цена без скидки была изменено Flags.Value |= FiscalArticleFlags.Changed; // устанавливаем флаг того, что позиция была изменена if (Price < 0) throw new ArgumentException("Цена товара не может быть отрицательной", "Цена товара"); //if (Quantity != 0 && Amount != 0) убрал 10.12.2013 при тестировании событий "добавления товара с нулевой ценой" и "удаления товара путем обнуления количества" { ArticleWriter.AppendTLVString((byte)OCPFiscalArticleTags.GoodsCode, GoodsCode, EncodingName); LeveledLog.Message("GoodsCode = '{0}'", GoodsCode); if (GoodsName.Length != 0) { ArticleWriter.AppendTLVString((byte)OCPFiscalArticleTags.GoodsName, GoodsName, EncodingName); LeveledLog.Message("GoodsName = '{0}'", GoodsName); } ArticleWriter.AppendTLVInt32((byte)OCPFiscalArticleTags.Quantity, Quantity.Value); LeveledLog.Message("Quantity = {0}", Quantity.Value); ArticleWriter.AppendTLVInt32((byte)OCPFiscalArticleTags.PriceWithoutDiscount, PriceWithoutDiscount.Value); LeveledLog.Message("PriceWithoutDiscount = {0}", PriceWithoutDiscount.Value); ArticleWriter.AppendTLVInt32((byte)OCPFiscalArticleTags.AmountWithoutDiscount, AmountWithoutDiscount.Value); LeveledLog.Message("AmountWithoutDiscount = {0}", AmountWithoutDiscount.Value); if (QuantityPrecision != 3) { ArticleWriter.AppendTLVByte((byte)OCPFiscalArticleTags.QuantityPrecision, QuantityPrecision); LeveledLog.Message("QuantityPrecision = {0}", QuantityPrecision); } if (Flags.Value != FiscalArticleFlags.None) { ArticleWriter.AppendTLVByte((byte)OCPFiscalArticleTags.Flags, (byte)Flags.Value); LeveledLog.Message("Flags = {0} ({1})", Flags.Value, (int)Flags.Value); } if (DiscountForPriceCurrent.Value != 0) { ArticleWriter.AppendTLVInt32((byte)OCPFiscalArticleTags.DiscountForPrice, DiscountForPriceCurrent.Value); LeveledLog.Message("DiscountForPriceCurrent = {0}", DiscountForPriceCurrent.Value); } if (DiscountForAmount.Value != 0) { ArticleWriter.AppendTLVInt32((byte)OCPFiscalArticleTags.DiscountForAmount, DiscountForAmount.Value); LeveledLog.Message("DiscountForAmount = {0}", DiscountForAmount.Value); } if (Bonuses.Value != 0) { ArticleWriter.AppendTLVInt32((byte)OCPFiscalArticleTags.Bonuses, Bonuses.Value); LeveledLog.Message("Bonuses = {0}", Bonuses.Value); } if (Fiscal.Payments.IsMixedPayment || paymentType.Received) // тип оплаты возвращаем тогда, когда используется смешанная оплату { ArticleWriter.AppendTLVByte((byte)OCPFiscalArticleTags.PaymentType, (byte)PaymentType.Value); LeveledLog.Message("PaymentType = {0} ({1})", PaymentType.Value, (int)PaymentType.Value); } //ArticleWriter.AppendTLVString((byte)CMPFiscalArticleTags.MeasureUnit, MeasureUnit, EncodingName); LeveledLog.Message("MeasureUnit = {0}", MeasureUnit); не передаётся обратно для экономии трафика } return ArticleWriter.Bytes; }
// parse TLV for fiscal receipt internal void Deserialize(byte[] Data, LeveledFileLogger LeveledLog) { var NextLeveledLog = LeveledLog.CloneNextLevel(); PaymentsReceived = false; byte Tag = 0; byte[] Value = null; TLVReader FiscalReader = new TLVReader(Data); while (FiscalReader.NextValue(out Tag, out Value)) switch ((CMPFiscalReceiptTags)Tag) { case CMPFiscalReceiptTags.Article: // может быть несколько позиций чека FiscalArticle Article = new FiscalArticle(this); LeveledLog.Message("Article = {"); Article.Deserialize(Value, NextLeveledLog); // в артикуле у нас все полученные значения LeveledLog.Message("}"); this.Articles.Add(Article); break; case CMPFiscalReceiptTags.Flags: Flags.Receive((FiscalReceiptFlags)TLVReader.ValueToByte(Value)); LeveledLog.Message("Flags = {0} ({1})", Flags.Value, (int)Flags.Value); break; case CMPFiscalReceiptTags.AmountWithoutDiscount: AmountWithoutDiscount.Receive(TLVReader.ValueToInt32(Value)); LeveledLog.Message("AmountWithoutDiscount = {0}", AmountWithoutDiscount.Value); break; case CMPFiscalReceiptTags.DiscountForAmount: DiscountForAmount.Receive(TLVReader.ValueToInt32(Value)); LeveledLog.Message("DiscountForAmount = {0}", DiscountForAmount.Value); break; case CMPFiscalReceiptTags.Payments: // performed payments LeveledLog.Message("Payments = {"); Payments.Deserialize(Value, NextLeveledLog); LeveledLog.Message("}"); PaymentsReceived = true; break; default: throw new Exception(string.Format("Unknown tag 0x{0:X} received", Tag)); } }
/*private void LeveledLog.Message(string Message) { const byte Level = 4; SessionLog.Message("".PadLeft(Level * 2) + Message); } private void LeveledLog.Message(string Message, params object[] Arguments) { LeveledLog.Message(string.Format(Message, Arguments)); }*/ public void Deserialize(byte[] Data, LeveledFileLogger LeveledLog) { byte Tag = 0; byte[] Value = null; TLVReader ArticleReader = new TLVReader(Data); while (ArticleReader.NextValue(out Tag, out Value)) switch ((OCPFiscalArticleTags)Tag) { case OCPFiscalArticleTags.GoodsCode: GoodsCode = TLVReader.ValueToString(Value, EncodingName); LeveledLog.Message("GoodsCode = '{0}'", GoodsCode); break; case OCPFiscalArticleTags.Quantity: Quantity.Receive(TLVReader.ValueToInt32(Value)); LeveledLog.Message("Quantity = {0}", Quantity.Value); break; case OCPFiscalArticleTags.PriceWithoutDiscount: PriceWithoutDiscount.Receive(TLVReader.ValueToUInt32(Value)); LeveledLog.Message("PriceWithoutDiscount = {0}", PriceWithoutDiscount.Value); break; case OCPFiscalArticleTags.AmountWithoutDiscount: AmountWithoutDiscount.Receive(TLVReader.ValueToInt32(Value)); LeveledLog.Message("AmountWithoutDiscount = {0}", AmountWithoutDiscount.Value); break; case OCPFiscalArticleTags.GoodsName: GoodsName = TLVReader.ValueToString(Value, EncodingName); LeveledLog.Message("GoodsName = '{0}'", GoodsName); break; case OCPFiscalArticleTags.Flags: Flags.Receive((FiscalArticleFlags)TLVReader.ValueToByte(Value)); LeveledLog.Message("Flags = {0} {1}", Flags.Value, (int)Flags.Value); break; case OCPFiscalArticleTags.DiscountForPrice: DiscountForPriceCurrent.Receive(TLVReader.ValueToInt32(Value)); LeveledLog.Message("DiscountForPrice = {0}", DiscountForPriceCurrent.Value); break; case OCPFiscalArticleTags.DiscountForAmount: DiscountForAmount.Receive(TLVReader.ValueToInt32(Value)); LeveledLog.Message("DiscountForAmount = {0}", DiscountForAmount.Value); break; case OCPFiscalArticleTags.Bonuses: Bonuses.Receive(TLVReader.ValueToInt32(Value)); LeveledLog.Message("Bonuses = {0}", Bonuses.Value); break; case OCPFiscalArticleTags.PaymentType: paymentType.Receive((PaymentTypes)TLVReader.ValueToByte(Value)); LeveledLog.Message("PaymentType = {0} ({1})", paymentType.Value, (int)paymentType.Value); break; case OCPFiscalArticleTags.MeasureUnit: MeasureUnit = Functions.LimitString(TLVReader.ValueToString(Value, EncodingName), 8).ToLower(); LeveledLog.Message("MeasureUnit = '{0}'", MeasureUnit); break; case OCPFiscalArticleTags.QuantityPrecision: QuantityPrecision = TLVReader.ValueToByte(Value); LeveledLog.Message("QuantityPrecision = {0}", QuantityPrecision); if (QuantityPrecision < 0 || QuantityPrecision > 3) Fiscal.ErrorMessage.Add("Неверное значение QuantityPrecision = {0}", QuantityPrecision); break; default: throw new Exception(string.Format("Unknown tag 0x{0:X} received", Tag)); } }
public byte[] Serialize(LeveledFileLogger LeveledLog) { var NextLeveledLog = LeveledLog.CloneNextLevel(); TLVWriter FiscalWriter = new TLVWriter(); if (Quantity > 0 && Articles.Count > 0) // сериализуем только если есть позиции в чеке и они ненулевые { foreach (FiscalArticle Article in Articles) { LeveledLog.Message("Article = {"); FiscalWriter.AppendTLV((byte)CMPFiscalReceiptTags.Article, Article.Serialize(NextLeveledLog)); LeveledLog.Message("}"); } if (Flags.Value != FiscalReceiptFlags.None) { FiscalWriter.AppendTLVByte((byte)CMPFiscalReceiptTags.Flags, (byte)Flags.Value); LeveledLog.Message("Flags = {0} ({1})", Flags.Value, (byte)Flags.Value); } if (AmountWithoutDiscount.Value != 0 || Articles.Count > 0) { FiscalWriter.AppendTLVInt32((byte)CMPFiscalReceiptTags.AmountWithoutDiscount, (Int32)AmountWithoutDiscount.Value); LeveledLog.Message("AmountWithoutDiscount = {0}", AmountWithoutDiscount.Value); } if (DiscountForAmount.Value != 0) { FiscalWriter.AppendTLVInt32((byte)CMPFiscalReceiptTags.DiscountForAmount, (Int32)DiscountForAmount.Value); LeveledLog.Message("DiscountForAmount = {0}", DiscountForAmount.Value); } LeveledLog.Message("Payments = {"); FiscalWriter.AppendTLV((byte)CMPFiscalReceiptTags.Payments, Payments.Serialize(NextLeveledLog)); LeveledLog.Message("}"); } return FiscalWriter.Bytes; }