How do I implement this example as a module?

 

Now I wrote like this: 

Ext.define("HmbCapturizePhotoModule", [], function() {
    Ext.define("Terrasoft.configuration.HmbCapturizePhotoModule", {
        extend: "Terrasoft.BaseModule",
        alternateClassName: "Terrasoft.HmbCapturizePhotoModule",
 
        init: function() {
            this.callParent(arguments);
        },
 
        render: function(renderTo) {
            this.callParent(arguments);
            var config = this.generateConfig();
            Ext.create(config, renderTo);
        },
 
        generateConfig: function() {
            var width = 750;
            var height = 500;
            var video;
 
            return {
                xtype: "panel",
                title: "Сделать фото клиента",
                height: height,
                width: width,
                draggable: true,
                closable: true,
                floating: true,
                layout: {
                    type: "vbox",
                    pack: "center",
                    align: "stretch"
                },
                items: [{
                    html: "<video id='video'></video>",
                    flex: 1,
                    listeners: {
                        afterrender: function() {
                            video = document.getElementById("video");
                        }
                    }
                }],
                bbar: [{
                    xtype: "button",
                    text: "Запустить камеру",
                    itemId: "startbutton",
                    enableToggle: true,
                    toggleHandler: function(btn, state) {
                        var streaming = false;
                        var stream;
                        if (state) {
                            navigator.mediaDevices.getUserMedia({ video: true, audio: false })
                                .then(function(stream) {
                                    stream = stream;
                                    video.srcObject = stream;
                                    video.play();
                                })
                                .catch(function(err) {
                                    window.console.error("An error occurred: " + err);
                                });
                            video.addEventListener("canplay", function(ev) {
                                if (!streaming) {
                                    height = video.videoHeight / (video.videoWidth / width);
                                    if (isNaN(height)) {
                                        height = width / (4 / 3);
                                    }
                                    video.setAttribute("width", width);
                                    video.setAttribute("height", height);
                                    streaming = true;
                                }
                            }, false);
                        } else {
                            video.pause();
                            video.src = "";
                            if (stream) {
                                stream.getTracks().forEach(function(track) {
                                    track.stop();
                                });
                            }
                            video.srcObject = null;
                        }
                        this.ownerCt.down("#takePhoto").setDisabled(!state);
                    }
                }, {
                    xtype: "button",
                    text: "Сделать снимок",
                    disabled: true,
                    itemId: "takePhoto",
                    handler: function() {
                        var canvas = document.createElement("canvas");
                        canvas.width = width;
                        canvas.height = height;
                        var context = canvas.getContext("2d");
                        context.drawImage(video, 0, 0, width, height);
 
                        var imageSrc = canvas.toDataURL("image/png");
                        Terrasoft.utils.log(imageSrc);
                        canvas = null;
                    }
                }]
            };
        }
    });
 
    return Terrasoft.HmbCapturizePhotoModule;
});

 

Like 0

Like

1 comments

I made a separate mixin: 



 

define("CameraPageMixin", [], function() { 
    Ext.define("Terrasoft.configuration.mixins.CameraPageMixin", {
        alternateClassName: "Terrasoft.CameraPageMixin",
 
		afterRender: function() {
            this.callParent(arguments);
            this.webcamStarted = false;
        },
 
	    videoWidth: 500,
	    videoHeight: 380,
	    videoStream: null,
	    containerId: "WebCamModuleContainer",
	    photoContainerId: "PhotoModuleContainer",
 
	    openWebCamClick: function() {
	           try {
	               var videoElement = document.createElement("video");
	               videoElement.setAttribute("autoplay", "true");
	               videoElement.width = this.videoWidth;
	               videoElement.height = this.videoHeight;
 
	               navigator.mediaDevices.getUserMedia({ video: true })
	                   .then(function(stream) {
	                       videoElement.srcObject = stream;
	                       this.videoStream = stream;
 
	                     var container = this.Ext.get(this.containerId);
	                     if (container) {
	                          container.dom.appendChild(videoElement);
	                          this.webcamStarted = true;
	                      } else {
	                          window.console.error("Ошибка: элемент с идентификатором " 
	                          + this.containerId + " не найден в DOM.");
	                }
	                   }.bind(this))
	                   .catch(function(error) {
	                       window.console.error("Ошибка при получении доступа к веб-камере:", error);
	                   }); 
	           } catch (e) {
	                 window.console.error("Произошла ошибка при инициализации веб-камеры:", e);
	           }
	    },
 
	    takePhoto: function() {
	        var videoElement = document.querySelector("video");
	        if (videoElement.srcObject) {
	            var canvas = document.createElement("canvas");
	            canvas.width = this.videoWidth;
	            canvas.height = this.videoHeight;
	            var context = canvas.getContext("2d");
	            context.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
 
	            var photoData = canvas.toDataURL("image/png");
 
	            this.closeWebCamAndRemoveContainer();
	            this.showModalWindow();
 
	        }
	    },
	    closeWebCamAndRemoveContainer: function() {
	        if (this.videoStream) {
	            this.videoStream.getTracks().forEach(function(track) {
	                track.stop();
	            });
	        }
	        var container = this.Ext.get(this.containerId);
	         if (container) {
	             container.dom.remove();
	         }
 
	    },
	    showModalWindow: function() {
	        this.showConfirmationDialog("Не пройдена по техническим причинам?", 
	            this.showModalCallback, 
	            [this.Terrasoft.MessageBoxButtons.NO.returnCode, this.Terrasoft.MessageBoxButtons.YES.returnCode], 
	            null);
	    },
 
	    showModalCallback: function(returnCode) {
	        if (returnCode === this.Terrasoft.MessageBoxButtons.YES.returnCode) {
	            Terrasoft.showInformation("Нажата кнопка ДА");
	        } else if (returnCode === this.Terrasoft.MessageBoxButtons.NO.returnCode) {
	            Terrasoft.showInformation("Нажата кнопка НЕТ");
	        }
	    }
	 });
    return Ext.create(Terrasoft.CameraPageMixin);
});

 

Show all comments

Hi, we have created a local smtp server only for sending e-mail. 

Is there any way to configure only the SMTP Outgoing mail server ?

In Service Setting Service type is IMAP , if we disable the imap configuration option, it will automatically disable smtp.

Is it possible to configure only the SMTP server on Creatio without filling the imap field?



Best regards 

File attachments
Like 0

Like

1 comments

Hello, Antonio!

 

When you turn on the SMTP setting but turn off the IMAP setting, you can type the value for SMTP, and it will work fine in your case.

Don't pay attention to the fact that the switch is displayed in gray, in fact, it is turned on and you can continue with the setup.

 

Best regards,

Kate

Show all comments

Hello, 

I am going to add custom function to this Search(Поиск) button which makes the Add (Добавить) enabled.

Like 1

Like

1 comments

Hello,

In order to modify this window, you need to create a new module that will expand LookupPage

define("CustomLookupPage", ["LookupPage", "LookupPageViewGenerator", "LookupPageViewModelGenerator",
"ProcessModuleUtilities", "LookupUtilities", "css!LookupPageCSS"],
	function(LookupPage, LookupPageViewGenerator, LookupPageViewModelGenerator, ProcessModuleUtilities) {
		return Ext.define("Terrasoft.configuration.CustomLookupPage", {
			alternateClassName: "Terrasoft.KmGMSLookupPage",
			extend: "Terrasoft.LookupPage",
			gridWrapClasses: ["custom-lookup-control"]
		})
	}
)

However, this is quite a difficult task. We recommend analysing the base methods of LookupPage to see what is their purpose and when they launch.

Show all comments

Hello guys!

How can I make these control buttons disabled, and enabled again when there is not result in search?

Please help me. Any ideas are valueable!

Like 0

Like

4 comments

Hello Muhammadjon,

 

Please note that it is only possible to implement such logic with the means of development, as such an option is not available using regular user tools. Please feel free to look for ideas here on community or on Creatio Academy. 

 

Kind regards,

Mira

Mira Dmitruk,

Hello Mira,

 

There is no way to do that? Do you have any idea how to make this development tools?

 

 

 

Hello,

 

Unfortunately, we have no examples of such logic implemented and this is considered to be a development consultation, which technical support does not provide. You could contact your manager and specify with them if it is possible for you to receive such a consultation.

 

Kind regards,

Mira

Mira Dmitruk, Thanks You!

Show all comments

Hi Community,

 

Any idea what might be the problem to why currently our on premise CRM is slow. Below is the screenshot of network log while navigating through section and edit pages.

 

Other  details:



1. It is using oracle DB

2. We monitored the application and db server while navigating through section and edit pages and the CPU usage is just hitting only 30%.

Like 1

Like

2 comments

Interesting, having the same issue with a client, on-prem with oracle DB

Hello Fulgen, Damien. 



Please make sure that your server machines fit  the requirements. 

You can check it here



On top of that, please analyze following information:



For both Appserver and DatabaseServer

  1. Analytics and monitoring results in graphs displaying the data for the problematic period:
  • % CPU load  
  • % RAM load
  • Disk transfers / sec (IOPS)
  • Disk Read / Write Latency
  1. Application logs (default direcotry C:\Windows\Temp\BPMonline\Site_<website number>\)

Note: how to find the website number?

  1. IIS logs for the period when issue occurred (C:\inetpub\logs\LogFiles\W3SVC<website number>)
  2. Windows logs for the period when issue occurred
  3. Website diagnostic information from procDumpLite utility

IMPORTANT: If you are using balancer or any other infrastructure to prevent fall-overs, it is necessary to provide the diagnostic data of all the nodes.

 

1.     Extended Events (for MS SQL Server) or AWR Report (for Oracle) for the problematic period Note: How to set up Extended Events https://docs.microsoft.com/en-us/sql/relational-databases/extended-events/quick-start-extended-events-in-sql-server?view=sql-server-2017

2.       MS SQL has the option to track the current server activity. Below are the scripts that will display the server activity for the problematic period.

 

Actions to perform when the issue persists

1.     Launch procDumpLite.exe utility in Web Server

procDumpLite.exe site=your_site_name collect=activeRequests,stackFrames,perfViewProfile,memoryInfo

2.     Launch the stored procedures to collect the diagnostic information in Database Server.

exec sp_collectBlockedProcess

exec sp_collectActiveProcess

Note: It is necessary to launch the following stored procedures in separate session and make sure they are running at the same time.

3.     Export the recent records from the ActiveProcess and BlockedProcess to Excel sheet.

select * from ActiveProcess where [CollectedTimeStamp] > cast(getdate() as date)

select * from BlockedProcess where [CollectedTimeStamp] > cast(getdate() as date)

Export the Extended Events (MS SQL) or AWR Report (Oracle)



Analyze received information. 

If after initial analysis you're still unable to find the reason of the slowness, please contact us at support@creatio.com and provide the information you've gathered. 



Best Regards,

Yurii.

Show all comments

Hi,

I have a process that sends feed notification when application registers email sent from particular domain. This email automatically creates a case.

How can I configure Add data action to pass to it Id of a case I want to be opened when user clicks on the notification?

Like 0

Like

1 comments

Dear Ela,

 

I would recommend you to use instruction from Oscar: https://community.creatio.com/questions/link-based-feed-notification

 

Best regards,

Angela

Show all comments

Hi Team,

 

Is there a way to add the tags in the Excel report section . For example, I have created a tag in the opportunity section. Is there a way to add that tag field in the excel reports too.

Thanks,

Gokul

Like 0

Like

1 comments

Hi Gokul,

 

Thank you for your feedback!

 

Kindly note that the Excel report section was created manually without adding the section tag functionality.

However, I will forward your suggestion to the responsible team for consideration.

 

Have a good day!

Show all comments

Hi,



I have created a business process for auto-filling field values. But, the fields will be auto-populated after saving the record and refreshing the page. But, I need it to be done without saving the record and refreshing the page. Here, I am attaching the business process and desired results screenshots. Please have a look and provide your valuable assistance as soon as possible. 

af.PNG

Requirement:

            After choosing the Existing contact using the Applicant Name lookup, the below fields will be auto-filled with the corresponding values without saving the record and refreshing the page. In my case, Applicant Name is the lookup field which is referencing the Contacts. 

 

af1.PNG

I know it is possible through JS Scripts and the onChange method. But, the fields belong to the Contacts section. How can I get the values from the Contacts section? Please provide your assistance. I was unable to get the values from the Contacts section. These are two different sections. The applications section is the custom section. Whenever the user selects the existing contact, some of his/her details will be auto-populated from the Contacts section. Please provide your valuable suggestions. 

Like 0

Like

5 comments

Hello Nagamani,

 

Could you please provide us with screenshots once again? Files in your post are corrupted.

 

Thank you in advance!

Olga. 

Olga Avis,

I have attached the screenshot below here. Please have a look and provide your valuable assistance.

There's really two main ways this is accomplished, both options do require programming. 

Option 1: Write code on the page that responds to a change of the checkbox property, then sets the values using this.set("Columnname", "Value") accordingly. I have an article on wiring up a change in the page code here: https://customerfx.com/article/triggering-an-event-when-a-field-is-chan…

Option 2: This route might work better since you already have the process in place. For this option, you'll add a script task in the process as a last step that will send a message to the page. The page will listen for this message and then refresh using this.reloadEntity(). I have an article on how to do this here: https://customerfx.com/article/how-to-refresh-a-page-from-a-process-in-…

Hope this helps,

Ryan

Ryan, thank you for the answer.

 

You're right, but there's lack of the "destroy" function in it:



define("DealBasePage", ["DCMUtilities", "UsrWaterfallConstants", "BusinessRuleModule", "css!DealPageCSS"],

function(DCMUtilities, UsrWaterfallConstants, BusinessRuleModule) {

  return {

    entitySchemaName: "Deal",

    methods: {

      init: function() {

        this.callParent(arguments);

        this.Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE, this.onStatusMessageReceived, this);

      },

      destroy: function() {

        this.Terrasoft.ServerChannel.un(Terrasoft.EventName.ON_MESSAGE, this.onStatusMessageReceived, this);

        this.callParent(arguments);

      },

      onStatusMessageReceived: function(sender, message) {

        if (message && message.Header && message.Header.Sender === "DealStatusSender") {

          var result = this.Ext.decode(message.Body);

          if (this.get("Id") === result.RecordId) {

            this.loadLookupDisplayValue("DealRank", result.StatusId);

          }

        }

      }

    }

  };

});





Thank you!

Bohdan Zdor,

Thanks I updated the article to include the unregister.

Show all comments

Hi,



I have to implement access permissions for a Applications in a 7.13.3 version. 

1. Every record in the Applications section should visible to all the users.

2. In my instance, 3 functional roles are there such as Agent, Manager, and Approver.

3. I have assigned 2 users for the Agent role. The records which are created by Agent1 should not be edited or deleted by the Agent2 except the manager. 

Step 1: The records which are created by Agent1/Agent2 are only edited by manager and it's owner. It is working as expected.

Step 2: The records which are created by Agent1/Agent2 are able to delete by every user event Agent2 also. But, in our case the record should not be deleted by other agent, other than manager and its owner.

I have given the default permissions like the attached screenshots below here:



Like 0

Like

3 comments

Hello!

 

You can check what access rights are distributed by going into the record and selecting "set up access rights". DSA Agents will be able to delete records if they created them. Other users may have access to deletion if there are incorrect roles inheritance. It will be better to deny access for delete operation to all roles and allow it only to certain roles. 

Angela Reyes,

Can you please tell me more clearly. Actually, I didn't get what you said.

Nagamani Dangeti,

 

Open record in Applications section and go to actions -> set up access rights to check who can delete records. To complete your task go to access to objects permissions and deny delete operation in access to object tab for Applications.

Show all comments

Hi,

 

I have implemented the features like Auto Filling and Auto Clearing fields through business processes. But, this happened after saving the record and running the business process. But, we want to implement the above features without saving the record and running the business processes. Can anyone please provide your valuable assistance?

Like 0

Like

4 comments

It's possible to implement Auto Filling and Auto Clearing fields functionality using "dependencies" property of the field attribute. There is an example below. In the example when the "Type" field value is changed, the "Owner" field is cleared. When the "Salutation" field value is changed, the "Gender" field is auto-filled (https://i.imgur.com/KwtOWH1.png).

 

define("ContactPageV2", [], function() {

    return {

        entitySchemaName: "Contact",

        attributes: {

            SalutationType: {

                dataValueType: this.Terrasoft.DataValueType.LOOKUP,

                dependencies: [{

                    columns: ["SalutationType"],

                    methodName: "onSalutationTypeChange"

                }

               ]

            },

            

            Type: {

                dataValueType: this.Terrasoft.DataValueType.LOOKUP,

                dependencies: [{

                    columns: ["Type"],

                    methodName: "onTypeChange"

                }

               ]

            },

        },

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

        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,

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

        methods: {

            onSalutationTypeChange: function(){

                const salutation = this.get("SalutationType").displayValue;

                if( salutation === "Mr." ){

                    this.set("Gender", {value: "EEAC42EE-65B6-DF11-831A-001D60E938C6", displayValue: "Male"});

                }

                if( salutation === "Mrs." ){

                    this.set("Gender", {value: "FC2483F8-65B6-DF11-831A-001D60E938C6", displayValue: "Female"});

                }

            },

            

            onTypeChange: function(){

                this.set("Owner", null);

            }

        },

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

        diff: /**SCHEMA_DIFF*/[

            

        ]/**SCHEMA_DIFF*/

    };

});

 

 

 

Alina Kazmirchuk,

Thank you for your response. But, I want it to happen in many fields. Here, below I am attaching the screenshot of desired results.

1. Auto Clearing - Whenever we check the boolean field of New Contact, the below fields will be automatically cleared. 

2. Auto Filling - Whenever we select the existing contact in Applicant Name then the below fields will be automatically filled with related information.



Is it possible to do using business processes?



Alina Kazmirchuk,

Thank you so much. 

I have done auto clearing by following your provided assistance. But, I was unable to do the Auto filling. Can you please provide more guidance on Auto Filling?

Alina Kazmirchuk,

In the above screenshot, the Applicant name is a lookup field that is referencing the Existing contact section. If we choose an existing contact, then some of the fields will be auto-filled with the corresponding values. The solution which was provided to me for auto-filling is not suitable for my problem. In your case, the salutation field is having a few values. So we can easily write if conditions. But in my case Applicant name is having so many values i.e., contacts. So, it is very difficult to write that many number of conditions. Can you please any other alternative for Auto filling the field when we select any value in the Applicant name field?

Show all comments