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

                var staffId = this.Context.GetPrincipal().UserId;

                if (!this.Context.GetPrincipal().IsInRole(AuthenticationHelper.ManagerPrivilegies))
                {
                    EmployeePermissions employeePermission = EmployeePermissionHelper.GetEmployeePermissions(this.Context, staffId);

                    if (employeePermission != null && (!(string.Equals(shift.StaffId, staffId) || string.Equals(shift.CurrentStaffId, staffId)) && ((shift.IsShared && !employeePermission.AllowUseSharedShift) || (!shift.IsShared && !employeePermission.AllowMultipleShiftLogOn))))
                    {
                        throw new UserAuthorizationException(SecurityErrors.Microsoft_Dynamics_Commerce_Runtime_UseExistingShiftPermissionDenied, string.Format(CultureInfo.CurrentUICulture, "Permission denied to use the existing shift: {0}", this.Context.GetPrincipal().UserId));
                    }
                }

                if (shift.Status != ShiftStatus.Open)
                {
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidRequest, "Only open shifts can be used. If the shift is suspended, try resuming instead.");
                }
                else if (!string.Equals(shift.CurrentTerminalId, request.TerminalId, StringComparison.OrdinalIgnoreCase) && !shift.IsShared)
                {
                    // we can only use an open shift on a different terminal if it is a shared shift
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_ShiftAlreadyOpenOnDifferentTerminal, "The shift is open on a different terminal.");
                }
            }
Esempio n. 2
0
    //新增員工個別權限至DB
    public void InsertEmployeePermission(EmployeePermissions employeePermission)
    {
        string str = "insert into [AMS_EmployeePermission] values(@EmployeeID,@SiteId,@Enable)";

        DatabaseTier dt = new DatabaseTier();

        dt.SQLHelperNonQuery(str, new Dictionary <string, object>()
        {
            { "@EmployeeID", employeePermission.EmployeeId },
            { "@SiteId", employeePermission.SiteId },
            { "@Enable", employeePermission.Enable },
        });
    }
            /// <summary>
            /// Verifies whether local authorization must be used as a fallback mode in case of error on remote authorization.
            /// </summary>
            /// <returns>A value indicating whether local authorization must be used as a fallback mode in case of error on remote authorization.</returns>
            private bool MustFallbackToLocalAuthorization()
            {
                // we can only fallback to local database if we have a channel id provided
                if (this.CanUseLocalDatabase)
                {
                    EmployeePermissions employeePermissions = null;

                    try
                    {
                        // Create a temporary context with the employee for getting employee permissions.
                        RequestContext tempContext = new RequestContext(this.context.Runtime);
                        var            employee    = new Employee()
                        {
                            StaffId = this.StaffId
                        };
                        ICommercePrincipal principal = this.context.GetPrincipal();
                        CommerceIdentity   identity  = new CommerceIdentity(
                            employee,
                            new Device()
                        {
                            DeviceNumber     = principal.DeviceNumber,
                            Token            = principal.DeviceToken,
                            ChannelId        = principal.ChannelId,
                            TerminalRecordId = principal.TerminalId
                        });
                        tempContext.SetPrincipal(new CommercePrincipal(identity));

                        // Get employee permissions
                        GetEmployeePermissionsDataRequest getEmployeePermissionsDataRequest = new GetEmployeePermissionsDataRequest(
                            this.StaffId,
                            new ColumnSet());

                        employeePermissions = tempContext.Execute <SingleEntityDataServiceResponse <EmployeePermissions> >(
                            getEmployeePermissionsDataRequest).Entity;
                    }
                    catch (Exception exception)
                    {
                        // this method occurs in an error handling scenario
                        // if this fails, we do not want to break the flow
                        // so we just log the exception internally
                        RetailLogger.Instance.CrtServicesStaffAuthorizationServiceGetEmployeePermissionsFailure(exception);
                    }

                    // we can fallback if it is allowed by user permissions
                    return(employeePermissions != null && employeePermissions.ContinueOnTSErrors);
                }

                return(false);
            }
            /// <summary>
            /// Executes the create shift staging workflow.
            /// </summary>
            /// <param name="request">The new Shift request.</param>
            /// <returns>The new Shift response.</returns>
            protected override ChangeShiftStatusResponse Process(ChangeShiftStatusRequest request)
            {
                ThrowIf.Null(request, "request");
                ThrowIf.Null(request.ShiftTerminalId, "request.ShiftTerminalId");

                if (this.Context.GetTerminal() != null)
                {
                    request.TerminalId = this.Context.GetTerminal().TerminalId;
                }

                EmployeePermissions permissions = EmployeePermissionHelper.GetEmployeePermissions(this.Context, this.Context.GetPrincipal().UserId);
                bool includeSharedShifts        = permissions.HasManagerPrivileges || permissions.AllowManageSharedShift || permissions.AllowUseSharedShift;
                var  staffId    = this.Context.GetPrincipal().UserId;
                var  terminalId = request.ShiftTerminalId;
                var  shifts     = ShiftDataDataServiceHelper.GetShifts(
                    this.Context,
                    this.Context.GetPrincipal().ChannelId,
                    terminalId,
                    request.ShiftId,
                    includeSharedShifts);

                Shift shift = ShiftDataDataServiceHelper.FilterShifts(shifts, terminalId, staffId).FirstOrDefault();

                if (shift == null)
                {
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_ObjectNotFound, "There is no shift with the given identifier.");
                }

                ShiftTransitionHelper shiftTransitionHelper = new ShiftTransitionHelper(this.Context, request);

                // Validate if the change of shift status can be performed
                shiftTransitionHelper.TransitShiftStatus(shift);

                shift.StatusDateTime = this.Context.GetNowInChannelTimeZone();

                UpdateShiftStagingTableDataRequest dataServiceRequest = new UpdateShiftStagingTableDataRequest(shift);

                request.RequestContext.Runtime.Execute <NullResponse>(dataServiceRequest, this.Context);

                this.SaveTransactionLog(shift, request.TransactionId);

                if (request.ToStatus == ShiftStatus.Closed)
                {
                    this.PurgeSalesTransactionData(request.RequestContext);
                }

                return(new ChangeShiftStatusResponse(shift));
            }
            /// <summary>
            /// Validates whether a status transition is possible on the specified shift.
            /// </summary>
            /// <param name="shift">The shift.</param>
            private void ValidateCanChangeStatus(Shift shift)
            {
                bool isManager = this.context.GetPrincipal().IsInRole(AuthenticationHelper.ManagerPrivilegies);

                if (shift.Status == ShiftStatus.Open &&
                    !string.Equals(shift.TerminalId, this.request.TerminalId, StringComparison.OrdinalIgnoreCase) &&
                    !string.Equals(shift.CurrentTerminalId, this.request.TerminalId, StringComparison.OrdinalIgnoreCase))
                {
                    if (shift.IsShared)
                    {
                        if (!isManager)
                        {
                            EmployeePermissions employeePermission = EmployeePermissionHelper.GetEmployeePermissions(this.context, this.context.GetPrincipal().UserId);
                            if (!employeePermission.AllowManageSharedShift)
                            {
                                throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_EmployeeNotAllowedManageSharedShift, "Employee not allowed to manage shared shift.");
                            }
                        }
                    }
                    else
                    {
                        throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_ShiftAlreadyOpenOnDifferentTerminal, "The shift is open on a different terminal.");
                    }
                }

                if (!isManager)
                {
                    if (shift.IsShared)
                    {
                        EmployeePermissions employeePermission = EmployeePermissionHelper.GetEmployeePermissions(this.context, this.context.GetPrincipal().UserId);
                        if (!employeePermission.AllowManageSharedShift)
                        {
                            throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_EmployeeNotAllowedManageSharedShift, "Employee not allowed to manage shared shift.");
                        }
                    }

                    // Get the original user id for manager override cases.
                    string userId = (!string.IsNullOrWhiteSpace(this.context.GetPrincipal().OriginalUserId) && this.context.GetPrincipal().UserId != this.context.GetPrincipal().OriginalUserId) ? this.context.GetPrincipal().OriginalUserId : this.context.GetPrincipal().UserId;
                    if (!string.Equals(shift.StaffId, userId, StringComparison.OrdinalIgnoreCase) &&
                        !string.Equals(shift.CurrentStaffId, userId, StringComparison.OrdinalIgnoreCase))
                    {
                        throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidRequest, "The user does not have permission to change shift status.");
                    }
                }
            }
            /// <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.");
                }
            }
            /// <summary>
            /// Gets the current shift and sets it on the context.
            /// </summary>
            /// <param name="context">The context.</param>
            private static void PopulateContextWithShiftInformation(RequestContext context)
            {
                ShiftDataQueryCriteria criteria = new ShiftDataQueryCriteria
                {
                    ChannelId  = context.GetPrincipal().ChannelId,
                    TerminalId = context.GetTerminal().TerminalId,
                    StaffId    =
                        string.IsNullOrWhiteSpace(context.GetPrincipal().OriginalUserId)
                            ? context.GetPrincipal().UserId
                            : context.GetPrincipal().OriginalUserId,
                    Status                    = (int)ShiftStatus.Open,
                    SearchByStaffId           = true,
                    SearchByCurrentStaffId    = true,
                    SearchByTerminalId        = true,
                    SearchByCurrentTerminalId = true
                };

                // Get original staff id (not a manager's) during elevated permission operations.
                GetEmployeePermissionsDataRequest permissionsDataRequest = new GetEmployeePermissionsDataRequest(criteria.StaffId, new ColumnSet());
                EmployeePermissions employeePermissions = context.Runtime.Execute <SingleEntityDataServiceResponse <EmployeePermissions> >(
                    permissionsDataRequest, context, skipRequestTriggers: true).Entity;

                if (employeePermissions != null)
                {
                    criteria.IncludeSharedShifts = employeePermissions.HasManagerPrivileges ||
                                                   employeePermissions.AllowManageSharedShift ||
                                                   employeePermissions.AllowUseSharedShift ||
                                                   employeePermissions.AllowMultipleShiftLogOn;
                }

                GetShiftDataDataRequest dataServiceRequest = new GetShiftDataDataRequest(criteria, QueryResultSettings.SingleRecord);
                Shift shift = context.Runtime.Execute <EntityDataServiceResponse <Shift> >(dataServiceRequest, context, skipRequestTriggers: true).PagedEntityCollection.Results.FirstOrDefault();

                if (shift != null)
                {
                    // TerminalId is the identifier of the terminal which creates the shift
                    context.GetPrincipal().ShiftId         = shift.ShiftId;
                    context.GetPrincipal().ShiftTerminalId = shift.TerminalId;
                }
            }
Esempio n. 8
0
            /// <summary>
            /// Workflow to process employee time clock activities.
            /// </summary>
            /// <param name="request">The request.</param>
            /// <returns>The response.</returns>
            protected override EmployeeTimeRegistrationResponse Process(EmployeeTimeRegistrationRequest request)
            {
                ThrowIf.Null(request, "request");
                EmployeeTimeRegistrationResponse response;

                if (request.IsLatestActivity && request.IsSelectStore)
                {
                    throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidRequest, "Both latest activity and selecting from stores is not supported");
                }

                bool enableTimeRegistration = EmployeeTimeRegistrationWorkflowHelper.ValidateTimeRegistrationFunctionalityProfile(this.Context);

                if (!enableTimeRegistration)
                {
                    throw new DataValidationException(
                              DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_TimeClockNotEnabled,
                              string.Format("Time Clock should be enabled before performing employee activities. EmployeeActivityType: {0}", request.EmployeeActivityType));
                }

                // This flag is set to true if client needs to retrieve the latest activity of the employee.
                if (request.IsLatestActivity)
                {
                    EmployeeActivity employeeActivity = this.GetLatestEmployeeActivity();

                    response = new EmployeeTimeRegistrationResponse(new[] { employeeActivity }.AsPagedResult());

                    return(response);
                }

                // The workflow follows any one of the activity chosen from client.
                switch (request.EmployeeActivityType)
                {
                case EmployeeActivityType.ClockIn:
                {
                    var currentActivityDateTimeOffset = this.ProcessClockIn();
                    response = new EmployeeTimeRegistrationResponse(currentActivityDateTimeOffset);
                    break;
                }

                case EmployeeActivityType.ClockOut:
                {
                    var currentActivityDateTimeOffset = this.ProcessClockOut();
                    response = new EmployeeTimeRegistrationResponse(currentActivityDateTimeOffset);
                    break;
                }

                case EmployeeActivityType.BreakFromWork:
                {
                    var currentActivityDateTimeOffset = this.ProcessBreakFlow(EmployeeTimeRegistrationWorkflowHelper.BreakFromWork);
                    response = new EmployeeTimeRegistrationResponse(currentActivityDateTimeOffset);
                    break;
                }

                case EmployeeActivityType.BreakForLunch:
                {
                    var currentActivityDateTimeOffset = this.ProcessBreakFlow(EmployeeTimeRegistrationWorkflowHelper.BreakForLunch);
                    response = new EmployeeTimeRegistrationResponse(currentActivityDateTimeOffset);
                    break;
                }

                case EmployeeActivityType.Logbook:
                {
                    if (request.IsManagerLogbook)
                    {
                        EmployeePermissions employeePermisssion = EmployeePermissionHelper.GetEmployeePermissions(this.Context, this.Context.GetPrincipal().UserId);

                        if (employeePermisssion == null || !employeePermisssion.AllowViewTimeClockEntries)
                        {
                            throw new DataValidationException(
                                      DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_ViewTimeClockNotEnabled,
                                      string.Format("View Time Clock Entries should be enabled to view other employee activities. EmployeeActivityType: {0}", request.EmployeeActivityType));
                        }

                        var employeeActivities = this.ProcessManagerLogBook(request.EmployeeActivitySearchCriteria, request.QueryResultSettings.Paging, request.QueryResultSettings.Sorting);
                        response = new EmployeeTimeRegistrationResponse(employeeActivities.AsPagedResult());
                    }
                    else
                    {
                        var employeeActivities = this.ProcessEmployeeLogBook(request.EmployeeActivitySearchCriteria, request.QueryResultSettings.Paging, request.QueryResultSettings.Sorting);
                        response = new EmployeeTimeRegistrationResponse(employeeActivities.AsPagedResult());
                    }

                    break;
                }

                default:
                    throw new DataValidationException(
                              DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_UnSupportedType,
                              string.Format("Unsupported type for Employee Activity {0}", request.EmployeeActivityType));
                }

                return(response);
            }
Esempio n. 9
0
    //新增employeePermission的物件
    public void InsertEmployeePermission(EmployeePermissions empPermission)
    {
        DatabaseTier dt = new DatabaseTier();

        dt.InsertEmployeePermission(empPermission);
    }
Esempio n. 10
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()));
            }
Esempio n. 11
0
            /// <summary>
            /// Helper method to get consolidated permission.
            /// </summary>
            /// <param name="employeePermissionsCollection">List of permission groups.</param>
            /// <param name="overriddenPermission">Overridden Permission.</param>
            /// <returns>The employee permissions.</returns>
            public static EmployeePermissions GetConsolidatedPermission(IEnumerable <EmployeePermissions> employeePermissionsCollection, EmployeePermissions overriddenPermission)
            {
                ThrowIf.Null(employeePermissionsCollection, "employeePermissionsCollection");

                EmployeePermissions employeePermissions = new EmployeePermissions();

                // First check if the employee has overridden permission
                // If override is  present return that permission.
                if (overriddenPermission != null)
                {
                    return(overriddenPermission);
                }

                // If only position is found, return the permission for the position.
                // For multiple positions, enumerate the permission for all associated positions and find consolidated permission.
                if (employeePermissionsCollection.Count() == 1)
                {
                    return(employeePermissionsCollection.First());
                }
                else
                {
                    foreach (EmployeePermissions settings in employeePermissionsCollection)
                    {
                        employeePermissions.AllowKitDisassembly            |= settings.AllowKitDisassembly;
                        employeePermissions.AllowBlindClose                |= settings.AllowBlindClose;
                        employeePermissions.AllowChangeNoVoid              |= settings.AllowChangeNoVoid;
                        employeePermissions.HasManagerPrivileges           |= settings.HasManagerPrivileges;
                        employeePermissions.AllowCreateOrder               |= settings.AllowCreateOrder;
                        employeePermissions.AllowEditOrder                 |= settings.AllowEditOrder;
                        employeePermissions.AllowFloatingTenderDeclaration |= settings.AllowFloatingTenderDeclaration;
                        employeePermissions.AllowMultipleLogins            |= settings.AllowMultipleLogins;
                        employeePermissions.AllowMultipleShiftLogOn        |= settings.AllowMultipleShiftLogOn;
                        employeePermissions.AllowOpenDrawer                |= settings.AllowOpenDrawer;

                        // Allow cumulative permissions for priceoverride from all positions
                        if ((employeePermissions.AllowPriceOverride == (int)EmployeePriceOverrideType.HigherOnly && settings.AllowPriceOverride == (int)EmployeePriceOverrideType.LowerOnly) ||
                            (employeePermissions.AllowPriceOverride == (int)EmployeePriceOverrideType.LowerOnly && settings.AllowPriceOverride == (int)EmployeePriceOverrideType.HigherOnly))
                        {
                            employeePermissions.AllowPriceOverride = (int)EmployeePriceOverrideType.HigherAndLower;
                        }
                        else
                        {
                            employeePermissions.AllowPriceOverride = Math.Min(employeePermissions.AllowPriceOverride, settings.AllowPriceOverride);
                        }

                        employeePermissions.AllowRetrieveOrder           |= settings.AllowRetrieveOrder;
                        employeePermissions.AllowSalesTaxChange          |= settings.AllowSalesTaxChange;
                        employeePermissions.AllowTenderDeclaration       |= settings.AllowTenderDeclaration;
                        employeePermissions.AllowTransactionSuspension   |= settings.AllowTransactionSuspension;
                        employeePermissions.AllowTransactionVoiding      |= settings.AllowTransactionVoiding;
                        employeePermissions.AllowXReportPrinting         |= settings.AllowXReportPrinting;
                        employeePermissions.AllowZReportPrinting         |= settings.AllowZReportPrinting;
                        employeePermissions.AllowUseHandheld             |= settings.AllowUseHandheld;
                        employeePermissions.AllowViewTimeClockEntries    |= settings.AllowViewTimeClockEntries;
                        employeePermissions.AllowChangePeripheralStation |= settings.AllowChangePeripheralStation;
                        employeePermissions.ManageDevice                  |= settings.ManageDevice;
                        employeePermissions.AllowPasswordChange           |= settings.AllowPasswordChange;
                        employeePermissions.AllowResetPassword            |= settings.AllowResetPassword;
                        employeePermissions.MaximumDiscountPercentage      = Math.Max(employeePermissions.MaximumDiscountPercentage, settings.MaximumDiscountPercentage);
                        employeePermissions.MaximumLineDiscountAmount      = Math.Max(employeePermissions.MaximumLineDiscountAmount, settings.MaximumLineDiscountAmount);
                        employeePermissions.MaximumLineReturnAmount        = Math.Max(employeePermissions.MaximumLineReturnAmount, settings.MaximumLineReturnAmount);
                        employeePermissions.MaximumTotalDiscountAmount     = Math.Max(employeePermissions.MaximumTotalDiscountAmount, settings.MaximumTotalDiscountAmount);
                        employeePermissions.MaximumTotalDiscountPercentage = Math.Max(employeePermissions.MaximumTotalDiscountPercentage, settings.MaximumTotalDiscountPercentage);
                        employeePermissions.MaxTotalReturnAmount           = Math.Max(employeePermissions.MaxTotalReturnAmount, settings.MaxTotalReturnAmount);
                    }
                }

                return(employeePermissions);
            }