Beispiel #1
0
        private static GenericOpinion PrepareOpinion(IWfActivity activity, WfClientOpinion opinion, IUser user)
        {
            GenericOpinion serverOpinion = null;

            if (opinion != null)
            {
                serverOpinion = opinion.ToGenericOpinion();
            }
            else
            {
                serverOpinion = new GenericOpinion()
                {
                    ID = UuidHelper.NewUuidString()
                }
            };

            serverOpinion.ProcessID  = activity.Process.ID;
            serverOpinion.ActivityID = activity.ID;
            serverOpinion.ResourceID = activity.Process.ResourceID;

            serverOpinion.IssuePerson  = user;
            serverOpinion.AppendPerson = user;

            return(serverOpinion);
        }
        private static GenericOpinion PrepareServerOpinion()
        {
            GenericOpinion opinion = new GenericOpinion();

            opinion.ID             = UuidHelper.NewUuidString();
            opinion.ResourceID     = UuidHelper.NewUuidString();
            opinion.ActivityID     = UuidHelper.NewUuidString();
            opinion.ProcessID      = UuidHelper.NewUuidString();
            opinion.LevelName      = "TestLevelName";
            opinion.LevelDesp      = "LevelDesp";
            opinion.OpinionType    = "OpinionType";
            opinion.IssueDatetime  = DateTime.Now;
            opinion.AppendDatetime = DateTime.Now;
            opinion.Content        = "Hello world";
            opinion.IssuePerson    = new OguUser(UuidHelper.NewUuidString())
            {
                DisplayName = "Shen Zheng"
            };
            opinion.AppendPerson = new OguUser(UuidHelper.NewUuidString())
            {
                DisplayName = "Shen Rong"
            };
            opinion.RawExtData = "Extra Data";

            return(opinion);
        }
 internal OpinionListViewBindEventArgs(GenericOpinion currentOpinion, IWfActivityDescriptor currentWfActDesc, Control container, bool readOnly)
 {
     _opinion   = currentOpinion;
     _wfActDesc = currentWfActDesc;
     _container = container;
     _readOnly  = readOnly;
 }
Beispiel #4
0
        public GenericOpinion ClientToServer(WfClientOpinion client, ref GenericOpinion server)
        {
            client.NullCheck("client");

            if (server == null)
            {
                server = new GenericOpinion();
            }

            server.ID          = client.ID;
            server.ResourceID  = client.ResourceID;
            server.ActivityID  = client.ActivityID;
            server.ProcessID   = client.ProcessID;
            server.Content     = client.Content;
            server.OpinionType = client.OpinionType;
            server.LevelName   = client.LevelName;
            server.LevelDesp   = client.LevelDesp;
            server.IssuePerson = new OguUser(client.IssuePersonID)
            {
                Name = client.IssuePersonName, DisplayName = client.IssuePersonName
            };
            server.AppendPerson = new OguUser(client.AppendPersonID)
            {
                Name = client.AppendPersonName, DisplayName = client.AppendPersonName
            };
            server.IssueDatetime  = client.IssueTime;
            server.AppendDatetime = client.AppendTime;
            server.RawExtData     = client.ExtraData;

            return(server);
        }
Beispiel #5
0
        public WfClientOpinion ServerToClient(GenericOpinion server, ref WfClientOpinion client)
        {
            server.NullCheck("server");

            if (client == null)
            {
                client = new WfClientOpinion();
            }

            client.ID          = server.ID;
            client.ResourceID  = server.ResourceID;
            client.ActivityID  = server.ActivityID;
            client.ProcessID   = server.ProcessID;
            client.Content     = server.Content;
            client.OpinionType = server.OpinionType;
            client.LevelName   = server.LevelName;
            client.LevelDesp   = server.LevelDesp;
            client.IssueTime   = server.IssueDatetime;
            client.AppendTime  = server.AppendDatetime;
            client.ExtraData   = server.RawExtData;

            if (server.IssuePerson != null)
            {
                client.IssuePersonID   = server.IssuePerson.ID;
                client.IssuePersonName = server.IssuePerson.DisplayName;
            }

            if (server.AppendPerson != null)
            {
                client.AppendPersonID   = server.AppendPerson.ID;
                client.AppendPersonName = server.AppendPerson.DisplayName;
            }

            return(client);
        }
		internal OpinionListViewBindEventArgs(GenericOpinion currentOpinion, IWfActivityDescriptor currentWfActDesc, Control container, bool readOnly)
		{
			_opinion = currentOpinion;
			_wfActDesc = currentWfActDesc;
			_container = container;
			_readOnly = readOnly;
		}
Beispiel #7
0
        public static WfClientProcess Cancel(WfClientCancelParameters parameters)
        {
            IWfProcess process = WfRuntime.GetProcessByProcessID(parameters.ProcessID);

            IWfActivity activity = process.CurrentActivity;

            if (activity == null || activity.Assignees == null)// || !activity.Assignees.Contains(UserHelper.UserId))
            {
                return(null);
            }

            WfCancelProcessExecutor executor = new WfCancelProcessExecutor(activity, process);

            GenericOpinion serverOpinion = PrepareOpinion(process.CurrentActivity, parameters.CurrentOpinion, DeluxeIdentity.CurrentUser);

            serverOpinion.OpinionType = "拒绝";

            if (serverOpinion.Content.IsNullOrEmpty())
            {
                serverOpinion.Content = "拒绝";
            }

            executor.PrepareApplicationData += dataContext => GenericOpinionAdapter.Instance.Update(serverOpinion);

            return(GetClientProcess(executor.Execute()));
        }
 public WfClientOpinion(GenericOpinion genericOpinion)
 {
     if (genericOpinion != null)
     {
         this.ID          = genericOpinion.ID;
         this.Content     = genericOpinion.Content;
         this.OpinionType = genericOpinion.OpinionType;
     }
 }
Beispiel #9
0
        private void RenderOneOpinionWithPrecense(GenericOpinion opinion, string opText, Control container)
        {
            HtmlGenericControl opTextContainer = new HtmlGenericControl("div");

            opTextContainer.Attributes["class"] = "text";
            opTextContainer.InnerHtml           = HttpUtility.HtmlEncode(opText).Replace("\r\n", "<br/>");
            container.Controls.Add(opTextContainer);

            HtmlGenericControl signName = new HtmlGenericControl("div");

            signName.Attributes["class"] = "signName";
            container.Controls.Add(signName);

            UserPresence presence = new UserPresence();

            if (OpinionListControlHelper.UserSignatures.ContainsKey(opinion.IssuePerson.ID))
            {
                HtmlImage sigImage = new HtmlImage();

                sigImage.Src = OpinionListControlHelper.UserSignatures[opinion.IssuePerson.ID];
                sigImage.Alt = opinion.IssuePerson.DisplayName;

                signName.Controls.Add(sigImage);

                presence.ShowUserDisplayName = false;
            }

            signName.Controls.Add(presence);

            presence.UserID          = opinion.IssuePerson.ID;
            presence.UserDisplayName = opinion.IssuePerson.DisplayName;                 //防止人员离职
            presence.EnsureInUserList();

            if (opinion.IssuePerson.ID != opinion.AppendPerson.ID)
            {
                HtmlGenericControl sp1 = new HtmlGenericControl("span");
                sp1.InnerText = "(";
                signName.Controls.Add(sp1);

                UserPresence presence2 = new UserPresence();
                signName.Controls.Add(presence2);
                presence2.UserID          = opinion.AppendPerson.ID;
                presence2.UserDisplayName = opinion.AppendPerson.DisplayName;                   //防止人员离职
                presence2.EnsureInUserList();

                HtmlGenericControl sp2 = new HtmlGenericControl("span");
                sp2.InnerText = string.Format(" {0})", Translator.Translate(Define.DefaultCulture, "代写"));
                signName.Controls.Add(sp2);
            }

            HtmlGenericControl dateContainer = new HtmlGenericControl("div");

            dateContainer.Attributes["class"] = "signDate";
            dateContainer.InnerText           = opinion.AppendDatetime.ToString("yyyy-MM-dd HH:mm:ss");
            container.Controls.Add(dateContainer);
        }
        public GenericOpinion ToGenericOpinion()
        {
            GenericOpinion opinion = new GenericOpinion();

            opinion.ID          = this.ID;
            opinion.Content     = this.Content;
            opinion.OpinionType = this.OpinionType;

            return(opinion);
        }
        public void SimpleOpinionClientToServerTest()
        {
            WfClientOpinion client = PrepareClientOpinion();

            GenericOpinion server = null;

            WfClientOpinionConverter.Instance.ClientToServer(client, ref server);

            client.AreSame(server);
        }
Beispiel #12
0
        private void RenderOneOpinion(GenericOpinion opinion, HtmlTableRow row, int index)
        {
            HtmlTableCell cell = new HtmlTableCell();

            cell.Attributes["class"] = "opinions";

            row.Controls.Add(cell);

            RenderOneOpinionContent(opinion, cell, index);
        }
        public void SimpleOpinionServerToClientTest()
        {
            GenericOpinion server = PrepareServerOpinion();

            WfClientOpinion client = null;

            WfClientOpinionConverter.Instance.ServerToClient(server, ref client);

            client.AreSame(server);
        }
        private static void SaveOpinion(WfClientOpinion client)
        {
            if (client != null)
            {
                GenericOpinion server = null;

                WfClientOpinionConverter.Instance.ClientToServer(client, ref server);

                GenericOpinionAdapter.Instance.Update(server);
            }
        }
Beispiel #15
0
        private void SaveOpinionState(GenericOpinion opinion)
        {
            string data = string.Empty;

            if (opinion != null)
            {
                data = SerializationHelper.SerializeObjectToString(opinion, SerializationFormatterType.Binary);
            }

            Page.ClientScript.RegisterHiddenField(this.UniqueID, data);
        }
        private void executor_PrepareNotifyTasks(WfExecutorDataContext dataContext, UserTaskCollection tasks)
        {
            GenericOpinion opnion = (GenericOpinion)dataContext["AbortOpinion"];

            tasks.ForEach(t =>
            {
                if (t.Body.IsNullOrEmpty())
                {
                    t.Body = opnion.Content;
                }
            });
        }
Beispiel #17
0
        private GenericOpinion CreateDefaultOpinion()
        {
            GenericOpinion opinion = new GenericOpinion();

            opinion.ID = UuidHelper.NewUuidString();

            FillOpinionInfoByProcess(opinion);

            opinion.Content = _TextArea.Value;

            return(opinion);
        }
Beispiel #18
0
        private GenericOpinion LoadOpinionState()
        {
            GenericOpinion opinion = null;

            string data = HttpContext.Current.Request.Form[this.UniqueID];

            if (data.IsNotEmpty())
            {
                opinion = (GenericOpinion)SerializationHelper.DeserializeStringToObject(data, SerializationFormatterType.Binary);
            }

            return(opinion);
        }
Beispiel #19
0
        private static void PrepareStartupOpinions(WfExecutorDataContext dataContext, IUser user, string content)
        {
            GenericOpinion opinion = new GenericOpinion();

            opinion.ID          = Guid.NewGuid().ToString();
            opinion.ProcessID   = dataContext.CurrentProcess.ID;
            opinion.ActivityID  = dataContext.CurrentProcess.Activities[0].ID;
            opinion.ResourceID  = dataContext.CurrentProcess.ResourceID;
            opinion.Content     = content;
            opinion.IssuePerson = user;
            opinion.OpinionType = "提交";

            GenericOpinionAdapter.Instance.Update(opinion);
        }
Beispiel #20
0
        private void RenderOneOpinionContent(GenericOpinion opinion, Control opinionContainer, int index)
        {
            HtmlGenericControl opDiv = new HtmlGenericControl("div");

            opDiv.Attributes["class"] = "opinion";
            opDiv.Style["padding"]    = "0px";

            if (index > 0)
            {
                opDiv.Style["border-top"] = "1px dotted silver";
            }

            object nextStepsString = string.Empty;

            if (opinion.ExtData.TryGetValue("NextSteps", out nextStepsString))
            {
                OpinionListView.RenderOriginalOpinionSelector(opinionContainer, (string)nextStepsString);
            }

            OpinionListViewNamingContainer container = new OpinionListViewNamingContainer();

            opDiv.Controls.Add(container);

            container.ID = "Opinion" + opinion.ID;

            OnOpinionBind(new OpinionListViewBindEventArgs(opinion, null, container, true));

            string opText = EmptyOpinionText;

            if (string.IsNullOrEmpty(opinion.Content) == false)
            {
                opText = opinion.Content;
            }

            HtmlGenericControl div = new HtmlGenericControl("div");

            div.Style["padding"] = "6px 8px";

            if (EnableUserPresence == false)
            {
                RenderOneOpinionWithoutPrecense(opinion, opText, div);
            }
            else
            {
                RenderOneOpinionWithPrecense(opinion, opText, div);
            }

            opDiv.Controls.Add(div);
            opinionContainer.Controls.Add(opDiv);
        }
Beispiel #21
0
        public static WfClientProcess Save(WfClientSaveParameters parameters)
        {
            IWfProcess process = WfRuntime.GetProcessByProcessID(parameters.ProcessID);

            IWfActivity activity = process.CurrentActivity;

            WfSaveDataExecutor executor = new WfSaveDataExecutor(activity, activity);

            WfClientOpinion opinion = parameters.CurrentOpinion;

            GenericOpinion serverOpinion = PrepareOpinion(process.CurrentActivity, parameters.CurrentOpinion, DeluxeIdentity.CurrentUser);

            executor.PrepareApplicationData += dataContext => GenericOpinionAdapter.Instance.Update(serverOpinion);

            return(GetClientProcess(executor.Execute()));
        }
        public GenericOpinion CreateAbortOpinion()
        {
            GenericOpinion opinion = new GenericOpinion();

            opinion.ID           = UuidHelper.NewUuidString();
            opinion.ResourceID   = WfClientContext.Current.CurrentActivity.Process.ResourceID;
            opinion.ProcessID    = "AbortProcess";
            opinion.ActivityID   = WfClientContext.Current.OriginalActivity.ID;
            opinion.LevelName    = WfClientContext.Current.OriginalActivity.ApprovalRootActivity.Descriptor.LevelName;
            opinion.IssuePerson  = WfClientContext.Current.User;
            opinion.AppendPerson = DeluxeIdentity.CurrentRealUser;
            opinion.Content      = this.opinionText;
            opinion.OpinionType  = this.opinionType;

            return(opinion);
        }
        public static void FillPersonInfo(this GenericOpinion opinion)
        {
            if (HttpContext.Current.Request.IsAuthenticated)
            {
                IWfActivity originalActivity = WfClientContext.Current.OriginalActivity;

                opinion.IssuePerson = WfClientContext.Current.User;

                if (originalActivity != null)
                {
                    opinion.IssuePerson = originalActivity.Assignees.FindDelegator(opinion.IssuePerson);
                }

                opinion.AppendPerson = DeluxeIdentity.CurrentRealUser;
            }
        }
Beispiel #24
0
        public static WfClientProcess Moveto(WfClientMovetoParameters parameters)
        {
            IWfProcess process = WfRuntime.GetProcessByProcessID(parameters.ProcessID);

            IWfActivity activity = process.CurrentActivity;

            if (activity == null || activity.Assignees == null)// || !activity.Assignees.Contains(UserHelper.UserId))
            {
                return(null);
            }

            WfTransferParams transferParams = WfTransferParams.FromNextDefaultActivity(process);

            UserTaskCollection userTask = new UserTaskCollection();
            WfMoveToExecutor   executor = new WfMoveToExecutor(activity, activity, transferParams);

            //调整待办的url和标题
            executor.PrepareMoveToTasks += (dataContext, tasks) =>
            {
                PrepareUserTasks(tasks, null, null, transferParams.NextActivityDescriptor.Name);
            };

            GenericOpinion serverOpinion = PrepareOpinion(process.CurrentActivity, parameters.CurrentOpinion, DeluxeIdentity.CurrentUser);

            if (activity.Descriptor.ActivityType == WfActivityType.InitialActivity)
            {
                serverOpinion.OpinionType = "提交";
            }
            else if (activity.Descriptor.ActivityType == WfActivityType.CompletedActivity)
            {
                serverOpinion.OpinionType = string.Empty;
            }
            else if (activity.Descriptor.ActivityType == WfActivityType.NormalActivity)
            {
                serverOpinion.OpinionType = "同意";

                if (serverOpinion.Content.IsNullOrEmpty())
                {
                    serverOpinion.Content = "同意";
                }
            }

            executor.PrepareApplicationData += dataContext => GenericOpinionAdapter.Instance.Update(serverOpinion);

            return(GetClientProcess(executor.Execute()));
        }
Beispiel #25
0
        protected override void OnPreRender(EventArgs e)
        {
            if (Page.IsCallback == false &&
                WfClientContext.Current.OriginalActivity != null &&
                (WfClientContext.Current.OriginalActivity.Process.Status == WfProcessStatus.Aborted ||
                 WfClientContext.Current.OriginalActivity.Process.SameResourceRootProcess.Status == WfProcessStatus.Aborted))
            {
                GenericOpinion opinion =
                    GenericOpinionAdapter.Instance.LoadAbortProcessOpinion(WfClientContext.Current.OriginalActivity.Process.ResourceID);
                if (opinion != null)
                {
                    CreateOpinionInfo(opinion);
                }
            }

            base.OnPreRender(e);
        }
Beispiel #26
0
        public static void AreSame(this WfClientOpinion expected, GenericOpinion actual)
        {
            Assert.AreEqual(expected.ID, actual.ID);
            Assert.AreEqual(expected.ResourceID, actual.ResourceID);
            Assert.AreEqual(expected.ActivityID, actual.ActivityID);
            Assert.AreEqual(expected.ProcessID, actual.ProcessID);
            Assert.AreEqual(expected.LevelName, actual.LevelName);
            Assert.AreEqual(expected.LevelDesp, actual.LevelDesp);
            Assert.AreEqual(expected.OpinionType, actual.OpinionType);
            Assert.AreEqual(expected.IssueTime, actual.IssueDatetime);
            Assert.AreEqual(expected.AppendTime, actual.AppendDatetime);

            Assert.AreEqual(expected.IssuePersonID, actual.IssuePerson.ID);
            Assert.AreEqual(expected.IssuePersonName, actual.IssuePerson.DisplayName);

            Assert.AreEqual(expected.AppendPersonID, actual.AppendPerson.ID);
            Assert.AreEqual(expected.AppendPersonName, actual.AppendPerson.DisplayName);

            Assert.AreEqual(expected.ExtraData, actual.RawExtData);
        }
		private void CreateOpinionInfo(GenericOpinion opinion)
		{
			HtmlTable table = new HtmlTable();

			table.Style["border"] = "1px solid #efae27";
			table.Style[HtmlTextWriterStyle.BackgroundColor] = "#ffffe8";
			table.Width = "100%";

			Controls.Add(table);

			HtmlTableRow row = new HtmlTableRow();

			table.Controls.Add(row);

			HtmlTableCell cellLeft = new HtmlTableCell();

			row.Controls.Add(cellLeft);

			HtmlTableCell cellRight = new HtmlTableCell();

			cellRight.Align = "right";

			row.Controls.Add(cellRight);

			HtmlImage logo = new HtmlImage();

			logo.Src = ControlResources.CancelledLogoUrl;
			logo.Align = "absmiddle";
			logo.Alt = "流程被作废";

			cellLeft.Controls.Add(logo);

			HtmlGenericControl span = new HtmlGenericControl("span");

			span.InnerHtml = HttpUtility.HtmlEncode(opinion.Content).Replace("\n", "<br/>");

			cellLeft.Controls.Add(span);

			cellRight.InnerText = opinion.IssuePerson.DisplayName + " " +
				string.Format("{0:yyyy-MM-dd HH:mm:ss}", opinion.IssueDatetime);
		}
Beispiel #28
0
        private void RenderOneOpinionWithoutPrecense(GenericOpinion opinion, string opText, Control container)
        {
            string signature = HttpUtility.HtmlEncode(opinion.IssuePerson.DisplayName);

            if (opinion.IssuePerson.ID != opinion.AppendPerson.ID)
            {
                signature = string.Format("{0}({1} {2})",
                                          HttpUtility.HtmlEncode(opinion.IssuePerson.DisplayName),
                                          HttpUtility.HtmlEncode(opinion.AppendPerson.DisplayName),
                                          Translator.Translate(Define.DefaultCulture, "代写"));
            }

            if (OpinionListControlHelper.UserSignatures.ContainsKey(opinion.IssuePerson.ID))
            {
                signature = string.Format("<img src=\"{0}\" alt=\"{1}\" title=\"{1}\" />",
                                          OpinionListControlHelper.UserSignatures[opinion.IssuePerson.ID],
                                          signature);
            }

            HtmlGenericControl divOpinion = new HtmlGenericControl("div");

            divOpinion.Attributes["class"] = "text";
            divOpinion.InnerHtml           = HttpUtility.HtmlEncode(opText).Replace("\r\n", "<br/>");

            container.Controls.Add(divOpinion);

            HtmlGenericControl divSignName = new HtmlGenericControl("div");

            divSignName.Attributes["class"] = "signName";

            divSignName.Controls.Add(new LiteralControl(signature));

            container.Controls.Add(divSignName);

            HtmlGenericControl divSignDate = new HtmlGenericControl("div");

            divSignDate.Attributes["class"] = "signDate";
            divSignDate.InnerText           = opinion.AppendDatetime.ToString("yyyy-MM-dd HH:mm:ss");

            container.Controls.Add(divSignDate);
        }
Beispiel #29
0
        private void CreateOpinionInfo(GenericOpinion opinion)
        {
            HtmlTable table = new HtmlTable();

            table.Style["border"] = "1px solid #efae27";
            table.Style[HtmlTextWriterStyle.BackgroundColor] = "#ffffe8";
            table.Width = "100%";

            Controls.Add(table);

            HtmlTableRow row = new HtmlTableRow();

            table.Controls.Add(row);

            HtmlTableCell cellLeft = new HtmlTableCell();

            row.Controls.Add(cellLeft);

            HtmlTableCell cellRight = new HtmlTableCell();

            cellRight.Align = "right";

            row.Controls.Add(cellRight);

            HtmlImage logo = new HtmlImage();

            logo.Src   = ControlResources.CancelledLogoUrl;
            logo.Align = "absmiddle";
            logo.Alt   = "流程被作废";

            cellLeft.Controls.Add(logo);

            HtmlGenericControl span = new HtmlGenericControl("span");

            span.InnerHtml = HttpUtility.HtmlEncode(opinion.Content).Replace("\n", "<br/>");

            cellLeft.Controls.Add(span);

            cellRight.InnerText = opinion.IssuePerson.DisplayName + " " +
                                  string.Format("{0:yyyy-MM-dd HH:mm:ss}", opinion.IssueDatetime);
        }
Beispiel #30
0
        /// <summary>
        /// 得到在当前活动的意见信息
        /// </summary>
        /// <param name="originalActivity"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public WfClientOpinion GetUserActivityOpinion(IWfActivity originalActivity, WfClientUser user)
        {
            WfClientOpinion opinion = null;

            if (originalActivity != null && user != null)
            {
                WhereSqlClauseBuilder builder = new WhereSqlClauseBuilder();

                builder.AppendItem("ACTIVITY_ID", originalActivity.ID);
                builder.AppendItem("ISSUE_PERSON_ID", user.ID);

                GenericOpinion serverOpinion = GenericOpinionAdapter.Instance.LoadByBuilder(builder).FirstOrDefault();

                if (serverOpinion != null)
                {
                    WfClientOpinionConverter.Instance.ServerToClient(serverOpinion, ref opinion);
                }
            }

            return(opinion);
        }
Beispiel #31
0
        private static WfClientOpinion GetUserActivityOpinion(GenericOpinionCollection opinions, IWfActivity originalActivity, IUser user)
        {
            WfClientOpinion opinion = null;

            GenericOpinion serverOpinion = opinions.Find(o =>
                                                         string.Compare(o.ActivityID, originalActivity.ID, true) == 0 &&
                                                         string.Compare(o.IssuePerson.ID, user.ID, true) == 0);

            if (serverOpinion != null)
            {
                opinion = new WfClientOpinion(serverOpinion);
            }
            else
            {
                opinion = new WfClientOpinion()
                {
                    ID = UuidHelper.NewUuidString()
                }
            };

            return(opinion);
        }
Beispiel #32
0
        public static void FillOpinionInfoByProcess(GenericOpinion opinion, IWfActivity originalActivity)
        {
            if (originalActivity != null)
            {
                opinion.ResourceID = originalActivity.Process.ResourceID;
                opinion.ProcessID  = originalActivity.Process.ID;
                opinion.ActivityID = originalActivity.ID;

                IWfActivity rootActivity = originalActivity.OpinionRootActivity;

                if (rootActivity.Process.MainStream != null && rootActivity.MainStreamActivityKey.IsNotEmpty())
                {
                    opinion.LevelName = rootActivity.MainStreamActivityKey;
                }
                else
                {
                    if (string.IsNullOrEmpty(rootActivity.Descriptor.AssociatedActivityKey))
                    {
                        opinion.LevelName = rootActivity.Descriptor.Key;
                    }
                    else
                    {
                        opinion.LevelName = rootActivity.Descriptor.AssociatedActivityKey;
                    }
                }

                if (rootActivity.Process.MainStream != null)
                {
                    opinion.LevelDesp = rootActivity.Process.MainStream.Activities[opinion.LevelName].Name;
                }
                else
                {
                    opinion.LevelDesp = rootActivity.Descriptor.Process.Activities[opinion.LevelName].Name;
                }
            }

            opinion.FillPersonInfo();
        }
        public static void AreSame(this WfClientOpinion expected, GenericOpinion actual)
        {
            Assert.AreEqual(expected.ID, actual.ID);
            Assert.AreEqual(expected.ResourceID, actual.ResourceID);
            Assert.AreEqual(expected.ActivityID, actual.ActivityID);
            Assert.AreEqual(expected.ProcessID, actual.ProcessID);
            Assert.AreEqual(expected.LevelName, actual.LevelName);
            Assert.AreEqual(expected.LevelDesp, actual.LevelDesp);
            Assert.AreEqual(expected.OpinionType, actual.OpinionType);
            Assert.AreEqual(expected.IssueTime, actual.IssueDatetime);
            Assert.AreEqual(expected.AppendTime, actual.AppendDatetime);

            Assert.AreEqual(expected.IssuePersonID, actual.IssuePerson.ID);
            Assert.AreEqual(expected.IssuePersonName, actual.IssuePerson.DisplayName);

            Assert.AreEqual(expected.AppendPersonID, actual.AppendPerson.ID);
            Assert.AreEqual(expected.AppendPersonName, actual.AppendPerson.DisplayName);

            Assert.AreEqual(expected.ExtraData, actual.RawExtData);
        }
		private void RenderOneOpinionWithoutPrecense(GenericOpinion opinion, string opText, Control container)
		{
			string signature = HttpUtility.HtmlEncode(opinion.IssuePerson.DisplayName);

			if (opinion.IssuePerson.ID != opinion.AppendPerson.ID)
			{
				signature = string.Format("{0}({1} {2})",
					HttpUtility.HtmlEncode(opinion.IssuePerson.DisplayName),
					HttpUtility.HtmlEncode(opinion.AppendPerson.DisplayName),
					Translator.Translate(Define.DefaultCulture, "代写"));
			}

			if (OpinionListControlHelper.UserSignatures.ContainsKey(opinion.IssuePerson.ID))
			{
				signature = string.Format("<img src=\"{0}\" alt=\"{1}\" title=\"{1}\" />",
					OpinionListControlHelper.UserSignatures[opinion.IssuePerson.ID],
					signature);
			}

			HtmlGenericControl divOpinion = new HtmlGenericControl("div");
			divOpinion.Attributes["class"] = "text";
			divOpinion.InnerHtml = HttpUtility.HtmlEncode(opText).Replace("\r\n", "<br/>");

			container.Controls.Add(divOpinion);

			HtmlGenericControl divSignName = new HtmlGenericControl("div");
			divSignName.Attributes["class"] = "signName";

			divSignName.Controls.Add(new LiteralControl(signature));

			container.Controls.Add(divSignName);

			HtmlGenericControl divSignDate = new HtmlGenericControl("div");
			divSignDate.Attributes["class"] = "signDate";
			divSignDate.InnerText = opinion.AppendDatetime.ToString("yyyy-MM-dd HH:mm:ss");

			container.Controls.Add(divSignDate);
		}
		private void RenderOneOpinionWithPrecense(GenericOpinion opinion, string opText, Control container)
		{
			HtmlGenericControl opTextContainer = new HtmlGenericControl("div");

			opTextContainer.Attributes["class"] = "text";
			opTextContainer.InnerHtml = HttpUtility.HtmlEncode(opText).Replace("\r\n", "<br/>");
			container.Controls.Add(opTextContainer);

			HtmlGenericControl signName = new HtmlGenericControl("div");
			signName.Attributes["class"] = "signName";
			container.Controls.Add(signName);

			UserPresence presence = new UserPresence();

			if (OpinionListControlHelper.UserSignatures.ContainsKey(opinion.IssuePerson.ID))
			{
				HtmlImage sigImage = new HtmlImage();

				sigImage.Src = OpinionListControlHelper.UserSignatures[opinion.IssuePerson.ID];
				sigImage.Alt = opinion.IssuePerson.DisplayName;

				signName.Controls.Add(sigImage);

				presence.ShowUserDisplayName = false;
			}

			signName.Controls.Add(presence);

			presence.UserID = opinion.IssuePerson.ID;
			presence.UserDisplayName = opinion.IssuePerson.DisplayName;	//防止人员离职
			presence.EnsureInUserList();

			if (opinion.IssuePerson.ID != opinion.AppendPerson.ID)
			{
				HtmlGenericControl sp1 = new HtmlGenericControl("span");
				sp1.InnerText = "(";
				signName.Controls.Add(sp1);

				UserPresence presence2 = new UserPresence();
				signName.Controls.Add(presence2);
				presence2.UserID = opinion.AppendPerson.ID;
				presence2.UserDisplayName = opinion.AppendPerson.DisplayName;	//防止人员离职
				presence2.EnsureInUserList();

				HtmlGenericControl sp2 = new HtmlGenericControl("span");
				sp2.InnerText = string.Format(" {0})", Translator.Translate(Define.DefaultCulture, "代写"));
				signName.Controls.Add(sp2);
			}

			HtmlGenericControl dateContainer = new HtmlGenericControl("div");

			dateContainer.Attributes["class"] = "signDate";
			dateContainer.InnerText = opinion.AppendDatetime.ToString("yyyy-MM-dd HH:mm:ss");
			container.Controls.Add(dateContainer);
		}
		private void RenderOneOpinionContent(GenericOpinion opinion, Control opinionContainer, int index)
		{		
			HtmlGenericControl opDiv = new HtmlGenericControl("div");
			opDiv.Attributes["class"] = "opinion";
			opDiv.Style["padding"] = "0px";

			if (index > 0)
				opDiv.Style["border-top"] = "1px dotted silver";

			object nextStepsString = string.Empty;

			if (opinion.ExtData.TryGetValue("NextSteps", out nextStepsString))
			{
				OpinionListView.RenderOriginalOpinionSelector(opinionContainer, (string)nextStepsString);
			}

			OpinionListViewNamingContainer container = new OpinionListViewNamingContainer();
			opDiv.Controls.Add(container);
	
			container.ID = "Opinion" + opinion.ID;

			OnOpinionBind(new OpinionListViewBindEventArgs(opinion, null, container, true));

			string opText = EmptyOpinionText;

			if (string.IsNullOrEmpty(opinion.Content) == false)
				opText = opinion.Content;

			HtmlGenericControl div = new HtmlGenericControl("div");
			div.Style["padding"] = "6px 8px";

			if (EnableUserPresence == false)
			{
				RenderOneOpinionWithoutPrecense(opinion, opText, div);
			}
			else
			{
				RenderOneOpinionWithPrecense(opinion, opText, div);
			}

			opDiv.Controls.Add(div);
			opinionContainer.Controls.Add(opDiv);
		}
		private void RenderOneOpinion(GenericOpinion opinion, HtmlTableRow row, int index)
		{
			HtmlTableCell cell = new HtmlTableCell();

			cell.Attributes["class"] = "opinions";

			row.Controls.Add(cell);

			RenderOneOpinionContent(opinion, cell, index);
		}
        private static GenericOpinion PrepareServerOpinion()
        {
            GenericOpinion opinion = new GenericOpinion();

            opinion.ID = UuidHelper.NewUuidString();
            opinion.ResourceID = UuidHelper.NewUuidString();
            opinion.ActivityID = UuidHelper.NewUuidString();
            opinion.ProcessID = UuidHelper.NewUuidString();
            opinion.LevelName = "TestLevelName";
            opinion.LevelDesp = "LevelDesp";
            opinion.OpinionType = "OpinionType";
            opinion.IssueDatetime = DateTime.Now;
            opinion.AppendDatetime = DateTime.Now;
            opinion.Content = "Hello world";
            opinion.IssuePerson = new OguUser(UuidHelper.NewUuidString()) { DisplayName = "Shen Zheng" };
            opinion.AppendPerson = new OguUser(UuidHelper.NewUuidString()) { DisplayName = "Shen Rong" };
            opinion.RawExtData = "Extra Data";

            return opinion;
        }
        public GenericOpinion CreateAbortOpinion()
        {
            GenericOpinion opinion = new GenericOpinion();

            opinion.ID = UuidHelper.NewUuidString();
            opinion.ResourceID = WfClientContext.Current.CurrentActivity.Process.ResourceID;
            opinion.ProcessID = "AbortProcess";
            opinion.ActivityID = WfClientContext.Current.OriginalActivity.ID;
            opinion.LevelName = WfClientContext.Current.OriginalActivity.ApprovalRootActivity.Descriptor.LevelName;
            opinion.IssuePerson = WfClientContext.Current.User;
            opinion.AppendPerson = DeluxeIdentity.CurrentRealUser;
            opinion.Content = this.opinionText;
            opinion.OpinionType = this.opinionType;

            return opinion;
        }
		protected override void LoadViewState(object savedState)
		{
			_CurrentOpinion = WebControlUtility.GetViewStateValue(ViewState, "CurrentOpinion", (GenericOpinion)null);

			string reqOType = string.Format("{0}${1}${2}", this.ClientID, "OpinionInput", "OpinionType");

			string opinionType = WebUtility.GetRequestFormString(reqOType, string.Empty);

			if (string.IsNullOrEmpty(opinionType) == false)
			{
				OpinionInput.SetOpinionType(opinionType);
			}

			base.LoadViewState(savedState);
		}