Case description:
We want to generate printable and send it as attachment by email.
Algorithm of realization:
-
- You should create new business process.
-
Add "Add data" which will create new activity with values:
a. Category - Email (lookup value)
b. Type - Email (lookup value)
c. From
d. To
e. Subject
-
Add "Script task" that will create ActivityFile entity and to generate print form:
Important: Uncheck "For interpreted process" in all blocks "Script task" that describes in this tutorial
Content of following script task:
var reportService = new Terrasoft.Configuration.ReportService.ReportService(); Terrasoft.Configuration.ReportService.ReportData report = reportService.GenerateMSWordReport( (PrintableId.ToString()), ObjectId.ToString(), ConvertToPdf); var entity = UserConnection.EntitySchemaManager.GetInstanceByName("ActivityFile"); var fileEntity = entity.CreateEntity(UserConnection); fileEntity.SetDefColumnValues(); fileEntity.SetColumnValue("ActivityId", AddActivityUserTask.RecordId); fileEntity.SetColumnValue("TypeId", AttachmentType); fileEntity.SetColumnValue("Name", "ExamplePrintable.docx"); fileEntity.SetColumnValue("Data", report.Data); fileEntity.Save(); return true;
PrintableId - Id of your printable from "Printable" lookup
ObjectId - Id of object for which we will generate printable
ConvertToPdf (bool) - if false than will generate printable with type .docx else .pdf
AddActivityUserTask.RecordId - Id of "Add activity" block that we added above
AttachmentType - value "File" from lookup "Attachment Type"
"ExamplePrintable.docx" - name of generated file
Important: you should add type of file (.docx or .pdf). It depends on bool argument when you generate printable by using "GenerateMSWordReport"
report.Data - generated printable
-
Add "Script task" that will send email with created attachment:
Uncheck "For interpreted process"
Add next usings for process: Terrasoft.Mail, Terrasoft.Mail.Sender, Terrasoft.Core.Factories: - Add following content:
var activityId = AddActivityUserTask.RecordId; var emailClientFactory = ClassFactory.Get<EmailClientFactory>(new ConstructorArgument("userConnection", UserConnection)); var activityEmailSender = new ActivityEmailSender(emailClientFactory, UserConnection); activityEmailSender.Send(activityId); return true;
AddActivityUserTask.RecordId - Id of added email activity from "Add email activity" block
Example:
I need to generate printable and send it as attachment by email when status of contract was changed on signed
- I created business process and add next parameters
MailSender - value from lookup "Mailbox synchronization settings". (Values in this lookup becomes allow when you sign in in BPMonline by your mail account)
Printable Id - Id of printable from lookup "Printable" which i want to use
2. Added signal "Contact signed" which start business process when Status becomes "Signed"
3. Added "Formula" block "Set signed contract id" that sets "Signed contract id" parameter on Id of contact that was signed
4. Added "Read data" that gives parameter "MailSender" and returns string value "Sender's email" (it uses for sending email)
5. Added "Read data" that gives parameter "Printable Id" and returns columns: Convert to PDF (bool) and Title of printable
6. Added "Formula" block "Set ConvertToPdf" that sets "Convert To Pdf" parameter on bool value from "Read Printable"
7. Added "Formula" block "Set File Name" that sets "File name" parameter on Text value which is formed by "Title" and "Convert to pdf" value (bool) for current record from lookup "Printable"
Formula value:
[#Read Printable.First item of resulting collection.Title#] + ([#Convert To Pdf#] ?
".pdf"
:
".docx"
)
8. Added "Add data" block "AddActivityUserTask" that create email activity by using added parameters
9. Added "Generate print form" script task with following content:
var reportService = new Terrasoft.Configuration.ReportService.ReportService(UserConnection); Terrasoft.Configuration.ReportService.ReportData report = reportService.GenerateMSWordReport( (PrintableId.ToString()), SignedContractId.ToString(), ConvertToPdf); var entity = UserConnection.EntitySchemaManager.GetInstanceByName("ActivityFile"); var fileEntity = entity.CreateEntity(UserConnection); fileEntity.SetDefColumnValues(); fileEntity.SetColumnValue("ActivityId", AddActivityUserTask.RecordId); fileEntity.SetColumnValue("TypeId", AttachmentTypeId); fileEntity.SetColumnValue("Name", FileName.ToString()); fileEntity.SetColumnValue("Data", report.Data); fileEntity.Save(); return true;
10. Added "Send email" script task with following content:
var activityId = AddActivityUserTask.RecordId; var emailClientFactory = ClassFactory.Get<EmailClientFactory>(new ConstructorArgument("userConnection", UserConnection)); var activityEmailSender = new ActivityEmailSender(emailClientFactory, UserConnection); activityEmailSender.Send(activityId); return true;
The final business process:
MD file of business process for import (Version 7.10.2) is attached.
Hi,
How about instead of generating a word printable(GenerateMSWordReport()) we will generate a FastReport, what would be the method we need to call?
Fulgen Ninofranco,
In order to generate a FastReport report please call the “CreateReport” method from the “FastReportService” service. You can find the source code of this service in the configuration.
Best regards,
Norton
Norton Lingard,
Thank you so much for your reply. on my script task i have this code below:
var reportService = new FastReportService(UserConnection);
var result = reportService.CreateReport(reportTemplateId, reportCaption, reportSchemaName, reportFilters);
Please note that I am passing correct values on the parameters, same value I am getting when generating my fastReport on section page.
But upon calling CreateReport method it is returning Internal Server Error. Please suggest, or show me the correct way please.
Fulgen Ninofranco,
Unfortunately, the provided way of generating a FastReport report is not correct. I tested it on my local instance and got the same error.
Therefore, I implemented another approach. Please find the example of the script task that generates the FastReport report and adds it to the Activity below:
Terrasoft.Configuration.ReportService.ReportData report = new Terrasoft.Configuration.ReportService.ReportData();
string reportSchemaName = "Contact";
Guid reportTemplateId = new Guid ("c4901c9f-3242-4b5e-9662-3c1970cd4505"); //id of printable
var reportFilters = "{\"items\":{\"e4e66f27-83af-4d2f-90fe-4bef3c91d07d\":{\"filterType\":4,\"comparisonType\":3,\"isEnabled\":true,\"trimDateTimeParameterToDate\":false,\"leftExpression\":{\"expressionType\":0,\"columnPath\":\"Id\"},\"rightExpressions\":[{\"expressionType\":2,\"parameter\":{\"dataValueType\":1,\"value\":\"c4ed336c-3e9b-40fe-8b82-5632476472b4\"}}]}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}";
var reportParameters = new Dictionary<string, object> {
["EsqFilters"] = new Dictionary<string, Filters> {
[reportSchemaName] = JsonConvert.DeserializeObject<Filters>(reportFilters)
}
};
IReportTemplateProvider reportTemplateProvider = new FastReportTemplateProvider(UserConnection);;
IDataSourceBuilderResolver dataSourceBuilderResolver = new FastReportDataSourceBuilderResolver(UserConnection);;
var CustomCreateReportGenerator = new ReportGenerator(reportTemplateProvider, dataSourceBuilderResolver);
var reportGenerator = CustomCreateReportGenerator;
var task = reportGenerator.Generate(reportTemplateId, reportParameters, ReportFormat.Pdf);
var reportBytes = task.Result;
var reportData = new ReportData();
reportData.Data = reportBytes;
reportData.Format = "docs";
reportData.Caption = "Test";
var entity = UserConnection.EntitySchemaManager.GetInstanceByName("ActivityFile");
var fileEntity = entity.CreateEntity(UserConnection);
fileEntity.SetDefColumnValues();
fileEntity.SetColumnValue("ActivityId", AddActivityUserTask.RecordId);
fileEntity.SetColumnValue("TypeId", AttachmentTypeId);
fileEntity.SetColumnValue("Name", FileName.ToString());
fileEntity.SetColumnValue("Data", reportBytes);
fileEntity.Save();
return true;
You can see how the reportFilters is formed if you generate FastReportManually and see how the parameters are passed to CreateReport requests. You can read the necessary Id's (red can be replaced with any valid Guid and green is an Id of the record) and insert them into reportFilters string. FileName is the name of the file, e.g. "Test.pdf".
Here are libraries that I used in the script task (some of them may not be necessary needed for the script and maybe removed) :
Terrasoft.Mail
Terrasoft.Mail.Sender
Terrasoft.Core.Factories
Terrasoft.Configuration
Terrasoft.Nui.ServiceModel.DataContract
Terrasoft.Reporting.Abstractions.Data
Terrasoft.Reporting.DataSource.Abstractions
Terrasoft.Reporting.FastReport
Terrasoft.Reporting.FastReport.Abstractions
Terrasoft.Web.Common
Terrasoft.Configuration.Reporting.FastReport
Terrasoft.Configuration.Reporting.FastReportEngine
Terrasoft.Configuration.ReportService
Best regards,
Norton
Norton Lingard,
Thank you Norton, the given solution is working fine.
Hello Norton, this is Julio Falcón. I'm trying to implement also the Fastreport version, but get an execution error.
The code we have in the Scrip Task is
Terrasoft.Configuration.ReportService.ReportData report = new Terrasoft.Configuration.ReportService.ReportData(); string reportSchemaName = "Account"; Guid reportTemplateId = new Guid ("8a474ce6-dd1f-4ad9-b7f7-df3026617f56"); //id of printable var reportFilters = "{\"items\":{\"CustomFilters\":{\"items\":{\"customFilterAccountCategory_Account\":{\"filterType\":1,\"comparisonType\":3,\"isEnabled\":true,\"trimDateTimeParameterToDate\":false,\"leftExpression\":{\"expressionType\":0,\"columnPath\":\"AccountCategory\"},\"rightExpression\":{\"expressionType\":2,\"parameter\":{\"dataValueType\":10,\"value\":\"37ea507c-55e6-df11-971b-001d60e938c6\"}}}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}"; //"{"items":{"CustomFilters":{"items":{"customFilterAccountCategory_Account":{"filterType":1,"comparisonType":3,"isEnabled":true,"trimDateTimeParameterToDate":false,"leftExpression":{"expressionType":0,"columnPath":"AccountCategory"},"rightExpression":{"expressionType":2,"parameter":{"dataValueType":10,"value":"37ea507c-55e6-df11-971b-001d60e938c6"}}}},"logicalOperation":0,"isEnabled":true,"filterType":6}},"logicalOperation":0,"isEnabled":true,"filterType":6}"; //"{\"items\":{\"e4e66f27-83af-4d2f-90fe-4bef3c91d07d\":{\"filterType\":4,\"comparisonType\":3,\"isEnabled\":true,\"trimDateTimeParameterToDate\":false,\"leftExpression\":{\"expressionType\":0,\"columnPath\":\"Id\"},\"rightExpressions\":[{\"expressionType\":2,\"parameter\":{\"dataValueType\":1,\"value\":\"c4ed336c-3e9b-40fe-8b82-5632476472b4\"}}]}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}"; var reportParameters = new Dictionary<string, object> { ["EsqFilters"] = new Dictionary<string, Filters> { [reportSchemaName] = JsonConvert.DeserializeObject<Filters>(reportFilters) } }; IReportTemplateProvider reportTemplateProvider = new FastReportTemplateProvider(UserConnection); IDataSourceBuilderResolver dataSourceBuilderResolver = new FastReportDataSourceBuilderResolver(UserConnection); var CustomCreateReportGenerator = new ReportGenerator(reportTemplateProvider, dataSourceBuilderResolver); var reportGenerator = CustomCreateReportGenerator; var task = reportGenerator.Generate(reportTemplateId, reportParameters, ReportFormat.Pdf); var reportBytes = task.Result; var reportData = new ReportData(); reportData.Data = reportBytes; reportData.Format = "docs"; reportData.Caption = "Test"; var entity = UserConnection.EntitySchemaManager.GetInstanceByName("ActivityFile"); var fileEntity = entity.CreateEntity(UserConnection); fileEntity.SetDefColumnValues(); fileEntity.SetColumnValue("ActivityId", Get<Guid>("EmailActivityId") ); //AddActivityUserTask.RecordId); fileEntity.SetColumnValue("TypeId", new Guid("529BC2F8-0EE0-DF11-971B-001D60E938C6"));//, AttachmentTypeId); fileEntity.SetColumnValue("Name", Get<string>("PrintableTitle") ); //FileName.ToString()); fileEntity.SetColumnValue("Data", reportBytes); fileEntity.Save(); return true;
The compilation works, but when I run it from another process who is on Accounts, because the report is from Accounts get this error.
What could be wrong?
System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null. Parameter name: g at System.Guid..ctor(String g) at Terrasoft.Configuration.AprFastReportDataSourceDataProvider.GetData(UserConnection userConnection, IReadOnlyDictionary`2 parameters) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetDataSourceData>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetData>d__5.MoveNext() --- End of inner exception stack trace --- at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at Terrasoft.Reporting.FastReport.Connection.ReportDataSourceConnection.FillTableData(DataTable table, String selectCommand, CommandParameterCollection parameters) at FastReport.Data.DataConnectionBase.FillTable(TableDataSource source) at FastReport.Data.TableDataSource.LoadData(ArrayList rows) at FastReport.Data.DataSourceBase.Init(Relation relation, String filter, SortCollection sort, Boolean useAllParentRows) at FastReport.Data.DataSourceBase.get_Item(Column column) at FastReport.Report.GetColumnValue(String complexName, Boolean convertNull) at FastReport.PictureObject.GetData() at FastReport.BandBase.GetData() at FastReport.Engine.ReportEngine.PrepareBand(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBandToPreparedPages(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBand(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBand(BandBase band) at FastReport.Engine.ReportEngine.StartFirstPage() at FastReport.Engine.ReportEngine.RunReportPage(ReportPage page) at FastReport.Engine.ReportEngine.RunReportPages() at FastReport.Engine.ReportEngine.RunReportPages(ReportPage page) at FastReport.Engine.ReportEngine.Run(Boolean runDialogs, Boolean append, Boolean resetDataState, ReportPage page) at FastReport.Report.Prepare(Boolean append) at Terrasoft.Reporting.FastReport.ReportGenerator.<Generate>d__6.MoveNext() --- End of inner exception stack trace --- at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at Terrasoft.Core.Process.UsrEnviarReporteEjecutivo_3052417MethodsWrapper.AttachPrintableExecute(ProcessExecutingContext context) at Terrasoft.Core.Process.ProcessScriptTask.InternalExecute(ProcessExecutingContext context) at Terrasoft.Core.Process.ProcessFlowElement.ExecuteItem(ProcessExecutingContext context) at Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context) ---> (Inner Exception #0) System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null. Parameter name: g at System.Guid..ctor(String g) at Terrasoft.Configuration.AprFastReportDataSourceDataProvider.GetData(UserConnection userConnection, IReadOnlyDictionary`2 parameters) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetDataSourceData>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetData>d__5.MoveNext() --- End of inner exception stack trace --- at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at Terrasoft.Reporting.FastReport.Connection.ReportDataSourceConnection.FillTableData(DataTable table, String selectCommand, CommandParameterCollection parameters) at FastReport.Data.DataConnectionBase.FillTable(TableDataSource source) at FastReport.Data.TableDataSource.LoadData(ArrayList rows) at FastReport.Data.DataSourceBase.Init(Relation relation, String filter, SortCollection sort, Boolean useAllParentRows) at FastReport.Data.DataSourceBase.get_Item(Column column) at FastReport.Report.GetColumnValue(String complexName, Boolean convertNull) at FastReport.PictureObject.GetData() at FastReport.BandBase.GetData() at FastReport.Engine.ReportEngine.PrepareBand(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBandToPreparedPages(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBand(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBand(BandBase band) at FastReport.Engine.ReportEngine.StartFirstPage() at FastReport.Engine.ReportEngine.RunReportPage(ReportPage page) at FastReport.Engine.ReportEngine.RunReportPages() at FastReport.Engine.ReportEngine.RunReportPages(ReportPage page) at FastReport.Engine.ReportEngine.Run(Boolean runDialogs, Boolean append, Boolean resetDataState, ReportPage page) at FastReport.Report.Prepare(Boolean append) at Terrasoft.Reporting.FastReport.ReportGenerator.<Generate>d__6.MoveNext() ---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null. Parameter name: g at System.Guid..ctor(String g) at Terrasoft.Configuration.AprFastReportDataSourceDataProvider.GetData(UserConnection userConnection, IReadOnlyDictionary`2 parameters) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetDataSourceData>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetData>d__5.MoveNext()<--- <---
Julio.Falcon_Nodos,
Hello,
Thank you for sharing the code! I've used it when performing tests on my side and the email with the attachment was generated correctly:
The error message "Value cannot be null. Parameter name: g" usually occurs in case there is a problem with access rights to some object with which the process interacts. In our case these objects are "ActivityFile", "FastReportTemplate", "Account" and "Activity". Please double-check that your user who runs the process has rigths to read data from "Accounts" and "FastReportTemplate", operation permissions to add data to "ActivityFile" and "Activity" and read access rights to "ActivityFile" and "Activity".
Best regards,
Oscar
Thanks Oscar, in this case I'm Supervisor, System Administrator
I have no this problem, becasue have permissions to everything, what else could be?
Julio.Falcon_Nodos,
The only thing left is to compare all the settings of your process with all the settings of mine below:
The list is:
Terrasoft.Mail Terrasoft.Mail.Sender Terrasoft.Core.Factories Terrasoft.Configuration Terrasoft.Nui.ServiceModel.DataContract Terrasoft.Reporting.Abstractions.Data Terrasoft.Reporting.DataSource.Abstractions Terrasoft.Reporting.FastReport Terrasoft.Reporting.FastReport.Abstractions Terrasoft.Web.Common Terrasoft.Configuration.Reporting.FastReport Terrasoft.Configuration.Reporting.FastReportEngine Terrasoft.Configuration.ReportService
Then parameters are:
The code is absolutely similar to yours:
Terrasoft.Configuration.ReportService.ReportData report = new Terrasoft.Configuration.ReportService.ReportData(); string reportSchemaName = "Account"; Guid reportTemplateId = new Guid ("7D12ED1B-5807-BA49-6E22-668836CF0BD4"); //id of printable var reportFilters = "{\"items\":{\"CustomFilters\":{\"items\":{\"customFilterAccountCategory_Account\":{\"filterType\":1,\"comparisonType\":3,\"isEnabled\":true,\"trimDateTimeParameterToDate\":false,\"leftExpression\":{\"expressionType\":0,\"columnPath\":\"AccountCategory\"},\"rightExpression\":{\"expressionType\":2,\"parameter\":{\"dataValueType\":10,\"value\":\"37ea507c-55e6-df11-971b-001d60e938c6\"}}}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}"; //"{"items":{"CustomFilters":{"items":{"customFilterAccountCategory_Account":{"filterType":1,"comparisonType":3,"isEnabled":true,"trimDateTimeParameterToDate":false,"leftExpression":{"expressionType":0,"columnPath":"AccountCategory"},"rightExpression":{"expressionType":2,"parameter":{"dataValueType":10,"value":"37ea507c-55e6-df11-971b-001d60e938c6"}}}},"logicalOperation":0,"isEnabled":true,"filterType":6}},"logicalOperation":0,"isEnabled":true,"filterType":6}"; //"{\"items\":{\"e4e66f27-83af-4d2f-90fe-4bef3c91d07d\":{\"filterType\":4,\"comparisonType\":3,\"isEnabled\":true,\"trimDateTimeParameterToDate\":false,\"leftExpression\":{\"expressionType\":0,\"columnPath\":\"Id\"},\"rightExpressions\":[{\"expressionType\":2,\"parameter\":{\"dataValueType\":1,\"value\":\"c4ed336c-3e9b-40fe-8b82-5632476472b4\"}}]}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}"; var reportParameters = new Dictionary<string, object> { ["EsqFilters"] = new Dictionary<string, Filters> { [reportSchemaName] = JsonConvert.DeserializeObject<Filters>(reportFilters) } }; IReportTemplateProvider reportTemplateProvider = new FastReportTemplateProvider(UserConnection); IDataSourceBuilderResolver dataSourceBuilderResolver = new FastReportDataSourceBuilderResolver(UserConnection); var CustomCreateReportGenerator = new ReportGenerator(reportTemplateProvider, dataSourceBuilderResolver); var reportGenerator = CustomCreateReportGenerator; var task = reportGenerator.Generate(reportTemplateId, reportParameters, ReportFormat.Pdf); var reportBytes = task.Result; var reportData = new ReportData(); reportData.Data = reportBytes; reportData.Format = "docs"; reportData.Caption = "Test"; var entity = UserConnection.EntitySchemaManager.GetInstanceByName("ActivityFile"); var fileEntity = entity.CreateEntity(UserConnection); fileEntity.SetDefColumnValues(); fileEntity.SetColumnValue("ActivityId", Get<Guid>("EmailActivityId") ); //AddActivityUserTask.RecordId); fileEntity.SetColumnValue("TypeId", new Guid("529BC2F8-0EE0-DF11-971B-001D60E938C6"));//, AttachmentTypeId); fileEntity.SetColumnValue("Name", Get<string>("PrintableTitle") ); //FileName.ToString()); fileEntity.SetColumnValue("Data", reportBytes); fileEntity.Save(); return true;
And the data source code for the accounts fast report:
namespace Terrasoft.Configuration { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using Terrasoft.Common; using Terrasoft.Configuration.Reporting.FastReport; using Terrasoft.Core; using Terrasoft.Core.Entities; using Terrasoft.Core.Factories; using Terrasoft.Nui.ServiceModel.Extensions; using EntitySchema = Terrasoft.Core.Entities.EntitySchema; using EntitySchemaColumn = Terrasoft.Core.Entities.EntitySchemaColumn; [DefaultBinding(typeof(IFastReportDataSourceDataProvider), Name = "AccountDataProvider")] public class AccountDataProvider : IFastReportDataSourceDataProvider { private Guid _entitySchemaUId = new Guid("25D7C1AB-1DE0-4501-B402-02E0E5A72D6E"); private readonly string _resourceManagerName = "UsrAccountDataSource"; private readonly string[] _localizableStringNames = new[] { "ReportTitle", "NameLabel", "TypeLabel" }; private IEnumerable<IReadOnlyDictionary<string, object>> GetAccountData( UserConnection userConnection, Guid entitySchemaUId, IEntitySchemaQueryFilterItem filter) { var entitySchema = userConnection.EntitySchemaManager.GetInstanceByUId(entitySchemaUId); EntitySchemaQuery query = new EntitySchemaQuery(entitySchema); query.AddColumn("Name"); query.AddColumn("Type"); query.Filters.Add(filter); var accounts = query.GetEntityCollection(userConnection); var accountsCollection = new Collection<Dictionary<string, object>>(); foreach (var entity in accounts) { accountsCollection.Add(new Dictionary<string, object> { ["Name"] = entity.GetTypedColumnValue<string>("Name"), ["Type"] = entity.GetTypedColumnValue<string>("Type") }); } return accountsCollection; } private IEnumerable<IReadOnlyDictionary<string, object>> GetLocalizableStrings(UserConnection userConnection) { var localizableStrings = _localizableStringNames.ToDictionary( x => x, x => (object)(new LocalizableString(userConnection.ResourceStorage, _resourceManagerName, $"LocalizableStrings.{x}.Value")).Value); return new[] { localizableStrings }; } private IEntitySchemaQueryFilterItem ExtractFilterFromParameters(UserConnection userConnection, Guid entitySchemaUId, IReadOnlyDictionary<string, object> parameters) { var managerItem = userConnection.EntitySchemaManager.GetItemByUId(entitySchemaUId); return parameters.ExtractEsqFilterFromReportParameters(userConnection, managerItem.Name) ?? throw new Exception(); } public Task<ReportDataDictionary> GetData(UserConnection userConnection, IReadOnlyDictionary<string, object> parameters) { var filter = ExtractFilterFromParameters(userConnection, _entitySchemaUId, parameters); var result = new ReportDataDictionary { ["AccountData"] = GetAccountData(userConnection, _entitySchemaUId, filter), ["LocalizableStrings"] = GetLocalizableStrings(userConnection) }; return Task.FromResult(result); } } }
Please compare it to the settings of your business process as well.
Best regards,
Oscar
Oscar, here you can see what I'm doing, check permissions and how get the error executing the code above, please help me https://share.vidyard.com/watch/zbDdhn2PAtTDyGcgrvR1vq?
In the Usings I have the same, except also have System.IO
The code of ScripTask is the same except the Guid for reportTemplateId and reportFilters
and regarding the data source code for the accounts fast report, I'm using https://marketplace.terrasoft.ru/app/no-code-reports-creatio
Oscar Dylan,
Hi @Oscar, please could you help me?
Thanks in advance
Julio.Falcon_Nodos,
Hello,
Since you are using the marketplace app you need to contact a partner who is responsible for the app (the email is support@crm-bpm.ru). Please ask them to take a look at the problem with generating a fast report in the system.
Best regards,
Oscar
Oscar Dylan,
Oscar, the generation of the report is working, what i need to do is could download it to share with customers by mail, in my case it doesn't works also with the Creatio Standard FastReports
Julio.Falcon_Nodos,
Then you need to double-check the business process settings and compare them to the business process settings of my business process that is working in my local app and generates a printable and add it as an attachment to an email. Also you need to try generating the source code for all items and compiling all items in the system.
Best regards,
Oscar
Hi Oscar
It doesn't works, sure it must be some vey simple, but I don's see where, so I enabled debug the process & Creatio and in Chrome there no any error...
I simplified the process, so it's:
In fact I just need id of KB Article to attach the file and:
- reportTemplateId
- reportFilters
And the code to attach the FastReport File is
Terrasoft.Configuration.ReportService.ReportData report = new Terrasoft.Configuration.ReportService.ReportData(); string reportSchemaName = "Account"; // id of printable Guid reportTemplateId = new Guid("b7abe9a9-bd14-4c7e-857b-0138c9b82462"); // reportFilters of Printable var reportFilters = "{\"items\":{\"23009387-7361-424b-a9af-0c29ec890696\":{\"filterType\":4,\"comparisonType\":3,\"isEnabled\":true,\"trimDateTimeParameterToDate\":false,\"leftExpression\":{\"expressionType\":0,\"columnPath\":\"Id\"},\"rightExpressions\":[{\"expressionType\":2,\"parameter\":{\"dataValueType\":1,\"value\":\"7bf558b3-1fd0-4cef-8df5-8e8816b12b54\"}}]}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}"; var reportParameters = new Dictionary<string, object> { ["EsqFilters"] = new Dictionary<string, Filters> { [reportSchemaName] = JsonConvert.DeserializeObject<Filters>(reportFilters) } }; IReportTemplateProvider reportTemplateProvider = new FastReportTemplateProvider(UserConnection); IDataSourceBuilderResolver dataSourceBuilderResolver = new FastReportDataSourceBuilderResolver(UserConnection); var CustomCreateReportGenerator = new ReportGenerator(reportTemplateProvider, dataSourceBuilderResolver); var reportGenerator = CustomCreateReportGenerator; var task = reportGenerator.Generate( reportTemplateId, reportParameters, ReportFormat.Pdf ); var reportBytes = task.Result; var reportData = new ReportData(); reportData.Data = reportBytes; reportData.Format = "docs"; reportData.Caption = "Test"; // Se conecta al KnowledgeBase var entity = UserConnection.EntitySchemaManager.GetInstanceByName("KnowledgeBaseFile"); // Crea nuevo registro var fileEntity = entity.CreateEntity(UserConnection); fileEntity.SetDefColumnValues(); fileEntity.SetColumnValue( "KnowledgeBaseId", Get<Guid>("NewKnowledgeBaseId") ); fileEntity.SetColumnValue( "TypeId", new Guid("529bc2f8-0ee0-df11-971b-001d60e938c6")); fileEntity.SetColumnValue( "Name", "Informe Ejecutivo Clientes VIP" ); fileEntity.SetColumnValue( "Data", reportBytes ); fileEntity.Save(); return true;
and get exactly the same error I get on the most complex process:
System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null. Parameter name: g at System.Guid..ctor(String g) at Terrasoft.Configuration.AprFastReportDataSourceDataProvider.GetData(UserConnection userConnection, IReadOnlyDictionary`2 parameters) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetDataSourceData>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetData>d__5.MoveNext() --- End of inner exception stack trace --- at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at Terrasoft.Reporting.FastReport.Connection.ReportDataSourceConnection.FillTableData(DataTable table, String selectCommand, CommandParameterCollection parameters) at FastReport.Data.DataConnectionBase.FillTable(TableDataSource source) at FastReport.Data.TableDataSource.LoadData(ArrayList rows) at FastReport.Data.DataSourceBase.Init(Relation relation, String filter, SortCollection sort, Boolean useAllParentRows) at FastReport.Data.DataSourceBase.get_Item(Column column) at FastReport.Report.GetColumnValue(String complexName, Boolean convertNull) at FastReport.PictureObject.GetData() at FastReport.BandBase.GetData() at FastReport.Engine.ReportEngine.PrepareBand(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBandToPreparedPages(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBand(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBand(BandBase band) at FastReport.Engine.ReportEngine.StartFirstPage() at FastReport.Engine.ReportEngine.RunReportPage(ReportPage page) at FastReport.Engine.ReportEngine.RunReportPages() at FastReport.Engine.ReportEngine.RunReportPages(ReportPage page) at FastReport.Engine.ReportEngine.Run(Boolean runDialogs, Boolean append, Boolean resetDataState, ReportPage page) at FastReport.Report.Prepare(Boolean append) at Terrasoft.Reporting.FastReport.ReportGenerator.<Generate>d__6.MoveNext() --- End of inner exception stack trace --- at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at Terrasoft.Core.Process.UsrEnviarReporteEjecutivo_Simplified_636e5cfMethodsWrapper.ScriptTask1Execute(ProcessExecutingContext context) at Terrasoft.Core.Process.ProcessScriptTask.InternalExecute(ProcessExecutingContext context) at Terrasoft.Core.Process.ProcessFlowElement.ExecuteItem(ProcessExecutingContext context) at Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context) ---> (Inner Exception #0) System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null. Parameter name: g at System.Guid..ctor(String g) at Terrasoft.Configuration.AprFastReportDataSourceDataProvider.GetData(UserConnection userConnection, IReadOnlyDictionary`2 parameters) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetDataSourceData>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetData>d__5.MoveNext() --- End of inner exception stack trace --- at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at Terrasoft.Reporting.FastReport.Connection.ReportDataSourceConnection.FillTableData(DataTable table, String selectCommand, CommandParameterCollection parameters) at FastReport.Data.DataConnectionBase.FillTable(TableDataSource source) at FastReport.Data.TableDataSource.LoadData(ArrayList rows) at FastReport.Data.DataSourceBase.Init(Relation relation, String filter, SortCollection sort, Boolean useAllParentRows) at FastReport.Data.DataSourceBase.get_Item(Column column) at FastReport.Report.GetColumnValue(String complexName, Boolean convertNull) at FastReport.PictureObject.GetData() at FastReport.BandBase.GetData() at FastReport.Engine.ReportEngine.PrepareBand(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBandToPreparedPages(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBand(BandBase band, Boolean getData) at FastReport.Engine.ReportEngine.ShowBand(BandBase band) at FastReport.Engine.ReportEngine.StartFirstPage() at FastReport.Engine.ReportEngine.RunReportPage(ReportPage page) at FastReport.Engine.ReportEngine.RunReportPages() at FastReport.Engine.ReportEngine.RunReportPages(ReportPage page) at FastReport.Engine.ReportEngine.Run(Boolean runDialogs, Boolean append, Boolean resetDataState, ReportPage page) at FastReport.Report.Prepare(Boolean append) at Terrasoft.Reporting.FastReport.ReportGenerator.<Generate>d__6.MoveNext() ---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null. Parameter name: g at System.Guid..ctor(String g) at Terrasoft.Configuration.AprFastReportDataSourceDataProvider.GetData(UserConnection userConnection, IReadOnlyDictionary`2 parameters) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetDataSourceData>d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Terrasoft.Configuration.Reporting.FastReportEngine.Custom.CustomDataProvider.<GetData>d__5.MoveNext()<--- <---
To test I start the process manually and use any account filtering by account name, here is the exported process to, please try yourself or anybody can help me. the exported process is on
https://1drv.ms/u/s!ApFItzjX7t0uhLog1J00MTBmVljgwg?e=J6gApR
Thanks in advance
If somebody wants to try the code to generate the FastReport and attach to some section files just copy the code above and decode it pasting on https://emn178.github.io/online-tools/html_decode.html or other site, there are a lot, just wait to found where this code fails. I'm sure it is so simple, because Oscar indicates use this code and works, but mus there some insignificant difference like the typical "0 vs O" :-(
I compare the code byte by byte and are the same code, just the differences are:
- id of object where it must attach the file
- reportTemplateId
- reportFilters
??? :-(
Hi Oscar, if you want, I have this on a demo site, I can provide access to you ?
Julio.Falcon_Nodos,
Hi Julio,
Yes please share the demo app and access to it and we will check the printable generation on our side.
Best regards,
Oscar
Oscar Dylan,
Good morning Oscar, I post you an internal message with details, please confirm me if you receive it or send by Email.
Thanks
Julio.Falcon_Nodos,
Hi Julio,
Yes, I received it thank you! And I am now looking into the report settings to see what happens.
Best regards,
Oscar
Julio.Falcon_Nodos,
I've reviewed the demo app and there is something really wrong with the report you are using in the script task. First of all it cannot be found in the UI (I've searched the Id from the script task of your process (Guid reportTemplateId = new Guid("b7abe9a9-bd14-4c7e-857b-0138c9b82462");))
while it can be accessed via a direct link -
https://paste_your_app_link_here/0/ClientApp/#/Printables/8def0f6d-b075-41dd-bcad-ca660c29f2e2/be729e12-67e7-4e12-9397-4a50010ba5fb
Also if you execute this query:
select * from "FastReportTemplate" where "Id" = 'b7abe9a9-bd14-4c7e-857b-0138c9b82462'
You will see that the "Data" column is empty, while it should contain the data of the template:
These are two main "problematic" places that could generate the error. Can you please create a new fast report record, generate a new template for it and use it in the process instead? This should help in generating an attachment in the email.
Best regards,
Oscar
Oscar Dylan,
Hi Oscar if I go to Account section, click on Banco Santander, for example and click on PRINT select the report and review, on the debug console, the Network folder, the execution returns as you can see the report ID is correct and also the filter
{"reportTemplateId":"b7abe9a9-bd14-4c7e-857b-0138c9b82462","reportCaption":"Informe Ejecutivo 01 cuentas VIP","reportSchemaName":"Account","reportFilters":"{\"items\":{\"179f3e78-3e7e-4294-b6d0-c81ee3b8010e\":{\"filterType\":4,\"comparisonType\":3,\"isEnabled\":true,\"trimDateTimeParameterToDate\":false,\"leftExpression\":{\"expressionType\":0,\"columnPath\":\"Id\"},\"rightExpressions\":[{\"expressionType\":2,\"parameter\":{\"dataValueType\":1,\"value\":\"7bf558b3-1fd0-4cef-8df5-8e8816b12b54\"}}]}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}"}
@Oscar, could be the problem is the report is created using https://marketplace.creatio.com/app/no-code-reports-creatio, but I understand it works like an standard Fastreport
Julio.Falcon_Nodos,
Yes, I also saw that the report is present on the account edit page, but it cannot be found in the UI of the report setup and this already tells us that there is something wrong with it. Also the "Data" column value for the template is empty that shouldn't happen in case the template contains some data.
Julio, can you please recreate the report completely? Also have you reported the problem to support@crm-bpm.ru?
Best regards,
Oscar
Oscar Dylan,
Thanks Oscar I'm already open a ticket with them, it's
#SR00000549
Oscar Dylan,
Also recreate the report completely using the Marketplace App? The reports created using this app doesn't list on Creatio standard FastReports, in the case of my demo site is there on Studio workplace a Report Section called "Reports setup"
Julio.Falcon_Nodos,
but the fact is the report is generated manually as usual :-(
Julio.Falcon_Nodos,
Yes, the report is generated manually, but the fact that it's not present in the UI and also doesn't have the template data in the database already gives us two questions that the partner needs to take a look at. Also as you said I am more than sure that this issue doesn't occur with regular reports that can be accessed from the fast reports section, am I right?
Best regards,
Oscar
Oscar Dylan,
Thanks Oscar, I didn't try with standard reports yet, because tomorrow is the demo of the POC with the customer and I have no time to code the standard way to provide the data.
But after the POC I will try, but sure we will need a solution for the guys of Automated Process, because this customer in case we win, need a lot of custom and complicated reports, and we cannot use a lot of hours writing code to create reports in Creatio, the Low code platform... Is in the backlog of Creatio a Low code tool to this?
Thanks again
Julio.Falcon_Nodos,
I agree with you that FastReports are not easy to design and require time to be created and unfortunately I haven't found the problem related to FastReport low-code re-design. Thus I've created one for the product owner who is responsible for custom reports and printables so the FastReports logic could be re-designed in the nearest future (it will be definitely re-designed since the low-code approach becomes the main idea for the Creatio app solutions development). The only working and tested approach that we have for custom reports is Word printables, but they are not as flexible as FastReport templates and logic.
Please also let me know once you test a new FastReport and the business process execution with it.
Best regards,
Oscar