/// <summary> /// Initializes a new instance of the <see cref="SqliteDatabaseContext"/> class. /// </summary> /// <param name="requestContext">The request context.</param> public SqliteDatabaseContext(RequestContext requestContext) : base(requestContext) { ChannelConfiguration channelConfiguration = requestContext.GetChannelConfiguration(); if (channelConfiguration != null) { this.ChannelId = channelConfiguration.RecordId; this.DataAreaId = channelConfiguration.InventLocationDataAreaId; } OrgUnit orgUnit = requestContext.GetOrgUnit(); if (orgUnit != null) { this.StoreNumber = orgUnit.OrgUnitNumber; } this.connectionElementUniqueIdentifier = 0; this.ShiftId = requestContext.GetPrincipal().ShiftId; this.ShiftTerminalId = requestContext.GetPrincipal().ShiftTerminalId; GetCurrentTerminalIdDataRequest dataRequest = new GetCurrentTerminalIdDataRequest(); this.TerminalId = requestContext.Runtime.Execute <SingleEntityDataServiceResponse <string> >(dataRequest, requestContext, skipRequestTriggers: true).Entity; }
/// <summary> /// Executes the resume shift workflow. /// </summary> /// <param name="request">The new shift request.</param> /// <returns>The resume shift response.</returns> protected override UseShiftResponse Process(UseShiftRequest request) { ThrowIf.Null(request, "request"); ThrowIf.Null(request.ShiftTerminalId, "request.ShiftTerminalId"); GetCurrentTerminalIdDataRequest dataRequest = new GetCurrentTerminalIdDataRequest(); request.TerminalId = this.Context.Execute <SingleEntityDataServiceResponse <string> >(dataRequest).Entity; GetShiftDataRequest getShiftDataRequest = new GetShiftDataRequest(request.ShiftTerminalId, request.ShiftId); Shift shift = this.Context.Execute <SingleEntityDataServiceResponse <Shift> >(getShiftDataRequest).Entity; if (shift == null) { throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_ObjectNotFound, "There is no shift with the given identifier."); } this.ValidateCanUseShift(request, shift); shift.CurrentStaffId = this.Context.GetPrincipal().UserId; shift.CurrentTerminalId = request.TerminalId; shift.StatusDateTime = this.Context.GetNowInChannelTimeZone(); UpdateShiftStagingTableDataRequest dataServiceRequest = new UpdateShiftStagingTableDataRequest(shift); request.RequestContext.Runtime.Execute <NullResponse>(dataServiceRequest, this.Context); return(new UseShiftResponse(shift)); }
/// <summary> /// Executes the workflow to deactivate a device. /// </summary> /// <param name="request">The deactivate device request.</param> /// <returns>The response.</returns> protected override NullResponse Process(DeactivateDeviceRequest request) { ThrowIf.Null(request, "request"); GetCurrentTerminalIdDataRequest dataRequest = new GetCurrentTerminalIdDataRequest(); string terminalId = this.Context.Execute <SingleEntityDataServiceResponse <string> >(dataRequest).Entity; // Slect all shifts. IList <Shift> shifts = ShiftDataDataServiceHelper.GetAllOpenedShiftsOnTerminal(this.Context, this.Context.GetPrincipal().ChannelId, terminalId, true); if (shifts.HasMultiple()) { throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_TerminalHasAnOpenShift); } var serviceRequest = new DeactivateDeviceServiceRequest(this.Context.GetPrincipal().DeviceNumber, terminalId, this.Context.GetPrincipal().UserId, this.Context.GetPrincipal().DeviceToken); DeactivateDeviceServiceResponse deactivationResponse = this.Context.Execute <DeactivateDeviceServiceResponse>(serviceRequest); if (!string.IsNullOrWhiteSpace(deactivationResponse.DeactivationResult.ErrorMessage)) { throw new DeviceAuthenticationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_DeviceDeactivationFailed, deactivationResponse.DeactivationResult.ErrorMessage); } // Log off the user. var userLogOffRequest = new UserLogOffRequest { StaffId = this.Context.GetPrincipal().UserId, LogOnConfiguration = this.Context.GetPrincipal().LogOnConfiguration }; AuthenticationHelper.LogOff(this.Context, userLogOffRequest); return(new NullResponse()); }
/// <summary> /// Gets the current working terminal identifier. /// </summary> /// <param name="request">The data service request.</param> /// <returns>The data service response.</returns> private SingleEntityDataServiceResponse <string> GetCurrentTerminalId(GetCurrentTerminalIdDataRequest request) { TerminalDataManager terminalDataManager = this.GetDataManagerInstance(request.RequestContext); string terminalId = terminalDataManager.GetCurrentTerminalId(); return(new SingleEntityDataServiceResponse <string>(terminalId)); }
/// <summary> /// Executes the create shift staging workflow. /// </summary> /// <param name="request">The new Shift request.</param> /// <returns>The new Shift response.</returns> protected override CreateShiftResponse Process(CreateShiftRequest request) { ThrowIf.Null(request, "request"); // Validate Shift id. if (request.ShiftId == null || request.ShiftId <= 0) { throw new ArgumentException("Shift identifier should not be null and should be greater than 0 to open a shift."); } GetCurrentTerminalIdDataRequest dataRequest = new GetCurrentTerminalIdDataRequest(); request.TerminalId = this.Context.Execute <SingleEntityDataServiceResponse <string> >(dataRequest).Entity; this.ValidateCanOpenShift(request); Shift shift = this.CreateNewShift(request); var createShiftRequest = new CreateShiftDataRequest(shift); request.RequestContext.Runtime.Execute <NullResponse>(createShiftRequest, this.Context); return(new CreateShiftResponse(shift)); }
/// <summary> /// Saves (updating if it exists and creating a new one if it does not) the shopping cart on the request. /// </summary> /// <param name="request">The request.</param> /// <returns><see cref="SaveCartResponse"/> object containing the cart with updated item quantities.</returns> protected override SaveCartResponse Process(SaveCartRequest request) { ThrowIf.Null(request, "request"); ThrowIf.Null(request.Cart, "request.Cart"); var validateCustomerAccountRequest = new GetValidatedCustomerAccountNumberServiceRequest(request.Cart.CustomerId, throwOnValidationFailure: false); var validateCustomerAccountResponse = this.Context.Execute <GetValidatedCustomerAccountNumberServiceResponse>(validateCustomerAccountRequest); if (validateCustomerAccountResponse.IsCustomerAccountNumberInContextDifferent) { request.Cart.CustomerId = validateCustomerAccountResponse.ValidatedAccountNumber; } bool isItemSale = request.Cart.CartLines.Any(l => string.IsNullOrWhiteSpace(l.LineId) && !l.IsGiftCardLine && !l.IsVoided && l.Quantity >= 0m); if (string.IsNullOrWhiteSpace(request.Cart.Id)) { request.Cart.Id = CartWorkflowHelper.GenerateRandomTransactionId(this.Context); } // Copy the logic from CartService.CreateCart(). foreach (CartLine line in request.Cart.CartLines) { // Sets the IsReturn flag to true, when ReturnTransactionId is specified. // The reason of doing so is that the IsReturn is not currently exposed on CartLine entity. if (!string.IsNullOrEmpty(line.ReturnTransactionId)) { line.LineData.IsReturnByReceipt = true; } } // Get the Sales Transaction SalesTransaction salesTransaction = CartWorkflowHelper.LoadSalesTransaction(this.Context, request.Cart.Id); if (salesTransaction == null) { // New transaction - set the default cart type to shopping if none if (request.Cart.CartType == CartType.None) { request.Cart.CartType = CartType.Shopping; } } CartWorkflowHelper.ValidateCartPermissions(salesTransaction, request.Cart, this.Context); if (salesTransaction == null) { // New transaction - set the default cart type to shopping if none if (request.Cart.CartType == CartType.None) { request.Cart.CartType = CartType.Shopping; } // Do not allow new transaction for blocked customer. CartWorkflowHelper.ValidateCustomerAccount(this.Context, request.Cart, null); // Set loyalty card from the customer number CartWorkflowHelper.SetLoyaltyCardFromCustomer(this.Context, request.Cart); // Set affiliations from the customer number CartWorkflowHelper.AddOrUpdateAffiliationLinesFromCustomer(this.Context, null, request.Cart); // If cannot find the transaction, create a new transaction. salesTransaction = CartWorkflowHelper.CreateSalesTransaction(this.Context, request.Cart.Id, request.Cart.CustomerId); // Set initial values on cart to be same as on transaction. request.Cart.CopyPropertiesFrom(salesTransaction); // Update transaction level reason code lines. ReasonCodesWorkflowHelper.AddOrUpdateReasonCodeLinesOnTransaction(salesTransaction, request.Cart); // Calculate required reason code lines for start of transaction. ReasonCodesWorkflowHelper.CalculateRequiredReasonCodesOnTransaction(this.Context, salesTransaction, ReasonCodeSourceType.StartOfTransaction); } // If cart or the sales transaction is suspended then update is not permitted if (salesTransaction.IsSuspended) { throw new CartValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_CartNotActive, request.Cart.Id); } // If the terminal id of the cart is not same as the context then it means that the cart is active on another terminal. GetCurrentTerminalIdDataRequest dataRequest = new GetCurrentTerminalIdDataRequest(); if (!(salesTransaction.TerminalId ?? string.Empty).Equals(this.Context.Execute <SingleEntityDataServiceResponse <string> >(dataRequest).Entity ?? string.Empty, StringComparison.OrdinalIgnoreCase)) { throw new CartValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_LoadingActiveCartFromAnotherTerminalNotAllowed, request.Cart.Id); } // At this point, the sales transaction is either newly created with no sales lines or just loaded from DB. // We are yet to add new sales lines or update existing sales lines. // Get the returned sales transaction if the cart contains a return line SalesTransaction returnTransaction = CartWorkflowHelper.LoadSalesTransactionForReturn(this.Context, request.Cart, salesTransaction, request.OperationType); // If customer account number is not specified on the request it should not be overriden. if (request.Cart.CustomerId == null) { request.Cart.CustomerId = salesTransaction.CustomerId; } // Get the products in the cart lines IDictionary <long, SimpleProduct> productsByRecordId = CartWorkflowHelper.GetProductsInCartLines(this.Context, request.Cart.CartLines); // Validate update cart request CartWorkflowHelper.ValidateUpdateCartRequest(this.Context, salesTransaction, returnTransaction, request.Cart, request.IsGiftCardOperation, productsByRecordId); request.Cart.IsReturnByReceipt = returnTransaction != null; request.Cart.ReturnTransactionHasLoyaltyPayment = returnTransaction != null && returnTransaction.HasLoyaltyPayment; if (returnTransaction != null && !string.IsNullOrWhiteSpace(returnTransaction.LoyaltyCardId) && string.IsNullOrWhiteSpace(salesTransaction.LoyaltyCardId)) { // Set the loyalty card of the returned transaction to the current transaction request.Cart.LoyaltyCardId = returnTransaction.LoyaltyCardId; } HashSet <string> newSalesLineIdSet = new HashSet <string>(StringComparer.OrdinalIgnoreCase); // Perform update cart operations CartWorkflowHelper.PerformSaveCartOperations(this.Context, request, salesTransaction, returnTransaction, newSalesLineIdSet, productsByRecordId); // Sets the wharehouse id and invent location id for each line ItemAvailabilityHelper.SetSalesLineInventory(this.Context, salesTransaction); // Calculate totals and saves the sales transaction CartWorkflowHelper.Calculate(this.Context, salesTransaction, request.CalculationModes, isItemSale, newSalesLineIdSet); // Validate price on sales line after calculations CartWorkflowHelper.ValidateSalesLinePrice(this.Context, salesTransaction, productsByRecordId); // Validate the customer account deposit transaction. AccountDepositHelper.ValidateCustomerAccountDepositTransaction(this.Context, salesTransaction); // Validate return item and return transaction permissions CartWorkflowHelper.ValidateReturnPermission(this.Context, salesTransaction, request.Cart.CartType); // Calculate the required reason codes after the price calculation ReasonCodesWorkflowHelper.CalculateRequiredReasonCodes(this.Context, salesTransaction, ReasonCodeSourceType.None); CartWorkflowHelper.SaveSalesTransaction(this.Context, salesTransaction); Cart cart = CartWorkflowHelper.ConvertToCart(this.Context, salesTransaction); CartWorkflowHelper.RemoveHistoricalTenderLines(cart); return(new SaveCartResponse(cart)); }
/// <summary> /// Executes the workflow to get available Shifts. /// </summary> /// <param name="request">The request.</param> /// <returns>The response.</returns> protected override GetAvailableShiftsResponse Process(GetAvailableShiftsRequest request) { ThrowIf.Null(request, "request"); IEnumerable <Shift> shifts; EmployeePermissions employeePermission = EmployeePermissionHelper.GetEmployeePermissions(this.Context, this.Context.GetPrincipal().UserId); var staffId = this.Context.GetPrincipal().UserId; GetCurrentTerminalIdDataRequest dataRequest = new GetCurrentTerminalIdDataRequest(); string terminalId = this.Context.Execute <SingleEntityDataServiceResponse <string> >(dataRequest).Entity; bool isManager = this.Context.GetPrincipal().IsInRole(AuthenticationHelper.ManagerPrivilegies); bool readAllShifts; bool includeSharedShifts; switch (request.Status) { case ShiftStatus.Suspended: case ShiftStatus.BlindClosed: includeSharedShifts = employeePermission.AllowManageSharedShift; // If user is manager or has permission to logon multiple shifts or allowed to manage shared shifts) // Read all shifts including shared // Else read only shifts that belong to the user and are not shared shifts. if (isManager || (employeePermission.AllowMultipleShiftLogOn && includeSharedShifts)) { // Read all shifts shifts = ShiftDataDataServiceHelper.GetAllStoreShiftsWithStatus(this.Context, this.Context.GetPrincipal().ChannelId, request.Status, request.QueryResultSettings, true); } else if (employeePermission.AllowMultipleShiftLogOn && !includeSharedShifts) { shifts = ShiftDataDataServiceHelper.GetShiftsForStaffWithStatus(this.Context, this.Context.GetPrincipal().ChannelId, request.Status, request.QueryResultSettings, false); } else if (includeSharedShifts && !employeePermission.AllowMultipleShiftLogOn) { var allShifts = ShiftDataDataServiceHelper.GetShiftsForStaffWithStatus(this.Context, this.Context.GetPrincipal().ChannelId, request.Status, request.QueryResultSettings, true); // Exclude non shared shifts and shift not opened or used by the current staff id. shifts = allShifts.Where(s => (s.IsShared == true || s.CurrentStaffId == staffId || s.StaffId == staffId)); } else { shifts = ShiftDataDataServiceHelper.GetShiftsForStaffWithStatus(this.Context, this.Context.GetPrincipal().ChannelId, staffId, request.Status, request.QueryResultSettings, false); } break; case ShiftStatus.Open: includeSharedShifts = employeePermission.AllowManageSharedShift || employeePermission.AllowUseSharedShift; readAllShifts = isManager || (includeSharedShifts && employeePermission.AllowMultipleShiftLogOn); // If user is manager or (has permission to logon multiple shifts and allowed to manage or use shared shifts) // Read all terminal shifts including shared // Else read only shifts that belong to the user and are not shared shifts. if (readAllShifts) { var openShiftsOnTerminal = ShiftDataDataServiceHelper.GetAllOpenedShiftsOnTerminal(this.Context, this.Context.GetPrincipal().ChannelId, terminalId, false); var openSharedShiftsOnStore = ShiftDataDataServiceHelper.GetAllOpenedSharedShiftsOnStore(this.Context, this.Context.GetPrincipal().ChannelId); shifts = openShiftsOnTerminal.Union(openSharedShiftsOnStore); } else { IEnumerable <Shift> usableShifts; if (employeePermission.AllowMultipleShiftLogOn) { usableShifts = ShiftDataDataServiceHelper.GetAllOpenedShiftsOnTerminal(this.Context, this.Context.GetPrincipal().ChannelId, terminalId, false); } else { usableShifts = ShiftDataDataServiceHelper.GetOpenedShiftsOnTerminalForStaff(this.Context, this.Context.GetPrincipal().ChannelId, staffId, terminalId, false); } if (includeSharedShifts) { var openSharedShiftsOnStore = ShiftDataDataServiceHelper.GetAllOpenedSharedShiftsOnStore(this.Context, this.Context.GetPrincipal().ChannelId); shifts = usableShifts.Union(openSharedShiftsOnStore); } else { shifts = usableShifts; } } break; default: shifts = new Shift[] { }; break; } if (shifts != null || shifts.Count() != 0) { shifts = ShiftDataDataServiceHelper.FilterShifts(shifts, terminalId, staffId); } return(new GetAvailableShiftsResponse(shifts.AsPagedResult())); }