Hi everyone,

I'm looking for a way to customize the Add order based on opportunity BP.

I added some fields to the 'product in opportunity' object, like: discount amount, discount %, semester and schoolyear. Added semester and schoolyear to the product in order object too (discount amount, discount % fields are already exist there).

Now, I want these values to be copied when creating an order from an opp, just like the other fields of the product in order do.

I found this process does the order and creates the products  

https://beable.creatio.com/0/Nui/ViewModule.aspx?vm=SchemaDesigner#process/be82d4e0-4638-4058-975d-050a3dcff8b5

but don't know how to extend the script there (the script that adds the products in on the Adding opportunity products to order  element. 

Is there a way to get to the function that are being executed in that script?

Adding the element's script here.

Thanks in advance,

Chani

if (ProductItems.ToString() != "" || IsCopyAllProduct) {
	var copyProductsOperation = Factories.ClassFactory.Get<
		Terrasoft.Configuration.CopyOrderProductsFromOpportunityOperation>(
		new Factories.ConstructorArgument("userConnection", UserConnection));
	copyProductsOperation.Execute(new Terrasoft.Configuration
		.CopyOrderProductsFromOpportunityOperation
		.CopyOrderProductsArgs {
			OpportunityId = CurrentOpportunity,
			OrderId = NewOrder,
			IsCopyAllProducts = IsCopyAllProduct,
			ProductItems = ProductItems
	});
}
return true;

 

Like 0

Like

4 comments

Hi Chani,

 

You can create your own process and modify the script-task in the way you need or you can copy products from the opportunity to the created order using the "Add data" process element and the sub-process that will receive a collection of OpportunityProduct records.

 

Now step-by-step:

 

1) In the OpportunityOrderUtilities schema there is the CreateOrderFromOpportunity method that is called upon clicking the "New order" button on the opportunity page:

 

this is the code of the button:

and here is the method itself:

As we can see here the method reads the value for the system setting with "CreateOrderFromOpportunityProcess" code. By default the value for this system setting is "Add order based on opportunity":

So we can place any process with the simple start signal there.

 

2) You can either create your own script task in the newly created process (use the code from the original OOB process as an example or paste it and extend in the new process). Or in the new process you can use the collection of records read from the OpportunityProduct object and if the number of records is greater than 1 you can pass this collection to the sub-process that will add data to the created order (the object is OrderProduct).

 

So you need to select one of these two options: either extend the script-task or use the collection of records and a sub-process.

 

Best regards,

Oscar

Oscar Dylan,

Thank you.

But I do want to use the option of selecting products (see pic), how can I have that and get the products list to use in the add data element?

I tried looking in the  Add order based on opportunity BP, but I only see a text parameter for products list.

 

Chani Karel,

 

This is a part of the showProductDialog method of the same OpportunityOrderUtilities module. This will be called regardless of if the process is changed or not. Once products are selected, they are passed to the runProcessCreateOrder method. The list of selected products will be passed as an array of ID's to the process:

 

Best regards,

Oscar

Oscar Dylan,

Thanks

Show all comments

The system is not respecting the price list registered for the account. I currently work with more than five price types for the same product.

The price list was registered and linked to the specified account, but when starting a new order for the account, it does not load the value referring to the list, but a base value.

Would have any tips or step by step to check this situation.

Like 0

Like

1 comments

Hello Alisosn!



Could you tell me some more information about that issue? What do you see on the page and what is the expected result? That would help us to solve the problem,



Best Regards,

Tetiana Bakai

Show all comments

Is it possible so that a new line is added to the product detail every time enter is pressed?

 

This way adding products is greatly sped up (compared to clicking + and going through the Product page).

 

Does anybody know how to achieve this?

Like 0

Like

5 comments
Best reply

Turns out using plain enter would conflict with the need of the dropdown lookup. I picked alt+enter. This is how:

define("OrderProductDetailV2", [], function() {
	return {
		entitySchemaName: "OrderProduct",
		messages: {
		},
		attributes: {
		},
		methods: {
            /** 
             * add Alt+Enter as a shortcut to an active record
             */
			initActiveRowKeyMap: function (keyMap)
			{
				keyMap.push({
					key: Ext.EventObject.ENTER,
					alt: true,
					defaultEventAction: "preventDefault",
					fn: this.onAltEnterKeyPressed,
					scope: this
				});
				this.callParent(arguments);
            },
            /**  
             * Enable the logic for saving the current row and
             * creating a new one
            */
			onAltEnterKeyPressed: function () {
				var activeRow = this.getActiveRow();
				this.unfocusRowControls(activeRow);
				Terrasoft.chain(function(next) {
				this.saveRowChanges(activeRow, next);
				}, function(next) {
					this.activeRowSaved(activeRow, next);
				}, function() {
					this.addRecord();
				}, this);
			}
		},
		diff: /**SCHEMA_DIFF*/[
            // this overides the little + button to skip the OrderProductPage
			{
				"operation": "merge",
				"name": "AddRecordButton",
				"values": {
					"click": {"bindTo": "addRecord"}
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

 

Turns out using plain enter would conflict with the need of the dropdown lookup. I picked alt+enter. This is how:

define("OrderProductDetailV2", [], function() {
	return {
		entitySchemaName: "OrderProduct",
		messages: {
		},
		attributes: {
		},
		methods: {
            /** 
             * add Alt+Enter as a shortcut to an active record
             */
			initActiveRowKeyMap: function (keyMap)
			{
				keyMap.push({
					key: Ext.EventObject.ENTER,
					alt: true,
					defaultEventAction: "preventDefault",
					fn: this.onAltEnterKeyPressed,
					scope: this
				});
				this.callParent(arguments);
            },
            /**  
             * Enable the logic for saving the current row and
             * creating a new one
            */
			onAltEnterKeyPressed: function () {
				var activeRow = this.getActiveRow();
				this.unfocusRowControls(activeRow);
				Terrasoft.chain(function(next) {
				this.saveRowChanges(activeRow, next);
				}, function(next) {
					this.activeRowSaved(activeRow, next);
				}, function() {
					this.addRecord();
				}, this);
			}
		},
		diff: /**SCHEMA_DIFF*/[
            // this overides the little + button to skip the OrderProductPage
			{
				"operation": "merge",
				"name": "AddRecordButton",
				"values": {
					"click": {"bindTo": "addRecord"}
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

 

Hi Jonas,

 

To avoid opening the "Products" section and simply switch to a new line, you can press the "Tab" button and add a new product to the detail, choosing it from an appeared lookup.

 

Regards,

Anastasiia

That is technically possible, but not what the customer requested.

Jonas,

 

Sure, there is one more option you can use. 

 

1. Create a replacing client module schema for the detail schema ("ProductDetailV2", UIv2 package). Here is the article on how you can do it:



https://academy.creatio.com/documents/technic-sdk/7-16/creating-custom-…

 

2. In a new replacing client schema, please set the parent object (Base detail - Products ( UIv2 )) and insert the code below:

 

define("ProductDetailV2", ["terrasoft", "ConfigurationEnums", "MaskHelper", "ConfigurationGrid",
    "ConfigurationGridGenerator", "ConfigurationGridUtilities"],
  function(Terrasoft, enums, MaskHelper) {
    return {
      mixins: {},
      attributes: {},
      messages: {},
      methods: {},
      diff: /**SCHEMA_DIFF*/[
        {
          "operation": "merge",
          "name": "AddRecordButton",
          "values": {
            "click":{"bindTo":"addRow"}
          }
        }
      ]/**SCHEMA_DIFF*/
    };
  });

3. Save your changes and hard-reload the page. Now, you are able to add a new line by clicking plus. 

 

Regards,

Anastasiia

True, but that does not enable adding a new line through a shortcut when in edit mode, which was the original question, that I solved per my answer above.

Show all comments

Hi, 

 

Hope someone can help me with replicating OrdersProducts in Quotes Section. I have tried that and while click on + icon products are not displaying.

 

Thank you.

Like 0

Like

7 comments

Dear Sushma,

The logic of the Product detail is implemented in OrderPage so if you page ss inherited from the BaseModulePage base page it will not work. You can investigate order page schema code to copy it to your new section or try the following example (the page should be modified according to the settings of your detail, otherwise it will not work):

define("UsrOrder3Page", ["EntityProductCountMixin"], function() {

    return {

        entitySchemaName: "Order",

        messages: {

            "GetOrderProductSummary": {

                mode: Terrasoft.MessageMode.PTP,

                direction: Terrasoft.MessageDirectionType.SUBSCRIBE

            },

            "UpdateOrderProductSummary": {

                mode: Terrasoft.MessageMode.PTP,

                direction: Terrasoft.MessageDirectionType.PUBLISH

            },

        },

        mixins: {

            EntityProductCountMixin: "Terrasoft.EntityProductCountMixin"

        },

        attributes: {

            "Currency": {

                dataValueType: Terrasoft.DataValueType.ENUM,

                lookupListConfig: {

                    columns: ["Division", "ShortName", "Symbol"]

                }

            },

            "AmountAndCurrency": {

                dependencies: [

                    {

                        columns: ["Amount", "Currency"],

                        methodName: "updateOrderProductSummary"

                    }

                ]

            },

            "IsPaymentAmountLargerThanAmount": {

                dataValueType: this.Terrasoft.DataValueType.BOOLEAN,

                type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,

                value: false,

                dependencies: [

                    {

                        columns: ["PaymentAmount", "Amount"],

                        methodName: "setIsPaymentAmountLargerThanAmount"

                    }

                ]

            }

        },

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

        details: /**SCHEMA_DETAILS*/{

            ProductInProductsTab: {

                schemaName: "OrderProductDetailV2",

                entitySchemaName: "OrderProduct",

                filter: {

                    masterColumn: "Id",

                    detailColumn: "Order"

                },

                subscriber: {methodName: "refreshAmount"},

                defaultValues: {

                    Currency: {masterColumn: "Currency"},

                    CurrencyRate: {masterColumn: "CurrencyRate"}

                }

            }

        }/**SCHEMA_DETAILS*/,

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

        methods: {

            refreshAmount: function() {

                this.updateAmount(function() {

                    this.updateOrderProductSummary();

                }, this);

            },

            subscribeSandboxEvents: function() {

                this.callParent(arguments);

                this.sandbox.subscribe("GetOrderProductSummary", this.getProductSummaryConfig, this,

                    [this.getDetailId("ProductInProductsTab")]);

            },

            updateOrderProductSummary: function() {

                this.sandbox.publish("UpdateOrderProductSummary", null,

                    [this.getDetailId("ProductInProductsTab"), this.getDetailId("ProductInResultsTab")]);

            },

            getProductSummaryConfig: function() {

                var currency = this.get("Currency") || {};

                return {

                    count: this.get("ProductCount"),

                    currency: currency.Symbol,

                    amount: this.get("Amount")

                };

            },

            setIsPaymentAmountLargerThanAmount: function() {

                var paymentAmount = this.get("PaymentAmount");

                var amount = this.get("Amount");

                var isLarger =

                    this.isNotEmpty(paymentAmount) &&

                    this.isNotEmpty(amount) &&

                    (paymentAmount > amount);

                this.set("IsPaymentAmountLargerThanAmount", isLarger);

            },

            onSaved: function() {

                this.callParent(arguments);

                var config = arguments[arguments.length - 1];

                if (config && config.isSilent) {

                    return;

                }

                this.updateAmountAfterSave("ProductInProductsTab",

                    function() {

                        this.updateDetail({detail: "ProductInResultsTab"});

                        this.updateOrderProductSummary();

                    },

                    this

                );

            },

            loadEntity: function(primaryColumnValue, callback, scope) {

                scope = scope || this;

                this.callParent([primaryColumnValue, function() {

                    this.setIsPaymentAmountLargerThanAmount();

                    this.setProductCount(primaryColumnValue, callback, scope);

                }, scope]);

            },

            getProductCountInEntityColumnName: function() {

                return "ProductCount";

            },

            setColumnValues: function(entity) {

                this.callParent(arguments);

                this.updateProductsCount(entity);

            },



            modifyAmountESQ: function(esq) {

                this.mixins.ProductEntryPageUtils.modifyAmountESQ.apply(this, arguments);

                this.addProductsCountColumn(esq);

            },

            updateAmountColumnValues: function(entity) {

                this.mixins.ProductEntryPageUtils.updateAmountColumnValues.apply(this, arguments);

                this.updateProductsCount(entity);

            },

            addProductsCountColumn: function(esq) {

                esq.addAggregationSchemaColumn("[OrderProduct:Order].Id",

                        this.Terrasoft.AggregationType.COUNT, "ProductCount");

            },

            updateProductsCount: function(entity) {

                var countColumn = "ProductCount";

                this.setColumnValue(countColumn, entity.get(countColumn), {preventValidation: true});

            }

        },

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

        diff: /**SCHEMA_DIFF*/[

            {

                "operation": "insert",

                "name": "ProductInProductsTab",

                "values": {

                    "itemType": 2,

                    "markerValue": "added-detail"

                },

                "parentName": "Tab0686e409TabLabel", //detail placement

                "propertyName": "items",

                "index": 0

            }

        ]/**SCHEMA_DIFF*/

    };

});

Angela Reyes,

Thank you for your help.  I successfully replicated that functionality. But Currency is not updating in ProductsSection when currency is changed in maing page.

sushma,

Can you please specify how it is not updated? Do you mean the currency that is specified in the price list? 

Angela Reyes,

There is multicurrency amount field in Quote page wich is sum of amounts of all products of detail and is not working as expected. when changing currency of amount field in quote page and click on save getting error as shown in attachment.

sushma,

It is hard to find the reason of this error as it is a custom object and there is no information in the pop-up. Try to debug (

https://academy.creatio.com/documents/technic-sdk/7-15/client-code-debugging) the application using developer tools to locate what causes this error. 

when trying to debug when i change 

 "Currency": {

                dataValueType: Terrasoft.DataValueType.ENUM,

                lookupListConfig: {

                    columns: ["Division", "ShortName", "Symbol"]

                }

            },

to  "Currency": {

                dataValueType: Terrasoft.DataValueType.LOOKUP,

                lookupListConfig: {

                    columns: ["Division", "ShortName", "Symbol"]

                }

            },

Error is not coming as it says when updating there is mismatch with datatype of currency. But still detail is not updating when currency is changed and total amount is not updating based on sum of amounts of all products

sushma,

why are you trying to change currency to lookup type? It should remain ENUM

Show all comments