3

I have created a Custom Object called CSVUpload__c that I insert a CSV file into using the Bulk API. I have created a trigger to then insert into the correct sObjects after the insert.

However, I have hit another road block. I recently saw that I was missing a sObject from my schema called Order Product which looks like it is actually OrderItem for the Apex trigger.

In the sObject Products, I have a few products named "Gold", "Commercial", and so on. In the CSVUpload__c object, there is a field called MemberType__c that is the product name. My goal is to add a product to the OrderItem object but I'm not sure how to go about this. I also have a single price book entry with the name of Standard Price Book.

Here is my trigger, and what I have tried so far.

trigger OnUploadInsert on CSVUpload__c (after insert) {
    Account[] accounts = new Account[] {};
    Contact[] contacts = new Contact[] {};
    Boat__c[] boats = new Boat__c[] {};
    Membership__c[] memberships = new Membership__c[]{};
    Order[] orders = new Order[]{};
    OrderItem[] productOrders = new OrderItem[]{};//testing
    Promotion_Code__c[] promos = new Promotion_Code__c[]{};
    Set<String> setMemberType = new Set<String>(); // Used to store MemberType from CSVUpload__c object
    Map<String,Id> mapMemberTypeProductId = new Map<String,Id>(); // Used to store map of MemberType to Product I
    Set<String> setProductId = new Set<String>();
    Map<String,Id> mapPriceBookEntryId = new Map<String,Id>();
    for (CSVUpload__c u : Trigger.new) {
        accounts.add(new Account(
                Name = u.FirstName__c + ' ' + u.LastName__c
        ));
        contacts.add(new Contact(
                FirstName = u.FirstName__c,
                LastName = u.LastName__c,
                MailingStreet = u.Address__c,
                MailingCity = u.City__c,
                MailingStateCode = u.State__c,
                MailingPostalCode = u.Zip__c,
                HomePhone = u.HomePhone__c,
                OtherPhone = u.BusinessPhone__c,
                MobilePhone = u.MobilePhone__c,
                Email = u.EmailAddress__C,
                Title = u.Title__c,
                Fax = u.FaxNo__c
        ));
        boats.add(new Boat__c(
               Address__c = u.BoatAddress__c,
               City__c = u.BoatCity__c,
               State__c = u.BoatState__c,
               Zip__c = u.BoatZip__c,
               Country__c = u.BoatCountry__c
        ));
        memberships.add(new Membership__c(
               Auto_Renew__c = u.AutoReNew__c,
               MemberSince__c = u.MemberSince__c,
               Expiration__c = u.ExpireDate__c,
               MemberSource__c = u.MemberSource__c,
               MemberStatus__c = u.MemberStatus__c,
               Trailer_Care__c = u.TrailerCoverage__c
        ));
        orders.add(new Order(
               Status = 'Draft',
               TypeAmt__c = u.TypeAmt__c,
               PoDate = u.TransDate__c,
               EffectiveDate = u.EffectiveDate__c
        ));
        promos.add(new Promotion_Code__c(
               Code__c = u.PromCode__c
        ));

        setMemberType.add(u.MemberType__c);
    }
    insert accounts;
    for (Integer i = 0; i < accounts.size(); i++) {
        contacts[i].AccountId = accounts[i].Id;
        boats[i].Account__c = accounts[i].Id;
        memberships[i].Account__c = accounts[i].Id;
        orders[i].AccountId = accounts[i].Id;
    }

    insert contacts;
    insert boats;
    insert memberships;

    //for(Integer m = 0; m < memberships.size(); m++)
    //{
    //    orders[m].Membership__c = memberships[m].Id;
    //}

    insert orders;

    for(Integer o = 0; o < orders.size(); o++)
    {
        promos[o].Order__c = orders[o].Id;
        //this is my effort, and it seems to be a poor one. 
        for(PriceBookEntry pe : [SELECT Id, Name FROM PriceBookEntry WHERE Product2Id IN : setProductId])
        {
            mapPriceBookEntryId.put(pe.Name, pe.Id);
        }

        productOrders[o].OrderId = orders[o].Id;//errors here
        productOrders[o].PriceBookEntryId= mapPriceBookEntryId.get(Trigger.new[o].MemberType__c);
        productOrders[o].Quantity = 1;
    }

    insert promos;
    insert productOrders;

    for(Product2 p : [Select Id,Name From Product2 Where Name IN : setMemberType]) {
        mapMemberTypeProductId.put(p.Name,p.Id);
        setProductId.Add(p.Id);

    }

    for(Integer ms = 0; ms < memberships.size(); ms++)
    {
        memberships[ms].Product__c = mapMemberTypeProductId.get(Trigger.new[ms].MemberType__c);
    }

    update memberships;

}

The error that I am receiving is this..

OnUploadInsert: execution of AfterInsert

caused by: System.ListException: List index out of bounds: 0

Trigger.OnUploadInsert: line 87, column 1

I'm new to all of this, so I'm still not sure what I'm doing.

EDIT: I have updated my code but I'm still receiving an error.

trigger OnUploadInsert on CSVUpload__c (after insert) {
Account[] accounts = new Account[] {};
Contact[] contacts = new Contact[] {};
Boat__c[] boats = new Boat__c[] {};
Membership__c[] memberships = new Membership__c[]{};
Order[] orders = new Order[]{};
OrderItem[] productOrders = new OrderItem[]{};//testing
Promotion_Code__c[] promos = new Promotion_Code__c[]{};
Set<String> setMemberType = new Set<String>(); // Used to store MemberType from CSVUpload__c object
Map<String,Id> mapMemberTypeProductId = new Map<String,Id>(); // Used to store map of MemberType to Product I
Set<String> setProductId = new Set<String>();
Set<String> setPriceBookEntryId = new Set<String>();
Map<String,Id> mapPriceBookEntryId = new Map<String,Id>();
Set<String> setPriceBookId = new Set<String>();
Map<String, Id> mapPriceBookId = new Map<String, Id>();
for (CSVUpload__c u : Trigger.new) {
    accounts.add(new Account(
            Name = u.FirstName__c + ' ' + u.LastName__c
    ));
    contacts.add(new Contact(
            FirstName = u.FirstName__c,
            LastName = u.LastName__c,
            MailingStreet = u.Address__c,
            MailingCity = u.City__c,
            MailingStateCode = u.State__c,
            MailingPostalCode = u.Zip__c,
            HomePhone = u.HomePhone__c,
            OtherPhone = u.BusinessPhone__c,
            MobilePhone = u.MobilePhone__c,
            Email = u.EmailAddress__C,
            Title = u.Title__c,
            Fax = u.FaxNo__c
    ));
    boats.add(new Boat__c(
           Address__c = u.BoatAddress__c,
           City__c = u.BoatCity__c,
           State__c = u.BoatState__c,
           Zip__c = u.BoatZip__c,
           Country__c = u.BoatCountry__c
    ));
    memberships.add(new Membership__c(
           Auto_Renew__c = u.AutoReNew__c,
           MemberSince__c = u.MemberSince__c,
           Expiration__c = u.ExpireDate__c,
           MemberSource__c = u.MemberSource__c,
           MemberStatus__c = u.MemberStatus__c,
           Trailer_Care__c = u.TrailerCoverage__c
    ));
    orders.add(new Order(
           Status = 'Draft',
           TypeAmt__c = u.TypeAmt__c,
           PoDate = u.TransDate__c,
           EffectiveDate = u.EffectiveDate__c
    ));
    promos.add(new Promotion_Code__c(
           Code__c = u.PromCode__c
    ));

    setMemberType.add(u.MemberType__c);
    productOrders.add(new OrderItem());
}
insert accounts;
for (Integer i = 0; i < accounts.size(); i++) {
    contacts[i].AccountId = accounts[i].Id;
    boats[i].Account__c = accounts[i].Id;
    memberships[i].Account__c = accounts[i].Id;
    orders[i].AccountId = accounts[i].Id;
}

insert contacts;
insert boats;
insert memberships;
insert orders;

for(Product2 p : [Select Id,Name From Product2 Where Name IN : setMemberType]) {
    mapMemberTypeProductId.put(p.Name,p.Id);
    setProductId.Add(p.Id);
}

for(PriceBookEntry pe : [SELECT Id, Name FROM PriceBookEntry WHERE Product2Id IN : setProductId])
{
    mapPriceBookEntryId.put(pe.Name, pe.Id);
    setPriceBookEntryId.Add(pe.Id);
}

//I thought this would be needed to set the PriceBook2Id in orders, but this returns the same error; Price Book Not Set on Orders: []
//for(PriceBook2 pb : [SELECT Id, Name FROM PriceBook2 WHERE Name = 'Standard Price Book'])
//{
//    mapPriceBookId.put(pb.Name, pb.Id);
//    setPriceBookId.Add(pb.Id);
//}

for(Integer o = 0; o < orders.size(); o++)
{
    promos[o].Order__c = orders[o].Id;          
    orders[o].Pricebook2Id = mapPriceBookEntryId.get(Trigger.new[o].MemberType__c);//I updated my code from your anwser, I now get Price Book ID: id value of incorrect type: 01u37000000wNq8AAE: [Pricebook2Id]
    productOrders[o].OrderId = orders[o].Id;
    productOrders[o].PriceBookEntryId = mapPriceBookEntryId.get(Trigger.new[o].MemberType__c);
    productOrders[o].Quantity = 1;
}

update orders;//added this to update the orders?

insert promos;

insert productOrders;

for(Integer ms = 0; ms < memberships.size(); ms++)
{
    memberships[ms].Product__c = mapMemberTypeProductId.get(Trigger.new[ms].MemberType__c);
}

update memberships;

}

1

The reason you are getting the error is productOrders is not initiated.

Also moved a for loop to a upper place.

trigger OnUploadInsert on CSVUpload__c (after insert) {
    Account[] accounts = new Account[] {};
    Contact[] contacts = new Contact[] {};
    Boat__c[] boats = new Boat__c[] {};
    Membership__c[] memberships = new Membership__c[]{};
    Order[] orders = new Order[]{};
    OrderItem[] productOrders = new OrderItem[]{};//testing
    Promotion_Code__c[] promos = new Promotion_Code__c[]{};
    Set<String> setMemberType = new Set<String>(); // Used to store MemberType from CSVUpload__c object
    Map<String,Id> mapMemberTypeProductId = new Map<String,Id>(); // Used to store map of MemberType to Product I
    Set<String> setProductId = new Set<String>();
    Map<String,Id> mapPriceBookEntryId = new Map<String,Id>();
    for (CSVUpload__c u : Trigger.new) {
        accounts.add(new Account(
                Name = u.FirstName__c + ' ' + u.LastName__c
        ));
        contacts.add(new Contact(
                FirstName = u.FirstName__c,
                LastName = u.LastName__c,
                MailingStreet = u.Address__c,
                MailingCity = u.City__c,
                MailingStateCode = u.State__c,
                MailingPostalCode = u.Zip__c,
                HomePhone = u.HomePhone__c,
                OtherPhone = u.BusinessPhone__c,
                MobilePhone = u.MobilePhone__c,
                Email = u.EmailAddress__C,
                Title = u.Title__c,
                Fax = u.FaxNo__c
        ));
        boats.add(new Boat__c(
               Address__c = u.BoatAddress__c,
               City__c = u.BoatCity__c,
               State__c = u.BoatState__c,
               Zip__c = u.BoatZip__c,
               Country__c = u.BoatCountry__c
        ));
        memberships.add(new Membership__c(
               Auto_Renew__c = u.AutoReNew__c,
               MemberSince__c = u.MemberSince__c,
               Expiration__c = u.ExpireDate__c,
               MemberSource__c = u.MemberSource__c,
               MemberStatus__c = u.MemberStatus__c,
               Trailer_Care__c = u.TrailerCoverage__c
        ));
        orders.add(new Order(
               Status = 'Draft',
               TypeAmt__c = u.TypeAmt__c,
               PoDate = u.TransDate__c,
               EffectiveDate = u.EffectiveDate__c
        ));
        promos.add(new Promotion_Code__c(
               Code__c = u.PromCode__c
        ));

        setMemberType.add(u.MemberType__c);
        // Start - Added to populate productOrders list with blank OrderItem
        productOrders.add(new OrderItem());
        // End - Added to populate productOrders list with blank OrderItem
    }
    insert accounts;
    for (Integer i = 0; i < accounts.size(); i++) {
        contacts[i].AccountId = accounts[i].Id;
        boats[i].Account__c = accounts[i].Id;
        memberships[i].Account__c = accounts[i].Id;
        orders[i].AccountId = accounts[i].Id;
    }

    insert contacts;
    insert boats;
    insert memberships;

    //for(Integer m = 0; m < memberships.size(); m++)
    //{
    //    orders[m].Membership__c = memberships[m].Id;
    //}

    insert orders;
    // Start
    for(Product2 p : [Select Id,Name From Product2 Where Name IN : setMemberType]) {
        mapMemberTypeProductId.put(p.Name,p.Id);
        setProductId.Add(p.Id);
    }
    // End
    //this is my effort, and it seems to be a poor one. 
    for(PriceBookEntry pe : [SELECT Id, Name FROM PriceBookEntry WHERE Product2Id IN : setProductId])
    {
        mapPriceBookEntryId.put(pe.Name, pe.Id);
    }
    for(Integer o = 0; o < orders.size(); o++)
    {
        promos[o].Order__c = orders[o].Id;      
        // Start - Added to update PriceBook2Id in Order before updating PriceBookEntryId in OrderItem
        orders[o].Pricebook2Id = mapPriceBookEntryId.get(Trigger.new[o].MemberType__c);
        // End - Added to update PriceBook2Id in Order before updating PriceBookEntryId in OrderItem
        productOrders[o].OrderId = orders[o].Id;//errors here
        productOrders[o].PriceBookEntryId= mapPriceBookEntryId.get(Trigger.new[o].MemberType__c);
        productOrders[o].Quantity = 1;
    }

    insert promos;
    insert productOrders;
    // Start - Commented and moved the code before order for loop
    /*for(Product2 p : [Select Id,Name From Product2 Where Name IN : setMemberType]) {
        mapMemberTypeProductId.put(p.Name,p.Id);
        setProductId.Add(p.Id);

    }*/
    // End - Commented and moved the code before order for loop

    for(Integer ms = 0; ms < memberships.size(); ms++)
    {
        memberships[ms].Product__c = mapMemberTypeProductId.get(Trigger.new[ms].MemberType__c);
    }

    update memberships;

}

Hope it helps.

  • Ah, I'm an idiot.. I just gave this a shot.. I'm getting this error >Failed with error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY:OnUploadInsert: System.LimitException: Too many SOQL queries: 101:-- .. I guess I hit a limit? – Humpy Sep 4 '15 at 18:15
  • Updated the answer by removing the for loop of pricebookentry outside of for loop of order. It not necessarily to be contained inside. One more thing to note is, if you have triggers on Account, Contact, Boat, Membership, Order, OrderItem objects, this trigger will invoke all those triggers and the SOQL queries contained in those triggers also counted in this transaction. So you should try to limit the batch size of CSV object to not have 200. – Vigneshwaran G Sep 4 '15 at 18:21
  • Ah okay, cool. I think it's almost there. I'm getting this error : FIELD_INTEGRITY_EXCEPTION, Price Book Not Set on Order: [] and I believe it's this line causing the issue.. productOrders[o].PriceBookEntryId= mapPriceBookEntryId.get(Trigger.new[o].MemberType__c); Do you know how to set it to the PriceBookEntryId? – Humpy Sep 4 '15 at 18:43
  • Before setting pricebookentryid to orderitem, you should set the pricebookentryid to order. – Vigneshwaran G Sep 4 '15 at 18:49
  • Ahhhh... once I read the error again... I see what you mean. – Humpy Sep 4 '15 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.