0

Newbie in SFA development, however I have experienced in ASP.NET (C#) development. I have a question regarding this output:

enter image description here

the NAME COLUMN is list of PRODUCT populated from the Salesforce Object. And I've added the REMARKS COLUMN as an input column to check the product whether Available or Not.

However, when I am trying to save this one to my custom object. All of the values from the REMARK COLUMN was captured.

ex. ITEM A - With Stock ITEM A - No Stock ITEM B - With Stock ITEM B - No Stock

My goal is to capture only the selected remarks for the specific product.

Here are my code:

CMP: 

<aura:attribute name="selectedProductsList" type="List" default="[] />
<aura:attribute name="pickListProductRemark" type="string[]" default="['With Stock','Critical Stock','No Stock']"/>

    <lightning:layout multipleRows="true">
    <lightning:layoutItem size="12" padding="around-small">
        <div class="slds-scrollable_x">
            <table class="slds-table slds-table_bordered slds-table_cell-buffer slds-table_col-bordered">
                <thead>
                    <tr class="slds-text-title_caps">
                        <th scope="col">
                            <div class="slds-truncate" title="Name">Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Name">Remarks</div>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <aura:iteration items="{! v.selectedProductsList }" var="record" >
                        <tr>
                            <th scope="row">
                                <div class="slds-truncate" title="{! record.prod2.Name }">
                                    {! record.prod2.Name }
                                </div>
                            </th>
                            <th scope="row">
                                <lightning:select aura:id="select" name="{!index}" Class="slds-col slds-size_1-of-2 slds-p-horizontal_x-small">
                                    <aura:iteration items="{!v.pickListProductRemark}" var="value">
                                        <option value="{!value}">{!value}</option>
                                    </aura:iteration>
                                </lightning:select>
                            </th>
                        </tr>
                    </aura:iteration>
                </tbody>
            </table>
            <div class="slds-p-bottom_small" />
        </div>
    </lightning:layoutItem>
</lightning:layout>

Controller - Save Record:
saveRecord : function(component, event, helper) {

        var selectedProductsIDList = component.get('v.selectedProductsIDList');
        var selectedAccount = component.get('v.selectedAccount');
        var pickListProductRemark = component.get('v.pickListProductRemark');
        var buttonName = event.getSource().get("v.name");

        if (Object.keys(selectedAccount).length == 0) {

            helper.showToastDisplay({
                "title" : "Required Field Missing",
                "message" : "Please select an Account.",
                "type" : "error"
            });

        }

        else {

            if (selectedProductsIDList.length == 0) {

                helper.showToastDisplay({
                    "title" : "Something went wrong",
                    "message" : "Please select at least one product",
                    "type" : "error"
                });

            }

            else {

                helper.saveRecord(component, event, helper, buttonName);

            }

        }

    }

Helper - Save Record:
saveRecord : function(component, event, helper, buttonName) {

        var recordParameters = {

            recordID : component.get('v.recordId'),
            accountID : component.get('v.selectedAccount').Id,
            productIDList : component.get('v.selectedProductsIDList'),
            productRemarkList: component.get('v.pickListProductRemark'),
            buttonName : buttonName,
            recordDate : component.get('v.recordDate')

        };

        var action = component.get('c.submitRecord');

        action.setParams({

            recordParameters : JSON.stringify(recordParameters)

        });

        action.setCallback(this, function(response) {

            var state = response.getState();

            if (state === "SUCCESS") {

                var recordID = response.getReturnValue();

                if (recordID != null) {

                    if ($A.get("$Browser.formFactor") == 'DESKTOP') {
                        window.location = '/' + recordID;
                    }

                    else {

                        var event = $A.get('e.force:navigateToSObject');

                        event.setParams({
                            'recordId' : recordID,
                            'slideDevName' : 'Detail'
                        }).fire();

                    }

                }

            }

            else {

                var errors = response.getError();

                if (errors && Array.isArray(errors) && errors.length > 0) {

                    this.showToastDisplay({
                        "title" : "Something went wrong",
                        "message" : errors[0].message,
                        "type" : "error"
                    });

                }

            }

        });

        $A.enqueueAction(action);

    },

Class:
@AuraEnabled public List<String> productIDList { get; set; }
@AuraEnabled public List<String> productRemarkList { get; set; }
@AuraEnabled
    public static String submitRecord(String recordParameters) {

        if (String.isNotBlank(recordParameters)) {

            SaveRecordParameters recordParams = (SaveRecordParameters) JSON.deserialize(recordParameters, SaveRecordParameters.class);

            String recordID = recordParams.recordID;
            String accountID = recordParams.accountID;
            List<String> productIDList = recordParams.productIDList;
            List<String> productRemarkList = recordParams.productRemarkList;
            String buttonName = recordParams.buttonName;
            Date recordDate = recordParams.recordDate;

            if (String.isNotBlank(accountID) && productIDList.size() > 0) {

                if (String.isBlank(String.valueOf(recordDate))) {
                    recordDate = Date.today();
                }

                Product_Availability_Check__c subActivityRep = new Product_Availability_Check__c();

                if (String.isBlank(recordID)) {

                    subActivityRep = new Product_Availability_Check__c(Account__c = accountID,
                                                                 Date__c = recordDate,
                                                                 RecordTypeId = Schema.SObjectType.Product_Availability_Check__c.getRecordTypeInfosByName().get('Product Availability Report').getRecordTypeId()
                                                                );

                    if (buttonName.contains('draftRecord')) {
                        subActivityRep.Status__c = 'Draft';
                    }

                    if (buttonName.contains('submittedRecord')) {
                        subActivityRep.Status__c = 'Submitted';
                    }

                    insert subActivityRep;

                }

                else {

                    subActivityRep = [SELECT Id,
                                             Account__c,
                                             Date__c,
                                             Status__c
                                      FROM Product_Availability_Check__c
                                      WHERE (Id = :recordID)
                                     ];

                    subActivityRep.Account__c = accountID;
                    subActivityRep.Date__c = recordDate;

                    if (buttonName.contains('draftRecord')) {
                        subActivityRep.Status__c = 'Draft';
                    }

                    if (buttonName.contains('submittedRecord')) {
                        subActivityRep.Status__c = 'Submitted';
                    }

                    update subActivityRep;

                }

                List<Product_Availability_Line_Item__c> subActivityReportLineItemList = new List<Product_Availability_Line_Item__c>();

                for (String productIDRec : productIDList) {

                    for (String productRem : productRemarkList) {
                    Product_Availability_Line_Item__c subActivityReportLineItem = new Product_Availability_Line_Item__c(Product__c = productIDRec,
                                                                                                                      RecordTypeId = Schema.SObjectType.Product_Availability_Line_Item__c.getRecordTypeInfosByName().get('Product Availability Report').getRecordTypeId(),
                                                                                                                      Sub_Activity_Report__c = subActivityRep.Id,
                                                                                                                      Remarks__c = productRem
                                                                                                                     );
                        subActivityReportLineItemList.add(subActivityReportLineItem);
                    }


                }

                if (String.isBlank(recordID)) {
                    insert subActivityReportLineItemList;
                }

                else {

                    List<Product_Availability_Line_Item__c> oldSARL = [SELECT Id,
                                                                      Sub_Activity_Report__c,
                                                                      Product__c
                                                               FROM Product_Availability_Line_Item__c
                                                               WHERE (Sub_Activity_Report__c = :recordID)
                                                              ];

                    if(oldSARL.size() == subActivityReportLineItemList.size()){
                        Boolean proceedDelete = false;
                        for(Product_Availability_Line_Item__c existingSARL : oldSARL){
                            if(proceedDelete == false){
                                for(Product_Availability_Line_Item__c newSARL : subActivityReportLineItemList){
                                    if(newSARL.Product__c != existingSARL.Product__c){
                                        proceedDelete = true;
                                    }else{
                                        proceedDelete = false;
                                        break;
                                    }   
                                }
                            }else{
                                break;
                            }
                        }

                        if(proceedDelete == true){
                            delete oldSARL;
                            insert subActivityReportLineItemList;
                        }
                    }else{
                        delete oldSARL;
                        insert subActivityReportLineItemList;
                    }



                }

                return subActivityRep.Id;

            }

            else {

                return null;

            }

        }

        else {

            return null;

        }

    }
7
  • Could you post the controller and helper JS code? Component markup code is insufficient to figure out what data is actually getting saved.
    – arut
    Apr 26, 2020 at 8:36
  • @arut done, sorry my post got truncated. Thank you!
    – Akosi Jeff
    Apr 26, 2020 at 8:48
  • In the helper JS [productIDList : component.get('v.selectedProductsIDList') & productRemarkList: component.get('v.pickListProductRemark'))], you are passing the entire list of products and entire list of picklist values. This doesn't specify the user selected value in the picklist. How are you handling this in this apex code??
    – arut
    Apr 26, 2020 at 9:31
  • @arut I already included the class on the post. Thanks.
    – Akosi Jeff
    Apr 26, 2020 at 9:37
  • sorry, my bad. I guess I didn't look at it.
    – arut
    Apr 26, 2020 at 9:39

1 Answer 1

1

In the Helper JS, you are passing the list of all selected products and list of all picklist values; and in the corresponding apex code, you are using them in nested for loops. This will create an entry for each combination of the product ID and each remarks picklist value. This is incorrect and you should create a key value pair in the helper or controller JS which will store the selected remark against each product ID (and pass this key value pair to the apex code).

Prod1 ID: With Stock
Prod2 ID: No Stock
...

Looks like the requirements for your source code is probably beyond the scope of this question and hence, I'm going to focus only on the problem you are facing. Please note that this solution will work only if you have the apex variable List<String> productIDList populated in the same order as they are displayed to the user. If it were up to me, I would probably change a lot in the design. May be even write a custom component for the data table which captures the product ID vs User Remarks as a key value pair and hand it over to a map collection in the apex code.

However, for the problem you are currently facing, this is the simplest solution without making too many changes to the code. You might need to make few tweaks to the code, but I guess it gives you a fair idea.

In the controller SaveRecord JS function, introduce the following code:

var len = component.find("select").length;
var remarks = [];
for (var i = 0; i < len; i++) {
    remarks.push(component.find("select")[i].get("v.value"));
}

Replace productRemarkList: component.get('v.pickListProductRemark'), with productRemarkList: remarks,

In the apex code, replace the following lines

for (String productIDRec : productIDList) {
    for (String productRem : productRemarkList) {
    Product_Availability_Line_Item__c subActivityReportLineItem = new Product_Availability_Line_Item__c(Product__c = productIDRec,
                                                                                                      RecordTypeId = Schema.SObjectType.Product_Availability_Line_Item__c.getRecordTypeInfosByName().get('Product Availability Report').getRecordTypeId(),
                                                                                                      Sub_Activity_Report__c = subActivityRep.Id,
                                                                                                      Remarks__c = productRem
                                                                                                     );
        subActivityReportLineItemList.add(subActivityReportLineItem);
    }
}

with

Integer count = 0;
for (String productIDRec : productIDList) {
    Product_Availability_Line_Item__c subActivityReportLineItem = new Product_Availability_Line_Item__c(Product__c = productIDRec,
                                                                                                      RecordTypeId = Schema.SObjectType.Product_Availability_Line_Item__c.getRecordTypeInfosByName().get('Product Availability Report').getRecordTypeId(),
                                                                                                      Sub_Activity_Report__c = subActivityRep.Id,
                                                                                                      Remarks__c = productRemarkList[count]
                                                                                                     );
    subActivityReportLineItemList.add(subActivityReportLineItem);
    count = count + 1;
}
3
  • Tried 2 products then it works :) However, when I put 10 products then the error prompted me. Error: List Index out of bound:3
    – Akosi Jeff
    Apr 26, 2020 at 12:41
  • Where are you getting the error? JS or Apex? Could you post some logs? This error occurs while trying to access an element beyond the length of the array or list.
    – arut
    Apr 26, 2020 at 13:01
  • I guess, I get it. i set the attribute component from the js controller to capture the number of value. Thank you :)
    – Akosi Jeff
    Apr 27, 2020 at 0:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .