Let me begin by saying that what you're trying to do is not a trivial task.
Next, this would seem to me to need to be an
AfterInsert, AfterUpdate trigger. Even if your org creates Opportunities that are already Closed-Won, then you'd still want to create this as an After Insert so you'd have the necessary Id's needed to relate the child Opps to their parents. You just couldn't do that with a
I also see that you've declared a Method within a trigger. You can call a class method from within a trigger to run the logic for you, but you can't declare one. You need to write that code separately. You'd use something like the Tidy Bulkified Trigger Pattern where you'd pass Trigger.new and Trigger.Old and possibly other things to the Class.
Below, I've rewritten your trigger code to show you the gist of the logic you'll want to have for the basic trigger. You can always move that logic to an external class using the above reference as a guide.
trigger ParentOppToChild on Opportunity (AfterInsert, AfterUpdate)
set<Id>oids = new set<Id>();
For(Opportunity o : trigger.new)
if(o.StageName = 'Closed-Won' && trigger.oldmap.get(o.Id).StageName != 'Closed-Won`)
//get opp.ids where stageName has just changed to Closed Won
map<Id,Opportunity>OppOLI = new map<Id,Opportunity>([SELECT Id, Name, Account.Id, Account.Name, StageName, Amount,(SELECT Id,Quantity, PricebookEntry.Product2.Name, TotalPrice, Dealership__c FROM OpportunityLineItems FROM Opportunity WHERE Id IN : oids];
//Have added more fields from OLI since you'll be duplicating them later. You'll probably want more.
//Extract Line Items
list<Account>Dealerships = new list<Account>();
map<Id,Dealership__c>Opp2Deal = new map<Id, Dealership__c>();
map<Id,Dealership__c>OLI2Deal = new map<Id, Dealership__c>();
map<Id,OpportunityLineItem>OliMap = new map<Id,OpportunityLineItem>();
For(Id OppId : OppOLI.keyset())
Opportunity opp = OppOLI.get(OppId);
List<OpportunityLineItem>OLI = opp.OpportunityLineItems;
for (OpportunityLineItem OppLI : OLI)
Account acc = new Account(Parent.Account = Opp.Account.Id, Id = OLI.Dealership__c);
// I've assumed the Dealers are child Accounts & Dealership__c is a look-up to Acct ID.
//Create new Opps for each Child Opp/Dealer
list<opportunity>toinsert = new list<opportunity>();
list<opportunityLineItem>oliInsert = new list<OpportunityLineItem>();
Decimal Amt = 0.00
For(opportunity o : oids)
Opportunity op = new Opportunity(Account = Opp2Deal.get(o.Id), Name = o.Name + ' Child', StageName = 'Pending' );
//Will leave details of Names and Stages to you
for(OpportunityLineItem oLnI : OLI2Deal.keyset())
for(Id olid : OLI2Deal.keyset())
if(OLI2Deal.get(olid).Dealership__c = Opp2Deal.get(o.Id)
OpportunityLineItem oppLnItm = new OpportunityLineItem(Quantity = OliMap.get(olid).Quantity, PricebookEntry.Product2.Name = OliMap.get(olid).PricebookEntry.Product2.Name, TotalPrice = OliMap.get(olid).TotalPrice);
// creates new line item for each matching Dealership__c OLI record
Amt += oppLnItm.TotalPrice;
//Calculates total of line items to get Opp Amount
op.Amount = Amt;
// add each OLI list to map separately to retrieve later to add Opp.ID
Amt = 0.00;
//reset Amt to 0
//insert the new Opps
integer i = 0;
list<OpportunityLineItem>oliInlst = new list<OpportunityLineItem>();
//Add Opp Ids to OLI's before insertion
for(opportunity opty : toinsert)
list<OpportunityLineItem>oliInlst = Opp2OLI.get(toinsert[i]);
//To be safe, using counter since lists in orig map didn't have Ids before insertion
for(OpportunityLineItem opli : oliInlst)
opli.OpportunityId = opty.Id;
//Insert related OLI records
}// end of trigger
Note: The above code has not been tested or debugged. It is intended as a guide. Check your org for required fields to create these objects. Also be sure to add plenty of debug statements as you proceed.
Edited to add One limitation of this code is that multiple Opps containing the same Dealership__c could be problematic. They might wind up being combined into a single Opportunity even though they may have come from different parents.
This code doesn't create a Parent-Child relationship of the Opps as there isn't a field I know of that does that (didn't see one in the Object Reference). You could choose to create a Parent Opp field to relate them or use the Name of the parent Opp as I did above as the first part of the child Opp's Name to help create the reference. Having a clearly defined Parent-child relationship could be used to solve any issues related to mulitple Opps hitting the trigger containing the same Dealership__c in it's record not being combined in the same new Opportunity.
The only other way I know of around the issue be to use hash code which is an advanced coding method. I strongly suspect introducing hash methods would make it very difficult for you to debug or modify your code in the future.