private void buildThisReport(XslFOProfileWriter w, ReportParams Params, IReportDataProvider Provider) { DateTime dtActualBegin; DateTime dtActualEnd; DateTime dtBegin; DateTime dtEnd; string OrganizationName; ArrayList arrDates = new ArrayList(); object IntervalBegin = Params.GetParam("IntervalBegin").Value; object IntervalEnd = Params.GetParam("IntervalEnd").Value; object Folder = Params.GetParam("Folder").Value; object Customer = Params.GetParam("Customer").Value; int ActivityAnalysDepth = (int)Params.GetParam("ActivityAnalysDepth").Value; int InsertRestrictions = (int)Params.GetParam("InsertRestrictions").Value; int FolderType = (int)Params.GetParam("FolderType").Value; int SectionByActivity = (int)Params.GetParam("SectionByActivity").Value; int DateDetalization = (int)Params.GetParam("DateDetalization").Value; int TimeMeasureUnits = (int)Params.GetParam("TimeMeasureUnits").Value; int ExpencesType = (int)Params.GetParam("ExpensesType").Value; int IncludeSubProjects = (int)Params.GetParam("IncludeSubProjects").Value; int SortType = (int)Params.GetParam("SortType").Value; int SortOrder = (int)Params.GetParam("SortOrder").Value; int ShowColumnWorkTimeNorm = (int)Params.GetParam("ShowColumnWorkTimeNorm").Value; /*int ShowColumnOverheads = (int)Params.GetParam("ShowColumnOverheads").Value; * int ShowColumnSalaryExpenses = (int)Params.GetParam("ShowColumnSalaryExpenses").Value;*/ CustomDataForDS oCustomData = new CustomDataForDS(); oCustomData.sTempTableName = "##UsersExpences_" + Guid.NewGuid().ToString("n"); // Первый запрос возвращает 2 рекордсета // 1 - Папка, Организация, Начало, Конец // 2 - Даты для которых строится отчёт using (IDataReader rdr = Provider.GetDataReader("dsUserExpencesPrimary", oCustomData)) { rdr.Read(); // По любому одна строка :) OrganizationName = rdr.GetString(1); dtActualBegin = rdr.IsDBNull(2)?DateTime.MinValue:rdr.GetDateTime(2); dtActualEnd = rdr.IsDBNull(3)?DateTime.MaxValue:rdr.GetDateTime(3); oCustomData.dtActualBegin = dtActualBegin; oCustomData.dtActualEnd = dtActualEnd; dtBegin = IntervalBegin == null?dtActualBegin:(DateTime)IntervalBegin; dtEnd = IntervalEnd == null?dtActualEnd:(DateTime)IntervalEnd; StringBuilder sb = new StringBuilder("<fo:block>Динамика затрат сотрудников</fo:block>"); // Создадим заголовок if (0 != InsertRestrictions) { sb.Append("<fo:block/>"); sb.Append("<fo:block font-size='14px'>Параметры отчета:</fo:block>"); sb.Append("<fo:table color='#FFFFFF' text-align='left' font-size='12px' font-family='MS Sans-serif'>"); sb.Append("<fo:table-column/>"); sb.Append("<fo:table-column/>"); sb.Append("<fo:table-body>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Период времени:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + xmlEncode(rdr.GetString(4)) + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Клиент:</fo:block></fo:table-cell>"); if (null == Customer) { sb.Append("<fo:table-cell><fo:block>" + xmlEncode(OrganizationName) + "</fo:block></fo:table-cell>"); } else { // ShowContextForOrganization(sID, sExtID, sDirectorEMail) sb.Append("<fo:table-cell><fo:block><fo:basic-link color=\"#ffffff\" external-destination=\"vbscript:ShowContextForOrganization("" + Customer + "","" + rdr.GetString(6) + "","" + rdr.GetString(7) + "")\">" + xmlEncode(OrganizationName) + "</fo:basic-link></fo:block></fo:table-cell>"); } sb.Append("</fo:table-row>"); if (!rdr.IsDBNull(5)) { sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Активность:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block><fo:basic-link color=\"#ffffff\" external-destination=\"vbscript:ShowContextForFolderEx("" + rdr.GetGuid(5) + "",true, " + ((dtBegin == DateTime.MinValue)?"NULL":dtBegin.ToString("#MM'/'dd'/'yyyy#")) + ", " + ((dtEnd == DateTime.MaxValue)?"NULL":dtEnd.ToString("#MM'/'dd'/'yyyy#")) + ")\">" + xmlEncode(rdr.GetString(0)) + "</fo:basic-link></fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); } sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Тип активности:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + xmlEncode(FolderTypeEnumItem.ToStringOfDescriptions((FolderTypeEnum)FolderType)) + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Глубина анализа активностей:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + xmlEncode(ActivityAnalysDepthItem.GetItem((ActivityAnalysDepth)ActivityAnalysDepth).Description) + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Секционирование по активностям:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + xmlEncode(SectionByActivityItem.GetItem((SectionByActivity)SectionByActivity).Description) + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Детализация по датам:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + xmlEncode(DateDetalizationItem.GetItem((DateDetalization)DateDetalization).Description) + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Виды трудозатрат:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + xmlEncode(ExpencesTypeItem.GetItem((ExpencesType)ExpencesType).Description) + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Включать в проект затраты подпроектов:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + ((IncludeSubProjects == 0)?"нет":"да") + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Сортировка:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + xmlEncode(SortExpencesItem.GetItem((SortExpences)SortType).Description) + ", " + xmlEncode(SortOrderItem.GetItem((SortOrder)SortOrder).Description) + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("<fo:table-row>"); sb.Append("<fo:table-cell width='35%'><fo:block>Единицы измерения времени:</fo:block></fo:table-cell>"); sb.Append("<fo:table-cell><fo:block>" + xmlEncode(TimeMeasureUnitsItem.GetItem((TimeMeasureUnits)TimeMeasureUnits).Description) + "</fo:block></fo:table-cell>"); sb.Append("</fo:table-row>"); sb.Append("</fo:table-body>"); sb.Append("</fo:table>"); } if (rdr.NextResult()) { while (rdr.Read()) { arrDates.Add(rdr.GetDateTime(0)); } } oCustomData.arrDates = arrDates; w.WriteLayoutMaster(); w.StartPageSequence(); w.StartPageBody(); w.Header(sb.ToString()); } if (dtActualBegin == DateTime.MinValue) { // Пустой отчёт, данные не нужны, табличка дропнута w.EmptyBody("Нет данных"); } else { // Теперь сформируем вторичный запрос на получение данных using (IDataReader rdr2 = Provider.GetDataReader("dsUserExpencesSecondary", oCustomData)) { int nActivityColSpan = 2; int nTotalColspan = 1; int nFieldCount = rdr2.FieldCount; const int nFirstDateColumn = 9; // Выведем тело отчёта w.TStart(true, "CELL_CLASS", false); /* * if(HideGroupColumns) * { ++nActivityColSpan; * w.TAddColumn("Активность", align.ALIGN_LEFT, valign.VALIGN_MIDDLE, "TABLE_HEADER"); * } */ w.TAddColumn("Сотрудник", align.ALIGN_LEFT, valign.VALIGN_MIDDLE, "TABLE_HEADER"); if (0 != ShowColumnWorkTimeNorm) { w.TAddColumn("Норма рабочего времени", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, "TABLE_HEADER"); ++nActivityColSpan; ++nTotalColspan; } w.TAddColumn("Сумма затрат (час)", align.ALIGN_CENTER, valign.VALIGN_MIDDLE, "TABLE_HEADER"); //w.TAddColumn("Сумма затрат", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, "TABLE_HEADER"); /*if(0!=ShowColumnOverheads) * { * w.TAddColumn("Накладные расходы", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, "TABLE_HEADER"); ++nActivityColSpan; * } * if(0!=ShowColumnSalaryExpenses) * { * w.TAddColumn("Затраты на з/п", align.ALIGN_RIGHT, valign.VALIGN_MIDDLE, "TABLE_HEADER"); ++nActivityColSpan; * } */ for (int i = nFirstDateColumn; i < nFieldCount; ++i) { w.TAddColumn(rdr2.GetName(i), align.ALIGN_CENTER, valign.VALIGN_MIDDLE, "TABLE_HEADER"); ++nActivityColSpan; } Guid prevFolderID = Guid.Empty; int[] arrLocalTotals = new int[nFieldCount]; int[] arrGlobalTotals = new int[nFieldCount]; int nLocalTotalTime = 0; int nGlobalTotalTime = 0; int nTimeFormatValue = (TimeMeasureUnits == (int)IncidentTracker.TimeMeasureUnits.Hours)?int.MaxValue:/*rdr.GetInt32(5)*/ 600; while (rdr2.Read()) { if (SectionByActivity != (int)Croc.IncidentTracker.SectionByActivity.NoSection) { Guid thisFolderID = rdr2.GetGuid(0); if (thisFolderID != prevFolderID) { if (prevFolderID != Guid.Empty) { // Итого ;) w.TRStart("SUBTOTAL"); w.TRAddCell("Итого по активности:", null, nTotalColspan, 1); w.TRAddCell(xmlEncode(_FormatTimeStringAtServer(nLocalTotalTime, nTimeFormatValue)), null); //w.TRAddCell(rLocalTotalCost, fixed_14_4); /*if(0!=ShowColumnOverheads) * w.TRAddCell( rLocalTotalOverheads, fixed_14_4); * if(0!=ShowColumnSalaryExpenses) * w.TRAddCell( rLocalTotalSalaryExpenses, fixed_14_4);*/ for (int i = nFirstDateColumn; i < nFieldCount; ++i) { w.TRAddCell(xmlEncode(_FormatTimeStringAtServer(arrLocalTotals[i], nTimeFormatValue)), null); } w.TREnd(); // Почистим локальный "ИТОГО" nLocalTotalTime = 0; System.Array.Clear(arrLocalTotals, 0, arrLocalTotals.Length); } prevFolderID = thisFolderID; // Сформируем подзаголовок w.TRStart("SUBTITLE"); w.TRAddCell(this._GetFolderAnchor(rdr2.GetString(1), thisFolderID, Guid.Empty, true, dtBegin, dtEnd), null, nActivityColSpan, 1); w.TREnd(); } } bool bIncludeInGlobals = rdr2.GetInt32(7) == 0; w.TRStart("CELL_CLASS"); w.TRAddCell(_GetUserMailAnchor(rdr2.GetString(3), rdr2.GetString(4), rdr2.GetGuid(2), Guid.Empty, rdr2.IsDBNull(0)?(Folder == null?Guid.Empty:((Guid)Folder)):rdr2.GetGuid(0)), null); if (0 != ShowColumnWorkTimeNorm) { w.TRAddCell(xmlEncode(this._FormatTimeStringAtServer(rdr2.GetInt32(8), nTimeFormatValue)), null); } int nTempInt32 = rdr2.GetInt32(6); w.TRAddCell(xmlEncode(_FormatTimeStringAtServer(nTempInt32, nTimeFormatValue)), null); if (bIncludeInGlobals) { nGlobalTotalTime += nTempInt32; } nLocalTotalTime += nTempInt32; /*decimal rTempDecimal = rdr2.GetDecimal(11); * w.TRAddCell( rTempDecimal, fixed_14_4); * if(bIncludeInGlobals) rGlobalTotalCost += rTempDecimal; * rLocalTotalCost += rTempDecimal;*/ /*if(0!=ShowColumnOverheads) * { * rTempDecimal = rdr2.GetDecimal(7); * w.TRAddCell( rTempDecimal, fixed_14_4); * if(bIncludeInGlobals) rGlobalTotalOverheads += rTempDecimal; * rLocalTotalOverheads += rTempDecimal; * } * if(0!=ShowColumnSalaryExpenses) * { * rTempDecimal = rdr2.GetDecimal(8); * w.TRAddCell( rTempDecimal, fixed_14_4); * if(bIncludeInGlobals) rGlobalTotalSalaryExpenses += rTempDecimal; * rLocalTotalSalaryExpenses += rTempDecimal; * }*/ for (int i = nFirstDateColumn; i < nFieldCount; ++i) { nTempInt32 = rdr2.GetInt32(i); w.TRAddCell(xmlEncode(_FormatTimeStringAtServer(nTempInt32, nTimeFormatValue)), null); if (bIncludeInGlobals) { arrGlobalTotals[i] = arrGlobalTotals[i] + nTempInt32; } arrLocalTotals[i] = arrLocalTotals[i] + nTempInt32; } w.TREnd(); } if (SectionByActivity != (int)Croc.IncidentTracker.SectionByActivity.NoSection) { if (prevFolderID != Guid.Empty) { // Итого ;) w.TRStart("SUBTOTAL"); w.TRAddCell("Итого по активности:", null, nTotalColspan, 1); w.TRAddCell(xmlEncode(_FormatTimeStringAtServer(nLocalTotalTime, nTimeFormatValue)), null); //w.TRAddCell(rLocalTotalCost, fixed_14_4); /*if(0!=ShowColumnOverheads) * w.TRAddCell( rLocalTotalOverheads, fixed_14_4); * if(0!=ShowColumnSalaryExpenses) * w.TRAddCell( rLocalTotalSalaryExpenses, fixed_14_4); */ for (int i = nFirstDateColumn; i < nFieldCount; ++i) { w.TRAddCell(xmlEncode(_FormatTimeStringAtServer(arrLocalTotals[i], nTimeFormatValue)), null); } w.TREnd(); } } // Итого ;) w.TRStart("TABLE_FOOTER"); w.TRAddCell("Итого:", null, nTotalColspan, 1); w.TRAddCell(xmlEncode(_FormatTimeStringAtServer(nGlobalTotalTime, nTimeFormatValue)), null); //w.TRAddCell(rGlobalTotalCost, fixed_14_4); /*if(0!=ShowColumnOverheads) * w.TRAddCell( rGlobalTotalOverheads, fixed_14_4); * if(0!=ShowColumnSalaryExpenses) * w.TRAddCell( rGlobalTotalSalaryExpenses, fixed_14_4); */ for (int i = nFirstDateColumn; i < nFieldCount; ++i) { w.TRAddCell(xmlEncode(_FormatTimeStringAtServer(arrGlobalTotals[i], nTimeFormatValue)), null); } w.TREnd(); w.TEnd(); } } w.EndPageBody(); w.EndPageSequence(); }
public XResponse Execute(MoveFolderRequest request, IXExecutionContext context) { XDbCommand cmd; DomainObjectDataSet dataSet = new DomainObjectDataSet(context.Connection.MetadataManager.XModel); foreach (Guid oid in request.ObjectsID) { DomainObjectData xobj = dataSet.CreateStubLoaded("Folder", oid, -1); if (request.NewParent != Guid.Empty) { // задана родительская папка xobj.SetUpdatedPropValue("Parent", request.NewParent); // родительская папка задана, однако, она может принадлежать другому клиенту и/или типу проектных затрат cmd = context.Connection.CreateCommand(@" SELECT CASE WHEN f1.Customer <> f2.Customer THEN f1.Customer ELSE cast(NULL as uniqueidentifier) END AS Customer, CASE WHEN f1.ActivityType <> f2.ActivityType THEN f1.ActivityType ELSE cast(NULL as uniqueidentifier) END AS ActivityType FROM Folder f1, Folder f2 WHERE f1.ObjectID = @NewParentID AND f2.ObjectID = @ObjectID AND (f1.Customer <> f2.Customer OR f1.ActivityType <> f2.ActivityType) " ); cmd.Parameters.Add("NewParentID", DbType.Guid, ParameterDirection.Input, false, request.NewParent); cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, oid); using (IDataReader reader = cmd.ExecuteReader()) { int nIndex; if (reader.Read()) { nIndex = reader.GetOrdinal("Customer"); if (!reader.IsDBNull(nIndex)) { xobj.SetUpdatedPropValue("Customer", reader.GetGuid(nIndex)); } nIndex = reader.GetOrdinal("ActivityType"); if (!reader.IsDBNull(nIndex)) { xobj.SetUpdatedPropValue("ActivityType", reader.GetGuid(nIndex)); } } } // Далее мы проверяем следующее: // каталог может быть подчинен папке любого типа, однако проект только проекту, // а пресейл и тендер вообще никому cmd.CommandText = @" SELECT f1.Type AS FolderType, f2.Type AS ParentFolderType, f1.LIndex, f1.RIndex, f2.LIndex AS ParentLIndex, f2.RIndex AS ParentRIndex FROM Folder f1, Folder f2 WHERE f1.ObjectID = @ObjectID AND f2.ObjectID = @NewParentID " ; // Примечание: используем созданную ранее команду с параметрами NewParentID и ObjectID using (IDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) { FolderTypeEnum folderType = (FolderTypeEnum)reader.GetInt16(reader.GetOrdinal("FolderType")); FolderTypeEnum parentFolderType = (FolderTypeEnum)reader.GetInt16(reader.GetOrdinal("ParentFolderType")); // Если у папки не изменилась ссылка на организацию клиента, то проверим, что ее не переносят в одну из дочерних папок if (!xobj.HasUpdatedProp("Customer")) { // Примечание: LIndex/RIndex будут пересчитываться в триггере int nLIndex = reader.GetInt32(reader.GetOrdinal("LIndex")); int nRIndex = reader.GetInt32(reader.GetOrdinal("RIndex")); int nParentLIndex = reader.GetInt32(reader.GetOrdinal("ParentLIndex")); int nParentRIndex = reader.GetInt32(reader.GetOrdinal("ParentRIndex")); // Проверим, что новый родитель не является дочерним (рекурсивно) узлом переносимой папки if (nParentLIndex >= nLIndex && nParentRIndex <= nRIndex) { throw new XBusinessLogicException(FolderTypeEnumItem.GetItem(folderType).Description + " не может быть перенесен в подчиненный " + FolderTypeEnumItem.GetItem(parentFolderType).Description.ToLower()); } } if (folderType == FolderTypeEnum.Project) { if (parentFolderType != FolderTypeEnum.Project) { throw new XBusinessLogicException("Проект не может быть перенесен в " + FolderTypeEnumItem.GetItem(parentFolderType).Description.ToLower()); } } else if (folderType == FolderTypeEnum.Tender || folderType == FolderTypeEnum.Presale) { throw new XBusinessLogicException("Тендер (тендерная активность) и пресейл (пресейл-активноть) не могут быть перенесены в папку"); } } } } else { // перенос в корень xobj.SetUpdatedPropValue("Parent", DBNull.Value); // однако при этом мог измениться клиент или тип проектных затрат if (request.NewActivityType != Guid.Empty) { // если изменился тип проектных затрат, то ссылка на клиента также должна быть задана (даже если он не изменился) if (request.NewCustomer == Guid.Empty) { throw new ArgumentException("Если задана ссылка на тип проектных затрат, то должна быть задана ссылка на организацию-клиента"); } // также нужно проверить, что выбранный типа проектных затрат поддерживает тип переносимой папки cmd = context.Connection.CreateCommand(@" SELECT 1 FROM ActivityType WHERE ObjectID = @ActivityTypeID AND FolderType & (SELECT [Type] FROM Folder WHERE ObjectID = @ObjectID) > 0 " ); cmd.Parameters.Add("ActivityTypeID", DbType.Guid, ParameterDirection.Input, false, request.NewActivityType); cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, oid); if (cmd.ExecuteScalar() == null) { throw new XBusinessLogicException("Перенос папки невозможен. Выбранный тип проектных затрат не может содержать папку переносимого типа."); } xobj.SetUpdatedPropValue("ActivityType", request.NewActivityType); xobj.SetUpdatedPropValue("Customer", request.NewCustomer); } else if (request.NewCustomer != Guid.Empty) { // Если выбрали организацию без изменения типа проектных затрат, то подразумевается, что он (ActivityTyoe) остается прежним, // однако такое возможно только при переносе либо между организациями-клиентами, либо между организациями-владельцами. cmd = context.Connection.CreateCommand(@" SELECT 1 FROM Organization c1, Organization c2 WHERE c1.ObjectID = (SELECT Customer FROM Folder WHERE ObjectID = @ObjectID) AND c2.ObjectID = @NewCustomerID AND c1.Home <> c2.Home " ); cmd.Parameters.Add("NewCustomerID", DbType.Guid, ParameterDirection.Input, false, request.NewCustomer); cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, oid); if (cmd.ExecuteScalar() != null) { throw new XBusinessLogicException("Перенос папки невозможен. Для переноса папок между разными типами проектных затрат следует выбрать узел, соответствующий требуемому типу проектных затрат."); } xobj.SetUpdatedPropValue("Customer", request.NewCustomer); } else { // Parent = Null, Customer = Null, ActivityType = Null - такого быть не может throw new ArgumentException("При незаданной ссылке на родительскую папку должны быть заданы ссылки на Клиента и/или Тип проектных затрат"); } } XSecurityManager.Instance.DemandSaveObjectPrivilege(xobj); } XStorageGateway.Save(context, dataSet, Guid.NewGuid()); // если все сохранилось хорошо, то отработали триггеры, изменяющие LIndex/RIndex, и возможно Customer. // Если у переносимой папки изменилась ссылка на тип проектных затрат , // то необходимо изменить эту ссылку всем подчиненным папкам (если они есть) StringBuilder cmdBuilder = new StringBuilder(); cmdBuilder.AppendFormat( @"UPDATE f SET f.ActivityType = p.ActivityType FROM Folder f JOIN Folder p ON f.LIndex > p.LIndex AND f.RIndex < p.RIndex AND f.Customer = p.Customer WHERE p.ObjectID IN (" ); cmd = context.Connection.CreateCommand(); string sParamName; int nParamIndex = 0; foreach (Guid oid in request.ObjectsID) { ++nParamIndex; sParamName = "ObjectID" + nParamIndex; cmd.Parameters.Add(sParamName, XPropType.vt_uuid, ParameterDirection.Input, false, oid); cmdBuilder.Append(context.Connection.GetParameterName(sParamName)); cmdBuilder.Append(","); } // Отрежим последнюю запятую cmdBuilder.Length--; cmdBuilder.Append(")"); cmd.CommandText = cmdBuilder.ToString(); cmd.ExecuteNonQuery(); // Если у переносимой папки были заданы направления, которые не соответствуют направлениям новой // родительской папки, то удалим эти направления if (request.NewParent != Guid.Empty) { cmdBuilder = new StringBuilder(); cmd = context.Connection.CreateCommand(); nParamIndex = 0; foreach (Guid oid in request.ObjectsID) { ++nParamIndex; sParamName = "FolderID" + nParamIndex; cmd.Parameters.Add(sParamName, XPropType.vt_uuid, ParameterDirection.Input, false, oid); cmdBuilder.Append(context.Connection.GetParameterName(sParamName)); cmdBuilder.Append(","); } // Отрежим последнюю запятую cmdBuilder.Length--; cmd.CommandText = @"IF (EXISTS( SELECT top 1 fd.Direction FROM dbo.FolderDirection fd WHERE (fd.Direction not in ( SELECT Direction FROM dbo.FolderDirection WHERE Folder = @ParentID) AND fd.Folder IN (" + cmdBuilder.ToString() + @")) OR EXISTS( SELECT COUNT(*) FROM dbo.FolderDirection WHERE Folder IN (" + cmdBuilder.ToString() + @") HAVING COUNT(*)>1))) AND EXISTS( SELECT TOP 1 * FROM dbo.Folder WHERE ObjectID = @ParentID ) BEGIN DELETE fd FROM FolderDirection fd WHERE fd.Folder IN (" + cmdBuilder.ToString() + @") END" ; cmd.Parameters.Add("ParentID", DbType.Guid, ParameterDirection.Input, false, request.NewParent); cmd.ExecuteNonQuery(); } return(new XResponse()); }
protected override void buildReport(Croc.XmlFramework.ReportService.Layouts.ReportLayoutData data) { Guid folderID = (Guid)data.Params.GetParam("ID").Value; IDictionary f = null; using (IDataReader r = data.DataProvider.GetDataReader("dsMain", data.CustomData)) { if (r.Read()) { f = _GetDataFromDataRow(r); } } if (null == f) { // Проект не найден writeEmptyBody(data.RepGen, "Проект не найден"); return; } data.RepGen.WriteLayoutMaster(); data.RepGen.StartPageSequence(); data.RepGen.StartPageBody(); data.RepGen.Header("<fo:basic-link color=\"#ffffff\" external-destination=\"x-tree.aspx?METANAME=Main&LocateFolderByID=" + folderID.ToString() + "\" target=\"_blank\" show-destination=\"new\">" + xmlEncode(f["Name"]) + "</fo:basic-link>"); data.RepGen.TStart(false, "CELL_CLASS", false); data.RepGen.TAddColumn(null, align.ALIGN_LEFT, valign.VALIGN_TOP, "30%"); data.RepGen.TAddColumn(null, align.ALIGN_LEFT, valign.VALIGN_TOP, "70%"); // основные свойства проекта data.RepGen.TRStart(); data.RepGen.TRAddCell("Клиент", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(xmlEncode(f["CustomerName"]), null); data.RepGen.TREnd(); data.RepGen.TRStart(); data.RepGen.TRAddCell("Название", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(_GetFolderAnchor(f["Name"], (Guid)f["ObjectID"], false), null); data.RepGen.TREnd(); if (null != f["Description"]) { data.RepGen.TRStart(); data.RepGen.TRAddCell("Описание", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(_LongText(f["Description"]), null); data.RepGen.TREnd(); } if (null != f["FirstDate"]) { data.RepGen.TRStart(); data.RepGen.TRAddCell("Дата начала", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(xmlEncode(((DateTime)f["FirstDate"]).ToLongDateString()) + " (" + getUserMailAnchor(f["FirstName"] + ", " + f["FirstDep"], f["FirstMail"], (Guid)f["FirstID"], folderID) + ")", null); data.RepGen.TREnd(); } if (null != f["LastDate"]) { data.RepGen.TRStart(); data.RepGen.TRAddCell("Дата последней активности", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(xmlEncode(((DateTime)f["LastDate"]).ToLongDateString()) + " (" + getUserMailAnchor(f["LastName"] + ", " + f["LastDep"], f["LastMail"], (Guid)f["LastID"], folderID) + ")", null); data.RepGen.TREnd(); } FolderStates folderState = (FolderStates)f["State"]; data.RepGen.TRStart(); data.RepGen.TRAddCell("Состояние", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(xmlEncode(FolderStatesItem.GetItem(folderState).Description), null); data.RepGen.TREnd(); FolderTypeEnum folderType = (FolderTypeEnum)f["Type"]; data.RepGen.TRStart(); data.RepGen.TRAddCell("Тип", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(xmlEncode(FolderTypeEnumItem.GetItem(folderType).Description), null); data.RepGen.TREnd(); data.RepGen.TRStart(); data.RepGen.TRAddCell("Тип проектной активности", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(xmlEncode(f["ActivityTypeName"]), null); data.RepGen.TREnd(); // Код проекта: // - только для активности; // - м.б. не задан: в этом случае показываем что данных нет if (folderType != FolderTypeEnum.Directory) { data.RepGen.TRStart(); data.RepGen.TRAddCell("Код", null, 1, 1, "BOLD"); if (null != f["ExternalID"]) { data.RepGen.TRAddCell(xmlEncode(f["ExternalID"]), null); } else { data.RepGen.TRAddCell(xmlEncode("(не задан)"), null); } data.RepGen.TREnd(); } if (null != f["DefaultIncidentTypeName"]) { data.RepGen.TRStart(); data.RepGen.TRAddCell("Тип инцидента по умолчанию", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(xmlEncode(f["DefaultIncidentTypeName"]), null); data.RepGen.TREnd(); } if ("0" != f["IsLocked"].ToString()) { data.RepGen.TRStart(); data.RepGen.TRAddCell("", null, 1, 1, "BOLD"); data.RepGen.TRAddCell("Списания на папку заблокированы", null, 1, 1, "BOLD-RED"); data.RepGen.TREnd(); } int nTotalSpent = (int)f["SummarySpent"]; if (0 != nTotalSpent) { data.RepGen.TRStart(); data.RepGen.TRAddCell("Суммарные трудозатраты", null, 1, 1, "BOLD"); data.RepGen.TRAddCell( string.Format("<fo:basic-link external-destination=\"x-get-report.aspx?name=r-ProjectIncidentsAndExpenses.xml&Folder={1}\">{0}</fo:basic-link>", xmlEncode(_FormatTimeStringAtServer(nTotalSpent, int.MaxValue)), folderID) , null); data.RepGen.TREnd(); } // Направления StringBuilder directions = new StringBuilder(); using (IDataReader r = data.DataProvider.GetDataReader("dsDirections", data.CustomData)) { while (r.Read()) { directions.AppendFormat("<fo:block>{0}</fo:block>", xmlEncode(r.GetString(0))); } } if (directions.Length != 0) { // Шапка data.RepGen.TRStart(); data.RepGen.TRAddCell("Направления", null, 1, 1, "BOLD"); data.RepGen.TRAddCell(directions.ToString(), null); data.RepGen.TREnd(); } data.RepGen.TEnd(); // проектная команда insertAdditionalProjectReports(data, folderID); // история insertFolderHistory(data, folderID); // инциденты insertWorkStaff(data, folderID); data.RepGen.EndPageBody(); data.RepGen.EndPageSequence(); }