[SalesForce] Create OrderItem (Order Product) from Bulk upload Object

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;

}

Best Answer

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.

Related Topic