/// <summary> /// Выполняет указанный источник данных; ожидается, что в результате /// выполнения этого источника данных получим идентификатор некого /// объекта (тип тут не задан) /// </summary> /// <param name="sDataSourceName">Наименование источника данных</param> /// <param name="dictionaryParams"> /// Хеш параметров; здесь в паре ключ пары - наименование параметра, /// значение пары - собственно значение параметра. Последний может быть /// типизированным значением, значением в стрковом представленнии. /// Технически допустимо значение в виде массива типизированных значений /// или их строковых представлений - в этом случае такие данные /// приводят к формированию условий виде Param IN (value1, ..., valueN) /// </param> /// <param name="connection">Соединение с СУБД; на момент вызова д.б. открыто</param> /// <returns>Значение ObjectID экземпляра объекта</returns> protected Guid processDataSource( string sDataSourceName, Hashtable dictionaryParams, XStorageConnection connection) { // Получим источник данных, подставим переданные параметры и выполним его: XDataSource dataSource = connection.GetDataSource(sDataSourceName); dataSource.SubstituteNamedParams(dictionaryParams, true); dataSource.SubstituteOrderBy(); object oResult = dataSource.ExecuteScalar(); // Ожидается, что в результате мы получаем GUID: Guid uidResult = Guid.Empty; if (null != oResult && DBNull.Value != oResult) { uidResult = connection.Behavior.CastGuidValueFromDB(oResult); } return(uidResult); }
/// <summary> /// ¬нутренний метод получени¤ данных объекта UserProfile дл¤ пользовател¤ /// системы, заданного идентификатором (SystemUser.ObjectID). /// </summary> /// <param name="uidSystemUserID">»дентификатор пользовател¤</param> /// <returns> /// -- »нифиализированный объект DomainObjectData, описывающий данные UserProfile /// -- null, если профил¤ пользовател¤ нет (что, в принципе возможно) /// </returns> protected DomainObjectData getUserProfile(Guid uidSystemUserID, XStorageConnection connection) { // ѕолучим идентификатор объекта UserProfile, соответствующего // указанному пользователю; дл¤ этого воспользуемс¤ запросом, // "зашитым" в data-source: // ...параметр запроса - идентификатор пользовател¤: XParamsCollection datasourceParams = new XParamsCollection(); datasourceParams.Add("UserID", uidSystemUserID); // ...получение и выполнение источника данных: XDataSource dataSource = connection.GetDataSource(DEF_DATASOURCE_NAME); dataSource.SubstituteNamedParams(datasourceParams, true); dataSource.SubstituteOrderBy(); object oResult = dataSource.ExecuteScalar(); // ќжидаетс¤, что в результате мы получаем GUID: если в результате // получили null - что говорит об отсутствии профил¤ - возвращаем null: Guid uidResult = Guid.Empty; if (null != oResult && DBNull.Value != oResult) { uidResult = connection.Behavior.CastGuidValueFromDB(oResult); } if (Guid.Empty == uidResult) { return(null); } // «агрузка данных профил¤ пользовател¤: DomainObjectDataSet dataSet = new DomainObjectDataSet(connection.MetadataManager.XModel); DomainObjectData xobj = dataSet.Load(connection, "UserProfile", uidResult); return(xobj); }
public GetMailMsgInfoResponse Execute(GetMailMsgInfoRequest request, IXExecutionContext context) { if (request.ObjectType != "Incident" && request.ObjectType != "Folder") { throw new ArgumentException("Поддерживается два типа Incident и Folder, передано: " + request.ObjectType); } bool bLinkToIncident = request.ObjectType == "Incident"; DomainObjectDataSet dataSet = new DomainObjectDataSet(context.Connection.MetadataManager.XModel); // загрузим Папку и Инцидент DomainObjectData xobjFolder = loadFolderAndIncident(dataSet, request, context); DomainObjectData xobjIncident = null; if (bLinkToIncident) { xobjIncident = dataSet.Find("Incident", request.ObjectID); } // Получим путь к папке от корневой XDataSource ds = context.Connection.GetDataSource("GetFolderPath"); Hashtable dsParams = new Hashtable(); dsParams.Add("FolderID", xobjFolder.ObjectID); ds.SubstituteNamedParams(dsParams, true); GetMailMsgInfoResponse response = new GetMailMsgInfoResponse(); response.FolderPath = "Проект: " + (string)ds.ExecuteScalar(); StringBuilder bld = new StringBuilder(); // заголовок - наименование инцидента или проекта bld.Append("ITRACKER: "); if (bLinkToIncident) { bld.Append("Инцидент №"); bld.Append(xobjIncident.GetLoadedPropValue("Number")); bld.Append(" - "); bld.Append(xobjIncident.GetLoadedPropValue("Name")); } else { bld.Append(xobjFolder.GetLoadedPropValue("Name")); } response.Subject = bld.ToString(); XmlNodeList xmlNodes = context.Config.SelectNodes("it:app-data/it:system-location/*"); string[] aAppInstanceUrls = new string[xmlNodes.Count]; for (int i = 0; i < xmlNodes.Count; ++i) { aAppInstanceUrls[i] = xmlNodes[i].InnerText; if (!aAppInstanceUrls[i].EndsWith("/")) { aAppInstanceUrls[i] = aAppInstanceUrls[i] + "/"; } } // ссылки на проект bld.Length = 0; bld.Append("Просмотр проекта:"); bld.Append(Environment.NewLine); foreach (string sAppUrl in aAppInstanceUrls) { bld.AppendFormat("\t{0}x-get-report.aspx?Name=r-Folder.xml&ID={1}{2}", sAppUrl, xobjFolder.ObjectID, Environment.NewLine); } bld.Append("Открыть в дереве:"); bld.Append(Environment.NewLine); foreach (string sAppUrl in aAppInstanceUrls) { bld.AppendFormat("\t{0}x-tree.aspx?METANAME=Main&LocateFolderByID={1}{2}", sAppUrl, xobjFolder.ObjectID, Environment.NewLine); } response.ProjectLinks = bld.ToString(); // ссылки на инцидент bld.Length = 0; if (bLinkToIncident) { bld.Append("Редактирование инцидента:"); bld.Append(Environment.NewLine); foreach (string sAppUrl in aAppInstanceUrls) { bld.AppendFormat("\t{0}x-list.aspx?OT=Incident&METANAME=IncidentSearchingList&OpenEditorByIncidentID={1}{2}", sAppUrl, xobjIncident.ObjectID, Environment.NewLine); } bld.Append("Просмотр инцидента:"); bld.Append(Environment.NewLine); foreach (string sAppUrl in aAppInstanceUrls) { bld.AppendFormat("\t{0}x-get-report.aspx?NAME=r-Incident.xml&DontCacheXslfo=true&IncidentID={1}{2}", sAppUrl, xobjIncident.ObjectID, Environment.NewLine); } bld.Append("Открыть в дереве:"); bld.Append(Environment.NewLine); foreach (string sAppUrl in aAppInstanceUrls) { bld.AppendFormat("\t{0}x-tree.aspx?METANAME=Main&LocateIncidentByID={1}{2}", sAppUrl, xobjIncident.ObjectID, Environment.NewLine); } response.IncidentLinks = bld.ToString(); } response.To = getUsersEMail(request, context); return(response); }
/// <summary> /// Метод запуска операции на выполнение, <входная> точка операции /// ПЕРЕГРУЖЕННЫЙ, СТРОГО ТИПИЗИРОВАННЫЙ МЕТОД /// ВЫЗЫВАЕТСЯ ЯДРОМ АВТОМАТИЧЕСКИ /// </summary> /// <param name="request">Запрос на выполнение операции</param> /// <param name="context">Контекст выполнения операции</param> /// <returns>Результат выполнения</returns> public XGetObjectResponse Execute(XRequest request, IXExecutionContext context) { // #1: Определяем идентификатор текущего пользователя // Используем внутренние механизмы аутентификации ITUser user = (ITUser)XSecurityManager.Instance.GetCurrentUser(); XParamsCollection datasourceParams = new XParamsCollection(); datasourceParams.Add("UserID", user.SystemUserID); // #2: Найдем идентификатор объекта - профиля, связанного с текущим // пользователем: испоьзуем для этого тривиальный запрос, заданный // в "источнике данных" XDataSource dataSource = context.Connection.GetDataSource(DEF_DATASOURCE_NAME); dataSource.SubstituteNamedParams(datasourceParams, true); dataSource.SubstituteOrderBy(); object oResult = dataSource.ExecuteScalar(); // Ожидается, что в результате мы получаем GUID: Guid uidResult = Guid.Empty; if (null != oResult && DBNull.Value != oResult) { uidResult = context.Connection.Behavior.CastGuidValueFromDB(oResult); } // #3: Загрузка данных профиля и всех сопутствующих объектов: DomainObjectDataSet dataSet = new DomainObjectDataSet(context.Connection.MetadataManager.XModel); DomainObjectData xobj; if (Guid.Empty != uidResult) { // Объект профиля уже есть; загружаем существующий xobj = dataSet.Load(context.Connection, "UserProfile", uidResult); } else { xobj = dataSet.CreateNew("UserProfile", false); // В новом объекте описания профиля сразу проставляем заглушку на текущего пользователя xobj.SetUpdatedPropValue("SystemUser", user.SystemUserID); // Задаем "собственную" стартовую страницу по умолчанию - список текущих инцидентов xobj.SetUpdatedPropValue("StartPage", StartPages.CurrentTaskList); } // Догружаем данные пользователя (SystemUser) и сотрудника (Employee) dataSet.PreloadProperty(context.Connection, xobj, "SystemUser.Employee"); // Сериализуем датасет с загруженными объектами в формат для Web-клиента DomainObjectDataXmlFormatter formatter = new DomainObjectDataXmlFormatter(context.Connection.MetadataManager); // ... при этом учитываем, что в сериализованные данные должны так же попасть // данные с описанием пользователя и сотрудника: XmlElement xmlObject = formatter.SerializeObject(xobj, new string[] { "SystemUser.Employee" }); if (Guid.Empty != uidResult) { // ..обработаем объект и все вложенные объекты в прогруженных свойства, расставим атрибуты ограничения доступа XmlObjectRightsProcessor.ProcessObject(xobj, xmlObject); } return(new XGetObjectResponse(xmlObject)); }
/// <summary> /// ћетод запуска операции на выполнение, <входна¤> точка операции /// ѕ≈–≈√–”∆≈ЌЌџ…, —“–ќ√ќ “»ѕ»«»–ќ¬јЌЌџ… ћ≈“ќƒ /// ¬џ«џ¬ј≈“—я яƒ–ќћ ј¬“ќћј“»„≈— » /// </summary> /// <param name="request">«апрос на выполнение операции</param> /// <param name="context"> онтекст выполнени¤ операции</param> /// <returns>–езультат выполнени¤</returns> public new GetExpensesDataResponse Execute(XRequest request, IXExecutionContext context) { ITUser user = (ITUser)XSecurityManager.Instance.GetCurrentUser(); Hashtable dictionaryParams = new Hashtable(); dictionaryParams.Add("EmployeeID", user.EmployeeID); // ѕолучим источник данных, подставим переданные параметры и выполним его: XDataSource dataSource = context.Connection.GetDataSource("GetEmployeeCurrentSummaryExpenses"); dataSource.SubstituteNamedParams(dictionaryParams, true); dataSource.SubstituteOrderBy(); DataTable resultDataTable = dataSource.ExecuteDataTable(); // в результирующей таблице должно быть шесть колонок, три строки: if (resultDataTable.Columns.Count != 6 && resultDataTable.Rows.Count != 3) { throw new ApplicationException("Ќекорректный результат получени¤ данных затрат сотрудника"); // TODO: ѕоправить текст сообщени¤! } // ‘ормируем результат: GetExpensesDataResponse response = new GetExpensesDataResponse(); response.EmployeeID = user.EmployeeID; for (int nRow = 0; nRow < resultDataTable.Rows.Count; nRow++) { PeriodExpensesInfo infoExpenses; switch ((int)resultDataTable.Rows[nRow]["RowCode"]) { case 1: infoExpenses = response.PreviousMonth; break; case 2: infoExpenses = response.CurrentMonth; break; case 3: (infoExpenses = response.CurrentDay).IsOneDayPeriod = true; break; default: throw new ApplicationException("Ќеожиданные данные!"); } // «ачитываем данные: // ...границы периода: infoExpenses.PeriodStartDate = (DateTime)resultDataTable.Rows[nRow]["PeriodStartDate"]; if (!infoExpenses.IsOneDayPeriod) { infoExpenses.PerionEndDate = (DateTime)resultDataTable.Rows[nRow]["PeriodEndDate"]; } // ...данные о продолжительности рабочего дн¤ (дл¤ корректного рассчета кол-ва дней в периоде) infoExpenses.ExpectedExpense.WorkDayDuration = (int)resultDataTable.Rows[nRow]["WorkDayDuration"]; infoExpenses.RealExpense.WorkDayDuration = infoExpenses.ExpectedExpense.WorkDayDuration; infoExpenses.RemainsExpense.WorkDayDuration = infoExpenses.ExpectedExpense.WorkDayDuration; // ...собственно данные о затратах: infoExpenses.ExpectedExpense.Duration = (int)resultDataTable.Rows[nRow]["ExpectedExpense"]; infoExpenses.RealExpense.Duration = (int)resultDataTable.Rows[nRow]["RealExpense"]; // ...остаток списаний имеет смысл только если реальные затраты меньше ожидаемых // (в остальных случа¤х остаток считаем равным нулю): if (infoExpenses.ExpectedExpense.Duration > infoExpenses.RealExpense.Duration) { infoExpenses.RemainsExpense.Duration = infoExpenses.ExpectedExpense.Duration - infoExpenses.RealExpense.Duration; } // ¬ычисл¤емые значени¤: // ...наименование периода: if (infoExpenses.IsOneDayPeriod) { infoExpenses.PeriodName = "—егодн¤"; } else { infoExpenses.PeriodName = getMonthName(infoExpenses.PeriodStartDate); } // ..."цвет" периода: дл¤ периода продолжительностью в мес¤ц // и однодневных периодов вычисл¤етс¤ по разному: if (infoExpenses.IsOneDayPeriod) { // "«еленый", если реальные затраты больше или равны ожидаемым: if (infoExpenses.RealExpense.Duration >= infoExpenses.ExpectedExpense.Duration) { infoExpenses.Completeness = ExpensesCompleteness.GreenZone; } // "—иний", если реальные затраты меньше ожидаемых менее чем на час (60 минут): else if (infoExpenses.ExpectedExpense.Duration - infoExpenses.RealExpense.Duration <= 60) { infoExpenses.Completeness = ExpensesCompleteness.BlueZone; } // " расна¤" зона - во всех остальных случа¤х: else { infoExpenses.Completeness = ExpensesCompleteness.RedZone; } } else { // "«еленый", если реальные затраты больше или равны ожидаемым: if (infoExpenses.RealExpense.Duration >= infoExpenses.ExpectedExpense.Duration) { infoExpenses.Completeness = ExpensesCompleteness.GreenZone; } // "—иний", если реальные затраты меньше ожидаемых менее чем на –јЅќ„»… ƒ≈Ќ№ (60 минут): else if (infoExpenses.ExpectedExpense.Duration - infoExpenses.RealExpense.Duration <= infoExpenses.RealExpense.WorkDayDuration) { infoExpenses.Completeness = ExpensesCompleteness.BlueZone; } // " расна¤" зона - во всех остальных случа¤х: else { infoExpenses.Completeness = ExpensesCompleteness.RedZone; } } } return(response); }