/// <summary> /// Gets sales tax form types from India Retail store table. /// </summary> private static Int64 GetSalesTaxFormTypes() { Int64 salesTaxFormTypes = 0; SqlConnection connection = ApplicationSettings.Database.LocalConnection; try { // Read sales tax form type record id from the India Retail store table DBUtil dbUtil = new DBUtil(connection); SqlParameter[] sqlParameter = { new SqlParameter("@STOREID", ApplicationSettings.Terminal.StoreId) }; DataTable table = dbUtil.GetTable(@"SELECT ISNULL(SALESTAXFORMTYPES, 0) AS SALESTAXFORMTYPES FROM RETAILSTORETABLE_IN INNER JOIN RETAILSTORETABLE ON RETAILSTORETABLE_IN.RETAILSTORETABLE = RETAILSTORETABLE.RECID AND RETAILSTORETABLE.STORENUMBER = @STOREID", sqlParameter); salesTaxFormTypes = table.Rows.Count > 0 ? (Int64)table.Rows[0]["SALESTAXFORMTYPES"] : 0; return(salesTaxFormTypes); } catch (Exception ex) { NetTracer.Error(ex, "GetSalesTaxFormTypes() failed in an Exception"); LSRetailPosis.ApplicationExceptionHandler.HandleException("TaxCodeProviderIndia", ex); return(0); } finally { if (connection.State == ConnectionState.Open) { connection.Close(); } } }
public virtual Image Create(string text, float xDpi = DEFAULT_DPI, float yDpi = DEFAULT_DPI) { NetTracer.Information("Peripheral [{0}] - Create", this); Bitmap barcodeImage = null; using (Font barcodeFont = new Font(FontName, FontSize)) { if (barcodeFont.Name.Equals(barcodeFont.OriginalFontName, StringComparison.Ordinal)) // If font installed. { using (Font barcodeTextFont = new Font(TEXT_FONT_NAME, TEXT_FONT_SIZE)) // Text font { try { text = Encode(text); SizeF barcodeSizeF = GetTextSizeF(text, barcodeFont, xDpi, yDpi); float barcodeTextHeight = barcodeTextFont.GetHeight(yDpi); barcodeImage = new Bitmap((int)barcodeSizeF.Width, (int)(barcodeSizeF.Height + barcodeTextHeight)); barcodeImage.SetResolution(xDpi, yDpi); using (Graphics graphic = Graphics.FromImage(barcodeImage)) { // Calculate left/right margin for drawing barcode considering dpi being used. float XYWithMargin = (xDpi / DEFAULT_DPI) * 5; // Draw barcode graphic.DrawString(text, barcodeFont, Brushes.Black, XYWithMargin, XYWithMargin); // Draw text below barcode in center RectangleF textRect = new RectangleF(0, barcodeSizeF.Height, barcodeSizeF.Width, barcodeTextHeight); using (StringFormat textFormat = new StringFormat(StringFormatFlags.NoClip) { Alignment = StringAlignment.Center }) { graphic.DrawString(text, barcodeTextFont, Brushes.Black, textRect, textFormat); } } } catch (Exception ex) { if (barcodeImage != null) { barcodeImage.Dispose(); } NetTracer.Error(ex, "Peripheral [{0}] - Exception during barcode creation.", this); } } } else { NetTracer.Error("Peripheral [{0}] - Barcode creation failed. Font {1} in not installed.", this, FontName); } } return(barcodeImage); }
private void AssignOperator() { using (ExtendedLogOnScanForm scanForm = new ExtendedLogOnScanForm()) { POSFormsManager.ShowPOSForm(scanForm); if (scanForm.DialogResult == DialogResult.OK) { try { viewModel.ExecuteAssign(scanForm.ExtendedLogOnInfo); } catch (PosisException pex) { NetTracer.Error(pex, "ExtendedLogOnForm::AssignOperator: Failed."); POSFormsManager.ShowPOSMessageDialog(pex.ErrorMessageNumber); } catch (Exception ex) { NetTracer.Error(ex, "ExtendedLogOnForm::AssignOperator: Failed."); POSFormsManager.ShowPOSMessageDialog(99412); // Generic failure. } } } }
private static string GetPurchRequestId() { string retVal = string.Empty; try { InputConfirmation inputConfirmation = new InputConfirmation() { PromptText = LSRetailPosis.ApplicationLocalizer.Language.Translate(51001), // Enter purchase request id }; InteractionRequestedEventArgs request = new InteractionRequestedEventArgs(inputConfirmation, () => { retVal = inputConfirmation.EnteredText; if (retVal.Length > 20) { retVal = retVal.Substring(0, 20); } } ); InternalApplication.Services.Interaction.InteractionRequest(request); } catch (Exception ex) { NetTracer.Error(ex, "Customer::GetPurchRequestId failed"); } return(retVal); }
/// <summary> /// Executes the assign on currently selected operator. /// </summary> /// <param name="extendedLogOnInfo">The extended log on info.</param> /// <exception cref="PosisException">Thrown if save failed.</exception> public void ExecuteAssign(IExtendedLogOnInfo extendedLogOnInfo) { NetTracer.Information("ExtendedLogOnViewModel::ExecuteAssign: Start."); bool saved = false; try { logonData.DbUtil.BeginTransaction(); // Save a local copy for immediate availability at store. logonData.CreateExtendedLogOn(this.SelectedResult.OperatorID, extendedLogOnInfo); // Save in HQ this.AxCreateExtendedLogOn(extendedLogOnInfo); saved = true; } catch (SqlException ex) { if (ex.Number == SQL_ERROR_DUPLICATE_RECORD) { throw new PosisException(ex.Number, ex) { ErrorMessageNumber = STRING_ALREADY_EXISTS }; } else if (ex.Number == SQL_ERROR_NULL_DATA) { throw new PosisException(ex.Number, ex) { ErrorMessageNumber = STRING_STAFF_NOT_FOUND }; } // Any other Sql error will be thrown as it is. throw; } finally { if (saved) { logonData.DbUtil.EndTransaction(); SelectedResult.ExtendedLogOnAssigned = true; OnPropertyChanged("Results"); NetTracer.Information("ExtendedLogOnViewModel::ExecuteAssign: Successful."); } else { logonData.DbUtil.CancelTransaction(); NetTracer.Error("ExtendedLogOnViewModel::ExecuteAssign: Failed."); } } }
static private MultibuyLine GetMultiBuyDiscountLine(string offerId, decimal quantity) { SqlConnection connection = Discount.InternalApplication.Settings.Database.Connection; string dataAreaId = Discount.InternalApplication.Settings.Database.DataAreaID; try { offerId = offerId ?? String.Empty; string queryString = @" SELECT * FROM POSMULTIBUYDISCOUNTLINE WHERE MINQUANTITY = (SELECT MAX(MINQUANTITY) FROM POSMULTIBUYDISCOUNTLINE WHERE MINQUANTITY <= @MINQUANTITY AND OFFERID = @OFFERID AND DATAAREAID = @DATAAREAID) AND DATAAREAID = @DATAAREAID AND OFFERID = @OFFERID"; using (SqlCommand command = new SqlCommand(queryString.ToString(), connection)) { command.Parameters.AddWithValue("@MINQUANTITY", quantity); command.Parameters.AddWithValue("@DATAAREAID", dataAreaId); command.Parameters.AddWithValue("@OFFERID", offerId); MultibuyLine multiBuyLine = null; if (connection.State != ConnectionState.Open) { connection.Open(); } using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow)) { if (reader.Read()) { multiBuyLine = new MultibuyLine((decimal)reader["MINQUANTITY"], (decimal)reader["UNITPRICEORDISCPCT"]); } } return(multiBuyLine ?? MultibuyLine.Empty()); } } catch (Exception ex) { NetTracer.Error(ex, "MultibuyLine::GetMultiBuyDiscountLine failed for offerId {0} quantity {1}", offerId, quantity); LSRetailPosis.ApplicationExceptionHandler.HandleException(typeof(MultibuyLine).ToString(), ex); throw; } finally { if (connection.State == ConnectionState.Open) { connection.Close(); } } }
/// <summary> /// Get the commerce runtime connection string from the application config file. /// </summary> /// <returns>The commerce runtime connection string.</returns> private static string GetCrtConnectionString() { var crtConnectionString = ConfigurationManager.ConnectionStrings[KeyCrtConnectionString].ConnectionString; if (string.IsNullOrEmpty(crtConnectionString)) { NetTracer.Error( "The commerce runtime connection string '{0}' was not found in the application config.", KeyCrtConnectionString); } return(crtConnectionString); }
/// <summary> /// Prepare report header. /// </summary> /// <param name="reportLayout"></param> /// <param name="reportType"></param> private static void PrepareHeader(this StringBuilder reportLayout, Batch batch, ReportType reportType) { reportLayout.AppendLine(singleLine); switch (reportType) { case ReportType.XReport: reportLayout.AppendReportLine(7000); break; case ReportType.ZReport: reportLayout.AppendReportLine(7001); break; default: String message = string.Format("Unsupported Report Type '{0}'.", reportType); NetTracer.Error(message); throw new NotSupportedException(message); } reportLayout.AppendReportHeaderLine(7002, ApplicationSettings.Terminal.StoreId, true); reportLayout.AppendReportHeaderLine(7006, DateTime.Now.ToShortDateString(), false); reportLayout.AppendReportHeaderLine(7003, ApplicationSettings.Terminal.TerminalId, true); reportLayout.AppendReportHeaderLine(7007, DateTime.Now.ToShortTimeString(), false); reportLayout.AppendReportHeaderLine(7004, ApplicationSettings.Terminal.TerminalOperator.OperatorId, true); reportLayout.AppendLine(); reportLayout.AppendLine(); reportLayout.AppendReportHeaderLine(7005, ApplicationLocalizer.Language.Translate(206, batch.TerminalId, batch.BatchId), true); reportLayout.AppendLine(); reportLayout.AppendReportHeaderLine(7008, batch.StartDateTime.ToShortDateString(), true); if (reportType == ReportType.ZReport) { reportLayout.AppendReportHeaderLine(7010, batch.CloseDateTime.ToShortDateString(), false); } else { reportLayout.AppendLine(); } reportLayout.AppendReportHeaderLine(7009, batch.StartDateTime.ToShortTimeString(), true); if (reportType == ReportType.ZReport) { reportLayout.AppendReportHeaderLine(7011, batch.CloseDateTime.ToShortTimeString(), false); } else { reportLayout.AppendLine(); } reportLayout.AppendLine(); }
/// <summary> /// Print a shift staging report. /// </summary> /// <param name="batchStaging"></param> public static void Print(this IPosBatchStaging batchStaging) { StringBuilder reportLayout = new StringBuilder(1000); int headerStringId = 0; int statusStringId = 0; switch (batchStaging.Status) { case PosBatchStatus.Suspended: headerStringId = 7063; statusStringId = 7067; break; case PosBatchStatus.BlindClosed: headerStringId = 7064; statusStringId = 7068; break; default: NetTracer.Error("Unsupported batchStaging status {0}", batchStaging.Status); throw new NotSupportedException(); } // Header reportLayout.AppendLine(ApplicationLocalizer.Language.Translate(headerStringId)); reportLayout.AppendLine(); // Current information reportLayout.AppendReportLine(7006, DateTime.Now.ToShortDateString()); reportLayout.AppendReportLine(7007, DateTime.Now.ToShortTimeString()); reportLayout.AppendReportLine(7003, ApplicationSettings.Terminal.TerminalId); reportLayout.AppendLine(); // Content reportLayout.AppendReportLine(7065, batchStaging.TerminalId); reportLayout.AppendReportLine(7005, batchStaging.BatchId); reportLayout.AppendReportLine(7066, ApplicationLocalizer.Language.Translate(statusStringId)); reportLayout.AppendReportLine(7008, batchStaging.StartDateTime.ToShortDateString()); reportLayout.AppendReportLine(7009, batchStaging.StartDateTime.ToShortTimeString()); reportLayout.AppendReportLine(7004, batchStaging.StaffId); EOD.InternalApplication.Services.Peripherals.Printer.PrintReceipt(reportLayout.ToString()); }
/// <summary> /// Processes the extended log on key. /// </summary> /// <param name="extendedLogOnInfo">The extended log on info.</param> private void ProcessExtendedLogOnKey(IExtendedLogOnInfo extendedLogOnInfo) { try { if (status == LogOnStatus.None) { operatorId = PosApplication.Instance.Services.Peripherals.LogOnDevice.Identify(extendedLogOnInfo); if (!string.IsNullOrWhiteSpace(operatorId)) { HandleStaffId(extendedLogOnInfo.PasswordRequired); } } } catch (Exception ex) { NetTracer.Error(ex, "Unabled to process extended log on type: {0}", extendedLogOnInfo.LogOnType); } }
public void CalculateTax(ISaleLineItem lineItem, IRetailTransaction transaction) { try { lineItem.TaxRatePct = 0; lineItem.TaxLines.Clear(); lineItem.CalculateLine(); foreach (ITaxProvider provider in Providers) { provider.CalculateTax(lineItem, transaction); } } catch (Exception x) { NetTracer.Error(x, "CalculateTax threw an exception: {0}", x.Message); LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), x); throw; } }
/// <summary> /// Unassign extend logon for the operator. /// </summary> private void UnassignOperator() { DialogResult dialogResult = PosApplication.Instance.Services.Dialog.ShowMessage(ApplicationLocalizer.Language.Translate(99407, viewModel.SelectedResult.OperatorName), MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.Yes) { try { viewModel.ExecuteUnassign(); } catch (Exception ex) { NetTracer.Error(ex, "RevokeExtendedLogon::RevokeOperator: Failed."); POSFormsManager.ShowPOSMessageDialog(99412); // Generic failure. } } }
public void CalculateLoyaltyPoints(IRetailTransaction retailTransaction) { try { LogMessage("Adding loyalty points...", LSRetailPosis.LogTraceLevel.Trace, "Loyalty.CalculateLoyaltyPoints"); this.transaction = (RetailTransaction)retailTransaction; //if we already have a loyalty item for tender, we don't accumulated points for this transaction. if (this.transaction.LoyaltyItem != null && this.transaction.LoyaltyItem.UsageType == LoyaltyItemUsageType.UsedForLoyaltyTender) { return; } //calculate points. this.transaction.LoyaltyItem.UsageType = LoyaltyItemUsageType.NotUsed; decimal totalNumberOfPoints = 0; // Get the table containing the point logic DataTable loyaltyPointsTable = GetLoyaltyPointsSchemeFromDB(this.transaction.LoyaltyItem.SchemeID); // Loop through the transaction and calculate the aquired loyalty points. if (loyaltyPointsTable != null && loyaltyPointsTable.Rows.Count > 0) { totalNumberOfPoints = CalculatePointsForTransaction(loyaltyPointsTable); this.transaction.LoyaltyItem.CalculatedLoyaltyPoints = totalNumberOfPoints; this.transaction.LoyaltyItem.UsageType = LoyaltyItemUsageType.UsedForLoyaltyRequest; } UpdateTransactionAccumulatedLoyaltyPoint(); } catch (Exception ex) { NetTracer.Error(ex, "Loyalty::CalculateLoyaltyPoints failed for retailTransaction {0}", retailTransaction.TransactionId); LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), ex); throw; } }
public FormItemInfo(DataRow formItem) { try { this.charIndex = Convert.ToInt16(formItem["nr"]); this.valueString = formItem["value"].ToString(); if (formItem["valign"].ToString() == "right") { this.vertAlign = valign.right; } else if (formItem["valign"].ToString() == "left") { this.vertAlign = valign.left; } else if (formItem["valign"].ToString() == "center") { this.vertAlign = valign.center; } this.fill = Convert.ToChar(string.Concat(formItem["fill"])); this.Variable = formItem["variable"].ToString(); this.IsVariable = formItem["variable"].ToString().Length != 0; this.Prefix = formItem["prefix"].ToString(); this.fontStyle = (System.Drawing.FontStyle)Convert.ToInt32(formItem["FontStyle"].ToString()); if (this.fontStyle == System.Drawing.FontStyle.Bold) { this.sizeFactor = 2; } else { this.sizeFactor = 1; } this.length = Convert.ToInt16(formItem["length"]) + (this.prefix.Length * this.sizeFactor); } catch (Exception ex) { NetTracer.Error(ex, "FormItemInfo::FormItemInfo failed"); } }
private void UpdateTransactionAccumulatedLoyaltyPoint() { try { bool valid = false; decimal points = 0; int loyaltyTenderTypeBase = 0; string comment1 = string.Empty; GetPointStatus(ref points, ref valid, ref comment1, ref loyaltyTenderTypeBase, this.transaction.LoyaltyItem.LoyaltyCardNumber); if (valid && (this.transaction.LoyaltyItem != null)) { this.transaction.LoyaltyItem.AccumulatedLoyaltyPoints = points; } } catch (Exception ex) { NetTracer.Error(ex, "Loyalty::UpdateTransactionAccumulatedLoyaltyPoint failed for LoyaltyCardNumber {0}", this.transaction.LoyaltyItem.LoyaltyCardNumber); LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), ex); throw; } }
/// <summary> /// Processes the extended log on key. /// </summary> /// <param name="extendedLogOnInfo">The extended log on info.</param> private void ProcessExtendedLogOnKey(IExtendedLogOnInfo extendedLogOnInfo) { try { operatorId = PosApplication.Instance.Services.Peripherals.LogOnDevice.Identify(extendedLogOnInfo); if (!string.IsNullOrEmpty(this.operatorId)) { if (extendedLogOnInfo.PasswordRequired) { PromptForPassword(); } else { ValidateCredentials(ApplicationSettings.Terminal.StoreId, this.operatorId, null); } } } catch (Exception ex) { NetTracer.Error(ex, "Unabled to process extended log on type: {0}", extendedLogOnInfo.LogOnType); } }
/// <summary> /// Calculates the tax for the last item. /// </summary> /// <param name="retailTransaction">The transaction to be calculated</param> public void CalculateTax(IRetailTransaction retailTransaction) { RetailTransaction transaction = retailTransaction as RetailTransaction; if (transaction == null) { NetTracer.Error("Argument retailTransaction is null"); throw new ArgumentNullException("retailTransaction"); } foreach (ISaleLineItem saleItem in transaction.SaleItems) { saleItem.TaxRatePct = 0; saleItem.TaxLines.Clear(); saleItem.CalculateLine(); } ClearMiscChargeTaxLines(transaction); foreach (ITaxProvider provider in Providers) { provider.CalculateTax(transaction); } }
/// <summary> /// Executes the unassign on currently selected operator. /// </summary> public void ExecuteUnassign() { NetTracer.Information("ExtendedLogOnViewModel::ExecuteUnassign: Start."); bool saved = false; try { logonData.DbUtil.BeginTransaction(); // Delete from local db for immediate availability at store. logonData.DeleteExtendedLogOn(this.SelectedResult.OperatorID); // Delete in HQ this.AxDeleteExtendedLogOn(); saved = true; } finally { if (saved) { logonData.DbUtil.EndTransaction(); SelectedResult.ExtendedLogOnAssigned = false; OnPropertyChanged("Results"); NetTracer.Information("ExtendedLogOnViewModel::ExecuteUnassign: Successful."); } else { logonData.DbUtil.CancelTransaction(); NetTracer.Error("ExtendedLogOnViewModel::ExecuteUnassign: Failed."); } } }
/// <summary> /// Validating the payment transaction from database. /// Print the transaction report in a specific format. /// </summary> /// <param name="customerId"></param> /// <param name="numberOfMonths"></param> public void Print(string customerId, int numberOfMonths) { const string returnSign = "\r\n"; try { //Find the start date DateTime fromDate = DateTime.Now; if (numberOfMonths == -1) { fromDate = fromDate.AddYears(-100); } else { fromDate = fromDate.AddMonths(-1 * numberOfMonths + 1); } fromDate = fromDate.AddDays(-1 * fromDate.Day + 1); fromDate = fromDate.AddHours(-1 * fromDate.Hour); fromDate = fromDate.AddMinutes(-1 * fromDate.Minute); fromDate = fromDate.AddSeconds(-1 * fromDate.Second); //Get the transactions customerData = new CustomerData(LSRetailPosis.Settings.ApplicationSettings.Database.LocalConnection, LSRetailPosis.Settings.ApplicationSettings.Database.DATAAREAID); customerTransactions = customerData.GetCustomerTransactions(customerId, fromDate); if (customerTransactions.Rows.Count > 0) { //Get customer information DM.CustomerDataManager customerDataManager = new DM.CustomerDataManager( ApplicationSettings.Database.LocalConnection, ApplicationSettings.Database.DATAAREAID); ICustomer customerInfo = customerDataManager.GetTransactionalCustomer(customerId); string line = "--------------------------------------------" + returnSign; #region Create the report //Print header information string report = "\n" + LSRetailPosis.ApplicationLocalizer.Language.Translate(51040) + " " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + returnSign + returnSign; //Report printed report += LSRetailPosis.ApplicationLocalizer.Language.Translate(51041).PadRight(15, '.').Substring(0, 15) + ": " + customerId + returnSign; //Customer Id report += LSRetailPosis.ApplicationLocalizer.Language.Translate(51042).PadRight(15, '.').Substring(0, 15) + ": " + customerInfo.Name + returnSign + returnSign; //Name //ReceiptId //Date //Type //Amount report += LSRetailPosis.ApplicationLocalizer.Language.Translate(51043).PadRight(10).Substring(0, 10) + " " + LSRetailPosis.ApplicationLocalizer.Language.Translate(51044).PadRight(10).Substring(0, 10) + " " + LSRetailPosis.ApplicationLocalizer.Language.Translate(51045).PadRight(8) + " " + LSRetailPosis.ApplicationLocalizer.Language.Translate(51046).PadLeft(13) + returnSign; report += line; Decimal subTotal = 0; Decimal total = 0; Decimal amount = 0; int prevMonthNumber = 0; string prevMonthName = string.Empty; DateTime transDate; string receiptId = string.Empty; string transactionType = string.Empty; string subTotalText = string.Empty; //Loop throug the customer transactions foreach (DataRow row in customerTransactions.Select()) { transDate = (DateTime)row["TRANSDATE"]; amount = (Decimal)row["AMOUNT"]; transactionType = (String)row["TRANSACTIONTYPE"]; if (row["RECEIPTID"] == DBNull.Value) { receiptId = string.Empty; } else { receiptId = (String)row["RECEIPTID"]; } if (prevMonthNumber == 0) { prevMonthNumber = transDate.Month; } if (transDate.Month != prevMonthNumber) { //Print subtotals report += line; subTotalText = LSRetailPosis.ApplicationLocalizer.Language.Translate(51047) + " " + prevMonthName.ToUpper() + ": "; report += subTotalText.PadLeft(32) + subTotal.ToString("n2").PadLeft(12) + returnSign; report += line; subTotal = 0; } subTotal += amount; total += amount; //Print tranactions report += receiptId.PadRight(10) + " " + transDate.ToShortDateString().PadRight(10) + " " + transactionType.PadRight(8) + amount.ToString("n2").PadLeft(14) + returnSign; prevMonthNumber = transDate.Month; prevMonthName = transDate.ToString("MMMM"); } report += line; //Print subtotals for the last month if more than one. if (numberOfMonths > 1) { subTotalText = LSRetailPosis.ApplicationLocalizer.Language.Translate(51047) + " " + prevMonthName.ToUpper() + ": "; report += subTotalText.PadLeft(32) + subTotal.ToString("n2").PadLeft(12) + returnSign; report += "============================================" + returnSign;; } //Print totals report += LSRetailPosis.ApplicationLocalizer.Language.Translate(51048).PadLeft(27) + ": " + total.ToString("n2").PadLeft(15) + returnSign + returnSign; decimal balanceNow = customerDataManager.GetBalance(customerId); report += LSRetailPosis.ApplicationLocalizer.Language.Translate(51049).PadRight(15, '.') + ": " + balanceNow.ToString("n2") + returnSign + returnSign + returnSign; //Send the report to the printer #endregion //System.Windows.Forms.DialogResult result = System.Windows.Forms.DialogResult.No; using (frmReportList reportPreview = new frmReportList(report)) { POSFormsManager.ShowPOSForm(reportPreview); if (reportPreview.DialogResult == DialogResult.OK) { if (Customer.InternalApplication.Services.Printing is Microsoft.Dynamics.Retail.Pos.Contracts.Services.IPrintingV2) { // Print to the default printer Customer.InternalApplication.Services.Printing.PrintDefault(true, report); } else { // Legacy support - direct print to printer #1 NetTracer.Warning("TransactionReport.Print - Printing service does not support default printer. Using printer #1"); Customer.InternalApplication.Services.Peripherals.Printer.PrintReceipt(report); } Customer.InternalApplication.Services.Peripherals.Printer.PrintReceipt(report); } } } } catch (Exception ex) { NetTracer.Error(ex, "TransactionReport::Print failed for customerId {0} numberOfMonths {1}", customerId, numberOfMonths); throw; } }
protected virtual ReadOnlyCollection <TaxCode> GetTaxCodes(ITaxableItem taxableItem) { if (taxableItem == null) { throw new ArgumentNullException("taxableItem"); } RetailTransaction transaction = (RetailTransaction)taxableItem.RetailTransaction; string customerId = string.Empty; // If the line has an EndDate specified (usually because it's a Returned line), // then use that value to calculate taxes, otherwise use BeginDate DateTime itemSaleDateTime = (taxableItem.EndDateTime <= NoDate) ? taxableItem.BeginDateTime : taxableItem.EndDateTime; if (transaction != null && transaction.Customer != null) { customerId = transaction.Customer.CustomerId; } CacheKey cacheKey = new CacheKey(taxableItem.ItemId, customerId, taxableItem.TaxGroupId, taxableItem.SalesTaxGroupId, itemSaleDateTime); if (taxCodeCache.ContainsKey(cacheKey)) { List <TaxCode> taxCodes = taxCodeCache[cacheKey]; // Update the lineItem object in cached Taxcode object (Everytime we get new SalesLine Object) taxCodes.ForEach(t => t.LineItem = taxableItem); return(SortCodes(taxCodes)); } NetTracer.Information("TaxCodeProvider::GetTaxCodes(): Quering database."); SqlConnection connection = Application.Settings.Database.Connection; string dataAreaId = Application.Settings.Database.DataAreaID; try { Dictionary <string, TaxCode> codes = new Dictionary <string, TaxCode>(); bool useDefaultTaxGroups = (cacheKey.TaxGroupID == null) || (cacheKey.SalesTaxGroupID == null); using (SqlCommand command = new SqlCommand()) { command.Connection = connection; string sb = string.Format(@"SELECT DISTINCT {0} FROM TAXGROUPHEADING ", TaxSelectSqlText); if (useDefaultTaxGroups) { // #1 Look in the DB for the default Customer/Store tax group mapping if (String.IsNullOrWhiteSpace(cacheKey.CustomerID)) { sb += @"INNER JOIN RETAILSTORETABLE ON TAXGROUPHEADING.TAXGROUP = RETAILSTORETABLE.TAXGROUP AND RETAILSTORETABLE.STORENUMBER = @STOREID "; command.Parameters.AddWithValue("@STOREID", ApplicationSettings.Terminal.StoreId); } else { sb += @"INNER JOIN CUSTTABLE ON TAXGROUPHEADING.TAXGROUP = CUSTTABLE.TAXGROUP AND CUSTTABLE.DATAAREAID = @DATAAREAID AND CUSTTABLE.ACCOUNTNUM = @CUSTOMERID "; command.Parameters.AddWithValue("@CUSTOMERID", cacheKey.CustomerID); } } sb += @"INNER JOIN TAXGROUPDATA ON TAXGROUPDATA.DATAAREAID = @DATAAREAID AND TAXGROUPHEADING.TAXGROUP = TAXGROUPDATA.TAXGROUP INNER JOIN TAXONITEM ON TAXONITEM.DATAAREAID = @DATAAREAID AND TAXGROUPDATA.TAXCODE = TAXONITEM.TAXCODE "; if (useDefaultTaxGroups) { // Join against the Item's default Item tax group sb += @"INNER JOIN INVENTTABLEMODULE ON INVENTTABLEMODULE.DATAAREAID = @DATAAREAID AND INVENTTABLEMODULE.TAXITEMGROUPID = TAXONITEM.TAXITEMGROUP "; } sb += @"INNER JOIN TAXDATA ON TAXDATA.DATAAREAID = @DATAAREAID AND TAXONITEM.TAXCODE = TAXDATA.TAXCODE INNER JOIN TAXTABLE ON TAXTABLE.DATAAREAID = @DATAAREAID AND TAXTABLE.TAXCODE = TAXDATA.TAXCODE LEFT JOIN TAXCOLLECTLIMIT ON TAXCOLLECTLIMIT.DATAAREAID = @DATAAREAID AND TAXCOLLECTLIMIT.TAXCODE = TAXDATA.TAXCODE AND (TAXCOLLECTLIMIT.TAXFROMDATE IS NULL OR @TRANSACTIONDATE >= TAXCOLLECTLIMIT.TAXFROMDATE OR TAXCOLLECTLIMIT.TAXFROMDATE < @NODATEBOUNDRY ) AND (TAXCOLLECTLIMIT.TAXTODATE IS NULL OR @TRANSACTIONDATE < DATEADD(d, 1, TAXCOLLECTLIMIT.TAXTODATE) OR TAXCOLLECTLIMIT.TAXTODATE < @NODATEBOUNDRY) WHERE (TAXGROUPHEADING.DATAAREAID = @DATAAREAID) "; command.Parameters.AddWithValue("@DATAAREAID", dataAreaId); if (useDefaultTaxGroups) { sb += @"AND (INVENTTABLEMODULE.ITEMID = @ITEMID) AND (INVENTTABLEMODULE.MODULETYPE = @MODULETYPE) "; command.Parameters.AddWithValue("@ITEMID", cacheKey.ItemID); command.Parameters.AddWithValue("@MODULETYPE", (int)ModuleType.Sales); } else { // Filter against the item's current Item Tax Group and Customer/Store tax group sb += @"AND TAXONITEM.TAXITEMGROUP = @ITEMTAXGROUP AND TAXGROUPHEADING.TAXGROUP = @SALESTAXGROUP "; command.Parameters.AddWithValue("@SALESTAXGROUP", cacheKey.SalesTaxGroupID ?? string.Empty); command.Parameters.AddWithValue("@ITEMTAXGROUP", cacheKey.TaxGroupID ?? string.Empty); } // Currently only evaluate taxes against the current time. // Note that the date value of '1900-01-01 00:00.000' is the marker for "no boundry". sb += @"AND ((@TRANSACTIONDATE >= TAXDATA.TAXFROMDATE OR TAXDATA.TAXFROMDATE < @NODATEBOUNDRY ) AND (@TRANSACTIONDATE < DATEADD(d, 1, TAXDATA.TAXTODATE) OR TAXDATA.TAXTODATE < @NODATEBOUNDRY)) "; command.Parameters.AddWithValue("@NODATEBOUNDRY", NoDate); command.Parameters.AddWithValue("@TRANSACTIONDATE", cacheKey.SaleDateTime); sb += AddTaxSelectSqlCondition(command); command.CommandText = sb.ToString(); if (connection.State != ConnectionState.Open) { connection.Open(); } using (SqlDataReader reader = command.ExecuteReader()) { string taxCodeKey = string.Empty; while (reader.Read()) { taxCodeKey = reader["TAXCODE"] as string; if (codes.ContainsKey(taxCodeKey)) { // Add a new 'value' entry for an existing tax code codes[taxCodeKey].TaxIntervals.Add( new TaxInterval( (decimal)reader["TAXLIMITMIN"], (decimal)reader["TAXLIMITMAX"], (decimal)reader["TAXVALUE"])); } else { AddTaxCode(cacheKey, reader, taxableItem, codes); } } } } // Link any taxes which rely on other taxes foreach (TaxCode tax in codes.Values) { if (!string.IsNullOrEmpty(tax.TaxOnTax) && (tax.TaxBase == TaxBase.PercentPerTax || tax.TaxBase == TaxBase.PercentPerGross) && codes.Keys.Contains(tax.TaxOnTax)) { tax.TaxOnTaxInstance = codes[tax.TaxOnTax] as TaxCode; } } return(SortCodes(codes.Values)); } catch (Exception ex) { NetTracer.Error(ex, "GetTaxCodes() failed in an Exception"); throw; } finally { if (connection.State == ConnectionState.Open) { connection.Close(); } } }
/// <summary> /// Print a batch to the printer as X or Z report. /// </summary> /// <param name="batch">Calculated batch object</param> /// <param name="reportType">Report type</param> public static void Print(this Batch batch, ReportType reportType) { // TextID's for the Z/X Report are reserved at 7000 - 7099 StringBuilder reportLayout = new StringBuilder(2500); // Header reportLayout.PrepareHeader(batch, reportType); // Total Amounts reportLayout.AppendReportLine(7015); reportLayout.AppendReportLine(7016, RoundDecimal(batch.SalesTotal)); reportLayout.AppendReportLine(7017, RoundDecimal(batch.ReturnsTotal)); reportLayout.AppendReportLine(7018, RoundDecimal(batch.TaxTotal)); reportLayout.AppendReportLine(7019, RoundDecimal(batch.DiscountTotal)); reportLayout.AppendReportLine(7020, RoundDecimal(batch.RoundedAmountTotal)); reportLayout.AppendReportLine(7021, RoundDecimal(batch.PaidToAccountTotal)); reportLayout.AppendReportLine(7022, RoundDecimal(batch.IncomeAccountTotal)); reportLayout.AppendReportLine(7023, RoundDecimal(batch.ExpenseAccountTotal)); reportLayout.AppendLine(); // Statistics reportLayout.AppendReportLine(7035); reportLayout.AppendReportLine(7036, batch.SalesCount); reportLayout.AppendReportLine(7038, batch.CustomersCount); reportLayout.AppendReportLine(7039, batch.VoidsCount); reportLayout.AppendReportLine(7040, batch.LogOnCount); reportLayout.AppendReportLine(7041, batch.NoSaleCount); if (reportType == ReportType.XReport) { reportLayout.AppendReportLine(7042, batch.SuspendedTransactionsCount); } reportLayout.AppendLine(); // Tender totals reportLayout.AppendReportLine(7045); reportLayout.AppendReportLine(7047, RoundDecimal(batch.TenderedTotal)); reportLayout.AppendReportLine(7048, RoundDecimal(batch.ChangeTotal)); reportLayout.AppendReportLine(7069, RoundDecimal(batch.StartingAmountTotal)); reportLayout.AppendReportLine(7049, RoundDecimal(batch.FloatEntryAmountTotal)); reportLayout.AppendReportLine(7050, RoundDecimal(batch.RemoveTenderAmountTotal)); reportLayout.AppendReportLine(7051, RoundDecimal(batch.BankDropTotal)); reportLayout.AppendReportLine(7052, RoundDecimal(batch.SafeDropTotal)); reportLayout.AppendReportLine(7053, RoundDecimal(batch.DeclareTenderAmountTotal)); bool amountShort = batch.OverShortTotal < 0; reportLayout.AppendReportLine(amountShort ? 7055 : 7054, RoundDecimal(amountShort ? decimal.Negate(batch.OverShortTotal) : batch.OverShortTotal)); reportLayout.AppendLine(); // Income/Expense if (batch.AccountLines.Count > 0) { reportLayout.AppendReportLine(7030); foreach (BatchAccountLine accountLine in batch.AccountLines.OrderBy(a => a.AccountType)) { int typeResourceId = 0; switch (accountLine.AccountType) { case IncomeExpenseAccountType.Income: typeResourceId = 7031; break; case IncomeExpenseAccountType.Expense: typeResourceId = 7032; break; default: String message = string.Format("Unsupported account Type '{0}'.", accountLine.AccountType); NetTracer.Error(message); throw new NotSupportedException(message); } reportLayout.AppendReportLine(string.Format(typeFormat, accountLine.AccountNumber, ApplicationLocalizer.Language.Translate(typeResourceId)), RoundDecimal(accountLine.Amount)); } reportLayout.AppendLine(); } // Tenders if (reportType == ReportType.ZReport && batch.TenderLines.Count > 0) { reportLayout.AppendReportLine(7046); foreach (BatchTenderLine tenderLine in batch.TenderLines.OrderBy(t => t.TenderName)) { string formatedTenderName = tenderLine.TenderName; if (ApplicationSettings.Terminal.StoreCurrency != tenderLine.Currency) { formatedTenderName = string.Format(currencyFormat, tenderLine.TenderName, tenderLine.Currency); } reportLayout.AppendReportLine(string.Format(typeFormat, formatedTenderName, ApplicationLocalizer.Language.Translate(7049)), RoundDecimal(tenderLine.AddToTenderAmountCur, tenderLine.Currency)); reportLayout.AppendReportLine(string.Format(typeFormat, formatedTenderName, ApplicationLocalizer.Language.Translate(7056)), RoundDecimal(tenderLine.ShiftAmountCur, tenderLine.Currency)); reportLayout.AppendReportLine(string.Format(typeFormat, formatedTenderName, ApplicationLocalizer.Language.Translate(7050)), RoundDecimal(tenderLine.RemoveFromTenderAmountCur, tenderLine.Currency)); if (tenderLine.CountingRequired) { reportLayout.AppendReportLine(string.Format(typeFormat, formatedTenderName, ApplicationLocalizer.Language.Translate(7053)), RoundDecimal(tenderLine.DeclareTenderAmountCur, tenderLine.Currency)); amountShort = tenderLine.OverShortAmountCur < 0; reportLayout.AppendReportLine(string.Format(typeFormat, formatedTenderName, ApplicationLocalizer.Language.Translate(amountShort ? 7055 : 7054)), RoundDecimal(amountShort ? decimal.Negate(tenderLine.OverShortAmountCur) : tenderLine.OverShortAmountCur, tenderLine.Currency)); } reportLayout.AppendReportLine(string.Format(typeFormat, formatedTenderName, ApplicationLocalizer.Language.Translate(7057)), tenderLine.Count); reportLayout.AppendLine(); } } if (((object)EOD.InternalApplication.Services.Printing) is IPrintingV2) { // Print to the default printer EOD.InternalApplication.Services.Printing.PrintDefault(true, reportLayout.ToString()); } else { // Legacy support - direct print to printer #1 NetTracer.Warning("BatchPrinting.Print - Printing service does not support default printer. Using printer #1"); EOD.InternalApplication.Services.Peripherals.Printer.PrintReceipt(reportLayout.ToString()); } }
/// <summary> /// Tender Lines /// </summary> /// <param name="dBCommand"></param> /// <param name="batch"></param> private static void CalculateTender(DbCommand dBCommand, Batch batch) { dBCommand.Initialize(sqlTenderDeclarationCalculationType); dBCommand.AddParameter("@STORE", ApplicationSettings.Terminal.StoreId); tenderDeclCalculationType = DBUtil.ToEnum <TenderDeclarationCalculationType>(dBCommand.ExecuteScalar()); // Calculate Tender addition/removal foreach (KeyValuePair <TypeOfTransaction, string> query in tenderLinesQueries) { // Checking store level setting whether Tender Declaration Calculation Type is Last or Sum. if (query.Key.Equals(PosTransaction.TypeOfTransaction.TenderDeclaration) && tenderDeclCalculationType.Equals(TenderDeclarationCalculationType.Last)) { dBCommand.Initialize(string.Format(sqlLastTenderDeclarationLine, query.Value), batch); } else { dBCommand.Initialize(string.Format(sqlTenderLines, query.Value), batch); } dBCommand.AddParameter("@TRANSACTIONSTATUS", TransactionStatus.Normal); dBCommand.AddParameter("@TRANSACTIONTYPE", (int)query.Key); using (DbDataReader reader = dBCommand.ExecuteReader()) { while (reader.Read()) { BatchTenderLine batchTenderLine = batch.TenderLines.FindOrCreate(reader); decimal amount = DBUtil.ToDecimal(reader["AMOUNT"]); decimal amountCur = DBUtil.ToDecimal(reader["AMOUNTCUR"]); batchTenderLine.CountingRequired = DBUtil.ToBool(reader["COUNTINGREQUIRED"]); switch (query.Key) { case TypeOfTransaction.StartingAmount: batchTenderLine.StartingAmount = amount; batchTenderLine.StartingAmountCur = amountCur; break; case TypeOfTransaction.FloatEntry: batchTenderLine.FloatEntryAmount = amount; batchTenderLine.FloatEntryAmountCur = amountCur; break; case TypeOfTransaction.RemoveTender: batchTenderLine.RemoveTenderAmount = decimal.Negate(amount); batchTenderLine.RemoveTenderAmountCur = decimal.Negate(amountCur); break; case TypeOfTransaction.SafeDrop: batchTenderLine.SafeDropAmount = amount; batchTenderLine.SafeDropAmountCur = amountCur; break; case TypeOfTransaction.BankDrop: batchTenderLine.BankDropAmount = amount; batchTenderLine.BankDropAmountCur = amountCur; break; case TypeOfTransaction.TenderDeclaration: batchTenderLine.DeclareTenderAmount = amount; batchTenderLine.DeclareTenderAmountCur = amountCur; break; default: String message = "Unsupported transaction type"; NetTracer.Error(message); throw new NotSupportedException(message); } } } } // Calcualte tendered and change. dBCommand.Initialize(sqlTenderCalculatedLines, batch); dBCommand.AddParameter("@TRANSACTIONSTATUS", TransactionStatus.Normal); dBCommand.AddParameter("@TYPE1", TypeOfTransaction.Sales); dBCommand.AddParameter("@TYPE2", TypeOfTransaction.Payment); dBCommand.AddParameter("@TYPE3", TypeOfTransaction.SalesInvoice); dBCommand.AddParameter("@TYPE4", TypeOfTransaction.SalesOrder); dBCommand.AddParameter("@TYPE5", TypeOfTransaction.CustomerOrder); using (DbDataReader reader = dBCommand.ExecuteReader()) { while (reader.Read()) { BatchTenderLine batchTenderLine = batch.TenderLines.FindOrCreate(reader); decimal amount = DBUtil.ToDecimal(reader["AMOUNT"]); decimal amountCur = DBUtil.ToDecimal(reader["AMOUNTCUR"]); if (DBUtil.ToBool(reader["CHANGELINE"])) { batchTenderLine.ChangeAmount = decimal.Negate(amount); batchTenderLine.ChangeAmountCur = decimal.Negate(amountCur); } else { batchTenderLine.TenderedAmount = amount; batchTenderLine.TenderedAmountCur = amountCur; batchTenderLine.Count = DBUtil.ToInt32(reader["COUNT"]); } batchTenderLine.CountingRequired = DBUtil.ToBool(reader["COUNTINGREQUIRED"]); } } }
/// <summary> /// Get discount parameters from the database. These parameters tell what search possibilities are active. /// </summary> private void GetDiscountParameters() { string queryString = "SELECT SALESLINEACCOUNTITEM, SALESLINEACCOUNTGROUP, SALESLINEACCOUNTALL," + "SALESLINEGROUPITEM, SALESLINEGROUPGROUP, SALESLINEGROUPALL, " + "SALESLINEALLITEM, SALESLINEALLGROUP, SALESLINEALLALL, " + "SALESMULTILNACCOUNTGROUP, SALESMULTILNACCOUNTALL," + "SALESMULTILNGROUPGROUP, SALESMULTILNGROUPALL," + "SALESMULTILNALLGROUP,SALESMULTILNALLALL, " + "SALESENDACCOUNTALL, SALESENDGROUPALL, SALESENDALLALL " + "FROM PRICEPARAMETERS WHERE " + "DATAAREAID = @DATAAREAID "; SqlConnection connection = Discount.InternalApplication.Settings.Database.Connection; string dataAreaId = Discount.InternalApplication.Settings.Database.DataAreaID; try { using (SqlCommand command = new SqlCommand(queryString, connection)) { command.Parameters.AddWithValue("@DATAAREAID", dataAreaId); if (connection.State != ConnectionState.Open) { connection.Open(); } using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow)) { reader.Read(); if (reader.HasRows) { //Line Account SalesLineAccountItem = Utility.ToBool(reader["SALESLINEACCOUNTITEM"]); SalesLineAccountGroup = Utility.ToBool(reader["SALESLINEACCOUNTGROUP"]); SalesLineAccountAll = Utility.ToBool(reader["SALESLINEACCOUNTALL"]); //Line Group SalesLineGroupItem = Utility.ToBool(reader["SALESLINEGROUPITEM"]); SalesLineGroupGroup = Utility.ToBool(reader["SALESLINEGROUPGROUP"]); SalesLineGroupAll = Utility.ToBool(reader["SALESLINEGROUPALL"]); //Line All SalesLineAllItem = Utility.ToBool(reader["SALESLINEALLITEM"]); SalesLineAllGroup = Utility.ToBool(reader["SALESLINEALLGROUP"]); SalesLineAllAll = Utility.ToBool(reader["SALESLINEALLALL"]); //MultiLine Account SalesMultiLineAccountGroup = Utility.ToBool(reader["SALESMULTILNACCOUNTGROUP"]); SalesMultiLineAccountAll = Utility.ToBool(reader["SALESMULTILNACCOUNTALL"]); //MultiLine Group SalesMultiLineGroupGroup = Utility.ToBool(reader["SALESMULTILNGROUPGROUP"]); SalesMultiLineGroupAll = Utility.ToBool(reader["SALESMULTILNGROUPALL"]); //MultiLine All SalesMultiLineAllGroup = Utility.ToBool(reader["SALESMULTILNALLGROUP"]); SalesMultiLineAllAll = Utility.ToBool(reader["SALESMULTILNALLALL"]); //Total SalesEndAccountAll = Utility.ToBool(reader["SALESENDACCOUNTALL"]); SalesEndGroupAll = Utility.ToBool(reader["SALESENDGROUPALL"]); SalesEndAllAll = Utility.ToBool(reader["SALESENDALLALL"]); } else { SalesLineAccountItem = false; SalesLineAccountGroup = false; SalesLineAccountAll = false; SalesLineGroupItem = false; SalesLineGroupGroup = false; SalesLineGroupAll = false; SalesLineAllItem = false; SalesLineAllGroup = false; SalesLineAllAll = false; SalesMultiLineAccountGroup = false; SalesMultiLineAccountAll = false; SalesMultiLineGroupGroup = false; SalesMultiLineGroupAll = false; SalesMultiLineAllGroup = false; SalesMultiLineAllAll = false; SalesEndAccountAll = false; SalesEndGroupAll = false; SalesEndAllAll = false; } } } } catch (Exception ex) { // Technically violates CA2214 calling this.ToString(). However this instance appears to be safe. NetTracer.Error(ex, "DiscountParameters::GetDiscountParameters failed"); LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), ex); throw; } finally { if (connection.State == ConnectionState.Open) { connection.Close(); } } }
private decimal CalculatePointsForTransactionByScheme(Int64 groupMemberLineRecId, decimal qtyAmountLimit, decimal points, CalculationTypeBase baseType, LoyaltyPointTypeBase type) { try { decimal totalQty = 0; decimal totalAmount = 0; Int64 variantId; Int64 productId; Int64 categoryId; DataRow groupMemberLine = GetRetailGroupLineMember(groupMemberLineRecId); if (groupMemberLine == null) { NetTracer.Warning("Loyalty:CalculatePointsForTranactionByScheme: groupMemberLine is null"); return(decimal.Zero); } categoryId = (Int64)groupMemberLine["Category"]; productId = (Int64)groupMemberLine["Product"]; variantId = (Int64)groupMemberLine["Variant"]; if (type != LoyaltyPointTypeBase.Tender) { foreach (SaleLineItem saleLineItem in this.transaction.SaleItems) { bool found = false; if (!saleLineItem.Voided) { ItemData itemData = new ItemData( ApplicationSettings.Database.LocalConnection, ApplicationSettings.Database.DATAAREAID, ApplicationSettings.Terminal.StorePrimaryId); // check for a variant being put on loyalty if (variantId != 0) { found = (variantId == saleLineItem.Dimension.DistinctProductVariantId); } // Check for a product or product master being put on loyalty else if (productId != 0) { found = (productId == saleLineItem.ProductId); } // Check for a category being put on loyalty else if (categoryId != 0) { found = itemData.ProductInCategory(saleLineItem.ProductId, saleLineItem.Dimension.DistinctProductVariantId, categoryId); } } if (found) { totalQty += saleLineItem.UnitQtyConversion.Convert(saleLineItem.Quantity); totalAmount += saleLineItem.NetAmount; } } } //when check limit, we use absolute value, as in return transaction, qty and amount could be nagative. if (qtyAmountLimit > 0) { if (baseType == CalculationTypeBase.Amounts) { decimal companyCurrencyAmount = this.Application.Services.Currency.CurrencyToCurrency( ApplicationSettings.Terminal.StoreCurrency, ApplicationSettings.Terminal.CompanyCurrency, totalAmount); //Check QtyAmountLimit only for non-tender loyalty point type. if (Math.Abs(companyCurrencyAmount) >= qtyAmountLimit || type == LoyaltyPointTypeBase.Tender) { return(companyCurrencyAmount > 0 ? Math.Floor(companyCurrencyAmount / qtyAmountLimit * points) : Math.Ceiling(companyCurrencyAmount / qtyAmountLimit * points)); } } else { if (Math.Abs(totalQty) >= qtyAmountLimit) { return(totalQty > 0 ? Math.Floor(totalQty / qtyAmountLimit * points) : Math.Ceiling(totalQty / qtyAmountLimit * points)); } } } // default return(0); } catch (Exception ex) { NetTracer.Error(ex, "Loyalty::CalculatePointsForTransactionByScheme failed for groupMemberLineRecId {0} qtyAmountLimit {1} points {2}", groupMemberLineRecId, qtyAmountLimit, points); LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), ex); throw; } }
/// <summary> /// Calculate the tax bases calculationBase and limitBase (which is zero for India). /// </summary> /// <param name="basePrice">The base price.</param> /// <param name="taxInStoreCurrency">if set to <c>true</c> [tax in store currency].</param> /// <param name="calculateBasePrice">if set to <c>true</c> [Calculate the base price].</param> /// <param name="calculationBase">The calculation base.</param> /// <param name="limitBase">The limit base.</param> protected override void GetBases(ReadOnlyCollection <TaxCode> codes, bool taxInStoreCurrency, bool calculateBasePrice, out decimal calculationBase, out decimal limitBase) { limitBase = decimal.Zero; // For amount by unit calculation base is just the quantity. if (this.TaxBase == TaxBase.AmountByUnit) { calculationBase = LineItem.Quantity; // If the tax is calculated in a different UOM, then convert if possible // this is only applicable for lineItem taxes. BaseSaleItem saleLineItem = this.LineItem as BaseSaleItem; if (saleLineItem != null && !string.Equals(this.Unit, this.LineItem.SalesOrderUnitOfMeasure, StringComparison.OrdinalIgnoreCase)) { UnitOfMeasureData uomData = new UnitOfMeasureData( ApplicationSettings.Database.LocalConnection, ApplicationSettings.Database.DATAAREAID, ApplicationSettings.Terminal.StorePrimaryId, TaxService.Tax.InternalApplication); UnitQtyConversion uomConversion = uomData.GetUOMFactor(this.LineItem.SalesOrderUnitOfMeasure, this.Unit, saleLineItem); calculationBase *= uomConversion.GetFactorForQty(this.LineItem.Quantity); } return; } // Determine the starting calculation base (includes the line price or not) switch (Formula.TaxableBasis) { case TaxableBases.LineAmount: calculationBase = this.LineItem.NetAmountWithAllInclusiveTaxPerUnit; break; case TaxableBases.MRP: calculationBase = GetMRP(); break; default: calculationBase = decimal.Zero; break; } if (this.TaxIncludedInPrice) { calculationBase = GetBasePriceForTaxIncluded(calculationBase, codes, Formula); } calculationBase *= Math.Abs(this.LineItem.Quantity); // Calculation expression is of the form: +[BCD]+[CVD]+[E-CESS_CVD]+[PE-C_CVD]+[SHE-C_CVD] // where the brackets are replaced with the delimiter char(164) // and BCD, CVD ... are tax codes. // The operator may be + - / *. string[] tokens = Formula.ParseExpression(); for (int index = 1; index < tokens.Length; index += 2) { ITaxItem taxItem = (from line in this.LineItem.TaxLines where line.TaxCode == tokens[index] select line).FirstOrDefault(); if (taxItem != null) { this.IsTaxOnTax = true; this.TaxCodesInFormula.Add(taxItem.TaxCode); } decimal amount = taxItem == null ? decimal.Zero : taxItem.Amount * Math.Sign(this.LineItem.Quantity); switch (tokens[index - 1]) { case "+": calculationBase += amount; break; case "-": calculationBase -= amount; break; case "*": calculationBase *= amount; break; case "/": calculationBase = (amount == decimal.Zero ? calculationBase : calculationBase /= amount); break; default: NetTracer.Error("GetBases(): Invalid operator in formula. tokens[{0}]: {1}", index - 1, tokens[index - 1]); System.Diagnostics.Debug.Fail("Invalid operator in formula"); break; } } // Knock any abatement off of the taxable basis calculationBase *= (100 - AbatementPercent) / 100; }
public bool AddLoyaltyRequest(IRetailTransaction retailTransaction, ICardInfo cardInfo) { try { try { NewMessageWindow(50050, LSPosMessageTypeButton.NoButtons, System.Windows.Forms.MessageBoxIcon.Information); LogMessage("Adding a loyalty record to the transaction...", LSRetailPosis.LogTraceLevel.Trace, "Loyalty.AddLoyaltyItem"); this.transaction = (RetailTransaction)retailTransaction; // If a previous loyalty item exists on the transaction, the system should prompt the user whether to // overwrite the existing loyalty item or cancel the operation. if (transaction.LoyaltyItem.LoyaltyCardNumber != null) { // Display the dialog using (frmMessage dialog = new frmMessage(50055, MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { LP.POSFormsManager.ShowPOSForm(dialog); DialogResult result = dialog.DialogResult; if (result != System.Windows.Forms.DialogResult.Yes) { return(false); } } // If card to be overridden is being used as tender type then block loyalty payment. if (transaction.LoyaltyItem.UsageType == LoyaltyItemUsageType.UsedForLoyaltyTender) { LP.POSFormsManager.ShowPOSMessageDialog(3223); // This transaction already contains a loyalty request. return(false); } } // Add the loyalty item to the transaction LoyaltyItem loyaltyItem = GetLoyaltyItem(ref cardInfo); if (loyaltyItem != null) { transaction.LoyaltyItem = loyaltyItem; this.transaction.LoyaltyItem.UsageType = LoyaltyItemUsageType.UsedForLoyaltyRequest; UpdateTransactionWithNewCustomer(loyaltyItem.CustID); return(true); } else { return(false); } } finally { CloseExistingMessageWindow(); } } catch (Exception ex) { NetTracer.Error(ex, "Loyalty::AddLoyaltyRequest failed for retailTransaction {0} cardInfo {1}", retailTransaction.TransactionId, cardInfo.CardNumber); LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), ex); throw; } }
public void AddLoyaltyPayment(IRetailTransaction retailTransaction, ICardInfo cardInfo, decimal amount) { try { try { NewMessageWindow(50051, LSPosMessageTypeButton.NoButtons, System.Windows.Forms.MessageBoxIcon.Information); this.transaction = (RetailTransaction)retailTransaction; // Getting the loyalty info for the card, how many points have previously been earned LoyaltyItem paymentLoyaltyItem = GetLoyaltyItem(ref cardInfo); if (paymentLoyaltyItem != null) { //customerData. if (this.transaction.Customer == null || string.Equals(this.transaction.Customer.CustomerId, paymentLoyaltyItem.CustID, StringComparison.OrdinalIgnoreCase) == false) { UpdateTransactionWithNewCustomer(paymentLoyaltyItem.CustID); } // if the amount is higher than the "new" NetAmountWithTax, then it is acceptable to lower the amount if (Math.Abs(amount) > Math.Abs(this.transaction.TransSalePmtDiff)) { amount = this.transaction.TransSalePmtDiff; } // Getting all possible loyalty posssiblities for the found scheme id DataTable loyaltyPointsTable = GetLoyaltyPointsSchemeFromDB(paymentLoyaltyItem.SchemeID); decimal totalNumberOfPoints = 0; bool tenderRuleFound = false; // now we add the points needed to pay current tender totalNumberOfPoints = CalculatePointsForTender(ref tenderRuleFound, cardInfo.TenderTypeId, amount, loyaltyPointsTable); if (tenderRuleFound) { bool cardIsValid = false; string comment = string.Empty; int loyaltyTenderTypeBase = 0; decimal pointsEarned = 0; // check to see if the user can afford so many points GetPointStatus(ref pointsEarned, ref cardIsValid, ref comment, ref loyaltyTenderTypeBase, paymentLoyaltyItem.LoyaltyCardNumber); if ((cardIsValid) && ((LoyaltyTenderTypeBase)loyaltyTenderTypeBase != LoyaltyTenderTypeBase.NoTender)) { if (pointsEarned >= (totalNumberOfPoints * -1)) { //customerData. if (this.transaction.Customer == null || string.Equals(this.transaction.Customer.CustomerId, paymentLoyaltyItem.CustID, StringComparison.OrdinalIgnoreCase) == false) { UpdateTransactionWithNewCustomer(paymentLoyaltyItem.CustID); } //Add loyalty item to transaction. this.transaction.LoyaltyItem = paymentLoyaltyItem; this.transaction.LoyaltyItem.UsageType = LoyaltyItemUsageType.UsedForLoyaltyTender; // Gathering tender information TenderData tenderData = new TenderData(ApplicationSettings.Database.LocalConnection, ApplicationSettings.Database.DATAAREAID); ITender tenderInfo = tenderData.GetTender(cardInfo.TenderTypeId, ApplicationSettings.Terminal.StoreId); // this is the grand total decimal totalAmountDue = this.transaction.TransSalePmtDiff - amount; TenderRequirement tenderRequirement = new TenderRequirement((Tender)tenderInfo, amount, true, this.transaction.TransSalePmtDiff); if (!string.IsNullOrWhiteSpace(tenderRequirement.ErrorText)) { using (LSRetailPosis.POSProcesses.frmMessage dialog = new LSRetailPosis.POSProcesses.frmMessage(tenderRequirement.ErrorText, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error)) { LSRetailPosis.POSProcesses.POSFormsManager.ShowPOSForm(dialog); } } //Add a loyalty tender item to transaction. LoyaltyTenderLineItem loyaltyTenderItem = (LoyaltyTenderLineItem)this.Application.BusinessLogic.Utility.CreateLoyaltyTenderLineItem(); loyaltyTenderItem.CardNumber = paymentLoyaltyItem.LoyaltyCardNumber; loyaltyTenderItem.CardTypeId = cardInfo.CardTypeId; loyaltyTenderItem.Amount = amount; //tenderInfo. loyaltyTenderItem.Description = tenderInfo.TenderName; loyaltyTenderItem.TenderTypeId = cardInfo.TenderTypeId; loyaltyTenderItem.LoyaltyPoints = totalNumberOfPoints; //convert from the store-currency to the company-currency... loyaltyTenderItem.CompanyCurrencyAmount = this.Application.Services.Currency.CurrencyToCurrency( ApplicationSettings.Terminal.StoreCurrency, ApplicationSettings.Terminal.CompanyCurrency, amount); // the exchange rate between the store amount(not the paid amount) and the company currency loyaltyTenderItem.ExchrateMST = this.Application.Services.Currency.ExchangeRate( ApplicationSettings.Terminal.StoreCurrency) * 100; // card tender processing and printing require an EFTInfo object to be attached. // however, we don't want loyalty info to show up where other EFT card info would on the receipt // because loyalty has its own receipt template fields, so we just assign empty EFTInfo object loyaltyTenderItem.EFTInfo = Application.BusinessLogic.Utility.CreateEFTInfo(); // we don't want Loyalty to be 'captured' by payment service, so explicitly set not to capture to be safe loyaltyTenderItem.EFTInfo.IsPendingCapture = false; loyaltyTenderItem.SignatureData = LSRetailPosis.POSProcesses.TenderOperation.ProcessSignatureCapture(tenderInfo, loyaltyTenderItem); this.transaction.Add(loyaltyTenderItem); } else { using (LSRetailPosis.POSProcesses.frmMessage dialog = new LSRetailPosis.POSProcesses.frmMessage(50057, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error)) { LSRetailPosis.POSProcesses.POSFormsManager.ShowPOSForm(dialog); } // Not enough points available to complete payment } } else { LSRetailPosis.POSProcesses.frmMessage dialog = null; try { if (string.IsNullOrEmpty(comment)) { dialog = new LSRetailPosis.POSProcesses.frmMessage(50058, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } else { dialog = new LSRetailPosis.POSProcesses.frmMessage(comment, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } LSRetailPosis.POSProcesses.POSFormsManager.ShowPOSForm(dialog); // Invalid loyaltycard } finally { if (dialog != null) { dialog.Dispose(); } } } } else { using (LSRetailPosis.POSProcesses.frmMessage dialog = new LSRetailPosis.POSProcesses.frmMessage(50059, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error)) { LSRetailPosis.POSProcesses.POSFormsManager.ShowPOSForm(dialog); // Not enough points available to complete payment } } } } finally { CloseExistingMessageWindow(); } } catch (Exception ex) { NetTracer.Error(ex, "Loyalty::AddLoyaltyPayment failed for retailTransaction {0} cardInfo {1} amount {2}", retailTransaction.TransactionId, cardInfo.CardNumber, amount); LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), ex); throw; } }
/// <summary> /// Calculates the tax amounts india. /// </summary> /// <param name="codes">The codes.</param> /// <param name="codeIndia">The code india.</param> /// <param name="amtPerUnitVal">The amt per unit val.</param> /// <param name="taxVal">The tax val.</param> /// <param name="formula">The formula val.</param> private static void CalculateTaxAmountsIndia(ReadOnlyCollection <TaxCode> codes, TaxCodeIndia codeIndia, ref decimal amtPerUnitVal, ref decimal taxVal, Formula formula) { decimal amtPerUnit = decimal.Zero; decimal taxCodeValue = decimal.Zero; decimal taxValueLoc; taxVal = decimal.Zero; amtPerUnitVal = decimal.Zero; if (codeIndia.Formula.TaxableBasis != TaxableBases.ExclAmount && codeIndia.Formula.TaxableBasis != formula.TaxableBasis) { return; } string[] tokens = codeIndia.Formula.ParseExpression(); if (tokens.Length > 1) { Formula basisFormula = FormulaData.GetFormula(codeIndia.TaxGroup, tokens[1]); if (basisFormula != null && basisFormula.TaxableBasis == formula.TaxableBasis) { // Iterate through the formula for (int index = 1; index < tokens.Length; index += 2) { TaxCode basisCode = (from c in codes where c.Code == tokens[index] select c).FirstOrDefault(); if ((basisCode != null) && !basisCode.Exempt) { codeIndia.IsTaxOnTax = true; codeIndia.TaxCodesInFormula.Add(basisCode.Code); // Either add or subtract the values based on the operator switch (tokens[index - 1]) { case "-": if (basisCode.TaxBase == TaxBase.AmountByUnit) { amtPerUnit -= basisCode.AmtPerUnitValue; } else { taxCodeValue -= basisCode.TaxValue; } break; case "+": if (basisCode.TaxBase == TaxBase.AmountByUnit) { amtPerUnit += basisCode.AmtPerUnitValue; } else { taxCodeValue += basisCode.TaxValue; } break; default: NetTracer.Error("CalculateTaxAmountsIndia(): Multiplication and division not currently supported in AX. tokens[{0}]: {1}", index - 1, tokens[index - 1]); Debug.Fail("Multiplication and division not currently supported in AX"); break; } } } } } taxValueLoc = codeIndia.Value; if (codeIndia.TaxBase == TaxBase.AmountByUnit) { taxVal = decimal.Zero; amtPerUnitVal = taxValueLoc; } else { if (codeIndia.Formula.TaxableBasis != TaxableBases.ExclAmount) { taxVal = ((1 + taxCodeValue) * taxValueLoc) / 100; } else { taxVal = (taxCodeValue * taxValueLoc) / 100; } taxVal *= (100 - codeIndia.AbatementPercent) / 100; amtPerUnitVal = amtPerUnit * taxValueLoc / 100; } }