Question

Hi Consultants,

I want to add some fields from contact section inside order section, Currently, only the contact lookup that shows the name of the contact is available out of the box, I want to add extra fields from contact like Country and City fields so they will be populated automatically once I select a contact inside order section.

We are using the cloud version of bmp'online sales commerce.

Best regards,

Mohammad

Like

1 comments

Dear Mohammad,

The easiest option to achieve your purpose would be creating a custom business process that would be triggered by the field Contact changed on the Order page. The process will read the contact data (including City and Country) and auto-populate the fields with the help of Modify Data element. So this would be a simple process that consists of three elements only. 

Lisa

Log in or register to comment
Question

Hi all,

I would like to know how to create a section for the InvoiceProduct schema.

I have found some info for the Usr one, but not on the standard ones ?

Like

2 comments

Dear Jerome,

The new section can be created based on the existing object in database directly only. 

Here is the example of the query you should run to create a new section based on the Activity object:

insert into SysModule
(Caption, SysModuleEntityId, Image16, Image20, FolderModeId, GlobalSearchAvailable, HasAnalytics, HasActions, HasRecent, Code, ModuleHeader, CardSchemaUId, SectionModuleSchemaUId, SectionSchemaUId, CardModuleUId, Image32Id, LogoId)
values
('Emails', 'a2e7bf65-7380-e011-afbc-00155d04320c', (select Image16 from SysModule where Id = '055063c9-8180-e011-afbc-00155d04320c'), (select Image20 from SysModule where Id = '055063c9-8180-e011-afbc-00155d04320c'), 'b659d704-3955-e011-981f-00155d043204',
1, 1, 1, 0, 'Email', 'List of mails', '80918b27-ff37-4d8c-ba73-c985d74d3dc2', 'df58589e-26a6-44d1-b8d4-edf1734d02b4', '569aaf1a-5943-4f87-ab47-948d941e4920', '4e1670dc-10db-4217-929a-669f906e5d75', 'abe30a95-e663-43a9-a881-834b70de5206', '631b1018-9b82-43fe-9f5e-aad272aae679' )

This is the first step to create a separate section that will display the activities with the type email only. The following actions you should perform are:

1) changing the section page schema

2) changing the edit page schema

3) changing the minipage schema etc

Lisa

 

 

Lisa Brown,

Thank you very much for your quick response.

Log in or register to comment
Question

Hello Community!

I need know how detect when a lookup is change get the old value and new value.

Any have a example?

Regards,

 

Like

1 comments

Dear Federico,

You can set up the Change Log for the object the lookup is based on. This way you'll be able to track all the modifications including old/new values.

Lisa

Log in or register to comment
Question

Hello community I'm trying show a Contact.Type in a custom profile. But i have a error when put the diff:

	{
		"operation": "insert",
		"name": "ContactType",
		"values": {
			"layout": {
				"colSpan": 24,
				"rowSpan": 1,
				"column": 0,
				"row": 1,
				"layoutName": "UsrLeftContainer"
			},
			"bindTo": "Contact.Type",
			"enabled": true,
			"contentType": 5
		},
		"parentName": "UsrLeftContainer",
		"propertyName": "items",
		"index": 0
	},

And the console return me:

Heading for label Contact.Type not found.

 

Is something worn in the code?

 

Regards,

 

 

 

Like

1 comments

Unfortunately, the out-of-the-box system doesn't allow displaying linked fields. If you want to do this, you need to create a custom control that will process the linked field. If you want only show the value without a modification option, please consider creating a new field linked to an attribute (virtual column). This way you'll need to fill the attribute in with the needed value with a method. Please search the "dependencies" keyword in an out-of-the-box js code for more information. 

Log in or register to comment
Question

Hi community!

How are you?

I hope you can help me with the following

 

I have a query with ESQ on "EmployeeMiniPage" to validate that the "NroLegajo" field in the Employee entity is not repeated. When I apply certain permissions on a record so that only certain users can see it, the query not consider that record when I log in with a user who does not have permissions, and therefore allows me to enter an existing "NroLegajo" that belongs to that record. To solve this I set the "QueryJoinRightLevel" system variable with value "2" (Disabled) but it does not work. 

 

I reassigned and denied permissions on the registry to do the test and when I logged in with the user who does not have permissions on the registry I can continue entering a repeated value in the field "NroLegajo"

Any idea?

Is there an alternative a ESQ?

King Regards,

Ezequiel

Like

3 comments

Dear Ezequiel,

In order to omit rights check you can create an ESQ on the server side by the means of C#. However, instead of using UserConnection, you can use SystemUserConnection, which would let you execute the functionality no matter under what user.

"Script task" business process element or service will perfectly fit and cover the task. Choose the means more comfortable for you.

Here is how to obtain SystemUserConnection:

private SystemUserConnection SystemUserConnection {
			get {
				return _systemUserConnection ?? (_systemUserConnection = (SystemUserConnection)AppConnection.SystemUserConnection);
			}

Here is an article of how to build ESQ on server side. Though, its pretty much the same as on the client side:

https://academy.bpmonline.com/documents/technic-sdk/7-11/use-entitysche…

Hope you find it helpful.

Regards,

Anastasia

Hi Anastasia!

Thanks you for your answer!

How could I validate in the Employee registration that the "Legajo" field value is not repeated in the way you are indicating?

 Can I call a business process from EmployeeMiniPage to return an answer?

I need that validation along with others before saving the employee!

King Regards!

Ezequiel

 

Dear Ezequiel,

In order to implement such functionality on the page, you need to do the following;

1. Create a webservice, which brushes through the Employee table for duplicates. Please see more details on how to write a service here:

https://academy.bpmonline.com/documents/technic-sdk/7-8/how-call-config…

2. Create a new virtual boolean attribute. We will use it in our further steps.

            "ESQCompleted": {
                dataValueType: Terrasoft.DataValueType.BOOLEAN,
                type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
                value: false
            }

3. Override a basic save() method and firstly insert a validation, that if this.get("ESQCompleted") true, than we call parent function, if not, than run service call, as in the article.

4. In the response, based on the result, you either show information dialog regarding existing duplicate, or set attribute to true and call save method again.

Regards, 

Anastasia

Log in or register to comment
Question

Hello Community!!

 

I have 2 sections appoint to contact and I regiter this sections in sysModule table and all works ok but the problem is the menssages on the Feed. 

If I put a menssage to ahoter user. When the user want open the message (in the notification Center) I get the function:

 

Terrasoft.ModuleUtils.getEntityStructureByName(entitySchemaName); 

 

TypeError: entityStructure is undefined NetworkUtilities.js:101:8

 

Any know if need register the section in other table related with Feed Notifications?

 

Regards,

 

Like

3 comments

Dear Federico,

First of all, we recommend you to create sections via the section wizard, since creating them the way you have described can lead to various conflicts in a database structure. Also, it is not recommended to create two sections, that point to the exact same object for the same reason.

Moreover, we recommend you to debug your customization using your browser's developers tools in case you still want to proceed working with your customization. Also, you can refer to the development documentation for more information.

Best regards,

Matt Watts

Matt Watts,

 Thank you! Can you please give me the code of the function?

Terrasoft.ModuleUtils.getEntityStructureByName(entitySchemaName); may be can check the code to see the error.

Federico Buffa,

You can find the needed method in the ModuleUtils schema of the NUI package.

Here is the code sample you need, but you can refer to the schema if needed.

getEntityStructureByName: function(entitySchemaName) {
			var entityStructure = this.entityStructure || {};
			return entityStructure[entitySchemaName];
		},

Best regards, 

Matt

Log in or register to comment
Question

Hello Community!!

How can add a new Left Container in the LeftModulesContainers? I need a new container with fields like profilecontainer.

Regards,

 

Like

3 comments

It seems like you can do this with a section wizard. Just add fields into the container showed on the screenshot below and the system will create a new container automatically. 

 

 

Eugene Podkovka,

 In the custom sections only shows the profilecontainer.

Please add a new container manually and then use "Section wizard" to fill it in.

{
        "operation": "insert",
        "name": "UsrLeftContainer",
        "parentName": "LeftModulesContainer",
        "propertyName": "items",
        "values": {
            "itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
            "items": []
        }
    }

 

Log in or register to comment
Question

Hi,

I am trying to make a php script to add thousands of pictures to existing contacts bpm.

Support helped me already and told that I should create (POST) a new entry in SysImageCollection with json {id: guid, name: guid}.

Then upload the image binary (base64, zipped or not, I tried them all) as an update (PUT) to SysImageCollection(guid'guid')/PreviewData.

Everything runs correct but I don't see any picture change in the contacts.

I use the guid of the contact in both steps.

Maybe I have to use a fresh guid and link that guid to the ContactCollection afterwards?

Does anyone have an idea what the json is to update the the profile picture for a contact?

Thanks in advance,

Kristof Leroux - Laranea

Like

3 comments

It's hard to say how to create the integration on PHP. I created the functionality on c# and caught the requests with fiddler.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Xml;
using System.Xml.Linq;
 
namespace TransferImageViaOData
{
    class Program
    {
        // String of address bpm’online OData servise.
        private const string serverUri = "https://023148-crm-bundle.bpmonline.com/0/ServiceModel/EntityDataService.svc/";
        private const string authServiceUtri = "https://023148-crm-bundle.bpmonline.com/ServiceModel/AuthService.svc/Login";
 
        // Links to XML name spaces.
        private static readonly XNamespace ds = "http://schemas.microsoft.com/ado/2007/08/dataservices";
        private static readonly XNamespace dsmd = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
        private static readonly XNamespace atom = "http://www.w3.org/2005/Atom";
 
        private static readonly Guid ContactId = new Guid("410006e1-ca4e-4502-a9ec-e54d922d2c00");
 
        static void Main(string[] args)
        {
            var file = ReadFile("z:/2SupportLine/features.png");
            var id = CreateBpmEntityByOdataHttpExample();
            TransferImage(id, "Data", file);
            UpdateContactAvatar(id);
 
        }
 
        public static Guid CreateBpmEntityByOdataHttpExample()
        {
            Guid id = Guid.NewGuid();
            // Creating a xml message containing data on the created object.
            var content = new XElement(dsmd + "properties",
                          new XElement(ds + "Id", id.ToString()),
                          new XElement(ds + "HasRef", 0),
                          new XElement(ds + "MimeType", "image/png"),
                          new XElement(ds + "Name", "test1.png")
                          );
            var entry = new XElement(atom + "entry",
                        new XElement(atom + "content",
                        new XAttribute("type", "application/xml"), content));
            Console.WriteLine(entry.ToString());
            // Creating a request to the service which will add a new object to the contacts collection.
            var request = (HttpWebRequest)HttpWebRequest.Create(serverUri + "SysImageCollection/");
            request.Credentials = new NetworkCredential("Supervisor", "Supervisor");
            request.Method = "POST";
            request.Accept = "application/atom+xml";
            request.ContentType = "application/atom+xml;type=entry";
            // Recording the xml message to the request stream.
            using (var writer = XmlWriter.Create(request.GetRequestStream()))
            {
                entry.WriteTo(writer);
            }
            // Receiving a response from the service regarding the operation implementation result.
            using (WebResponse response = request.GetResponse())
            {
                if (((HttpWebResponse)response).StatusCode == HttpStatusCode.Created)
                {
                    // Processing the operation implementation result.
                }
            }
            return id;
        }
 
        public static void TransferImage(Guid fileRecordId, string columnName, byte[] file)
        {
            // Creating a request to the service which will add a new object to the contacts collection.
            var request = (HttpWebRequest)HttpWebRequest.Create(serverUri + "SysImageCollection(guid'" + fileRecordId.ToString() + "')/" + columnName);
            request.Credentials = new NetworkCredential("Supervisor", "Supervisor");
            request.Method = "PUT";
            request.Accept = "application/octet-stream,application/json;odata=verbose";
            request.ContentType = "multipart/form-data;boundary=+++++";
            // Recording the xml message to the request stream.
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(file, 0, file.Length);
            }
            // Receiving a response from the service regarding the operation implementation result.
            using (WebResponse response = request.GetResponse())
            {
                if (((HttpWebResponse)response).StatusCode == HttpStatusCode.Created)
                {
                    // Processing the operation implementation result.
                }
            }
        }
 
        public static void UpdateContactAvatar(Guid fileRecordId)
        {
            var content = new XElement(dsmd + "properties",
                    new XElement(ds + "PhotoId", fileRecordId)
            );
            var entry = new XElement(atom + "entry",
                    new XElement(atom + "content",
                            new XAttribute("type", "application/xml"),
                            content)
                    );
            var request = (HttpWebRequest)HttpWebRequest.Create(serverUri
                    + "ContactCollection(guid'" + ContactId + "')");
            request.Credentials = new NetworkCredential("Supervisor", "Supervisor");
            // or request.Method = "MERGE";
            request.Method = "PUT";
            request.Accept = "application/atom+xml";
            request.ContentType = "application/atom+xml;type=entry";
            // Recording the xml message to the request stream.
            using (var writer = XmlWriter.Create(request.GetRequestStream()))
            {
                entry.WriteTo(writer);
            }
            // Receiving a response from the service regarding the operation implementation result.
            using (WebResponse response = request.GetResponse())
            {
                // Processing the operation implementation result.
            }
        }
 
        public static byte[] ReadFile(string filePath)
        {
            byte[] imageArray = System.IO.File.ReadAllBytes(filePath);
            return imageArray;
        }
    }
}

 

Please use the code below:

<?php

/*Please change this to you product name*/
define("baseUri", "https://023665-crm-bundle.bpmonline.com");
define("serverUri", baseUri . "/0/ServiceModel/EntityDataService.svc");

/*Please change this to you account setting*/
define("user", "Dmitro");
define("password", "123456789");

/*Please change this user_id to new user_id value for the user whose avatar needs to be changed*/
$user_id = 'c4ed336c-3e9b-40fe-8b82-5632476472b4';
/*Please change this file name*/
$file_name = 'test_img.png';

$file_id = CreateBpmEntityFile($file_name);
TransferImage($file_id, $file_name);
UpdateContactAvatar($user_id, $file_id);

function CreateBpmEntityFile($file_name) {
    $headers = [
      'Accept: application/atom+xml',
      'Content-Type: application/atom+xml;type=entry',
      "Authorization: Basic " . base64_encode(user . ':' . password),
      'Expect: 100-continue',
    ];

    $uid = GetUid();

    $postData = <<<XML
<?xml version="1.0" encoding="utf-8"?><entry xmlns="http://www.w3.org/2005/Atom"><content type="application/xml"><properties xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><Id xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">$uid</Id><HasRef xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">0</HasRef><MimeType xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">image/png</MimeType><Name xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">$file_name</Name></properties></content></entry>
XML;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, serverUri . "/SysImageCollection/");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

    curl_exec($ch);
    curl_close($ch);

    return $uid;
}

function TransferImage($id, $file_name) {
    $fh_res = fopen($file_name, 'r');
    $xml_data = fread($fh_res, filesize($file_name));

    $headers = [
      "Accept: application/octet-stream,application/json;odata=verbose",
      "Content-type: multipart/form-data;boundary=+++++",
      "Authorization: Basic " . base64_encode(user . ':' . password),
      "Expect: 100-continue",
    ];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, serverUri . "/SysImageCollection(guid'$id')/Data");
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);

    curl_exec($ch);
    fclose($fh_res);
}

function UpdateContactAvatar($user_id, $file_id) {
    $headers = [
      'Accept: application/atom+xml',
      'Content-Type: application/atom+xml;type=entry',
      "Authorization: Basic " . base64_encode(user . ':' . password),
    ];

    $postData = <<<XML
<?xml version="1.0" encoding="utf-8"?><entry xmlns="http://www.w3.org/2005/Atom"><content type="application/xml"><properties xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><PhotoId xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">$file_id</PhotoId></properties></content></entry> 
XML;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, serverUri . "/ContactCollection(guid'$user_id')");
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

    curl_exec($ch);
    curl_close($ch);
}

/**
 * Generate uniq id
 *
 * @return string
 */
function GetUid() {
    $uid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
      mt_rand(0, 0xffff), mt_rand(0, 0xffff),
      mt_rand(0, 0xffff),
      mt_rand(0, 0x0fff) | 0x4000,
      mt_rand(0, 0x3fff) | 0x8000,
      mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff));

    return $uid;
}

 

Log in or register to comment
Question

Hi All,

We would like to put extra filter on a detail.

For example: A list of open opportunities. I could not file good example in the documentaion.

Is there anyone who has same experience?

Like

2 comments

Dear Cheng,

You can use the Email detail from the Contact page as an example. There is a fixed filter there that allows the user to see the activities with the certain category (Email) only. 

The schema looks like this:

EmailDetailV2: {
   schemaName: "EmailDetailV2",
   filter: {
      masterColumn: "Id",
      detailColumn: "Contact"
   },
   filterMethod: "emailDetailFilter"
}

You need to pay attention to the filterMethod usage and create the necessary ESQ filters inside the method:

filterGroup.add(
   "EmailFilter",
   this.Terrasoft.createColumnFilterWithParameter(
      this.Terrasoft.ComparisonType.EQUAL,
      "Type",
      ConfigurationConstants.Activity.Type.Email
   )
);

Lisa

Lisa Brown,

Thank you. It works now.

Log in or register to comment
Question

How can we add a Product Image in the Product Selection page in the [Orders] section? Please suggest.

Like

1 comments

Dear Anupama,

This is a quite complex functionality to implement, which requires developer's skills. In the core, the idea is to add one extra column to the grid of product selection page and display product image there.

In order to add extra field to the grid you need to do the following:

1. Add the ProductSelectionViewModel replacing schema

2. Copy all the code to the replaced schema from the parent schema

3. Add Dependencies as in the parent schema

4. Add a custom variable in all methods where the standard fields "Unit, Price , Currency, Tax, Code, Available" are

5. Save the replaced schema

6. Add the ProductSelectionView replacement schema

7. Copy all the code to the replaced schema from the parent

8. Add Dependencies from the parent schema

9. In the getEditableGridConfig and getGridCaptionConfig methods, add the custom field for the picture

 10. Save replacement schema

By the means of basic JS methods like "getImageURL" (it is also present in the ProductSelectionViewModel schema) insert image to the  column. You can also take a product page as an example of usage of image functionality.

Hope you find it helpful.

Regards,

Anastasia

Log in or register to comment