private void DynamicLoadFiscalPrinter() { try { // Allow the user to override the default printer loaded. string assemblyName; // e.g., "SimulatedFiscalPrinter.dll"; string className; // e.g., "SimulatedFiscalPrinter.MyFiscalPrinter"; assemblyName = Properties.Settings.Default.FiscalPrinterAssembly; className = Properties.Settings.Default.FiscalPrinterClass; if (!string.IsNullOrEmpty(assemblyName) && !string.IsNullOrEmpty(className)) { // Try to dynamically load the user specified assembly Assembly theAssembly = Assembly.LoadFrom(assemblyName); _fiscalPrinter = theAssembly.CreateInstance(className) as IFiscalOperations; } } catch (Exception ex) { // Ignore errors Debug.WriteLine(ex.Message); } if (_fiscalPrinter == null) { // Use default _fiscalPrinter = new MyFiscalPrinter(); } }
public void PostVoidTransaction(IPosTransaction posTransaction) { FiscalPrinterSingleton fiscalCore = FiscalPrinterSingleton.Instance; IFiscalOperations fiscalPrinter = fiscalCore.FiscalPrinter; if (fiscalPrinter.OperatingState == FiscalPrinterState.FiscalReceipt) { fiscalPrinter.CancelReceipt(); } }
public void PostVoidItem(IPosTransaction posTransaction, int lineId) { IFiscalOperations fiscalPrinter = FiscalPrinterSingleton.Instance.FiscalPrinter; if (fiscalPrinter != null && FiscalPrinterSingleton.Instance.SalesLineItemData.ContainsKey(lineId)) { LineItemTagalong tagalong = FiscalPrinterSingleton.Instance.SalesLineItemData[lineId]; if (!tagalong.Voided) { fiscalPrinter.RemoveItem(tagalong.PrinterItemNumber); tagalong.Voided = true; } } }
public void UpdateFiscalCouponSalesItemsQty(RetailTransaction retailTransaction) { if (retailTransaction == null) { throw new ArgumentNullException("retailTransaction"); } LinkedList <SaleLineItem> salesLines = retailTransaction.SaleItems; IFiscalOperations fiscalPrinter = this.FiscalPrinter; foreach (SaleLineItem lineItem in salesLines) { // Check for changes from what was last sent to fiscal printer... LineItemTagalong tagalong; if (this.SalesLineItemData.ContainsKey(lineItem.LineId)) { // Check an existing item for changes... tagalong = this.SalesLineItemData[lineItem.LineId]; if (!tagalong.Voided) { // Process any quantity changes... if (lineItem.Quantity != tagalong.PostedQuantity) { // Update the qty for the item... int newQuantity = (int)lineItem.Quantity; fiscalPrinter.RemoveItem(tagalong.PrinterItemNumber); tagalong.PrinterItemNumber = fiscalPrinter.AddItem(lineItem.ItemId, lineItem.Description, tagalong.PostedPrice, tagalong.TaxRateId, newQuantity); tagalong.PostedQuantity = (decimal)newQuantity; } } } else { // Add a new item // Update the printer for this change string itemLookupCode = lineItem.ItemId; string itemDescription = lineItem.Description; decimal itemPrice = lineItem.Price; string taxRateId = FindTaxRateId(lineItem); int itemQuantity = (int)lineItem.Quantity; int printerItemNumber = fiscalPrinter.AddItem(itemLookupCode, itemDescription, itemPrice, taxRateId, itemQuantity); tagalong = new LineItemTagalong(printerItemNumber, itemPrice, (decimal)itemQuantity, taxRateId); this.SalesLineItemData.Add(lineItem.LineId, tagalong); } } }
private static void PrintTenderManagementReports(LinkedList <TenderLineItem> tenderLines) { FiscalPrinterSingleton fiscalCore = FiscalPrinterSingleton.Instance; IFiscalOperations fiscalPrinter = fiscalCore.FiscalPrinter; // Print any desired management reports (CC, etc) foreach (TenderLineItem tenderLine in tenderLines) { if (!tenderLine.Voided && (tenderLine.TenderTypeId != "1")) { // filtered out voided or cash if (fiscalPrinter.ManagementReportTryBegin()) { fiscalPrinter.ManagementReportPrintLine("================================================"); fiscalPrinter.ManagementReportPrintLine("\r\n" + "Tender Payment" + "\r\n"); fiscalPrinter.ManagementReportPrintLine("\r\n" + "TenderTypeId: " + tenderLine.TenderTypeId + "\r\n"); fiscalPrinter.ManagementReportPrintLine("================================================"); fiscalPrinter.ManagementReportEnd(); } } } }
public void PostSale(IPosTransaction posTransaction) { Debug.WriteLine("PostSale"); RetailTransaction retailTransaction = posTransaction as RetailTransaction; if (retailTransaction != null) { // We are a retail transaction // The Sale Item may not alway be the last item. // If the last has alredy been added, then it is a qty change so consder // handling later... SaleLineItem saleLineItem = retailTransaction.SaleItems.Last.Value; if (saleLineItem != null) { if (!(saleLineItem is IncomeExpenseItem)) { // Note: Depending upon requriments, we may want to skip fiscal receipt coupons for certain // types of saleLineItems such as Income or Expense account FiscalPrinterSingleton fiscalCore = FiscalPrinterSingleton.Instance; IFiscalOperations fiscalPrinter = fiscalCore.FiscalPrinter; if (fiscalPrinter.OperatingState != FiscalPrinterState.FiscalReceipt) { FiscalPrinterSingleton.Instance.SalesLineItemData.Clear(); string customerAccountNumber = UserMessages.RequestCustomerTaxId(string.Empty); fiscalPrinter.BeginReceipt(customerAccountNumber); } if (!fiscalCore.SalesLineItemData.ContainsKey(saleLineItem.LineId)) { // We found at leat one new item (not just a quantity change) fiscalCore.UpdateFiscalCouponSalesItemsQty(retailTransaction); } } } } }
public void PreEndTransaction(IPreTriggerResult preTriggerResult, IPosTransaction posTransaction) { if (preTriggerResult == null) { throw new ArgumentNullException("preTriggerResult"); } if (posTransaction == null) { throw new ArgumentNullException("posTransaction"); } Debug.WriteLine("PreEndTransaction"); bool abortTransaction = false; FiscalPrinterSingleton fiscalCore = FiscalPrinterSingleton.Instance; IFiscalOperations fiscalPrinter = fiscalCore.FiscalPrinter; PersistentPrinterData printerData = fiscalCore.PrinterData; RetailTransaction retailTransaction = posTransaction as RetailTransaction; LinkedList <TenderLineItem> tenderLines = null; LinkedList <SaleLineItem> salesLines = null; ComputePosExeMD5Text(); // Note: Other transaction types (CustomerPaymentTransaction) may also apply. if (retailTransaction != null) { // We are a retail transaction // Add all payments to the fiscal printer // Alternative option is to do this as ar result of IPaymentTriggers tenderLines = retailTransaction.TenderLines; salesLines = retailTransaction.SaleItems; if (fiscalPrinter.OperatingState == FiscalPrinterState.FiscalReceipt) { Decimal totalDiscountAmount = 0m; Decimal totalDiscountPercent = 0m; // Post any quantity changes to the printer fiscalCore.UpdateFiscalCouponSalesItemsQty(retailTransaction); UpdateFiscalPrinterTransactionData(fiscalCore, fiscalPrinter, salesLines, ref totalDiscountAmount, ref totalDiscountPercent); // Start payment, apply total/transaction discount or surcharge // Note: we are not implementing a surcharge if (totalDiscountPercent != 0) { // Transaction level % discount fiscalPrinter.StartTotalPaymentWithDiscount((int)(totalDiscountPercent * 100)); } else if (totalDiscountAmount != 0) { // Transaction level amount discount fiscalPrinter.StartTotalPaymentWithDiscount(totalDiscountAmount); } else { // No transaction level discounts or surcharge fiscalPrinter.StartTotalPayment(); } // Process Payments... Decimal posPaymentTotal = 0m; foreach (TenderLineItem tenderLine in tenderLines) { if (!tenderLine.Voided) { string paymentMethod = fiscalCore.MapTenderTypeIdToPaymentMethod(tenderLine.TenderTypeId); decimal paymentAmount = tenderLine.Amount; if (paymentAmount > 0m) { // only process positive payments with the fiscal printer // Cash-back should is ignored fiscalPrinter.MakePayment(paymentMethod, paymentAmount); posPaymentTotal += paymentAmount; } } } string couponNumber = fiscalPrinter.GetCouponNumber(); posTransaction.FiscalDocumentId = couponNumber; string serialNumber = fiscalPrinter.GetSerialNumber(); posTransaction.FiscalSerialId = serialNumber; Debug.WriteLine("Balance due: " + fiscalPrinter.GetBalanceDue()); Debug.WriteLine("Subtotal " + fiscalPrinter.GetSubtotal()); Debug.WriteLine("Pos Payment total " + posPaymentTotal); Debug.Assert(fiscalPrinter.GetBalanceDue() == 0m, "Not enough payment was made as expected by the fiscal printer"); if (fiscalPrinter.GetBalanceDue() > 0m) { // user will need to void transaction or fix the shortage to proceed. preTriggerResult.ContinueOperation = false; preTriggerResult.MessageId = 4042; // The action is not valid for this type of transaction. } else { // End and finalize the Fiscal Coupon fiscalPrinter.EndReceipt(string.Format(CultureInfo.CurrentCulture, "Thank you! MD5:{0}", _posExeMd5Text)); printerData.SetGrandTotal(fiscalPrinter.GetGrandTotal()); PrintTenderManagementReports(tenderLines); } } else { // Check to see if there are sales items on this transaction if (ContainsItemsRequiringFiscalPrinter(retailTransaction)) { // A Fiscal Coupon has not been created - Abort this operation. preTriggerResult.ContinueOperation = false; preTriggerResult.MessageId = 4042; // The action is not valid for this type of transaction. } } if (abortTransaction) { // Abort the transaction fiscalPrinter.CancelReceipt(); preTriggerResult.ContinueOperation = false; preTriggerResult.MessageId = 4042; // The action is not valid for this type of transaction. } } }
private static void UpdateFiscalPrinterTransactionData(FiscalPrinterSingleton fiscalCore, IFiscalOperations fiscalPrinter, LinkedList <SaleLineItem> salesLines, ref Decimal totalDiscountAmount, ref Decimal totalDiscountPercent) { foreach (SaleLineItem lineItem in salesLines) { // Check for changes from what was last sent to fiscal printer... if (fiscalCore.SalesLineItemData.ContainsKey(lineItem.LineId)) { // We have a tag along LineItemTagalong tagalong = fiscalCore.SalesLineItemData[lineItem.LineId]; if (!tagalong.Voided) { // Process line discounts/additional charges... // Consdier if check lineItem.NoDiscountAllowed should be done first foreach (DiscountItem discount in lineItem.DiscountLines) { // Future enhancment - determine if discounts must be applied in a specific order and // if % discounts are applied to the running total or to the base price // and if multiple % discounts are allowed? if (discount is LineDiscountItem) { if (discount.Amount != 0) { // Apply amount discount fiscalPrinter.ApplyDiscount(tagalong.PrinterItemNumber, discount.Amount); } if (discount.Percentage != 0) { // Apply % discount fiscalPrinter.ApplyDiscount(tagalong.PrinterItemNumber, (int)(discount.Percentage * 100)); } } else if (discount is TotalDiscountItem) { Debug.Assert((totalDiscountAmount == 0) || (totalDiscountAmount == discount.Amount), "TotalDiscountAmount has multiple value"); totalDiscountAmount = discount.Amount; Debug.Assert((totalDiscountPercent == 0) || (totalDiscountPercent == discount.Percentage), "totalDiscountPercent has multiple value"); totalDiscountPercent = discount.Percentage; } } } } } }
public GeneralFiscalForm() { InitializeComponent(); fiscalPrinter = FiscalPrinterSingleton.Instance.FiscalPrinter; }