/// <summary>
            /// Validates whether the shift can be resumed.
            /// </summary>
            /// <param name="request">The request.</param>
            /// <param name="shift">The shift.</param>
            private void ValidateCanResumeShift(ResumeShiftRequest request, Shift shift)
            {
                if (shift == null)
                {
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_ObjectNotFound, "There is no shift with the given identifier.");
                }

                if (shift.Status != ShiftStatus.Suspended)
                {
                    // we cannot resume an opened shift, only use it
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidRequest, "Cannot resume a non-suspended shift. If the shift is open, try using it instead.");
                }

                if (!this.Permissions.HasManagerPrivileges)
                {
                    if (shift.IsShared && !this.Permissions.AllowManageSharedShift)
                    {
                        throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_EmployeeNotAllowedManageSharedShift, "Employee not allowed to manage shared shift.");
                    }

                    // if it is not shared shift and if the user is not a manager, the user can only resume a shift that she/he owns or have permissions to
                    if (!shift.IsShared &&
                        !string.Equals(shift.StaffId, this.Context.GetPrincipal().UserId, StringComparison.OrdinalIgnoreCase) &&
                        !string.Equals(shift.CurrentStaffId, this.Context.GetPrincipal().UserId, StringComparison.OrdinalIgnoreCase) &&
                        !this.Permissions.AllowMultipleShiftLogOn)
                    {
                        throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidRequest, "The user does not have permission to resume shift.");
                    }
                }

                IList <Shift> openShiftsOnStore = ShiftDataDataServiceHelper.GetAllStoreShiftsWithStatus(this.Context, this.Context.GetPrincipal().ChannelId, ShiftStatus.Open, request.QueryResultSettings, true);
                bool          cannotOpenShift   = openShiftsOnStore.Any(openShift =>
                {
                    bool cashDrawerHasOpenShift = string.Equals(openShift.CashDrawer, request.CashDrawer, StringComparison.OrdinalIgnoreCase);
                    return((openShift.IsShared || string.Equals(openShift.CurrentTerminalId, request.TerminalId, StringComparison.OrdinalIgnoreCase)) && cashDrawerHasOpenShift);
                });

                if (cannotOpenShift)
                {
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_CashDrawerHasAnOpenShift, "There is an open shift on the current cash drawer.");
                }
            }
            /// <summary>
            /// Validates whether employee can open shifts.
            /// </summary>
            /// <param name="request">The create shift request.</param>
            private void ValidateCanOpenShift(CreateShiftRequest request)
            {
                IList <Shift> shifts = ShiftDataDataServiceHelper.GetAllStoreShiftsWithStatus(this.Context, this.Context.GetPrincipal().ChannelId, ShiftStatus.Open, new QueryResultSettings(PagingInfo.AllRecords), true);

                if (!this.Context.GetPrincipal().IsInRole(AuthenticationHelper.ManagerPrivilegies))
                {
                    EmployeePermissions employeePermission = EmployeePermissionHelper.GetEmployeePermissions(this.Context, this.Context.GetPrincipal().UserId);
                    if (employeePermission != null && employeePermission.AllowMultipleLogins == false && shifts.Any(shift => (string.Equals(shift.StaffId, this.Context.GetPrincipal().UserId, StringComparison.OrdinalIgnoreCase) || string.Equals(shift.CurrentStaffId, this.Context.GetPrincipal().UserId, StringComparison.OrdinalIgnoreCase))))
                    {
                        throw new UserAuthorizationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_OpenMultipleShiftsNotAllowed, string.Format(CultureInfo.CurrentUICulture, "Permission denied to open multiple shifts: {0}", this.Context.GetPrincipal().UserId));
                    }

                    if (request.IsShared)
                    {
                        if (!employeePermission.AllowManageSharedShift)
                        {
                            throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_EmployeeNotAllowedManageSharedShift, "Employee not allowed to manage shared shift.");
                        }
                    }
                }

                // Validate if shift is already open with given shift identifier.
                if (request.ShiftId != null && shifts.Any(shift => shift.ShiftId == request.ShiftId && string.Equals(shift.TerminalId, request.TerminalId, StringComparison.OrdinalIgnoreCase)))
                {
                    throw new DataValidationException(
                              DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_TerminalHasAnOpenShift,
                              string.Format("There is already an open shift with shift id {0} on the current terminal.", request.ShiftId));
                }

                // Validate if any shift is open for the cash drawer specified in request.
                bool cannotOpenShift = shifts.Any(shift =>
                {
                    bool cashDrawerHasOpenShift = string.Equals(shift.CashDrawer, request.CashDrawer, StringComparison.OrdinalIgnoreCase);
                    return(cashDrawerHasOpenShift && (shift.IsShared || string.Equals(shift.CurrentTerminalId, request.TerminalId, StringComparison.OrdinalIgnoreCase)));
                });

                if (cannotOpenShift)
                {
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_CashDrawerHasAnOpenShift, "There is an open shift on the current cash drawer.");
                }
            }
Esempio n. 3
0
            /// <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()));
            }
 internal static IList <Shift> GetAllOpenedSharedShiftsOnStore(RequestContext context, long channelId)
 {
     return(ShiftDataDataServiceHelper.GetAllStoreShiftsWithStatus(context, channelId, ShiftStatus.Open, QueryResultSettings.AllRecords, true)
            .Where(s => s.IsShared).AsReadOnly());
 }