예제 #1
0
        public EmployeeActor(EmployeeStoredInformation storedInformation, IActorRef imageResizer, IActorRef vacationsRegistry)
        {
            this.employeeMetadata = storedInformation.Metadata;
            this.PersistenceId    = $"employee-info-{Uri.EscapeDataString(this.employeeMetadata.EmployeeId)}";

            this.photo = Context.ActorOf(Props.Create(() => new PhotoActor(imageResizer)), "photo");
            this.photo.Tell(new PhotoActor.SetSource(storedInformation.Photo));

            this.employeeFeed = Context.ActorOf(FeedActor.GetProps(), "feed");
            var sendEmailActor = Context.ActorOf(SendEmailSickLeaveActor.GetProps(), "sendEmail");

            sendEmailActor.Tell(new SendEmailSickLeaveActor.SetEmployeesActor(Context.Parent));

            var vacationsActor  = Context.ActorOf(EmployeeVacationsActor.CreateProps(this.employeeMetadata.EmployeeId, this.employeeFeed, vacationsRegistry), "vacations");
            var sickLeavesActor = Context.ActorOf(EmployeeSickLeaveActor.CreateProps(this.employeeMetadata.EmployeeId, sendEmailActor), "sick-leaves");
            var workHoursActor  = Context.ActorOf(EmployeeWorkHoursActor.CreateProps(this.employeeMetadata.EmployeeId), "work-hours");

            Context.Watch(vacationsActor);
            Context.Watch(sickLeavesActor);
            Context.Watch(workHoursActor);

            var calendarActor = Context.ActorOf(EmployeeCalendarActor.CreateProps(this.employeeMetadata.EmployeeId, vacationsActor, workHoursActor, sickLeavesActor), "all-calendar-events");

            this.calendar = new EmployeeCalendarContainer(vacationsActor, workHoursActor, sickLeavesActor, calendarActor);
        }
        private async Task UpsertCalendarEvent(CalendarEvent @event, EmployeeMetadata employeeMetadata)
        {
            var externalStorage     = this.externalStorageProvider();
            var departmentCalendars = this.GetSharepointCalendarsByDepartment(employeeMetadata.DepartmentId);

            var sharepointTasks = departmentCalendars.Select(async calendar =>
            {
                var existingItem = await this.GetSharepointItemForCalendarEvent(externalStorage, calendar, @event);

                var upsertItem = this.CalendarEventToStorageItem(@event, employeeMetadata);
                upsertItem.Id  = existingItem?.Id;

                if (existingItem == null)
                {
                    await externalStorage.AddItem(
                        calendar,
                        upsertItem);
                }
                else if (!this.sharepointStorageItemComparer.Equals(upsertItem, existingItem))
                {
                    await externalStorage.UpdateItem(
                        calendar,
                        upsertItem);
                }
            });

            await Task.WhenAll(sharepointTasks);
        }
예제 #3
0
        private string GetNextApproverOnlyHeadStrategy(
            EmployeeMetadata employee,
            List <DepartmentInfo> departments,
            IEnumerable <string> existingApprovals,
            IEnumerable <string> skippedApprovers)
        {
            if (existingApprovals.Any())
            {
                return(null);
            }

            var ownDepartment   = departments.First(d => d.DepartmentId == employee.DepartmentId);
            var isEmployeeChief = ownDepartment.ChiefId == employee.EmployeeId;

            if (ownDepartment.IsHeadDepartment && isEmployeeChief)
            {
                // No approvals required for Director General
                return(null);
            }

            var parentDepartments = this.GetParentDepartments(ownDepartment, departments);
            var allDepartments    = !isEmployeeChief
                ? parentDepartments.Prepend(ownDepartment)
                : parentDepartments;

            var acceptedApprovers = allDepartments
                                    .Select(d => d.ChiefId)
                                    .ToArray();

            var availableApprovers = acceptedApprovers
                                     .Except(skippedApprovers ?? Enumerable.Empty <string>());

            return(availableApprovers.FirstOrDefault());
        }
        private UntypedReceive GetOwnDepartments(EmployeeMetadata employee)
        {
            void OnMessage(object message)
            {
                switch (message)
                {
                case DepartmentsQuery.Response response:
                    BulkBumpPermissions(
                        response.Departments.Select(x => x.Department.DepartmentId),
                        OwnDepartmentPermissions,
                        this.permissionsForDepartments);

                    this.Become(this.LoadSupervisedDepartmentsPermissions(employee.EmployeeId));

                    break;

                case ReceiveTimeout _:
                    this.ReplyAndStop();
                    break;

                default:
                    this.Unhandled(message);
                    break;
                }
            }

            this.organizationActor.Tell(DepartmentsQuery.Create().WithId(employee.DepartmentId));
            return(OnMessage);
        }
예제 #5
0
 public CalendarEventChangedWithAdditionalData(CalendarEvent @event,
                                               EmployeeMetadata owner,
                                               UserPreferences ownerUserPreferences)
 {
     this.Event = @event;
     this.Owner = owner;
     this.OwnerUserPreferences = ownerUserPreferences;
 }
 private void OnReceiveEventRemove(CalendarEvent @event, EmployeeMetadata employeeMetadata)
 {
     this.RemoveCalendarEvent(@event, employeeMetadata)
     .PipeTo(
         this.Self,
         success: () => new CalendarEventRemoveSuccess(@event),
         failure: err => new CalendarEventRemoveFailed(@event, err));
 }
예제 #7
0
        protected override Message GetDateMessageForEmployee(EmployeeMetadata employee, DateTime date)
        {
            var title   = employee.Name;
            var text    = $"{employee.Name} turns {employee.AgeAt(date)}! Happy Birthday!";
            var message = new Message($"employee-birthday-{employee.EmployeeId}-at-{date}", employee.EmployeeId, title, text, date);

            return(message);
        }
        public EmployeeActor(
            EmployeeStoredInformation storedInformation,
            IActorRef imageResizer,
            IActorRef vacationsCreditRegistry,
            IEmployeeVacationsRegistryPropsFactory employeeVacationsRegistryPropsFactory,
            IEmployeeSickLeavesRegistryPropsFactory employeeSickLeavesRegistryPropsFactory)
        {
            this.employeeMetadata = storedInformation.Metadata;
            this.PersistenceId    = $"employee-info-{Uri.EscapeDataString(this.employeeMetadata.EmployeeId)}";

            this.photo = Context.ActorOf(Props.Create(() => new PhotoActor(imageResizer)), "photo");
            this.photo.Tell(new PhotoActor.SetSource(storedInformation.Photo));

            this.employeeFeed = Context.ActorOf(FeedActor.GetProps(), "feed");

            var persistenceSupervisorFactory = new PersistenceSupervisorFactory();

            var vacationActorProps = EmployeeVacationsActor.CreateProps(
                this.employeeMetadata.EmployeeId,
                this.employeeFeed,
                vacationsCreditRegistry,
                employeeVacationsRegistryPropsFactory);

            var sickLeaveActorProps = EmployeeSickLeaveActor.CreateProps(
                this.employeeMetadata.EmployeeId,
                employeeSickLeavesRegistryPropsFactory);

            var workHoursActorProps = EmployeeWorkHoursActor.CreateProps(this.employeeMetadata.EmployeeId);

            var vacationsActor = Context.ActorOf(vacationActorProps, "vacations");

            var sickLeavesActor = Context.ActorOf(sickLeaveActorProps, "sick-leaves");

            var workHoursActor = Context.ActorOf(
                persistenceSupervisorFactory.Get(workHoursActorProps),
                "work-hours");

            var calendarActor = Context.ActorOf(
                EmployeeCalendarActor.CreateProps(
                    this.employeeMetadata.EmployeeId,
                    vacationsActor,
                    workHoursActor,
                    sickLeavesActor),
                "all-calendar-events"
                );

            var pendingActionsActor = Context.ActorOf(
                EmployeePendingActionsActor.CreateProps(this.employeeMetadata.EmployeeId),
                "pending-actions"
                );

            this.calendar = new EmployeeCalendarContainer(
                vacationsActor,
                workHoursActor,
                sickLeavesActor,
                calendarActor,
                pendingActionsActor);
        }
예제 #9
0
        protected override Message GetDateMessageForEmployee(EmployeeMetadata employee, DateTime date)
        {
            var pronoun = employee.Sex == Sex.Female ? "her" : "his";
            var title   = employee.Name;
            var text    = $"{employee.Name} celebrates {pronoun} birthday on {date.ToString("MMMM dd")}!";
            var message = new Message($"employee-birthday-{employee.EmployeeId}-at-{date}", employee.EmployeeId, title, text, date);

            return(message);
        }
 public CalendarEventAssignedWithAdditionalData(
     CalendarEvent @event,
     EmployeeMetadata owner,
     UserPreferences approverUserPreferences,
     EmployeeMetadata approver)
 {
     this.Event = @event;
     this.Owner = owner;
     this.ApproverUserPreferences = approverUserPreferences;
     this.Approver = approver;
 }
 public CalendarEventApprovalsChangedWithAdditionalData(
     CalendarEvent @event,
     UserPreferences ownerUserPreferences,
     IEnumerable <DevicePushToken> ownerPushTokens,
     EmployeeMetadata approver)
 {
     this.Event = @event;
     this.OwnerUserPreferences = ownerUserPreferences;
     this.OwnerPushTokens      = ownerPushTokens;
     this.Approver             = approver;
 }
 public CalendarEventWithAdditionalData(
     CalendarEvent @event,
     NotificationType notificationType,
     EmployeeMetadata owner,
     EmployeeMetadata manager = null,
     UserPreferences managerUserPreferences = null)
 {
     this.Event                  = @event;
     this.NotificationType       = notificationType;
     this.Owner                  = owner;
     this.Manager                = manager;
     this.ManagerUserPreferences = managerUserPreferences;
 }
예제 #13
0
 public CalendarEventAssignedWithAdditionalData(
     CalendarEvent @event,
     string approverId,
     EmployeeMetadata owner,
     UserPreferences approverUserPreferences,
     IEnumerable <DevicePushToken> approverPushTokens)
 {
     this.Event      = @event;
     this.ApproverId = approverId;
     this.Owner      = owner;
     this.ApproverUserPreferences = approverUserPreferences;
     this.ApproverPushTokens      = approverPushTokens;
 }
        private static bool CheckFilter(EmployeeMetadata employee, EmployeesQuery query)
        {
            if ((query.DepartmentId != null) && (employee.DepartmentId != query.DepartmentId))
            {
                return(false);
            }

            if ((query.EmployeeId != null) && (employee.EmployeeId != query.EmployeeId))
            {
                return(false);
            }

            if ((query.RoomNumber != null) && (employee.RoomNumber != query.RoomNumber))
            {
                return(false);
            }

            if ((query.Sid != null) && !string.Equals(employee.Sid, query.Sid, StringComparison.InvariantCultureIgnoreCase))
            {
                return(false);
            }

            if ((query.Identity != null) && !employee.IdentityAliases.Contains(query.Identity))
            {
                return(false);
            }

            if ((query.NameFilter != null) && !(employee.Name?.IndexOf(query.NameFilter, 0, StringComparison.InvariantCultureIgnoreCase) >= 0))
            {
                return(false);
            }

            if ((query.HireDate != null) && !query.HireDate.Matches(employee.HireDate))
            {
                return(false);
            }

            if ((query.BirthDate != null) && (!employee.BirthDate.HasValue || !query.BirthDate.Matches(employee.BirthDate.Value)))
            {
                return(false);
            }

            if ((query.IsWorking == true && employee.FireDate != null) || (query.IsWorking == false && employee.FireDate == null))
            {
                return(false);
            }

            return(true);
        }
        protected override Message GetDateMessageForEmployee(EmployeeMetadata employee, DateTime date)
        {
            var title = employee.Name;

            var yearsServed = employee.YearsServedAt(date);

            if (yearsServed <= 0)
            {
                return(null);
            }

            var msg = $"Congratulations with Anniversary! {employee.YearsServedAt(date)} years served!";

            return(new Message($"employee-anniversary-{employee.EmployeeId}-at-{date}", employee.EmployeeId, title, msg, date));
        }
예제 #16
0
 public static EmployeeModel FromMetadata(EmployeeMetadata metadata)
 {
     return(new EmployeeModel()
     {
         EmployeeId = metadata.EmployeeId,
         BirthDate = metadata.BirthDate,
         DepartmentId = metadata.DepartmentId,
         Email = metadata.Email,
         HireDate = metadata.HireDate,
         MobilePhone = metadata.MobilePhone,
         Name = metadata.Name,
         Position = metadata.Position,
         Sex = metadata.Sex,
         RoomNumber = metadata.RoomNumber
     });
 }
예제 #17
0
        private EmailNotification CreateEmailNotification(CalendarEvent @event, EmployeeMetadata employeeMetadata)
        {
            var templateExpressionContext = new Dictionary <string, string>
            {
                ["startDate"] = @event.Dates.StartDate.ToString("dd/MM/yyyy"),
                ["endDate"]   = @event.Dates.EndDate.ToString("dd/MM/yyyy")
            };

            templateExpressionContext = new DictionaryMerge().Perform(
                templateExpressionContext,
                @event.AdditionalData.ToDictionary(x => x.Key, x => x.Value));

            var sender    = this.reminderConfiguration.ReminderEmail.NotificationSender;
            var recipient = employeeMetadata.Email;
            var subject   = this.reminderConfiguration.ReminderEmail.Subject;
            var body      = new TemplateExpressionParser().Parse(this.reminderConfiguration.ReminderEmail.Body, templateExpressionContext);

            return(new EmailNotification(sender, new[] { recipient }, subject, body));
        }
 private void OnReceiveEventUpdate(CalendarEvent @event, EmployeeMetadata employeeMetadata)
 {
     if (this.NeedToStoreCalendarEvent(@event))
     {
         this.UpsertCalendarEvent(@event, employeeMetadata)
         .PipeTo(
             this.Self,
             success: () => new CalendarEventUpsertSuccess(@event),
             failure: err => new CalendarEventUpsertFailed(@event, err));
     }
     else
     {
         this.RemoveCalendarEvent(@event, employeeMetadata)
         .PipeTo(
             this.Self,
             success: () => new CalendarEventRemoveSuccess(@event),
             failure: err => new CalendarEventRemoveFailed(@event, err));
     }
 }
        private async Task RemoveCalendarEvent(CalendarEvent @event, EmployeeMetadata employeeMetadata)
        {
            var externalStorage     = this.externalStorageProvider();
            var departmentCalendars = this.GetSharepointCalendarsByDepartment(employeeMetadata.DepartmentId);

            var sharepointTasks = departmentCalendars.Select(async calendar =>
            {
                var existingItem = await this.GetSharepointItemForCalendarEvent(externalStorage, calendar, @event);

                if (existingItem != null)
                {
                    await externalStorage.DeleteItem(
                        calendar,
                        existingItem.Id);
                }
            });

            await Task.WhenAll(sharepointTasks);
        }
예제 #20
0
        private bool CheckFilter(EmployeeMetadata employee)
        {
            if ((this.query.DepartmentId != null) && (employee.DepartmentId != this.query.DepartmentId))
            {
                return(false);
            }

            if ((this.query.EmployeeId != null) && (employee.EmployeeId != this.query.EmployeeId))
            {
                return(false);
            }

            if ((this.query.RoomNumber != null) && (employee.RoomNumber != this.query.RoomNumber))
            {
                return(false);
            }

            if ((this.query.Sid != null) && !string.Equals(employee.Sid, this.query.Sid, StringComparison.InvariantCultureIgnoreCase))
            {
                return(false);
            }

            if ((this.query.Email != null) && !string.Equals(employee.Email, this.query.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                return(false);
            }

            if ((this.query.HireDate != null) && !this.query.HireDate.Matches(employee.HireDate))
            {
                return(false);
            }

            if ((this.query.BirthDate != null) && (!employee.BirthDate.HasValue || !this.query.BirthDate.Matches(employee.BirthDate.Value)))
            {
                return(false);
            }

            return(true);
        }
        private StorageItem CalendarEventToStorageItem(CalendarEvent @event, EmployeeMetadata employeeMetadata)
        {
            var totalHours = @event.Dates.FinishWorkingHour - @event.Dates.StartWorkingHour;

            var longEventsTitle  = $"{employeeMetadata.Name} ({@event.Type})";
            var shortEventsTitle = $"{employeeMetadata.Name} ({@event.Type}: {totalHours} hours)";

            var title = @event.Type == CalendarEventTypes.Vacation || @event.Type == CalendarEventTypes.Sickleave
                ? longEventsTitle
                : shortEventsTitle;

            var storageItem = new StorageItem
            {
                Title           = title,
                StartDate       = @event.Dates.StartDate,
                EndDate         = @event.Dates.EndDate,
                Category        = @event.Type,
                AllDayEvent     = true,
                CalendarEventId = @event.EventId
            };

            return(storageItem);
        }
예제 #22
0
        private void UpdateEmployeeMetadata(EmployeeMetadata informationMetadata)
        {
            if (informationMetadata.Position != this.employeeMetadata.Position)
            {
                var ev = new EmployeeChangedPosition()
                {
                    EmployeeId  = this.employeeMetadata.EmployeeId,
                    NewPosition = informationMetadata.Position,
                    OldPosition = this.employeeMetadata.Position,
                    TimeStamp   = DateTimeOffset.UtcNow
                };
                this.Persist(ev, this.OnEmployeePositionChange);
                this.employeeMetadata.Position = ev.NewPosition;
            }

            if (informationMetadata.Name != this.employeeMetadata.Name)
            {
                var ev = new EmployeeChangedName()
                {
                    EmployeeId = this.employeeMetadata.EmployeeId,
                    NewName    = informationMetadata.Name,
                    OldName    = this.employeeMetadata.Name,
                    TimeStamp  = DateTimeOffset.UtcNow
                };

                this.Persist(ev, this.OnEmployeeNameChange);
                this.employeeMetadata.Name = informationMetadata.Name;
            }

            if (informationMetadata.DepartmentId != this.employeeMetadata.DepartmentId)
            {
                //TODO: department id change handler
                this.employeeMetadata.DepartmentId = informationMetadata.DepartmentId;
            }

            this.employeeMetadata = informationMetadata;
        }
 protected abstract Message GetDateMessageForEmployee(EmployeeMetadata employee, DateTime date);
예제 #24
0
 public StoreCalendarEventToSharepoint(CalendarEvent @event, EmployeeMetadata employeeMetadata)
 {
     this.Event            = @event;
     this.EmployeeMetadata = employeeMetadata;
 }
예제 #25
0
 public EmployeeIndexEntry(IActorRef employeeActor, EmployeeMetadata metadata)
 {
     this.EmployeeActor = employeeActor;
     this.Metadata      = metadata;
 }
 public GetPendingActions(EmployeeMetadata approver, DependentDepartmentsPendingActions dependentDepartmentsPendingActions)
 {
     this.Approver = approver;
     DependentDepartmentsPendingActions = dependentDepartmentsPendingActions;
 }
예제 #27
0
 public RemoveCalendarEventFromSharepoint(CalendarEvent @event, EmployeeMetadata employeeMetadata)
 {
     this.Event            = @event;
     this.EmployeeMetadata = employeeMetadata;
 }
        private UntypedReceive GatherEmployeeInfo(
            EmployeeMetadata approver,
            DependentDepartmentsPendingActions dependentDepartmentsPendingActions)
        {
            this.organization.Tell(
                DepartmentsQuery.Create()
                .WithHead(approver.EmployeeId)
                .IncludeDirectDescendants());

            void OnMessage(object message)
            {
                switch (message)
                {
                case DepartmentsQuery.Response response when response.Departments.Count == 0:
                    this.FinishProcessing();
                    break;

                case DepartmentsQuery.Response response:
                    var ownDepartmentsEmployees = response.Departments
                                                  .Where(d => d.Department.ChiefId == approver.EmployeeId)
                                                  .SelectMany(d => d.Employees);

                    var otherDepartmentsEmployees = response.Departments
                                                    .Where(d => d.Department.ChiefId != approver.EmployeeId)
                                                    .Select(d => new
                    {
                        d.Department.ChiefId,
                        Employees = d.Employees.Where(e =>
                        {
                            if (dependentDepartmentsPendingActions == DependentDepartmentsPendingActions.All)
                            {
                                return(true);
                            }

                            if (dependentDepartmentsPendingActions == DependentDepartmentsPendingActions.HeadsOnly)
                            {
                                return(e.Metadata.EmployeeId == d.Department.ChiefId);
                            }

                            return(false);
                        })
                    })
                                                    .SelectMany(x => x.Employees);

                    var subordinates = ownDepartmentsEmployees
                                       .Union(otherDepartmentsEmployees)
                                       .GroupBy(x => x.Metadata.EmployeeId)
                                       .Select(x => x.First())
                                       .ToList();

                    if (subordinates.Count == 0)
                    {
                        this.FinishProcessing();
                    }

                    this.Become(this.GatherCalendarEvents(subordinates));

                    break;

                default:
                    this.DefaultMessageHandler(message);
                    break;
                }
            }

            return(OnMessage);
        }
 public CalendarEventChangedWithAdditionalData(CalendarEvent @event, NotificationType notificationType, EmployeeMetadata employee)
 {
     this.Event            = @event;
     this.NotificationType = notificationType;
     this.Employee         = employee;
 }