Article

Generate printable and send it as attachment by email

Case description:

We want to generate printable and send it as attachment by email.

Algorithm of realization:

    1. You should create new business process.
    2. 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

       

    3. 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

    4. 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:

    5. 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

  1. 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.

Like 0

Like

Share

39 comments

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.

Hi Norton Lingard, any update 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&lt;string, object&gt; {
                    ["EsqFilters"] = new Dictionary&lt;string, Filters&gt; {
                    [reportSchemaName] = JsonConvert.DeserializeObject&lt;Filters&gt;(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&lt;Guid&gt;("EmailActivityId") ); //AddActivityUserTask.RecordId);
fileEntity.SetColumnValue("TypeId", new Guid("529BC2F8-0EE0-DF11-971B-001D60E938C6"));//, AttachmentTypeId);
fileEntity.SetColumnValue("Name", Get&lt;string&gt;("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. ---&gt; System.AggregateException: One or more errors occurred. ---&gt; 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.&lt;GetDataSourceData&gt;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.&lt;GetData&gt;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.&lt;Generate&gt;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)
---&gt; (Inner Exception #0) System.AggregateException: One or more errors occurred. ---&gt; 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.&lt;GetDataSourceData&gt;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.&lt;GetData&gt;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.&lt;Generate&gt;d__6.MoveNext()
---&gt; (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.&lt;GetDataSourceData&gt;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.&lt;GetData&gt;d__5.MoveNext()&lt;---
&lt;---

 

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&lt;string, object&gt; {
                    ["EsqFilters"] = new Dictionary&lt;string, Filters&gt; {
                    [reportSchemaName] = JsonConvert.DeserializeObject&lt;Filters&gt;(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&lt;Guid&gt;("EmailActivityId") ); //AddActivityUserTask.RecordId);
fileEntity.SetColumnValue("TypeId", new Guid("529BC2F8-0EE0-DF11-971B-001D60E938C6"));//, AttachmentTypeId);
fileEntity.SetColumnValue("Name", Get&lt;string&gt;("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&lt;IReadOnlyDictionary&lt;string, object&gt;&gt; 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&lt;Dictionary&lt;string, object&gt;&gt;();
 
                foreach (var entity in accounts)
                {
                    accountsCollection.Add(new Dictionary&lt;string, object&gt; {
                        ["Name"] = entity.GetTypedColumnValue&lt;string&gt;("Name"),
                        ["Type"] = entity.GetTypedColumnValue&lt;string&gt;("Type")
                    });
                }
                return accountsCollection;
        }
 
        private IEnumerable&lt;IReadOnlyDictionary&lt;string, object&gt;&gt; GetLocalizableStrings(UserConnection userConnection) {
            var localizableStrings = _localizableStringNames.ToDictionary(
                x =&gt; x,
                x =&gt; (object)(new LocalizableString(userConnection.ResourceStorage, _resourceManagerName, $"LocalizableStrings.{x}.Value")).Value);
            return new[] { localizableStrings };
        }
 
        private IEntitySchemaQueryFilterItem ExtractFilterFromParameters(UserConnection userConnection, Guid entitySchemaUId,
                IReadOnlyDictionary&lt;string, object&gt; parameters) {
            var managerItem = userConnection.EntitySchemaManager.GetItemByUId(entitySchemaUId);
            return parameters.ExtractEsqFilterFromReportParameters(userConnection, managerItem.Name) ?? throw new Exception();
        } 
 
        public Task&lt;ReportDataDictionary&gt; GetData(UserConnection userConnection, IReadOnlyDictionary&lt;string, object&gt; 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&lt;string, object&gt; {
                    ["EsqFilters"] = new Dictionary&lt;string, Filters&gt; {
                    [reportSchemaName] = JsonConvert.DeserializeObject&lt;Filters&gt;(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&lt;Guid&gt;("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. ---&gt; System.AggregateException: One or more errors occurred. ---&gt; 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.&lt;GetDataSourceData&gt;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.&lt;GetData&gt;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.&lt;Generate&gt;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)
---&gt; (Inner Exception #0) System.AggregateException: One or more errors occurred. ---&gt; 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.&lt;GetDataSourceData&gt;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.&lt;GetData&gt;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.&lt;Generate&gt;d__6.MoveNext()
---&gt; (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.&lt;GetDataSourceData&gt;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.&lt;GetData&gt;d__5.MoveNext()&lt;---
&lt;---

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}"}

 

my mistake, don't consider this

not applicable

@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

Oscar Dylan,

Thanks Oscar,

 

Have a nice week

Show all comments