/// <summary> /// Gets the tender detail object from the client. /// </summary> /// <param name="context">The request context.</param> /// <param name="tenderDetail">The tender detail object from client.</param> /// <returns>The tender detail object to be saved on channel database.</returns> internal static TenderDetail ConvertToTenderDetail(RequestContext context, TenderDetail tenderDetail) { var tender = new TenderDetail { BankBagNumber = tenderDetail.BankBagNumber, // bankbag number TenderTypeId = tenderDetail.TenderTypeId, // tender type identifier Amount = tenderDetail.Amount // amount in channel currency }; string channelCurrency = context.GetChannelConfiguration().Currency; string foreignCurrency = string.IsNullOrWhiteSpace(tenderDetail.ForeignCurrency) ? channelCurrency : tenderDetail.ForeignCurrency; // Check if the foreign currency of the transaction is in channel currency if (foreignCurrency.Equals(channelCurrency, StringComparison.OrdinalIgnoreCase)) { tender.ForeignCurrency = channelCurrency; // foreign currency code is same as store currency code tender.AmountInForeignCurrency = tenderDetail.Amount; // foreign amount is same as store amount tender.ForeignCurrencyExchangeRate = 1m; // foreign to channel currency exchange rate is 1 } else { tender.ForeignCurrency = foreignCurrency; // foreign currency code tender.AmountInForeignCurrency = tenderDetail.AmountInForeignCurrency; // foreign amount tender.ForeignCurrencyExchangeRate = tenderDetail.ForeignCurrencyExchangeRate; // foreign to channel currency exchange rate } // Retrieve the amount in company currency with the exchange rate between foreign and company currency Tuple <decimal, decimal> companyCurrencyValues = StoreOperationServiceHelper.GetCompanyCurrencyValues(context, tender.AmountInForeignCurrency, tender.ForeignCurrency); tender.AmountInCompanyCurrency = companyCurrencyValues.Item1; // amount MST tender.CompanyCurrencyExchangeRate = companyCurrencyValues.Item2; // exchange rate MST return(tender); }
/// <summary> /// Invoke the method to get non sale tender transaction list for the given non sale tender type. /// </summary> /// <param name="request">Request for non sale tender service.</param> /// <returns>Returns the response for non sale tender operation get request.</returns> private static GetNonSaleTenderServiceResponse GetNonSaleTenderTransactions(GetNonSaleTenderServiceRequest request) { NonSalesTransaction tenderTransaction = StoreOperationServiceHelper.ConvertToNonSalesTenderTransaction(request.RequestContext, request.ShiftId, request.ShiftTerminalId, request.TransactionType); var getCurrentShiftNonSalesTransactionsdataServiceRequest = new GetCurrentShiftNonSalesTransactionsDataRequest(tenderTransaction, request.TransactionId); PagedResult <NonSalesTransaction> nonSaleOperationList = request.RequestContext.Runtime.Execute <EntityDataServiceResponse <NonSalesTransaction> >(getCurrentShiftNonSalesTransactionsdataServiceRequest, request.RequestContext).PagedEntityCollection; return(new GetNonSaleTenderServiceResponse(nonSaleOperationList)); }
/// <summary> /// Gets the object of non sales tender operation. /// </summary> /// <param name="context">The request context.</param> /// <param name="shiftId">The shift identifier.</param> /// <param name="shiftTerminalId">The shift terminal identifier.</param> /// <param name="tenderType">The non sale tender type.</param> /// <returns>The non sales tender operation object.</returns> internal static NonSalesTransaction ConvertToNonSalesTenderTransaction(RequestContext context, string shiftId, string shiftTerminalId, TransactionType tenderType) { var transaction = new NonSalesTransaction { ShiftId = shiftId, TransactionType = tenderType, TenderTypeId = StoreOperationServiceHelper.GetCashTenderTypeIdentifier(context), // Default it to cash. StoreId = context.GetOrgUnit().OrgUnitNumber, StaffId = context.GetPrincipal().UserId, TerminalId = context.GetTerminal().TerminalId, ShiftTerminalId = string.IsNullOrWhiteSpace(shiftTerminalId) ? context.GetPrincipal().ShiftTerminalId : shiftTerminalId }; return(transaction); }
/// <summary> /// Validates the counting difference for tender declaration operation. /// </summary> /// <param name="request">Drop and declare service request.</param> internal static void ValidateTenderDeclarationCountingDifference(SaveDropAndDeclareServiceRequest request) { ThrowIf.Null(request, "request"); ThrowIf.NullOrWhiteSpace(request.ShiftId, "request.ShiftId"); if (request.TransactionType == TransactionType.TenderDeclaration) { // Retrieves the tender types info Dictionary <string, TenderType> tenderTypeDict = StoreOperationServiceHelper.GetChannelTenderTypes(request.RequestContext); // Check if tender declaration recount is needed bool isRecountNeeded = request.TenderDetails.All(t => tenderTypeDict.ContainsKey(t.TenderTypeId)) && request.TenderDetails.Any(t => t.TenderRecount < tenderTypeDict[t.TenderTypeId].MaxRecount); if (isRecountNeeded) { // Retrieves the expected shift tender amounts per tender type Dictionary <string, ShiftTenderLine> expectedShiftTenderAmounts = StoreOperationServiceHelper.GetShiftRequiredAmountsPerTender(request.RequestContext, request.ShiftTerminalId, request.ShiftId); // Validates the counting amount in tender declaration lines foreach (TenderDetail declartionLine in request.TenderDetails) { string tenderTypeId = declartionLine.TenderTypeId; decimal countingDifferenceAllowed = tenderTypeDict[tenderTypeId].MaxCountingDifference; decimal expectedShiftTenderAmount = expectedShiftTenderAmounts.ContainsKey(tenderTypeId) ? expectedShiftTenderAmounts[tenderTypeId].TenderedAmountOfStoreCurrency : 0M; int maxRecountAllowed = tenderTypeDict[tenderTypeId].MaxRecount; string tenderName = tenderTypeDict[tenderTypeId].Name; // Checks if current number of recount exceeds the permissible recount if (declartionLine.TenderRecount < maxRecountAllowed) { // Checks if the difference between current tender delcartion amount with expected tender amounts // exceeds the permissible counting difference for that tender type if (Math.Abs(declartionLine.Amount - expectedShiftTenderAmount) > countingDifferenceAllowed) { throw new TenderValidationException( tenderTypeId, DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_MaxCountingDifferenceExceeded, string.Format("The counted amount differs from the total sales amount for the {0} tender type.", tenderName)) { LocalizedMessageParameters = new object[] { tenderName } }; } } } } } }
/// <summary> /// Invoke the method to save non sale tender type transactions. /// </summary> /// <param name="request">Request for non sale tender transactions.</param> /// <returns>Returns the non sale tender transactions.</returns> private static SaveNonSaleTenderServiceResponse SaveNonSaleTenderTransactions(SaveNonSaleTenderServiceRequest request) { NonSalesTransaction nonSalesTransaction = StoreOperationServiceHelper.ConvertToNonSalesTenderTransaction(request.RequestContext, request); // If the previously created tender transaction response did not get received due to network connection issue. // On client retry, check if it was already saved. If true, returns saved object. var getCurrentShiftNonSalesTransactionsdataServiceRequest = new GetCurrentShiftNonSalesTransactionsDataRequest(nonSalesTransaction, request.TransactionId); NonSalesTransaction savedNonSalesTransaction = request.RequestContext.Runtime.Execute <EntityDataServiceResponse <NonSalesTransaction> >(getCurrentShiftNonSalesTransactionsdataServiceRequest, request.RequestContext).PagedEntityCollection.FirstOrDefault(); if (savedNonSalesTransaction == null) { var saveNonSalesTransactionsdataServiceRequest = new SaveNonSalesTransactionDataRequest(nonSalesTransaction); savedNonSalesTransaction = request.RequestContext.Runtime.Execute <SingleEntityDataServiceResponse <NonSalesTransaction> >(saveNonSalesTransactionsdataServiceRequest, request.RequestContext).Entity; } return(new SaveNonSaleTenderServiceResponse(savedNonSalesTransaction)); }
/// <summary> /// Gets the object of non sales tender operation. /// </summary> /// <param name="context">The request context.</param> /// <param name="nonSaleTenderServiceRequest">The non-sale shift tender operation request.</param> /// <returns>The non sales tender operation object.</returns> internal static NonSalesTransaction ConvertToNonSalesTenderTransaction(RequestContext context, SaveNonSaleTenderServiceRequest nonSaleTenderServiceRequest) { string channelCurrency = context.GetChannelConfiguration().Currency; var transaction = new NonSalesTransaction { Id = nonSaleTenderServiceRequest.TransactionId, ShiftId = nonSaleTenderServiceRequest.ShiftId, ShiftTerminalId = string.IsNullOrWhiteSpace(nonSaleTenderServiceRequest.ShiftTerminalId) ? context.GetPrincipal().ShiftTerminalId : nonSaleTenderServiceRequest.ShiftTerminalId, Description = nonSaleTenderServiceRequest.Description, TransactionType = nonSaleTenderServiceRequest.TransactionType, TenderTypeId = StoreOperationServiceHelper.GetCashTenderTypeIdentifier(context), // Default it to cash. StoreId = context.GetOrgUnit().OrgUnitNumber, StaffId = context.GetPrincipal().UserId, TerminalId = context.GetTerminal().TerminalId, ChannelCurrencyExchangeRate = StoreOperationServiceHelper.GetExchangeRate(context), Amount = nonSaleTenderServiceRequest.Amount, // amount in store currency ForeignCurrency = string.IsNullOrWhiteSpace(nonSaleTenderServiceRequest.Currency) ? channelCurrency : nonSaleTenderServiceRequest.Currency, ChannelCurrency = context.GetChannelConfiguration().Currency // channel currency code }; // Retrieve the amount in foreign currency with the exchange rate between foreign and channel currency Tuple <decimal, decimal> foreignCurrencyValues = StoreOperationServiceHelper.GetForeignCurrencyValues(context, transaction.Amount, transaction.ForeignCurrency); transaction.AmountInForeignCurrency = foreignCurrencyValues.Item1; // foreign currency amount transaction.ForeignCurrencyExchangeRate = foreignCurrencyValues.Item2; // foreign currency exchange rate // Retrieve the amount in company currency with the exchange rate between foreign and company currency Tuple <decimal, decimal> companyCurrencyValues = StoreOperationServiceHelper.GetCompanyCurrencyValues(context, transaction.AmountInForeignCurrency, transaction.ForeignCurrency); transaction.AmountInCompanyCurrency = companyCurrencyValues.Item1; // amount MST transaction.CompanyCurrencyExchangeRate = companyCurrencyValues.Item2; // exchange rate MST if (nonSaleTenderServiceRequest.ReasonCodeLines != null && nonSaleTenderServiceRequest.ReasonCodeLines.Any()) { // Read reason code details from service request for open drawer operation transaction.ReasonCodeLines = new Collection <ReasonCodeLine>(); foreach (var reasonCodeLine in nonSaleTenderServiceRequest.ReasonCodeLines) { transaction.ReasonCodeLines.Add(reasonCodeLine); } } return(transaction); }
/// <summary> /// Gets the object of tender drop and declare operation. /// </summary> /// <param name="request">The SaveDropAndDeclareServiceRequest object.</param> /// <returns>The tender drop and declare operation object.</returns> internal static DropAndDeclareTransaction ConvertTenderDropAndDeclareTransaction(SaveDropAndDeclareServiceRequest request) { RequestContext context = request.RequestContext; var transaction = new DropAndDeclareTransaction { Id = request.TransactionId, ShiftId = request.ShiftId, ShiftTerminalId = string.IsNullOrWhiteSpace(request.ShiftTerminalId) ? context.GetPrincipal().ShiftTerminalId : request.ShiftTerminalId, TransactionType = request.TransactionType, ChannelCurrencyExchangeRate = StoreOperationServiceHelper.GetExchangeRate(context), StoreId = context.GetOrgUnit().OrgUnitNumber, StaffId = context.GetPrincipal().UserId, TerminalId = context.GetTerminal().TerminalId, ChannelCurrency = context.GetChannelConfiguration().Currency, // channel currency code Description = request.Description }; transaction.TenderDetails = new Collection <TenderDetail>(); foreach (var tenderDetail in request.TenderDetails) { TenderDetail tender = ConvertToTenderDetail(context, tenderDetail); transaction.TenderDetails.Add(tender); } if (request.ReasonCodeLines != null && request.ReasonCodeLines.Any()) { // Read reason code details from request for [Tender Declaration] store operation transaction.ReasonCodeLines = new Collection <ReasonCodeLine>(); foreach (var reasonCodeLine in request.ReasonCodeLines) { transaction.ReasonCodeLines.Add(reasonCodeLine); } } return(transaction); }
/// <summary> /// Invoke the method to save drop and declare transactions. /// </summary> /// <param name="request">Request context.</param> /// <returns>Returns response for save drop and declare.</returns> private static SaveDropAndDeclareServiceResponse SaveDropAndDeclareTransactions(SaveDropAndDeclareServiceRequest request) { StoreOperationServiceHelper.ValidateTenderDeclarationCountingDifference(request); DropAndDeclareTransaction tenderDropAndDeclare = StoreOperationServiceHelper.ConvertTenderDropAndDeclareTransaction(request); // If the previously created drop transaction response did not get received due to network connection issue. // On client retry, check if it was already saved. If true, returns saved object. var getDropAndDeclareTransactionDataRequest = new GetDropAndDeclareTransactionDataRequest(tenderDropAndDeclare.Id, QueryResultSettings.SingleRecord); DropAndDeclareTransaction transaction = request.RequestContext.Runtime.Execute <EntityDataServiceResponse <DropAndDeclareTransaction> >(getDropAndDeclareTransactionDataRequest, request.RequestContext).PagedEntityCollection.FirstOrDefault(); if (transaction != null) { var getDropAndDeclareTransactionTenderDetailsDataRequest = new GetDropAndDeclareTransactionTenderDetailsDataRequest(tenderDropAndDeclare.Id, QueryResultSettings.AllRecords); transaction.TenderDetails = request.RequestContext.Runtime.Execute <EntityDataServiceResponse <TenderDetail> >(getDropAndDeclareTransactionTenderDetailsDataRequest, request.RequestContext).PagedEntityCollection.Results; } else { var saveDropAndDeclareTransactionDataRequest = new SaveDropAndDeclareTransactionDataRequest(tenderDropAndDeclare); transaction = request.RequestContext.Runtime.Execute <SingleEntityDataServiceResponse <DropAndDeclareTransaction> >(saveDropAndDeclareTransactionDataRequest, request.RequestContext).Entity; } return(new SaveDropAndDeclareServiceResponse(transaction)); }