Hi,

We have tried to implement Static Code analysis for the creatio codes (both JS, C#)

using SonarQube - Static code analyzing tool. This setup has separate code analyzing

for client and server-side. We could get a successful result on running the client code(JS Part), but not the same in the case of Server code(C#). The main reason we couldn't get results is that in Creatio we get a build over the Tools ->BuildWorkspace which we set in External Tools  (in Terrasoft.Tools.WorkspaceConsole.exe), Ref:  https://academy.creatio.com/documents/technic-sdk/7-16/ide-settings-development but SonarQube works over the MSBuild.exe which gets build over Build Solution in Visual Studio. What is the exact interaction between Workspace Build(External Tools) and MSBuild in respective to creatio? Have an integration of Creatiocode with SonarQube is feasible for C#? Or, Is there any specific static code analyzing tool for creatio?

Like 1

Like

2 comments

Dear Adharsh, 

 

You can build a project in any way needed, you can find the project following this path in installation files: 

Terrasoft.WebApp\Terrasoft.Configuration\Terrasoft.Configuration.Dev.csproj

You can try building this project in a needed way to use SonarQube. 

Unfortunately, there is no specific coded analyzing tool for Creatio.

 

Best regards, 

Dennis 

Dennis Hudson,

Thanks

Show all comments

Hi, 

 

How to develop the functionality of updating multiple selected records using custom button or section action on creatio mobile application side?

 

I have developed the above functionality in the main application (creatio server) side.

 

Please respond to this.

Many thanks.

Like 0

Like

5 comments

Dear Akshit, 

 

You can implement this by creating an action that will display a lookup with multi-select choice, similarly to how it is implemented in the section filters. After that, you would be able to perform some action on chosen records. You can look into how filters in a section are implemented and implement similar functionality. 

Also, you can create an action that will take the filters in the section, send a request to db with those filters, and perform some action with the received records.  You can get the section filter in getFilterPanel method that you can find in the view that you can get from current page controller. 

 

Best regards, 

Dennis 

Hi Dennis Hudson,



Is there any documentation or way to implement custom action on creatio mobile application.

I have already gone through this https://academy.creatio.com/documents/technic-sdkmob/7-16/creatio-development-guide but creating a custom action (creatio mobile application) is not a development case here.



Thanks.

Dear Akshit,

 

Here is a community article on creating custom actions: 

https://community.creatio.com/articles/adding-custom-user-action-mobile-application

 

Best regards, 

Dennis 

Hi Dennis Hudson,

 

I am not able to open this page It says that I am not authorized. Did you know why?

Any other option? 



Thanks.

Dear Akshit, 

 

Unfortunately, I am not aware of any other article on creating custom actions. I've checked this one and it seems to open without an issue. Please try clearing the cache and logging in once again.  

 

Best regards, 

Dennis 

Show all comments

I have asked the same question in past. But it was on cloud environment.

https://community.creatio.com/questions/websocket-connection-error-sales-enterprise-trial

Today I switched my on-site environment to file system mode and these errors are still not going away even after disabling call center settings.

setting changed in web.config - set the filedesignmode to true and usestaticfilecontent to false

Like 0

Like

2 comments
Best reply

Hello,

 

This error message is not related to the telephony and is related to the https setup for the on-site app and the usual case is that the WebSocket connection was setup for 443 port (as it can be seen from the error message in the console where the link is https://localhost/...), but you are logged in and using the application via 450 port. Please review all the settings due to this article https://academy.creatio.com/documents/administration/7-16/switch-creatio-website-http-https#XREF_32303_Web_config and also check the web-sockets using this article https://academy.creatio.com/documents/administration/7-16/set-websockets.

 

Best regards,

Oscar

Hello,

 

This error message is not related to the telephony and is related to the https setup for the on-site app and the usual case is that the WebSocket connection was setup for 443 port (as it can be seen from the error message in the console where the link is https://localhost/...), but you are logged in and using the application via 450 port. Please review all the settings due to this article https://academy.creatio.com/documents/administration/7-16/switch-creatio-website-http-https#XREF_32303_Web_config and also check the web-sockets using this article https://academy.creatio.com/documents/administration/7-16/set-websockets.

 

Best regards,

Oscar

Oscar Dylan,

 

Thanks. I fount out that I needed to change the port connection setting

portForClientConnection="450" in root/Terrasoft.WebApp/Web.config file which I forgot to change.

The issue is resolved now.

 

Thanks

Ramnath

Show all comments

Hi

 

I'm following the Kubernetes tutorial in the Academy to deploy the Exchange service:

https://academy.creatio.com/documents/administration/7-16/deploying-synchronization-service-kubernetes?document=administration#CSH_3

 

I deployed Redis database and ExchangeListener package using Helm.

When I deployed the ExchangeListener package and forwarded the local port to the host I got "Connection Refused" and the service crashed.

Any help! 

PS C:\Windows\system32> helm install --set apiVersion=apps/v1 --set env.host=exchange-listener-redis-master.default.svc.cluster.local --name creatioexchangelistener "C:\Program Files\kubernetes\exchangelistener-0.5.0.tgz"
NAME:   creatioexchangelistener
LAST DEPLOYED: Wed Jun 17 22:23:52 2020
NAMESPACE: default
STATUS: DEPLOYED
 
RESOURCES:
==> v1/ConfigMap
NAME                            DATA  AGE
creatioexchangelistener-worker  2     0s
 
==> v1/Pod(related)
NAME                           READY  STATUS             RESTARTS  AGE
creatioexchangelistener-api-0  0/1    ContainerCreating  0         0s
 
==> v1/Service
NAME                         TYPE       CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE
creatioexchangelistener-api  ClusterIP  10.96.65.102  <none>       80/TCP   0s
 
==> v1/StatefulSet
NAME                         READY  AGE
creatioexchangelistener-api  0/2    0s
 
==> v1beta1/Ingress
NAME                         CLASS   HOSTS           ADDRESS  PORTS  AGE
creatioexchangelistener-api  <none>  test.tscrm.com  80       0s
 
 
NOTES:
1. Get the application URL by running these commands:
 
PS C:\Windows\system32> kubectl port-forward creatioexchangelistener-api-0  8089:80
Forwarding from 127.0.0.1:8089 -> 80
Forwarding from [::1]:8089 -> 80
Handling connection for 8089
Handling connection for 8089
E0617 22:25:06.332296    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:06 socat[53947] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
E0617 22:25:06.332296    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:06 socat[53948] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
Handling connection for 8089
E0617 22:25:06.360263    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:06 socat[53949] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
Handling connection for 8089
Handling connection for 8089
E0617 22:25:06.459266    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:06 socat[53950] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
E0617 22:25:06.464261    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:06 socat[53951] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
Handling connection for 8089
E0617 22:25:06.475264    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:06 socat[53952] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
Handling connection for 8089
Handling connection for 8089
E0617 22:25:11.511131    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:11 socat[54236] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
E0617 22:25:11.513105    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:11 socat[54237] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused
Handling connection for 8089
E0617 22:25:11.527104    9584 portforward.go:400] an error occurred forwarding 8089 -> 80: error forwarding port 80 to pod ec2e3c86d81d27efeb0ff525ce5898f1ac78a2b7c1358837c3da569965831451, uid : exit status 1: 2020/06/17 20:25:11 socat[54238] E connect(5, AF=2 127.0.0.1:80, 16): Connection refused

 

 

Thank you

Mohamed

Like 0

Like

3 comments

Hello Mohamed,

 

Seems that your 8089 has no process that listens to this port so that's why you cannot forward the listener to this port. Try running this command:

 

netstat -abn | findstr "LISTENING" | findstr "your host IP-address" | findstr "8089"

 

and check if this command shows the result.

 

Then try running

 

kubectl -n default exec -it creatioexchangelistener curl -v host_IP_address:8089

 

and let's check the result then (we will need to run kubectl describe pods creatioexchangelistener)

 

Best regards,

Oscar

Hi Oscar

Can you please provide me a YAML file to deploy the pod (Redis + Exchange Listener + Expose Service Address)?

 

Thank you

Mohamed

Mohamed Ouederni,

Hello Mohamed,

 

We don't have a separate YAML file for this proposes and Redis should be installed separately. All available .yaml files can be found in the exchangelistener-0.6.9.tgz file that is downloaded via this link 

 

http://ftp.bpmonline.com/support/downloads/Exchangelistener/exchangelis…

 

Best regards,

Oscar

Show all comments

Hello all,

 

I have been working on setting up Agent Desktop to be used for processing queues of incoming emails. Though it lists each email in queue as separate entities even if they are part of an email thread. Is there a way that I could filter the queue to show only the most recent email in a thread?

 

 

I know that Creatio is able to recognize threads through the related emails detail but I'm not sure how to adapt it for use with the queue.

Like 0

Like

1 comments

Dear Kevin,

 

Creatio can sort emails by threads via Cases section - each email will create new case unless this email is somehow connected to already an existing chain of emails (by case number or thread). You can use cases instead of emails for your queues. 

 

Best regards,

Angela

Show all comments

Hello

I'm deploying Creatio Exchange Listener for my developing environment. 

I'm following this academy guide:

https://academy.creatio.com/documents/administration/7-16/deploying-synchronization-service-docker?document=administration#CSH_4

I got this error message when I created the listener container:

PS C:\Users\medouederni-pc> docker run -p 8808:80 --env ExchangeListenerRedisHost=172.17.0.2 --env ExchangeListenerRedisDatabase=0 --env PodName=CreatioExchangeListener  --name CreatioExchangeListener bpmonline/exchangelistener:0.5.0                                                                                                                               Unable to find image 'bpmonline/exchangelistener:0.5.0' locally
0.5.0: Pulling from bpmonline/exchangelistener
804555ee0376: Pull complete                                                                                                                                                         970251047358: Pull complete                                                                                                                                                         f3d4c41a4fd1: Pull complete                                                                                                                                                         1cccda79a5f9: Pull complete                                                                                                                                                         a02b6037fa5e: Pull complete                                                                                                                                                         5a51c6fa0bad: Pull complete                                                                                                                                                         Digest: sha256:bb4e356161faade8783fbb86a820f96b837222a11dce7311617b4236777c49c4
Status: Downloaded newer image for bpmonline/exchangelistener:0.5.0
log4net:ERROR Could not create Appender [ExchangeListenerGelfAmqpAppender] of type [Gelf4Net.Appender.GelfAmqpAppender, Gelf4Net.AmqpAppender]. Reported error follows.
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> RabbitMQ.Client.Exceptions.ConnectFailureException: Connection failed ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: No such device or address
   at System.Net.Dns.InternalGetHostByName(String hostName)
   at System.Net.Dns.ResolveCallback(Object context)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult)
   at System.Net.Dns.EndGetHostAddresses(IAsyncResult asyncResult)
   at System.Net.Dns.<>c.<GetHostAddressesAsync>b__25_1(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at RabbitMQ.Client.TcpClientAdapter.ConnectAsync(String host, Int32 port)
   at RabbitMQ.Client.Impl.TaskExtensions.TimeoutAfter(Task task, Int32 millisecondsTimeout)
   at RabbitMQ.Client.Impl.SocketFrameHandler.Connect(ITcpClient socket, AmqpTcpEndpoint endpoint, Int32 timeout)
   --- End of inner exception stack trace ---
   at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, Func`2 selector)
   at RabbitMQ.Client.Framing.Impl.AutorecoveringConnection.Init(IEndpointResolver endpoints)
   at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
   --- End of inner exception stack trace ---
   at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
   at Gelf4Net.Appender.GelfAmqpAppender.InitializeConnectionFactory()
   at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(XmlElement appenderElement)
log4net:ERROR Appender named [ExchangeListenerGelfAmqpAppender] not found.
Hosting environment: Production
Content root path: /app
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.

 

I tested the service and its working:

{
  "ServiceStatus": "Started",
  "version": "0.5.0",
  "connections": {}
}

I made the creatio configuration side:

https://academy.creatio.com/documents/administration/7-16/set-exchange-listener-service-side-creatio?document=administration#CSH_5 

Now, I can send emails but when I try to sync the mailbox I got this error:

[ExchangeListener.Subscription.ServiceFactory] 2020-06-16 11:57:47,885 [39] INFO : [18e30f9f-a1e7-4718-9cd1-e16577924fa2] End processing EmailMessage with id '31'.
[ExchangeListener.DataSend.EventDataSender] 2020-06-16 11:57:47,886 [39] DEBUG:  EventDataSender sending request to http://localhost:7700/0/ServiceModel/ExchangeListenerService.svc/ProcessFullEmail
[ExchangeListener.Email.Events.EmailEventProcessor] 2020-06-16 11:57:47,890 [42] ERROR: [18e30f9f-a1e7-4718-9cd1-e16577924fa2] [06/16/2020 11:57:47] Mailbox creatio123456789@gmail.com: error sending emails ['<71fe88dc-0198-4eca-8cc9-a8771976b3ab@gmail.com>' in folder ,'<71fe88dc-0198-4eca-8cc9-a8771976b3ab@gmail.com>' in folder ] to http://localhost:7700/0/ServiceModel/ExchangeListenerService.svc/NewEmail.
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.CurlException: Couldn't connect to server
   at System.Net.Http.CurlHandler.ThrowIfCURLEError(CURLcode error)
   at System.Net.Http.CurlHandler.MultiAgent.FinishRequest(StrongToWeakReference`1 easyWrapper, CURLcode messageResult)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at ExchangeListener.DataSend.EventClient.PostAsync(String requestUri, HttpContent content) in /src/src/ExchangeListener/DataSend/EventClient.cs:line 42
   at ExchangeListener.DataSend.EventDataSender.Send(String url, Object data) in /src/src/ExchangeListener/DataSend/EventDataSender.cs:line 85
   at ExchangeListener.DataSend.EventDataSender.SendEmail(Object data, SynchronizationCredentials credentials) in /src/src/ExchangeListener/DataSend/EventDataSender.cs:line 95
   at ExchangeListener.Email.Events.BaseEventProcessor.SendRequestObject(Object requstDtoObject, SynchronizationCredentials credentials) in /src/src/ExchangeListener/Email/Events/BaseEventProcessor.cs:line 149
   at ExchangeListener.Email.Events.EmailEventProcessor.SendEmailMessagesToBpm(List`1 messages, SynchronizationCredentials credentials) in /src/src/ExchangeListener/Email/Events/EmailEventProcessor.cs:line 66
[ExchangeListener.Imap.Subscription.ResentEmailsSynchronization] 2020-06-16 11:57:47,892 [39] INFO : [18e30f9f-a1e7-4718-9cd1-e16577924fa2] Email ids sended to bpm.
[ExchangeListener.Imap.Subscription.ResentEmailsSynchronization] 2020-06-16 11:57:47,892 [39] INFO : [18e30f9f-a1e7-4718-9cd1-e16577924fa2] Synchronization session for creatio123456789@gmail.com ended.

 

Thank you

Mohamed

Like 1

Like

4 comments

Hello Mohamed,

 

This is strange that your Exchange service returns this:

{
  "ServiceStatus": "Started",
  "version": "0.5.0",
  "connections": {}
}

even after the mailbox was used for emails sending. Please go to the mailbox settings and apply any changes there and see if you see something similar to this after that:

So you see the record about your mailbox there. Or try re-adding your mailbox to the app from scratch.

 

The error message you receive states that ExcahgneListener services couldn't establish the connection to the mail server. Please use this command:

 

ping mail_server_ip_address

 

from the ExchangeListener server so to test the connectivity. Also please check if the "The URL of the Exchange event processing service in Creatio" system setting has the value of https://mycreatio.com/0/ServiceModel/ExchangeListenerService.svc/NewEmail.

 

I've deployed the service on my end using the Academy instructions and everything is working properly so it should work as expected on your end and the problem can be in the connection between the email server and the ExchagneListener service.

 

Best regards,

Oscar

Dear Oscar Dylan,

 

Problem solved! It was a networking issue in Docker for Windows.

 

For everyone who may have this issue, you have to use host.docker.internal variable as your host IP address.

More information: https://docs.docker.com/docker-for-windows/networking/

Hi Mohamed,

 

I am running into the same issue for an on-prem dev image.  You indicated the issue was resolved via "For everyone who may have this issue, you have to use host.docker.internal variable as your host IP address."  Could you elaborate on that?  I read the article on docker for windows networking but wasn't clear on how you implemented the resolution.  Thanks so much :)

 

Update - never mind. Figured it out.  Using host.docker.internal in place of localhost in all cases. This resolves everything and ExchangeListener is working for both syncing and sending.  Thanks!!  :)

Hi Mohamed,

Can you help me with following questions:

Did you use OS setup file or pull request for installing Redis?

How did you set up redis host address?

Where exactly we use "host.docker.internal" variable. The link you shared doesnt seem to work.

 

Thank you

Gokul

Show all comments

Hello,

 

I want to enable a "Completed & Follow" status en activities, in the process to treat this activity status I want to enable the possibility to create a Zoom meeting in case of, but on the Activity table i didn't found the "Create Zoom Meeting" field, how can I did it?

 

I found a "Zoom Meeting" but have no idea how to complete it, and didn't found how to relate with Activity table.

 

Thanks in advance

Like 0

Like

4 comments
Best reply

Hello Julio,



We recommend you to log out and log back in the application after you add the 'ZoomIntegration' package to the dependencies.



The 'Create Zoom Meeting' field should become available for the 'Activity' table in the 'Add data' process element after you do this. 

 

Hope this helps.

Hi Julio, 

 

Are you trying to configure your business process in the "Custom" package or any other? 

Hello S.Kobizka,

 

In another Package, I add the ZoomIntegration package to the dependencies, see at http://prntscr.com/t0snjq

Hello Julio,



We recommend you to log out and log back in the application after you add the 'ZoomIntegration' package to the dependencies.



The 'Create Zoom Meeting' field should become available for the 'Activity' table in the 'Add data' process element after you do this. 

 

Hope this helps.

S.Kobizka,

Thanks, now works, I'm sure I will logout & login and also clear the cache, but today I did it again and have the field, thank you very much!

Show all comments

Hello all,

 

I am trying to use the show on map function from the contact section page and add it to the actions on the contact record page.

I have added the function to the page schema and added it to the actions menu. However, when I load the page, the button works and displays the map but it doesn't display the caption string on the button. 

Though oddly, when I reload the page, the string appears but the map then won't load.

 

What could be causing this?

Like 0

Like

3 comments

Hello Kevin,

 

Caption is not displayed since once the edit page is reviewed in combined mode then localizable values are being received from the section schema. To resolve this problem you need to:

 

1) Add the same localizable value to the ContactSectionV2 schema as on the ContactPageV2 schema

2) Add this part of code to the contact page schema:

 

define("ContactPageV2",["ContactPageV2Resources", "MapsHelper", "MapsUtilities"],

        function(resources, MapsHelper, MapsUtilities){

    return{

        entitySchemaName:"Contact",

        modules:/**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,

        messages: {

            "GetMapsConfig": {

                mode: Terrasoft.MessageMode.PTP,

                direction: Terrasoft.MessageDirectionType.SUBSCRIBE

            }

        },

        businessRules:/**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,

        methods:{

            getActions: function() {

                var actionMenuItems = this.callParent(arguments);

                actionMenuItems.addItem(this.getButtonMenuItem({

                    "Tag": "showOnMap",

                    "Click": {"bindTo": "openShowOnMap"},

                    "Caption": {"bindTo": "Resources.Strings.ShowOnMapCaption"},

                    "Visible": true

                }));

            

                return actionMenuItems;

            },

            showOnMap: function(schemaName, items, callback) {

                var config = config || {};

                items = items || this.getesqedItems();

                var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {

                    rootSchemaName: "ContactAddress"

                });

                esq.addColumn(schemaName + ".Name");

                esq.addColumn("AddressType");

                esq.addColumn("Address");

                esq.addColumn("City");

                esq.addColumn("Region");

                esq.addColumn("Country");

                if(config.columnNameLongitude){

                    esq.addColumn(config.columnNameLongitude);

                }

                if(config.columnNameLatitude){

                    esq.addColumn(config.columnNameLatitude);

                }

                esq.filters.addItem(this.Terrasoft.createColumnInFilterWithParameters(schemaName, items));

                esq.getEntityCollection(function(result) {

                    var addresses = result.collection;

                    if (result.success && !addresses.isEmpty()) {

                        var mapsData = [];

                        var mapsConfig = {

                            mapsData: mapsData

                        };

                        addresses.each(function(item) {

                            var addressType = item.get("AddressType").displayValue;

                            var address = MapsHelper.getFullAddress.call(item);

                            var content = this.Ext.String.format("<h2>{0}</h2><div>{1}</div>", addressType, address);

                            var dataItem = {

                                caption: addressType,

                                content: content,

                                address: address,

                                gpsE: item.get(config.columnNameLongitude),

                                gpsN: item.get(config.columnNameLatitude)

                            };

                            mapsData.push(dataItem);

                        }, this);

                        callback.call(this, mapsConfig);

                    } else {

                        this.showInformationDialog(resources.localizableStrings.EmptyAddressDetailMessage);

                    }

                }, this);

            },

            openShowOnMap: function() {

                var items = [];

                items.push(this.get("Id"));

                this.showOnMap.call(this, this.entitySchemaName, items, function(mapsConfig) {

                    MapsUtilities.open({

                        scope: this,

                        mapsConfig: mapsConfig

                    });

                });

            }

}

 

3) Add the EmptyAddressDetailMessage localizable string to the ContactPageV2 schema

 

Best regards,

Oscar

Dear Oscar,

I m trying to display the adresse on the map, but when i do the final step:

callback.call(this, mapsConfig);

i ve got the error:

message: Uncaught Error: Map container is already initialized.

 

Here's my code :

define("UsrNearestAccountsf7482dd9Page", ["MapsHelper", "MapsUtilities"], function(MapsHelper, MapsUtilities) {
	return {
		entitySchemaName: "UsrNearestAccounts",
		attributes: {},
        messages: {
            "GetMapsConfig": {
                mode: Terrasoft.MessageMode.PTP,
                direction: Terrasoft.MessageDirectionType.SUBSCRIBE
            }
        },
		modules: /**SCHEMA_MODULES*/{
			"Indicator7c02186a-07da-467a-90ed-cf5286772816": {
				"moduleId": "Indicator7c02186a-07da-467a-90ed-cf5286772816",
				"moduleName": "CardWidgetModule",
				"config": {
					"parameters": {
						"viewModelConfig": {
							"widgetKey": "Indicator7c02186a-07da-467a-90ed-cf5286772816",
							"recordId": "cb62f87b-52b6-4482-8283-344ec2f94e1a",
							"primaryColumnValue": {
								"getValueMethod": "getPrimaryColumnValue"
							}
						}
					}
				}
			},
			"Indicator32f96c54-6fbf-45be-b641-95268da60efc": {
				"moduleId": "Indicator32f96c54-6fbf-45be-b641-95268da60efc",
				"moduleName": "CardWidgetModule",
				"config": {
					"parameters": {
						"viewModelConfig": {
							"widgetKey": "Indicator32f96c54-6fbf-45be-b641-95268da60efc",
							"recordId": "cb62f87b-52b6-4482-8283-344ec2f94e1a",
							"primaryColumnValue": {
								"getValueMethod": "getPrimaryColumnValue"
							}
						}
					}
				}
			}
		}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		methods: {
            getActions: function() {
                var actionMenuItems = this.callParent(arguments);
                actionMenuItems.addItem(this.getButtonMenuItem({
                    "Tag": "showOnMap",
                    "Click": {"bindTo": "openShowOnMap"},
                    "Caption": "openShowOnMap",
                    "Visible": true
                }));
 
                return actionMenuItems;
            },
            openShowOnMap: function() {
                var items = [];
                items.push(this.get("NearAccount"));
                this.showOnMap.call(this, "Account", items, function(mapsConfig) {
                    MapsUtilities.open({
                        scope: this,
                        mapsConfig: mapsConfig
                    });
                });
            },
 
            showOnMap: function(schemaName, items, callback) {
 
                var config = config || {};
                items = items || this.getesqedItems();
 
                var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "AccountAddress"
                });
 
                esq.addColumn("AddressType");
                esq.addColumn("Address");
                esq.addColumn("City");
                esq.addColumn("Region");
                esq.addColumn("Country");
                esq.addColumn("GPSE");
                esq.addColumn("GPSN");
 
                esq.filters.addItem(this.Terrasoft.createColumnInFilterWithParameters(schemaName, items));
                esq.getEntityCollection(function(result) {
                    var addresses = result.collection;
                    if (result.success &amp;&amp; !addresses.isEmpty()) {
 
                        var mapsData = [];
                        var mapsConfig = {
                            mapsData: mapsData
                        };
 
                        addresses.each(function(item) {
                            this.console.log('item: '+this.print_r(item));
                            var addressType = item.get("AddressType").displayValue;
                            var gpsE = item.get("GPSE");
                            var gpsN = item.get("GPSN");
                            var address = MapsHelper.getFullAddress.call(item);
                            var content = this.Ext.String.format("&lt;h2&gt;{0}&lt;/h2&gt;&lt;div&gt;{1}&lt;/div&gt;", addressType, address);
                            var dataItem = {
                                caption: addressType,
                                content: content,
                                address: address,
                                gpsE: gpsE,
                                gpsN: gpsN
                            };
 
                            this.console.log('dataItem:'+this.print_r(dataItem));
                            mapsData.push(dataItem);
 
                        }, this);
 
                        this.console.log('mapsConfig:'+this.print_r(mapsConfig));
                        callback.call(this, mapsConfig);
 
                    } else {
                        this.showInformationDialog("EmptyAddressDetailMessage");
                    }
                }, this);
            }, 
             print_r: function(obj) { //debug
              let cache = [];
              let str = JSON.stringify(obj, function(key, value) {
                if (typeof value === "object" &amp;&amp; value !== null) {
                  if (cache.indexOf(value) !== -1) {
                    // Référence circulaire trouvée
                    return;
                  }
                  // enregistrement de la valeur dans la collection
                  cache.push(value);
                }
                return value;
              });
              cache = null; // reset
              return str;
            }          
        },
		dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "NearAccountaf54e816-a480-49e1-b827-362d9259418c",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 0,
						"layoutName": "Header"
					},
					"bindTo": "NearAccount"
				},
				"parentName": "Header",
				"propertyName": "items",
				"index": 0
			},
			{
				"operation": "insert",
				"name": "NearAddress0e195398-6b7e-4bed-81c7-4250803f37dd",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 1,
						"layoutName": "Header"
					},
					"bindTo": "NearAddress"
				},
				"parentName": "Header",
				"propertyName": "items",
				"index": 1
			},
			{
				"operation": "insert",
				"name": "Distanced9f7c441-62cf-4789-bad3-d9452054b13f",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 2,
						"layoutName": "Header"
					},
					"bindTo": "Distance"
				},
				"parentName": "Header",
				"propertyName": "items",
				"index": 2
			},
			{
				"operation": "merge",
				"name": "ChangesHistoryTab",
				"values": {
					"order": 0
				}
			},
			{
				"operation": "merge",
				"name": "MapTab",
				"values": {
					"order": 1
				}
			},
			{
				"operation": "merge",
				"name": "ESNTab",
				"values": {
					"order": 2
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

 

Here is the screenshot:

screenShot

 

I retrieve the address and coordinates correctly but I cannot display the marker on the map

 

Do you have an idea why i ve got this error ?

 

Thank you,

Nicolas

 

LÉZORAY Nicolas,

 

I change BaseModulePageWithMap to BaseModulePageV2 on my object page nad now it works !

 

thank you !

Show all comments

I implemented the auto numbering logic in client side. I am noticing that the Code is generated when the record is added manually. But not when record is added via a business process.

1. Record created by business process has empty code value

2. Created Manually

3. Business process

 

Like 0

Like

9 comments

Hello,

 

There are several ways of implementing numeration for records. Can you please specify how the numeration was added? Numeration functionality depends on how it was added. 

 

Best regards,

Angela

Angela Reyes,

 

I followed the client side implementation given in the article (Link). I created the code mask and last number system settings and added the code given in the article and changed the column name to UsrName - (Application Number).

 

Thanks 

Ramnath

RAMNATH SHARMA,

If you want to add records via business process it is better to use an example described in CASE IMPLEMENTATION ALGORITHM: SERVER-SIDE part of the link. This is happening because the code that should number records is not triggered when it is created via a process. Server-side implementation should fix it. 

 

Best regards,

Angela

Angela Reyes,

 

I have tried the server side implementation algorithm. But it does not seem to work right now. It also does not show any error while saving and publishing the object. There is no error on console in browser while adding a record manually.

I tried to see if I have missed anything but could not find any mistake. I can share screenshots of changes I have made in the object.

 

Thanks 

Ramnath

RAMNATH SHARMA,

 

Yes please provide us with screenshots of all settings you've set on your side so to create the auto-numeration.

 

Best regards,

Oscar

Oscar Dylan,

 

Here are the screen shots

1. Object in which I am implementing numeration - https://prntscr.com/synbnw

2. Column name - https://prntscr.com/synbo3

3. Event handler - https://prntscr.com/syncls

4. Process-

 a. Signal - https://prntscr.com/syncpl

 b. Conditional flow - https://prntscr.com/syncq1

 c. Script task 1 - https://prntscr.com/synd3h

 d. User task - https://prntscr.com/syndj2, user task code - https://prntscr.com/syndlq

 e. Script task 2 - https://prntscr.com/syndo8

 

Let me know if links are not working as I am not much familiar with Lightshot. 

 

Thanks 

Ramnath

 

Hello RAMNATH,

 

In this case you need to implement the Server Side logic, also when you generate records from some external integration, the Client side just works when the record is created inside the section.

 

Kinds Regards from Chile!

Julio.Falcon_Nodos,

I have tried the server side implementation but it does not work.

You can see the details of settings in the images I have shared above.

Regards

Ramnath

RAMNATH SHARMA,

If the process is added to "Before Record Adding" then it should trigger for processes. If this does not happen to try to debug this by using server-code debugging: 

https://academy.creatio.com/documents/technic-sdk/7-16/server-code-debugging

Show all comments

Hi

 

I can create an iFrame inside a page / tab.

I can create a button to do things.

 

How can I make the button open floating page in which I can show my iFrame ?

 

And please do not refer me to this article: https://community.creatio.com/articles/add-iframe-modalbox , it is not working.

 

Thanks

Like 0

Like

7 comments

Hello Oren,

 

Could you please provide detailed answers to the following questions: 

1) What is the current version of your system? 

2) What exactly is not working according to the article?

 

Thank you in advance!

Olga. 

Olga Avis,

 

Hi Olga

 

Thanks for trying to help.

 

The three callings to the Sandbox Subscribe inside the subscribeSandboxEvents function are preventing the page from working. They are causing error.

 

I guess there are some parameters inside such as 

 

IntEntitySchemaName,

IntRelatedSchemasDetail,

IntUploadFileClick

 

That needs to be replaced with something unclear.

 

 

Hello Oren,

 

Thank you for your reply! 

 

Could you please provide a screenshot of the developer console of what kind of error you exactly faced?

Please, do not hesitate to provide as many details as possible.

Also, it will be useful for us to know the current version of your system.

 

Thank you beforehand!

Olga. 

Olga Avis,

Hi Olga

 

Just to make sure I am not mistaken.

On stage 2 in the article, creating IntDonateModalPage, it says to create a page. 

Should I create this page as a "Replacing Client Module" ?

And if so, what is the parrent object ?

 

Anwering to your question.

 

These lines:

 

this.sandbox.subscribe("GetMasterEntitySchema", function() {
    return this.get("IntEntitySchemaName");
    }, this, [this.getDetailId("IntRelatedSchemasDetail") + "_DetailModalBox"]);
this.sandbox.subscribe("IntUploadFileClick", this.onFilesSelected, this, [this.sandbox.id]);
this.sandbox.subscribe("GetModuleInfo", this.getDonateModalBoxConfig, this,
    [this.getDonateModalBoxId()]);

 

Cause this error on the console:

 

 message: Uncaught Terrasoft.UnsupportedTypeException: Message GetMasterEntitySchema is not defined in CardModuleV2 (CardModuleV2_aca24ae1-319c-4e8c-94b5-a7ca7bd5cc07_UsrApplications1Page) module 

 

 

Thanks

Hello Oren,

 

Here is a detailed instruction on how to create an Iframe module:

 

1. Create an Iframe module (Module)

(GlbIframeControl)

 

Ext.define("Terrasoft.controls.GlbIframeControl", {

            extend: "Terrasoft.Component",

            alternateClassName: "Terrasoft.GlbIframeControl",

            tpl: [

                        /*jshint quotmark:true */

                        '<iframe id="{id}" src="{src}" class="{wrapClass}"></iframe>'

                        /*jshint quotmark:false */

            ],

            id: null,

            src: null,//"https://academy.terrasoft.ru/",

            wrapClass: ["glb-iframe"],

            setIframeSrc: function(value) {

                        value = value || "";

                        if (this.src !== value) {

                                    this.src = value;

                                    this.safeRerender();

                        }

            },

            init: function() {

                        this.callParent(arguments);

                        var selectors = this.selectors = this.selectors || {};

                        selectors.wrapEl = selectors.wrapEl || "#" + this.id;

            },

            LoadPageBySrc: function() {

                        var iframe = this.getWrapEl();

                        iframe.dom.src = this.src;

            },

            onAfterRender: function() {

                        this.callParent(arguments);

                        this.LoadPageBySrc();

            },

            getBindConfig: function() {

                        var bindConfig = this.callParent(arguments);

                        return Ext.apply(bindConfig, {

                                    src: {

                                                changeMethod: "setIframeSrc"

                                    }

                        });

            },

            getTplData: function() {

                        var tplData = this.callParent(arguments);

                        return Ext.apply(tplData, {

                                    src: this.src,

                                    wrapClass: this.wrapClass

                        });

            }

});

In less tab create your css class

.glb-iframe {

            width: 643px;

            height: 400px;

}

 

2. Create a page that will contain Iframe and will be displayed in Modal Box

(GlbIframeModalPage)

 

Parent object: Base modal box page schema ( NUI )

 

define("GlbIframeModalPage", ["GlbIframeControl", "css!GlbIframeControl"], function() {

    return {

        attributes: {

            "UsrLink": {

                dataValueType: Terrasoft.DataValueType.TEXT,

                type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN

            }

        },

        messages: {

        },

        methods: {

            init: function(callback, scope) {

//get system settings value which is responsible for the site link

                this.callParent([function() {

                                                            var sysSettingsNameArray = ["UsrLink"];

                                                            Terrasoft.SysSettings.querySysSettings(sysSettingsNameArray, function(values) {

                                                                        this.set("UsrLink", values.UsrLink);

                                                                        callback.call(scope);

                                                            }, this);

                                                }, this]);

            },

                                    getSource: function() {

                                                return this.get("UsrLink");

                                    },

            getHeader: function() {

                return this.get("Resources.Strings.PageCaption");

            },

            onRender: function() {

                this.callParent(arguments);

                var moduleInfo = this.get("moduleInfo");

                var boxSizes = moduleInfo.modalBoxSize;

                var width = boxSizes.width;

                var height = boxSizes.height;

                this.updateSize(width, height);

            }

        },

        //Insert already existed Iframe

        diff: [

            {

                "operation": "insert",

                "parentName": "CardContentContainer",

                "propertyName": "items",

                "name": "IntDonateIframe",

                "values": {

                    "generator": function() {

                        return {

                            "className": "Terrasoft.GlbIframeControl",

//set the link

                            "src": {"bindTo": "getSource"}

                        };

                    }

                }

            },

            {

                "operation": "insert",

                "name": "MyContainer",

                "propertyName": "items",

                "values": {

                    "itemType": Terrasoft.ViewItemType.CONTAINER,

                    "items": []

                }

            },

            {

                "operation": "insert",

                "parentName": "MyContainer",

                "propertyName": "items",

                "name": "MyGridContainer",

                "values": {

                    "itemType": Terrasoft.ViewItemType.GRID_LAYOUT,

                    "items": []

                }

            },

            {

                "operation": "insert",

                "parentName": "MyGridContainer",

                "propertyName": "items",

                "name": "TestText",

                "values": {

                    "bindTo": "UsrLink",

                    "caption": "Test text",

                    "layout": {"column": 0, "row": 0, "colSpan": 10}

                }

            }

        ]

    };

});

ADD localizable string PageCaption

 

3. Insert a button on a page.

 

After button click, Modal Dialog with Iframe should appear. 

define("UsrCarPage", ["UsrCarPageResources","MaskHelper"], function(resources, MaskHelper) {

            return {

                        entitySchemaName: "UsrCarSection",

                        messages: {

                                    "GetModuleInfo": {

                                                direction: Terrasoft.MessageDirectionType.SUBSCRIBE,

                                                mode: Terrasoft.MessageMode.PTP

                                    }

                        },

                        attributes: {

                        },

                        modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,

                        details: /**SCHEMA_DETAILS*/{

                        }/**SCHEMA_DETAILS*/,

                        businessRules: /**SCHEMA_BUSINESS_RULES*/{

                        }/**SCHEMA_BUSINESS_RULES*/,

                        methods: {

                        subscribeSandboxEvents: function() {

                this.callParent(arguments);

                this.sandbox.subscribe("GetModuleInfo", this.getDonateModalBoxConfig, this,

                    [this.getDonateModalBoxId()]);

            },

                            donateButtonClick: function() {

                this.sandbox.loadModule("ModalBoxSchemaModule", {

                    id: this.getDonateModalBoxId()

                });

            },

            getDonateModalBoxConfig: function() {

                return {

                    "schemaName": "GlbIframeModalPage",

                    "modalBoxSize": {

                        "width": "643px",

                        "height": "400px"

                    }

                };

            },

            getDonateModalBoxId: function() {

                return this.sandbox.id + "_DonateModalBox";

            }

                        },

                        dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,

                        diff: /**SCHEMA_DIFF*/[

                                    {

                "operation": "insert",

                "name": "DonateButton",

                "values": {

                      "layout": {

                                                                        "colSpan": 6,

                                                                        "rowSpan": 1,

                                                                        "column": 18,

                                                                        "row": 1,

                                                                        "layoutName": "Header"

                                                            },

                    "itemType": Terrasoft.ViewItemType.BUTTON,

                    "style": Terrasoft.controls.ButtonEnums.style.RED,

                    "caption": {

                        "bindTo": "Resources.Strings.DonateButton"

                    },

                    "click": {

                        "bindTo": "donateButtonClick"

                    }

                },

                "parentName": "Header",

                "propertyName": "items",

                "index": 1

            }

            ]/**SCHEMA_DIFF*/

    };

});

 

Add localizable string

 

 

Please, let us know in case any additional information is required.

 

Best regards,

Olga.

Olga Avis,

 

Thanks Olga.

 

Did all according to your instructions but the button is not responding at all.

 

Maybe I should fix the getDonateModalBoxId function ?

 

Like this,

 

            getDonateModalBoxId: function() {

                

                return this.sandbox.id + "_GlbIframeModalPage";;

            },

When GlbIframeModalPage stands for the name of the page instead of  DonateModalBox

 

 

Hello Oren,

 

Thank you for your reply!

 

Unfortunately, there is not enough information to provide you with a proper solution. Could you please send your request with a detailed description of the issue to the support team (support@creatio.com) and your personal Creatio manager?

 

Thank you in advance.

Olga. 

Show all comments