Пример #1
0
        private void fillDataSetWithChildFoldersWithUpdatedState(XStorageConnection con, DomainObjectDataSet dataSet, Guid objectID, FolderStates folderState)
        {
            // зачитаем идентификаторы всех подчиненных папок, состояние которых отличается от требуемого
            XDbCommand cmd = con.CreateCommand(@"
				SELECT f.ObjectID
				FROM Folder f_s WITH(NOLOCK)
					JOIN Folder f  WITH(NOLOCK) ON f.LIndex > f_s.LIndex AND f.RIndex < f_s.RIndex AND f.Customer = f_s.Customer
				WHERE f_s.ObjectID = @ObjectID AND f.State <> @TargetState
				"                );

            // закрытие закрывает все вложенные папки без учета их состояния:
            // if (folderState == FolderStates.Closed) - Nothing to do

            // замораживание замораживает открытые и ожидающие закрытия
            if (folderState == FolderStates.Frozen)
            {
                cmd.CommandText = cmd.CommandText + " AND f.State IN (" + FolderStatesItem.Open.IntValue + "," + FolderStatesItem.WaitingToClose.IntValue + ")";
            }
            // перевод в "ожидание закрытие" применим только для открытых (т.е. замороженные и закрытые не трогаются)
            //else if (folderState == FolderStates.WaitingToClose)
            //cmd.CommandText = cmd.CommandText + " AND f.State = " + FolderStatesItem.Open.IntValue;

            cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, objectID);
            cmd.Parameters.Add("TargetState", DbType.Int16, ParameterDirection.Input, false, (Int16)folderState);
            using (IDataReader reader = cmd.ExecuteReader())
            {
                DomainObjectData xobjSubFolder;
                while (reader.Read())
                {
                    xobjSubFolder = dataSet.GetLoadedStub("Folder", reader.GetGuid(0));
                    xobjSubFolder.SetUpdatedPropValue("State", folderState);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Возвращает строку из емейлов, считанных из первой колонки результата выполнения переданной команды
        /// ВНИМАНИЕ: В список емейлов не включается емейл текущего пользователя
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private string readEMails(XDbCommand cmd)
        {
            StringBuilder bld     = new StringBuilder();
            ITUser        user    = (ITUser)XSecurityManager.Instance.GetCurrentUser();
            string        sIgnore = null;

            if (user.EMail != null && user.EMail.Length > 0)
            {
                sIgnore = user.EMail;
            }
            using (IDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    if (!reader.IsDBNull(reader.GetOrdinal("EMail")))
                    {
                        string sEmail = reader.GetString(reader.GetOrdinal("EMail"));
                        if (!sEmail.Equals(sIgnore))
                        {
                            if (bld.Length > 0)
                            {
                                bld.Append(";");
                            }
                            bld.Append(sEmail);
                        }
                    }
                }
            }
            return(bld.ToString());
        }
Пример #3
0
        private void UpdateChildDepartments(XStorageConnection con, DomainObjectDataSet dataSet, Guid objectID, bool IsArchive)
        {
            // Обновляем вложенные департаменты, если мы меняем признак на "Архивный".
            // Если признак "Архивный" снимается, каскадной разархивации не происходит.
            // зачитаем идентификаторы всех подчиненных департаментов, состояние которых отличается от требуемого
            if (IsArchive)
            {
                XDbCommand cmd = con.CreateCommand(@"
				    SELECT d.ObjectID
				    FROM dbo.Department as d_s WITH(NOLOCK)
					    JOIN dbo.Department as d  WITH(NOLOCK) ON d.LIndex > d_s.LIndex AND d.RIndex < d_s.RIndex AND d.Organization = d_s.Organization
				    WHERE d_s.ObjectID = @ObjectID AND d.IsArchive <> @IsArchive
				    "                );
                cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, objectID);
                cmd.Parameters.Add("IsArchive", DbType.Boolean, ParameterDirection.Input, false, IsArchive);
                using (IDataReader reader = cmd.ExecuteReader())
                {
                    DomainObjectData xobjSubDepartment;
                    while (reader.Read())
                    {
                        xobjSubDepartment = dataSet.GetLoadedStub("Department", reader.GetGuid(0));
                        xobjSubDepartment.SetUpdatedPropValue("IsArchive", IsArchive);
                    }
                }
            }
        }
Пример #4
0
        private static List <string> GetMemoTableList(XDbConnection con)
        {
            List <string> lst = new List <string>();
            DataTable     dt  = new DataTable();

            string commandString = string.Format("Exec SP_COLUMNS_EX N'{0}'", XDbEnvironment.CalculateLinkedSrvName(con.InputFile));

            using (DbCommand comm = new XDbCommand(commandString, con))
            {
                using (DbDataReader reader = comm.ExecuteReader())
                {
                    dt.Load(reader, LoadOption.OverwriteChanges);
                }

                // Go through the table rows and search for the memo fields( TYPE_NAME = VarChar && COLUMN_SIZE = 0 )
                foreach (DataRow row in dt.Rows)
                {
                    if ((row["TYPE_NAME"].ToString() == "VarChar") && (row["COLUMN_SIZE"].ToString() == "0"))
                    {
                        if (!lst.Contains(row["TABLE_NAME"].ToString()))
                        {
                            lst.Add(row["TABLE_NAME"].ToString());
                        }
                    }
                }
            }
            return(lst);
        }
Пример #5
0
        private DomainObjectData loadFolderAndIncident(DomainObjectDataSet dataSet, GetMailMsgInfoRequest request, IXExecutionContext context)
        {
            DomainObjectData xobjFolder;

            if (request.ObjectType == "Folder")
            {
                xobjFolder = dataSet.GetLoadedStub("Folder", request.ObjectID);
                dataSet.LoadProperty(context.Connection, xobjFolder, "Name");
            }
            else
            {
                XDbCommand cmd = context.Connection.CreateCommand(
                    @"SELECT f.ObjectID as FolderID, f.Name as FolderName, i.Name as IncidentName, i.Number as IncidentNumber
					FROM Incident i JOIN Folder f ON i.Folder=f.ObjectID 
					WHERE i.ObjectID = @IncidentID"                    );
                cmd.Parameters.Add("IncidentID", DbType.Guid, ParameterDirection.Input, false, request.ObjectID);
                DomainObjectData xobjIncident = dataSet.GetLoadedStub("Incident", request.ObjectID);
                using (IDataReader reader = cmd.ExecuteReader())
                {
                    if (!reader.Read())
                    {
                        throw new XObjectNotFoundException("Incident", request.ObjectID);
                    }
                    xobjFolder = dataSet.GetLoadedStub("Folder", reader.GetGuid(reader.GetOrdinal("FolderID")));
                    xobjFolder.SetLoadedPropValue("Name", reader.GetString(reader.GetOrdinal("FolderName")));
                    xobjIncident.SetLoadedPropValue("Name", reader.GetString(reader.GetOrdinal("IncidentName")));
                    xobjIncident.SetLoadedPropValue("Number", reader.GetInt32(reader.GetOrdinal("IncidentNumber")));
                    xobjIncident.SetLoadedPropValue("Folder", xobjFolder.ObjectID);
                }
            }
            return(xobjFolder);
        }
Пример #6
0
        /// <summary>
        /// Команда получения данных для фильтра списка тендеров
        /// </summary>
        public GetFilterTendersInfoResponse Execute(GetFilterTendersInfoRequest request, IXExecutionContext context)
        {
            GetFilterTendersInfoResponse resp = new GetFilterTendersInfoResponse();

            using (XDbCommand cmd = context.Connection.CreateCommand())
            {
                // Если идентификатор тендера не задан
                if (request.SelectedTenderID == Guid.Empty)
                {
                    cmd.CommandText =
                        @"SELECT TOP 1 ObjectID
						FROM dbo.Organization with (nolock)
						WHERE Home <> 0"                        ;
                    object temp = cmd.ExecuteScalar();
                    resp.OrganizationID = (temp == null) ?
                                          Guid.Empty : (Guid)temp;
                }
                // Если задан
                else
                {
                    cmd.CommandText =
                        @"SELECT TOP 1 O.ObjectID, T.DocFeedingDate
						FROM dbo.Tender AS T with (nolock)
						LEFT JOIN dbo.Lot AS L with (nolock) ON L.Tender = T.ObjectID
						LEFT JOIN dbo.LotParticipant AS P with (nolock) ON P.Lot = L.ObjectID
						LEFT JOIN dbo.Organization AS O with (nolock) ON O.ObjectID = P.ParticipantOrganization
						WHERE O.OwnTenderParticipant <> 0
							AND T.ObjectID = @SelectedTenderID"                            ;
                    // Передадим в параметр ID тендера
                    cmd.Parameters.Add("SelectedTenderID",
                                       DbType.Guid,
                                       ParameterDirection.Input,
                                       false,
                                       request.SelectedTenderID);

                    using (IDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            // Проставим значения ID огранизации и "даты подачи документов"
                            resp.OrganizationID = reader.IsDBNull(0) ?
                                                  Guid.Empty : reader.GetGuid(0);
                            resp.DocFeedingDate = reader.IsDBNull(1) ?
                                                  DateTime.MinValue : reader.GetDateTime(1);
                        }
                        else
                        {
                            resp.OrganizationID = Guid.Empty;
                            resp.DocFeedingDate = DateTime.MinValue;
                        }
                    }
                }
            }

            return(resp);
        }
Пример #7
0
        /// <summary>
        /// Возвращает полный путь до инцидента, заданного идентификатором, либо номером
        /// </summary>
        /// <param name="con"></param>
        /// <param name="IncidentNumber">номер инцидента</param>
        /// <param name="IncidentOID">идентификатор инцидента или Guid.Empty</param>
        /// <returns></returns>
        private XTreePath GetIncidentFullPath(XStorageConnection con, Int32 IncidentNumber, Guid IncidentOID)
        {
            Guid organizationID = Guid.Empty;                           // идентификатор организации, в которой расположен инцидент
            Guid activityTypeID = Guid.Empty;                           // идентификатор вида активности,на которую ссылается папка, в которой разположен инцидент

            // сфомируем путь из каталогов
            string sQuery = String.Format(
                @"SELECT i.ObjectID AS IncidentID, f.ObjectID, f_s.Customer, f_s.ActivityType
				FROM Incident i with (nolock)
					JOIN Folder f_s with (nolock) ON i.Folder = f_s.ObjectID
						JOIN Folder f with (nolock) ON f.LIndex <= f_s.LIndex AND f.RIndex >= f_s.RIndex AND f.Customer = f_s.Customer
				WHERE {0}
				ORDER BY f.LRLevel DESC"                ,
                IncidentOID == Guid.Empty ?
                "i.Number = @Number" :
                "i.ObjectID = @ObjectID"
                );
            XDbCommand cmd = con.CreateCommand(sQuery);

            if (IncidentOID == Guid.Empty)
            {
                cmd.Parameters.Add("Number", DbType.Int32, ParameterDirection.Input, false, IncidentNumber);
            }
            else
            {
                cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, IncidentOID);
            }

            XTreePath path = new XTreePath();                   // путь

            using (IDataReader reader = cmd.ExecuteReader())
            {
                int nObjectIDIndex = -1;                                        // индекс поля ObjectID
                while (reader.Read())
                {
                    if (nObjectIDIndex < 0)
                    {
                        // первая итерация
                        IncidentOID    = reader.GetGuid(reader.GetOrdinal("IncidentID"));
                        organizationID = reader.GetGuid(reader.GetOrdinal("Customer"));
                        activityTypeID = reader.GetGuid(reader.GetOrdinal("ActivityType"));
                        nObjectIDIndex = reader.GetOrdinal("ObjectID");
                    }
                    path.Append(TYPE_Folder, reader.GetGuid(nObjectIDIndex));
                }
            }
            if (path.Length > 0)
            {
                path.Append(GetPathToFolder(con, organizationID, activityTypeID));
                path.InsertAtBeginning(TYPE_Incident, IncidentOID);
            }

            return(path);
        }
Пример #8
0
        private DataTable GetDataTable(string sql)
        {
            if (!IsConnectionValid)
            {
                return(null);
            }

            using (DbCommand cmd = new XDbCommand(sql, m_XDbConnection))
            {
                using (DbDataReader rd = cmd.ExecuteReader())
                {
                    DataTable data = new DataTable();
                    data.Load(rd);
                    return(data);
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Метод получения идентификатора объекта "Сотрудник" по идентификатору объекта "Пользователь приложения"
        /// </summary>
        private Guid getEmployeeID(XStorageConnection con, Guid objectID)
        {
            Guid uidEmployeeID = Guid.Empty;  // идентификатор сотрудника
            // Зачитаем идентификатор
            XDbCommand cmd = con.CreateCommand(@"SELECT e.ObjectID
                    FROM [dbo].[Employee] e
	                JOIN [dbo].[SystemUser] su ON e.SystemUser = su.ObjectID
                    WHERE su.ObjectID = @ObjectID
            ");

            cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, objectID);
            using (IDataReader reader = cmd.ExecuteReader())
            {
                if (reader.Read())
                {
                    uidEmployeeID = reader.GetGuid(0);
                }
            }
            return(uidEmployeeID);
        }
Пример #10
0
 public GetKassBallanceResponse Execute(GetKassBallanceRequest request, IXExecutionContext context)
 {
     using (XDbCommand cmd = context.Connection.CreateCommand())
     {
         cmd.CommandType = CommandType.StoredProcedure;
         cmd.CommandText = "[dbo].[app_GetKassBallance]";
         GetKassBallanceResponse response = new GetKassBallanceResponse();
         using (IDataReader reader = cmd.ExecuteReader())
         {
             if (0 != reader.FieldCount)
             {
                 while (reader.Read())
                 {
                     response.sKassBallance = reader.GetString(0);
                 }
             }
             return(response);
         }
     }
 }
Пример #11
0
        /// <summary>
        /// Возвращает полный путь к проекту: Folder|oid|..|Folder|{oid}|ActivitType|{oid}|Organization|{oid}
        /// </summary>
        /// <param name="con"></param>
        /// <param name="FolderExID">Код проекта</param>
        /// <returns></returns>
        public XTreePath GetFolderFullPath(XStorageConnection con, string FolderExID)
        {
            // сфомируем путь из каталогов
            XDbCommand cmd = con.CreateCommand(@"
				SELECT f.ObjectID, f.Customer, f_s.ActivityType
				FROM Folder f_s with (nolock)
						JOIN Folder f with (nolock) ON f.LIndex <= f_s.LIndex AND f.RIndex >= f_s.RIndex AND f.Customer = f_s.Customer
				WHERE f_s.ExternalID = @FolderExID
				ORDER BY f.LRLevel DESC"
                                               );

            cmd.Parameters.Add("FolderExID", DbType.String, ParameterDirection.Input, false, FolderExID);
            XTreePath path           = new XTreePath(); // путь
            Guid      organizationID = Guid.Empty;      // идентификатор организации, в которой расположен инцидент
            Guid      activityTypeID = Guid.Empty;      // идентификатор вида активности,на которую ссылается папка, в которой разположен инцидент

            using (IDataReader reader = cmd.ExecuteReader())
            {
                int nObjectIDIndex = -1;                        // индекс поля ObjectID
                while (reader.Read())
                {
                    if (nObjectIDIndex < 0)
                    {
                        organizationID = reader.GetGuid(reader.GetOrdinal("Customer"));
                        activityTypeID = reader.GetGuid(reader.GetOrdinal("ActivityType"));
                        nObjectIDIndex = reader.GetOrdinal("ObjectID");
                    }
                    path.Append(TYPE_Folder, reader.GetGuid(nObjectIDIndex));
                }
            }
            // Сформируем путь из организаций и типов проектных затрат
            if (path.Length > 0)
            {
                XTreePath pathToFolder = GetPathToFolder(con, organizationID, activityTypeID);
                path.Append(pathToFolder);
            }
            return(path);
        }
Пример #12
0
        /// <summary>
        /// Конструирует описание пользователя по наименованию.
        /// Если пользователя с таким наименованием не найдено, то возвращает null
        /// </summary>
        /// <param name="sUserName">Наименование пользователя</param>
        /// <returns></returns>
        public XUser CreateUser(string sUserName)
        {
            ITUser user;

            using (XStorageConnection con = getConnection())
            {
                con.Open();
                XDbCommand cmd = con.CreateCommand();
                cmd.CommandText =

                    /* Получим описание пользователя (который может быть сотрудником),
                     * системные привилегии (как выданные явно, так и полученные через роли).
                     * Примечания:	- пользователь приложения может не быть сотрудником.
                     *				- для пользователя приложения могут быть не заданы роли
                     *				- GetWorkdayDuration возвращает количество минут
                     *  */
                    @"SELECT su.ObjectID AS SysUserID, su.IsAdmin, su.IsServiceAccount,
	emp.ObjectID AS EmpID, emp.LastName, emp.FirstName, emp.EMail, 
	su.SystemPrivileges, 
	sr.Name as RoleName, 
	sr.Description as RoleDescription, 
	sr.Priviliges as RolePrivileges,
	dbo.GetWorkdayGlobalDuration() as WorkingMinutesInDay,
	CASE WHEN emp.WorkEndDate < getDate() THEN 0 ELSE 1 END as AccessPermitted
FROM SystemUser su WITH (nolock)
	LEFT JOIN Employee emp WITH (nolock) ON emp.SystemUser = su.ObjectID
	LEFT JOIN (SystemUser_SystemRoles su_sr WITH (nolock)
		JOIN SystemRole sr WITH (nolock) ON su_sr.Value = sr.ObjectID
	) ON su.ObjectID = su_sr.ObjectID
WHERE su.Login = @UserLogin";
                cmd.Parameters.Add("UserLogin", DbType.String, ParameterDirection.Input, false, sUserName);
                using (IDataReader reader = cmd.ExecuteReader())
                {
                    XRole[] roles;                                      // массив системных ролей
                    Guid    SystemUserID;                               // идентификатор пользователя
                    Guid    EmployeeID = Guid.Empty;                    // идентификатор сотрудника
                    string  sLastName  = null;                          // фамилия сотрудника
                    string  sFirstName = null;                          // имя сотрудника
                    string  sEMail     = null;                          // email сотрудника
                    bool    bIsAdmin;                                   // признак админа (необграниченного пользователя)
                    bool    bIsServiceAccount;                          // признак сервисного аккаунта
                    int     nIndex;                                     // временная - индекс колонки
                    int     nPrivileges;                                // числовая маска привилегий (в БД привилегии лежат как флаги)
                    int     nWorkingMinutesInDay;                       // количество рабочих часов в сутках
                    bool    bAccesssPermitted = true;

                    if (reader.Read())
                    {
                        // получим маску привилегий, выданных пользователю явно
                        nPrivileges          = reader.GetInt32(reader.GetOrdinal("SystemPrivileges"));                          // поле SystemPrivileges - not null
                        SystemUserID         = reader.GetGuid(reader.GetOrdinal("SysUserID"));
                        bIsAdmin             = reader.GetBoolean(reader.GetOrdinal("IsAdmin"));
                        bIsServiceAccount    = reader.GetBoolean(reader.GetOrdinal("IsServiceAccount"));
                        nWorkingMinutesInDay = reader.GetInt32(reader.GetOrdinal("WorkingMinutesInDay"));
                        nIndex = reader.GetOrdinal("EmpID");
                        if (!reader.IsDBNull(nIndex))
                        {
                            // если пользователь является сотрудником
                            EmployeeID        = reader.GetGuid(nIndex);
                            sLastName         = reader.GetString(reader.GetOrdinal("LastName"));
                            sFirstName        = reader.GetString(reader.GetOrdinal("FirstName"));
                            bAccesssPermitted = reader.GetInt32(reader.GetOrdinal("AccessPermitted")) == 1;
                            nIndex            = reader.GetOrdinal("EMail");
                            if (!reader.IsDBNull(nIndex))
                            {
                                sEMail = reader.GetString(nIndex);
                            }
                        }
                    }
                    else
                    {
                        // не нашли пользователя
                        return(CreateAnonymousUser());
                    }

                    // зачитаем все роли текущего юзера
                    ArrayList aRoles                 = new ArrayList();                 // список объектов XRole - роли пользователя
                    int       nIndex_RoleName        = reader.GetOrdinal("RoleName");
                    int       nIndex_RoleDescription = reader.GetOrdinal("RoleDescription");
                    int       nIndex_RolePrivileges  = reader.GetOrdinal("RolePrivileges");
                    if (!reader.IsDBNull(nIndex_RoleName))
                    {
                        // по всем ролям пользователя
                        do
                        {
                            string sDescription = String.Empty;
                            if (!reader.IsDBNull(nIndex_RoleDescription))
                            {
                                sDescription = reader.GetString(nIndex_RoleDescription);
                            }
                            // объединим маску привилегий с привилегиями текущей роли
                            nPrivileges = nPrivileges | reader.GetInt32(nIndex_RolePrivileges);
                            aRoles.Add(new XRole(reader.GetString(nIndex_RoleName), sDescription));
                        } while(reader.Read());
                    }
                    roles = new XRole[aRoles.Count];
                    aRoles.CopyTo(roles);
                    // превратим маску привилегий в массив объектов
                    XPrivilegeSet privilege_set = PrivilegesHelper.CreatePrivilegeSet((SystemPrivileges)nPrivileges);

                    // создадим описание пользователя и дополним атрибуты, специфичные для нашего приложения
                    user = new ITUser(sUserName, roles, privilege_set);
                    user.SystemUserID     = SystemUserID;
                    user.IsUnrestricted   = bIsAdmin;
                    user.IsServiceAccount = bIsServiceAccount;
                    user.AccessPermitted  = bAccesssPermitted;
                    if (EmployeeID != Guid.Empty)
                    {
                        // если пользователь - сотрудник
                        user.EmployeeID      = EmployeeID;
                        user.LastName        = sLastName;
                        user.FirstName       = sFirstName;
                        user.EMail           = sEMail;
                        user.WorkdayDuration = nWorkingMinutesInDay;
                    }
                }
                readUserActivityTypes(user, con);
                readUserManagedOrganizations(user, con);
            }
            return(user);
        }
        /// <summary>
        /// Метод вызова команды ядром
        /// </summary>
        public TreeLocatorResponse Execute(EmployeeLocatorInCompanyTreeRequest request, IXExecutionContext context)
        {
            string             sTreePath = "";          // путь в дереве до найденного объекта
            Guid               foundOID  = Guid.Empty;  // идентификатор найденного объекта
            bool               bMore     = false;       // признак того, что есть еще объекты удовлетворяющие заданному условию
            XStorageConnection con       = context.Connection;

            string sQuery =
                @"SELECT emp.ObjectID, d.ObjectID as DepID, d.LIndex, d.RIndex, emp.Organization
FROM Employee emp 
	LEFT JOIN Department d ON emp.Department = d.ObjectID
WHERE emp.LastName LIKE " + con.GetParameterName("LastName");

            // если задан список игнорируемых объектов, добавим ограничение
            if (request.IgnoredObjects != null && request.IgnoredObjects.Length > 0)
            {
                StringBuilder bld = new StringBuilder();
                bld.Append("\n\tAND NOT emp.ObjectID IN (");
                foreach (Guid oid in request.IgnoredObjects)
                {
                    bld.Append(con.ArrangeSqlGuid(oid));
                    bld.Append(", ");
                }
                bld.Length -= 2;
                bld.Append(")");
                sQuery = sQuery + bld.ToString();
            }
            // по умолчанию выводим (и, следовательно, ищем среди) неархивных сотрудников и сотрудников без временной нетрудоспособности.
            if (!request.AllowArchive)
            {
                sQuery = sQuery + " AND (emp.WorkEndDate IS NULL) AND (emp.TemporaryDisability  = 0)";
            }

            sQuery = sQuery + "\nORDER BY emp.Organization, emp.Department, emp.FirstName";

            XDbCommand cmd = con.CreateCommand(sQuery);

            cmd.Parameters.Add("LastName", DbType.String, ParameterDirection.Input, false, request.LastName + "%");
            using (IDataReader reader = cmd.ExecuteReader())
            {
                if (reader.Read())
                {
                    foundOID = reader.GetGuid(reader.GetOrdinal("ObjectID"));
                    Guid OrgOID = reader.GetGuid(reader.GetOrdinal("Organization"));
                    Guid DepID;
                    int  nLIndex = -1;
                    int  nRIndex = -1;
                    sTreePath = "Employee|" + foundOID.ToString();

                    if (!reader.IsDBNull(reader.GetOrdinal("DepID")))
                    {
                        // если сотрудник входит в подразделение, то сформируем путь по всем подразделениям к корневому
                        int nLIndexOrdinal = reader.GetOrdinal("LIndex");
                        int nRIndexOrdinal = reader.GetOrdinal("RIndex");
                        if (!reader.IsDBNull(nLIndexOrdinal) && !reader.IsDBNull(nRIndexOrdinal))
                        {
                            nLIndex = reader.GetInt32(nLIndexOrdinal);
                            nRIndex = reader.GetInt32(nRIndexOrdinal);
                        }
                        DepID = reader.GetGuid(reader.GetOrdinal("DepID"));
                        bMore = reader.Read();
                        reader.Close();
                        if (nLIndex > -1 && nRIndex > -1)
                        {
                            sQuery =
                                @"SELECT ObjectID FROM Department 
WHERE LIndex < @LIndex AND RIndex > @RIndex AND Organization = @OrgID
ORDER BY [LRLevel] DESC";
                            cmd = context.Connection.CreateCommand(sQuery);
                            cmd.Parameters.Add("LIndex", DbType.Int32, ParameterDirection.Input, false, nLIndex);
                            cmd.Parameters.Add("RIndex", DbType.Int32, ParameterDirection.Input, false, nRIndex);
                            cmd.Parameters.Add("OrgID", DbType.Guid, ParameterDirection.Input, false, OrgOID);
                            sTreePath = sTreePath + "|Department|" + DepID.ToString();
                            using (IDataReader reader2 = cmd.ExecuteReader())
                            {
                                while (reader2.Read())
                                {
                                    sTreePath = sTreePath + "|Department|" + reader2.GetGuid(0);
                                }
                            }
                        }
                    }
                    else
                    {
                        bMore = reader.Read();
                    }
                    // на корневом уровне организации
                    sTreePath = sTreePath + "|Organization|" + OrgOID.ToString();
                }
            }
            return(new TreeLocatorResponse(sTreePath, foundOID, bMore));
        }
Пример #14
0
        /// <summary>
        /// Метод запуска операции на выполнение, <входная> точка операции
        /// ПЕРЕГРУЖЕННЫЙ, СТРОГО ТИПИЗИРОВАННЫЙ МЕТОД
        /// ВЫЗЫВАЕТСЯ ЯДРОМ АВТОМАТИЧЕСКИ
        /// </summary>
        /// <param name="request">Запрос на выполнение операции</param>
        /// <param name="context">Контекст выполнения операции</param>
        /// <returns>Результат выполнения</returns>
        public GetEmployeesExpensesResponse Execute(GetEmployeesExpensesRequest request, IXExecutionContext context)
        {
            // Проверка / коррекция параметров
            if (null == request.ExceptDepartmentIDsList)
            {
                request.ExceptDepartmentIDsList = String.Empty;
            }

            // Результат операции - массив экземпляров EmployeeExpenseInfo; все
            // экземплряры, полученные в результате расчетов (таких итераций может
            // быть несколько - см. далее), будут накапливаться в общем "массиве":
            ArrayList arrResults = new ArrayList();

            // Собственно расчет данных выполняется на уровне БД; создаем команду:
            using (XDbCommand cmd = context.Connection.CreateCommand())
            {
                // ... команда - вызов хранимой процедцуры. Процедура принимает
                // список идентификаторов в том же виде - как строку; но ее длина,
                // в случае SQL, ограничена макс. размерностью. Вероятность передачи
                // строки с перечнем идентификаторов, общая длина которой превышает
                // размероность параметра, велика (скажем, для 1000 сотрудников со
                // средней длиной логина в 10 символов длина строки списка - уже
                // 10000, при том что макс. длина значения параметра - 4000).
                //
                // Поэтому весь список разбивается на части, по длине соотв. макс.
                // длине значения параметра. Процедура, т.о., выполняется итеративно,
                // пока не будет обработан весь список идентификаторов.

                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "[dbo].[app_GetEmployeesExpenses]";

                // Все остальные параметры при повторных вызовах не изменяются;
                // поэтому задаются только один раз:
                cmd.Parameters.Add("nIdentificationMethod", DbType.Int32, ParameterDirection.Input, false, (int)request.IdentificationMethod);
                cmd.Parameters.Add("sExceptedDepIDs", DbType.String, ParameterDirection.Input, false, request.ExceptDepartmentIDsList);
                cmd.Parameters.Add("dtPeriodBeginDate", DbType.Date, ParameterDirection.Input, false, request.PeriodBegin);
                cmd.Parameters.Add("dtPeriodEndDate", DbType.Date, ParameterDirection.Input, false, request.PeriodEnd);
                // ... пустая строка - недопустимый параметр; здесь задается для
                // того, чтоб сразу добавить параетр в коллекцию:
                cmd.Parameters.Add("sEmployeesIDs", DbType.String, ParameterDirection.Input, false, String.Empty);

                // Далее - итерации по "частям" списка; до тех пор, пока не будет обработан весь список:
                string sSrcEmpIDsList = request.EmployeesIDsList;
                for (int nCurrPos = 0; nCurrPos < sSrcEmpIDsList.Length;)
                {
                    // Выделение "части" списка:
                    string sCurrIDsListPart;
                    if (sSrcEmpIDsList.Length - nCurrPos < DEF_EmployeesIDsList_MaxLength)
                    {
                        sCurrIDsListPart = (0 == nCurrPos ? sSrcEmpIDsList : sSrcEmpIDsList.Substring(nCurrPos));
                        nCurrPos        += sCurrIDsListPart.Length;
                    }
                    else
                    {
                        int nNextPartPos = sSrcEmpIDsList.LastIndexOf(",", nCurrPos + DEF_EmployeesIDsList_MaxLength, DEF_EmployeesIDsList_MaxLength - 1);
                        if (-1 == nNextPartPos)
                        {
                            throw new ArgumentException(
                                      String.Format(
                                          "Список идентификаторов включает идентификатор, длина которого недопустима (более {0})",
                                          DEF_EmployeesIDsList_MaxLength),
                                      "[request].EmployeesIDsList");
                        }

                        sCurrIDsListPart = sSrcEmpIDsList.Substring(nCurrPos, nNextPartPos - nCurrPos);
                        nCurrPos         = nNextPartPos + 1;
                    }
                    // Выделенная "часть" задается как значение параметра:
                    cmd.Parameters["sEmployeesIDs"].Value = sCurrIDsListPart;

                    using (IDataReader reader = cmd.ExecuteReader())
                    {
                        if (0 != reader.FieldCount)
                        {
                            if (reader.FieldCount < 4)
                            {
                                throw new ApplicationException("Некорректные данные расчета (SQL): недостататочное количество колонок в результирующем наборе (" + reader.FieldCount + ")");
                            }

                            // Результат выполнения процедуры - рекордсет, каждая строка
                            // которого содержит идентификатор сотрудника, требуемое время для
                            // списания и реальное списанное время:
                            int nOrd_EmployeeID   = reader.GetOrdinal("EmployeeID");
                            int nOrd_RateExpenses = reader.GetOrdinal("RateExpenses");
                            int nOrd_RealExpenses = reader.GetOrdinal("RealExpenses");

                            while (reader.Read())
                            {
                                EmployeeExpenseInfo info = new EmployeeExpenseInfo();
                                info.EmployeeID  = reader.GetString(nOrd_EmployeeID);
                                info.RateExpense = reader.GetInt32(nOrd_RateExpenses);
                                info.RealExpense = reader.GetInt32(nOrd_RealExpenses);
                                arrResults.Add(info);
                            }
                        }
                    }
                }
            }

            // Итоговый результат операции:
            GetEmployeesExpensesResponse response = new GetEmployeesExpensesResponse();

            response.PeriodBegin = request.PeriodBegin;
            response.PeriodEnd   = request.PeriodEnd;
            response.Expenses    = new EmployeeExpenseInfo[arrResults.Count];
            if (arrResults.Count > 0)
            {
                arrResults.CopyTo(0, response.Expenses, 0, arrResults.Count);
            }

            return(response);
        }
Пример #15
0
        public XResponse Execute(SaveObjectInternalRequest request, IXExecutionContext context)
        {
            ITUser    user     = (ITUser)XSecurityManager.Instance.GetCurrentUser();
            ArrayList aObjects = request.DataSet.GetModifiedObjectsByType("TimeLoss", true);

            foreach (DomainObjectData xobj in aObjects)
            {
                if (!xobj.HasUpdatedProp("Worker") && xobj.IsNew)
                {
                    xobj.SetUpdatedPropValue("Worker", user.EmployeeID);
                }

                // получим папку, проверим у папки отсутствие флага IsLocked
                object           vValue     = xobj.GetPropValue("Folder", DomainObjectDataSetWalkingStrategies.UseUpdatedPropsThanLoadedProps);
                DomainObjectData xobjFolder = null;
                if (vValue is Guid)
                {
                    xobjFolder = xobj.Context.Get(context.Connection, xobj, "Folder", DomainObjectDataSetWalkingStrategies.UseUpdatedPropsThanLoadedProps, true);
                    // проверим состояние папки. если она закрыта или в ожидании закрытия, то запретим списание

                    if ((FolderStates)xobjFolder.GetLoadedPropValue("State") == FolderStates.Closed ||
                        (FolderStates)xobjFolder.GetLoadedPropValue("State") == FolderStates.WaitingToClose ||
                        (FolderStates)xobjFolder.GetLoadedPropValue("State") == FolderStates.Frozen)
                    {
                        throw new XSecurityException("Списания в папку в состоянии \"Закрыто\" или \"Ожидание закрытия\" запрещены. По вопросам списаний обращайтесь к менеджеру.");
                    }
                    // проверим наличие у папки специального аттрибута, запрещающего списание
                    if ((bool)xobjFolder.GetPropValue("IsLocked", DomainObjectDataSetWalkingStrategies.UseUpdatedPropsThanLoadedProps))
                    {
                        throw new XSecurityException("<b>Списания в данную папку запрещены.</b><br/>По вопросам списаний обращайтесь к менеджеру.");
                    }
                    FolderPrivilegeManager manager = (XSecurityManager.Instance.SecurityProvider as SecurityProvider).FolderPrivilegeManager;
                    // у пользователя должны быть права на списание в данной папке
                    if (!manager.HasFolderPrivilege(user, FolderPrivileges.SpentTimeByProject, xobjFolder, context.Connection))
                    {
                        throw new XSecurityException("<b>Пользователь должен обладать в проекте привилегией \"Списание времение на проект\".</b><br/>По вопросам списаний обращайтесь к менеджеру.");
                    }

                    // если у пользователя нет привилегии «Разрешение списания на папку с неоднозначным определением направления»
                    // проверим - является ли данная папка папкой с неоднозначным определением направления
                    if (!manager.HasFolderPrivilege(user, FolderPrivileges.TimeLossOnUnspecifiedDirection, xobjFolder, context.Connection))
                    {
                        using (XDbCommand c = context.Connection.CreateCommand())
                        {
                            c.CommandType = CommandType.Text;
                            c.CommandText = @"
IF	(
		SELECT t.AccountRelated 
		FROM dbo.ActivityType t WITH(NOLOCK) JOIN dbo.Folder fT WITH(NOLOCK) ON fT.ActivityType = t.ObjectID 
		WHERE fT.ObjectID = @FolderID
	) = 0
	SELECT 1
ELSE
	SELECT TOP 1 t.DirsQnt
	FROM (
		SELECT
			fU.ObjectID, fU.LRLevel,
			( SELECT COUNT(*) FROM dbo.FolderDirection fd WITH(NOLOCK) WHERE fd.Folder = fU.ObjectID ) AS DirsQnt
		FROM
			dbo.Folder fT WITH(NOLOCK)
			JOIN dbo.Folder fU WITH(NOLOCK) ON fU.Customer = fT.Customer AND fU.LIndex <= fT.LIndex AND fU.RIndex >= fT.RIndex
		WHERE
			fT.ObjectID = @FolderID
	) t
	WHERE DirsQnt > 0		
	ORDER BY LRLevel DESC 
";
                            c.Parameters.Add("FolderID", DbType.Guid, ParameterDirection.Input, false, vValue);

                            object oResult = c.ExecuteScalar();
                            string sReport = null;

                            if (null == oResult || DBNull.Value == oResult)
                            {
                                sReport = "для которой не определено ни одного направления";
                            }
                            else if (1 != (int)oResult)
                            {
                                sReport = "для которой определено более одного направления";
                            }

                            if (null != sReport)
                            {
                                throw new XSecurityException(
                                          "<b>Списания в данную папку запрещены.</b><br/>" +
                                          "У Вас нет прав списывать в папку, " + sReport + ". " +
                                          "По вопросам списаний <b>обращайтесь к менеджеру</b>.");
                            }
                        }
                    }
                }


                // если в объекте заданы "виртуальные" свойства
                if (xobj.HasUpdatedProp("LossFixedStart") && xobj.GetUpdatedPropValue("LossFixedStart") is DateTime &&
                    xobj.HasUpdatedProp("LossFixedEnd") && xobj.GetUpdatedPropValue("LossFixedEnd") is DateTime)
                {
                    if (!xobj.IsNew)
                    {
                        throw new ApplicationException("Задание диапазона допустимо только при создании объекта \"Списание времени\"");
                    }
                    // получим даты начала и окончания периода
                    DateTime dtPeriodStart = (DateTime)xobj.GetUpdatedPropValue("LossFixedStart");
                    DateTime dtPeriodEnd   = (DateTime)xobj.GetUpdatedPropValue("LossFixedEnd");
                    if (dtPeriodStart > dtPeriodEnd)
                    {
                        DateTime dtTemp = dtPeriodEnd;
                        dtPeriodEnd   = dtPeriodStart;
                        dtPeriodStart = dtTemp;
                    }

                    Guid employeeID = (Guid)xobj.GetUpdatedPropValue("Worker");
                    // проверим, что в данном периоде отсутствуют списания
                    XDbCommand cmd = context.Connection.CreateCommand("");
                    cmd.CommandText = @"SELECT DISTINCT CONVERT(varchar, x.SpentDate, 104) FROM (
						SELECT ts.RegDate AS SpentDate
						FROM TimeSpent ts
							JOIN Task t ON ts.Task = t.ObjectID
						WHERE t.Worker = @EmployeeID 
							AND ts.RegDate >= @dtPeriodStart AND ts.RegDate < @dtPeriodEnd
						UNION
						SELECT ts.LossFixed AS SpentDate
						FROM TimeLoss ts WHERE ts.Worker = @EmployeeID
							AND ts.LossFixed >= @dtPeriodStart AND ts.LossFixed < @dtPeriodEnd
						) x"                        ;
                    cmd.Parameters.Add("EmployeeID", DbType.Guid, ParameterDirection.Input, false, employeeID);
                    cmd.Parameters.Add("dtPeriodStart", DbType.Date, ParameterDirection.Input, false, dtPeriodStart);
                    // AddDays(1) - т.к. в условии запроса знак "меньше"
                    cmd.Parameters.Add("dtPeriodEnd", DbType.Date, ParameterDirection.Input, false, dtPeriodEnd.AddDays(1));
                    using (IDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            StringBuilder bld = new StringBuilder();
                            do
                            {
                                if (bld.Length > 0)
                                {
                                    bld.Append(", ");
                                }
                                bld.Append(reader.GetString(0));
                            } while(reader.Read());
                            throw new XBusinessLogicException(
                                      String.Format("У вас уже имеются списания на следующие даты в заданном периоде ({0},{1}): {2}",
                                                    dtPeriodStart.ToShortDateString(),
                                                    dtPeriodEnd.ToShortDateString(),
                                                    bld.ToString())
                                      );
                        }
                    }
                    // Получаем "набор пар" дата - норма сотрудника на дату
                    Dictionary <DateTime, int> dictDateRates = new Dictionary <DateTime, int>();
                    dictDateRates = GetDayRates(context.Connection, dtPeriodStart, dtPeriodEnd, employeeID);
                    // пойдем по всем дням периода (dtPeriodEnd, dtPeriodStart)
                    // и для каждой даты создадим новый объект Списание времени с количеством времени равном рабочему дню
                    // При этом, будем игнорировать даты, попадающие на выходные/праздники
                    TimeSpan period = (dtPeriodEnd - dtPeriodStart);
                    for (int nOffSet = 0; nOffSet <= period.TotalDays; ++nOffSet)
                    {
                        int      nRate  = 0;
                        DateTime dtDate = dtPeriodStart.AddDays(nOffSet);
                        // Если удалось получить норму сотрудника на соотв. дату, то создадим объект
                        if (dictDateRates.TryGetValue(dtDate, out nRate))
                        {
                            // Если полученная норма больше 0, тогда создадим списание
                            if (nRate > 0)
                            {
                                DomainObjectData xobjNew = createTimeLossObject(request.DataSet, xobj, user);
                                xobjNew.SetUpdatedPropValue("LossFixed", dtDate);
                                // списание длиной в количество минут в рабочем дне
                                xobjNew.SetUpdatedPropValue("LostTime", nRate);
                            }
                        }
                    }
                    // исходный объект надо удалить
                    request.DataSet.Remove(xobj);
                }
            }

            XSecurityManager sec_man    = XSecurityManager.Instance;
            IEnumerator      enumerator = request.DataSet.GetModifiedObjectsEnumerator(false);
            DomainObjectData xobject;

            while (enumerator.MoveNext())
            {
                xobject = (DomainObjectData)enumerator.Current;
                if (xobject.ToDelete)
                {
                    sec_man.DemandDeleteObjectPrivilege(xobject);
                }
                else
                {
                    sec_man.DemandSaveObjectPrivilege(xobject);
                }
            }
            // #1: Запись данных
            XStorageGateway.Save(context, request.DataSet, request.TransactionID);
            // Специального результата операция не возвращает
            return(new XResponse());
        }