/// <summary>
        /// Save a workplan to the database
        /// </summary>
        public static WorkplanEntity SaveWorkplan(IUnitOfWork uow, Workplan workplan)
        {
            var workplanRepo  = uow.GetRepository <IWorkplanEntityRepository>();
            var referenceRepo = uow.GetRepository <IWorkplanReferenceRepository>();

            // Try to get the current object
            var workplanEntity = workplanRepo.GetByKey(workplan.Id);

            // If it is a new plan we need a new object
            if (workplanEntity == null)
            {
                workplanEntity = workplanRepo.Create(workplan.Name, workplan.Version, (int)workplan.State);
                EntityIdListener.Listen(workplanEntity, workplan);
            }
            // If it was modified or the version increased we create a new one and reference the old one
            else if (workplan.Version > workplanEntity.Version)
            {
                var reference = referenceRepo.Create((int)WorkplanReferenceType.NewVersion);
                reference.Source = workplanEntity;
                reference.Target = workplanEntity = workplanRepo.Create(workplan.Name, workplan.Version, (int)workplan.State);
                EntityIdListener.Listen(workplanEntity, workplan);
            }

            // Set properties of the workplan entity
            workplanEntity.Name         = workplan.Name;
            workplanEntity.State        = (int)workplan.State;
            workplanEntity.MaxElementId = workplan.MaxElementId;

            // Save connectors and steps
            var steps      = SaveSteps(uow, workplanEntity, workplan);
            var connectors = SaveConnectors(uow, workplanEntity, workplan);

            LinkSteps(uow, workplan, steps, connectors);
            RemoveUnusedConnectors(uow, workplanEntity, workplan);

            return(workplanEntity);
        }
 public long SaveWorkplan(Workplan workplan)
 {
     ValidateHealthState();
     return(Workplans.SaveWorkplan(workplan));
 }
        /// <summary>
        /// Adds a step to the workplan
        /// </summary>
        /// <param name="workplan">The workplan.</param>
        /// <param name="task">The task to add.</param>
        /// <param name="parameter">The parameter for the task.</param>
        /// <param name="input">The input for the step</param>
        /// <param name="outputs">The outputs of the steps.</param>
        /// <returns></returns>
        public static TaskStep <TActivity, TProcParam, TParam> AddStep <TActivity, TProcParam, TParam>(this Workplan workplan, TaskStep <TActivity, TProcParam, TParam> task, TParam parameter, IConnector input, params IConnector[] outputs)
            where TActivity : IActivity <TProcParam>, new()
            where TProcParam : IParameters
            where TParam : TProcParam, new()
        {
            task.Parameters = parameter;
            task.Inputs[0]  = input;

            for (var i = 0; i < outputs.Length; i++)
            {
                task.Outputs[i] = outputs[i];
            }

            if (task.Outputs.Length != outputs.Length)
            {
                throw new ArgumentException($"Wrong number of outputs for the task {task.Name}");
            }

            workplan.Add(task);

            return(task);
        }
 /// <summary>
 /// Adds a intermediate connector to the workplan.
 /// </summary>
 /// <param name="workplan">The workplan.</param>
 /// <param name="name">The name of the connector.</param>
 /// <returns></returns>
 public static IConnector AddConnector(this Workplan workplan, string name)
 {
     return(workplan.AddConnector(name, NodeClassification.Intermediate));
 }
        /// <summary>
        /// Adds a step to the workplan
        /// </summary>
        /// <param name="workplan">The workplan.</param>
        /// <param name="task">The task to add.</param>
        /// <param name="parameter">The parameter for the task.</param>
        /// <param name="input">The input for the step</param>
        /// <param name="outputs">The outputs of the steps.</param>
        /// <returns></returns>
        public static TaskStep <TActivity, TProcParam, TParam> AddStep <TActivity, TProcParam, TParam>(this Workplan workplan, TaskStep <TActivity, TProcParam, TParam> task, TParam parameter, IConnector[] input, params IConnector[] outputs)
            where TActivity : Activity <TProcParam>, new()
            where TProcParam : IParameters
            where TParam : TProcParam, new()
        {
            task.Parameters = parameter;
            for (var i = 0; i < input.Length; i++)
            {
                task.Inputs[i] = input[i];
            }

            for (var i = 0; i < outputs.Length; i++)
            {
                task.Outputs[i] = outputs[i];
            }

            workplan.Add(task);

            return(task);
        }
        /// <summary>
        /// Remove all unused connectors AFTER the new linking was applied
        /// </summary>
        private static void RemoveUnusedConnectors(IUnitOfWork uow, WorkplanEntity workplanEntity, Workplan workplan)
        {
            var connectorRepo = uow.GetRepository <IConnectorEntityRepository>();

            // Remove connectors, that are now longer part of the workplan
            var removedConnectors = workplanEntity.Connectors.Where(ce => workplan.Connectors.All(c => c.Id != ce.ConnectorId));

            connectorRepo.RemoveRange(removedConnectors);
        }
        /// <summary>
        /// Save or update steps of the workplan and return a map of StepId => Entity
        /// </summary>
        private static IDictionary <long, StepEntity> SaveSteps(IUnitOfWork uow, WorkplanEntity workplanEntity, Workplan workplan)
        {
            var stepRepo        = uow.GetRepository <IStepEntityRepository>();
            var descriptionRepo = uow.GetRepository <IOutputDescriptionEntityRepository>();
            var referenceRepo   = uow.GetRepository <IConnectorReferenceRepository>();

            // Remove connectors, that are now longer used. We only use Created/Updated columns
            // and do not want the entities flagged as deleted
            var removedSteps = workplanEntity.Steps.Where(se => workplan.Steps.All(s => s.Id != se.StepId));

            foreach (var removedStep in removedSteps.ToList())
            {
                descriptionRepo.RemoveRange(removedStep.OutputDescriptions);
                referenceRepo.RemoveRange(removedStep.Connectors);
                stepRepo.Remove(removedStep);
            }

            var stepEntities = new Dictionary <long, StepEntity>();

            foreach (var step in workplan.Steps)
            {
                // Get or create entity
                var stepEntity = workplanEntity.Steps.FirstOrDefault(se => se.StepId == step.Id);
                if (stepEntity == null)
                {
                    var stepType     = step.GetType();
                    var assemblyName = stepType.Assembly.GetName().Name;
                    stepEntity = stepRepo.Create(step.Id, step.Name, assemblyName, stepType.Namespace, stepType.Name);
                    workplanEntity.Steps.Add(stepEntity);
                }
                else
                {
                    stepEntity.Name = step.Name;
                }

                // Update all output descriptions
                for (int index = 0; index < step.OutputDescriptions.Length; index++)
                {
                    var description       = step.OutputDescriptions[index];
                    var descriptionEntity = stepEntity.OutputDescriptions.FirstOrDefault(ode => ode.Index == index);
                    if (descriptionEntity == null)
                    {
                        descriptionEntity = descriptionRepo.Create(index, (int)description.OutputType, description.MappingValue);
                        stepEntity.OutputDescriptions.Add(descriptionEntity);
                    }
                    else
                    {
                        descriptionEntity.OutputType   = (int)description.OutputType;
                        descriptionEntity.MappingValue = description.MappingValue;
                    }
                    descriptionEntity.Name = description.Name;
                }

                // Task steps need parameters
                if (step is ITaskStep <IParameters> taskStep)
                {
                    stepEntity.Parameters = JsonConvert.SerializeObject(taskStep.Parameters);
                }

                // Subworkplan steps and need a reference to the workplan
                if (step is ISubworkplanStep subworkPlanStep)
                {
                    stepEntity.SubWorkplanId = subworkPlanStep.WorkplanId;
                }

                stepEntities[step.Id] = stepEntity;
            }

            return(stepEntities);
        }
        /// <summary>
        /// Save or update connectors of the workplan and return a map of StepId => Entity
        /// </summary>
        private static IDictionary <long, ConnectorEntity> SaveConnectors(IUnitOfWork uow, WorkplanEntity workplanEntity, Workplan workplan)
        {
            var connectorRepo = uow.GetRepository <IConnectorEntityRepository>();

            var connectorEntities = new Dictionary <long, ConnectorEntity>();

            foreach (var connector in workplan.Connectors)
            {
                var connectorEntity = workplanEntity.Connectors.FirstOrDefault(ce => ce.ConnectorId == connector.Id);
                if (connectorEntity == null)
                {
                    connectorEntity = connectorRepo.Create(connector.Id, (int)connector.Classification);
                    workplanEntity.Connectors.Add(connectorEntity);
                }
                connectorEntity.Name            = connector.Name;
                connectorEntities[connector.Id] = connectorEntity;
            }

            return(connectorEntities);
        }
Example #9
0
        public void CheckOrderWorkpieceWorkplanMutations()
        {
            var testOrder = new Faker <Order>()
                            .RuleFor(o => o.ExternalOrderId, f => "AutoOrder " + f.Company.CompanyName() + "_" + f.Finance.Amount(1, 10000))
                            .RuleFor(o => o.CustomerId, f => f.PickRandom(OrdersData.Customers.Values.ToList()))
                            .RuleFor(o => o.Comments, f => f.Hacker.Phrase()).RuleFor(o => o.DeliveryDate, f => f.Date.Future(1));

            Order orderToCreate = testOrder;

            var orderId = this.App.GraphApi.ProjectManager.CreateOrder(orderToCreate);

            var orderDb = this.App.Db.ProjectManager.GetOrder(orderId);

            Assert.That(
                orderToCreate.ExternalOrderId.Equals(orderDb.ExternalOrderId) &&
                orderToCreate.CustomerId.Equals(orderDb.CustomerId) &&
                orderToCreate.Comments.Equals(orderDb.Comments) && orderDb.CreatedDate.ToString("yyyy-MM-dd").Equals(DateTime.Now.ToString("yyyy-MM-dd")),
                "Order wasn't created correctly. Some data is wrong");

            var orders = this.App.Db.ProjectManager.GetOrders().Where(o => o.ExternalOrderId.Equals(orderToCreate.ExternalOrderId))
                         .ToList();

            Assert.That(orders.Count == 1, $"Only 1 order should have been created. But was {orders.Count}");

            var testWorkpiece = new Faker <Workpiece>().Rules(
                (f, o) =>
            {
                o.Name                = f.Hacker.Noun() + "_" + f.Hacker.Adjective();
                o.DeliveryDate        = f.Date.Future(1);
                o.ExternalWorkpieceId = f.Hacker.Noun() + "_" + f.Hacker.Abbreviation() + "_" + f.Finance.Amount();
                o.OrderId             = orderId;
                o.Quantity            = f.Random.Int(2, 10000);
            });

            Workpiece workpiece   = testWorkpiece;
            var       workpieceId = this.App.GraphApi.ProjectManager.CreateWorkpiece(workpiece);

            var workpieceDb = this.App.Db.ProjectManager.GetWorkpiece(workpieceId);

            bool workpieceIsCorrect = workpiece.Name.Equals(workpieceDb.Name) &&
                                      workpiece.DeliveryDate.ToString("yyyy-MM-dd").Equals(
                workpieceDb.DeliveryDate.ToString("yyyy-MM-dd")) &&
                                      workpiece.ExternalWorkpieceId.Equals(workpieceDb.ExternalWorkpieceId) &&
                                      workpiece.OrderId.Equals(workpieceDb.OrderId) &&
                                      workpiece.Quantity.Equals(workpieceDb.Quantity) && workpieceDb.CreatedDate
                                      .ToString("yyyy-MM-dd").Equals(DateTime.Now.ToString("yyyy-MM-dd"));
            string errorMessage = string.Empty;

            if (!workpieceIsCorrect)
            {
                errorMessage = this.FormWorkpieceErrorMessage(workpiece, workpieceDb);
            }

            Assert.That(
                workpieceIsCorrect,
                $"Workpiece wasn't created correctly. Some data is wrong. Workpiece Id -  {workpiece.ExternalWorkpieceId}. {errorMessage}");

            var workpieces = this.App.Db.ProjectManager.GetWorkpieces()
                             .Where(w => w.ExternalWorkpieceId.Equals(workpiece.ExternalWorkpieceId)).ToList();

            Assert.That(workpieces.Count == 1, $"Only 1 workpiece should have been created. But was {workpieces.Count}. ExternalWorkpieceId is '{workpiece.ExternalWorkpieceId}'");

            Workplan workplan = new Workplan();

            workplan.WorkpieceId = workpieceId;

            var workplanId = this.App.GraphApi.ProjectManager.CreateWorkPlan(workplan);

            var workplanDb = this.App.Db.ProjectManager.GetWorkplan(workplanId);

            Assert.That(
                workplan.WorkpieceId.Equals(workplanDb.WorkpieceId) && workplanDb.CreatedDate.ToString("yyyy-MM-dd")
                .Equals(DateTime.Now.ToString("yyyy-MM-dd")),
                "Workplan wasn't created correctly. Some data is wrong");

            var workplans = this.App.Db.ProjectManager.GetWorkplans().Where(w => w.WorkpieceId.Equals(workpieceId))
                            .ToList();

            Assert.That(workplans.Count == 1, $"Only 1 workplan should have been created. But was {workplans.Count}");
        }
    private void drawTable()
    {
        this.calenderTable.Rows.Clear();
        TableRow  row  = new TableRow();
        TableCell cell = new TableCell();

        cell.Style.Add("text-align", "center");
        cell.Text       = "Date: " + this.startOfWeek.ToLongDateString() + " Week: " + GetWeekOfYear(this.startOfWeek);
        cell.ColumnSpan = 8;
        row.Cells.Add(cell);
        this.calenderTable.Rows.Add(row);

        List <Workplan> workplans = this.services.Getworkplans();
        TimeSpan        timeHours = new TimeSpan(8, 0, 0);

        for (int y = 1; y < 10; y++)
        {
            TableRow tRow = new TableRow();
            this.calenderTable.Rows.Add(tRow);
            for (int x = 0; x < 6; x++)
            {
                TableCell tCell = new TableCell();

                if (x != 0 && y != 1)
                {
                    Workplan workplanTime = workplans.Find(workplan => {
                        if (DateTime.Parse(workplan.Date) == this.startOfWeek.AddDays(x - 1).Date&&
                            (timeHours.TotalHours).ToString() + ":00" == workplan.Time)
                        {
                            return(true);
                        }

                        return(false);
                    });

                    Button btnCell = new Button();
                    if (workplanTime != null)
                    {
                        btnCell.Attributes.Add("date", this.startOfWeek.AddDays(x - 1).Date.ToString());
                        btnCell.Attributes.Add("time", (timeHours.TotalHours).ToString());
                        btnCell.Attributes.Add("workplanID", workplanTime.WorkPlanID.ToString());
                        btnCell.Attributes.Add("bookingID", workplanTime.BookingID.ToString());
                        btnCell.Attributes.Add("staffID", workplanTime.AssignedStaffMemberID.ToString());
                        btnCell.Click   += viewWorkPlan_Click;
                        btnCell.CssClass = "btn-warning";
                        btnCell.Text     = "View";
                    }
                    else
                    {
                        btnCell.Attributes.Add("date", this.startOfWeek.AddDays(x - 1).Date.ToString());
                        btnCell.Attributes.Add("time", (timeHours.TotalHours).ToString());

                        btnCell.Click   += AddWorkPlan_Click;
                        btnCell.CssClass = "btn-success";
                        btnCell.Text     = "Allocate";
                    }
                    tCell.Controls.Add(btnCell);
                }
                tCell.Style.Add("text-align", "center");

                tRow.Cells.Add(tCell);
            }
            timeHours = timeHours.Add(new TimeSpan(1, 0, 0));
        }

        Button previousWeek = new Button();

        previousWeek.Click   += PreviousWeek_Click;
        previousWeek.CssClass = "btn-secondary";
        previousWeek.Text     = "Previous";

        Button nextWeek = new Button();

        nextWeek.Click   += NextWeek_Click;
        nextWeek.CssClass = "btn-secondary";
        nextWeek.Text     = "Next";

        this.calenderTable.Rows[1].Cells[0].Controls.Add(previousWeek);
        this.calenderTable.Rows[1].Cells.Add(new TableCell());
        this.calenderTable.Rows[1].Cells[6].Controls.Add(nextWeek);

        for (int x = 1; x <= 5; x++)
        {
            this.calenderTable.Rows[1].Cells[x].Text = this.startOfWeek.AddDays(x - 1).ToShortDateString() + " " + Enum.Parse(typeof(DayOfWeek), x.ToString()).ToString();
        }
        TimeSpan time = new TimeSpan(9, 0, 0);

        for (int y = 2; y <= 9; y++)
        {
            this.calenderTable.Rows[y].Cells[0].Text = (time.Hours + ":00 - " + (time.Hours + 1) + ":00").ToString();
            time = time.Add(new TimeSpan(1, 0, 0));
        }
    }