[SalesForce] Making trigger into a custom button

I am new to Salesforce development. I made a trigger that creates a new asset record and autofills some of the fields on said record. What I want ultimately would be a button that I can put on the "Products" related list on the opportunity page that does what my trigger does. From what I understand, I can't just call my trigger on the button click, and I have to create a VF page or an Apex class that uses the trigger's logic. Does anyone know how I would go about doing this? Here's my code:

trigger ConvertOpportunitiesToAssets on Opportunity (after update) {

    List<Asset> a = new List<Asset>();
    OpportunityLineItem oli = new OpportunityLineItem();

    for(Opportunity o: Trigger.new)
    {          
        a.add( new Asset(
            PSI_Supplier__c = o.Supplier__c,
            PSI_Opportunity__c = oli.Product2Id,
            AccountId = o.Accountid,
            Name = oli.Product2Id,
            Product2Id = oli.Product2Id,
            Product_Name__c = oli.Product_Name__c
            ));       
    }
    insert a;
}

Thanks in advance!

UPDATE So I tried making the trigger into a class and button (thanks sfdcfox!), but now it won't work. Here's what I've got:

    global class OpportunityWS{
    webservice static void createAsset(Id opportunityId)
    {
        List<Asset> a = new List<Asset>();
        Opportunity o = new Opportunity();
        OpportunityLineItem oli = new OpportunityLineItem();

        a.add( new Asset(
            PSI_Supplier__c = o.Supplier__c,
            PSI_Opportunity__c = oli.Product2Id,
            AccountId = o.Accountid,
            Name = oli.Product2Id,
            Product2Id = oli.Product2Id,
            Product_Name__c = oli.Product_Name__c
            ));       

        insert a;

    }
}

{!RequireScript("/soap/ajax/34.0/connection.js")}
{!RequireScript("/soap/ajax/34.0/apex.js")}
function success() {
var alertString="Success!"; 
alert(alertString); 
}
function error() {
var alertString="Error!"; 
alert(alertString); 
}
sforce.connection.sessionId = "{!$Api.Session_ID}";
sforce.apex.execute("OpportunityWS", "createAsset", { opportunityId: "{!Opportunity.Id}" }, { onSuccess: success, onFailure: error });

I can't tell if it's something wrong with the class or the button. I think it must be the class.

UPDATE(AGAIN) Alright so I followed Doug's advice and tried to use the opportunityId to query the opportunity and opportunityLineItem sobjects, was able to compile without errors. But now I'm getting the error message that I made in the button thrown and the asset isn't being created. Unfortunately, I haven't been able to track down the issue. Here's the OpportunityWS apex class that I've updated since last edit:

global class OpportunityWS{
webservice static void createAsset(Id opportunityId)
{
    List<Asset> a = new List<Asset>();
    List<Opportunity> o = [SELECT Supplier__c, Accountid FROM Opportunity WHERE Id = :opportunityId];
    List<OpportunityLineItem> oli = [SELECT Product2Id, Product_Name__c FROM OpportunityLineItem WHERE Id = :opportunityId];

    a.add( new Asset(
        PSI_Supplier__c = o[0].Supplier__c,
        PSI_Opportunity__c = oli[0].Product2Id,
        AccountId = o[1].Accountid,
        Name = oli[0].Product2Id,
        Product2Id = oli[0].Product2Id,
        Product_Name__c = oli[1].Product_Name__c
        ));       

    insert a;
}

}

Best Answer

First, make your trigger into a static webservice function:

global class OpportunityWS {
    webservice static void createAsset(Id opportunityId) {
    // Do logic here
    }
}

Then, create a custom JS button or link on the opportunity:

{!RequireScript("/soap/ajax/34.0/connection.js")}
{!RequireScript("/soap/ajax/34.0/apex.js")}
function success() {
    // Indicate success
}
function error() {
    // Indicate failure
}
sforce.connection.sessionId = "{!$Api.Session_ID}";
sforce.apex.execute("OpportunityWS", "createAsset", { opportunityId: "{!Opportunity.Id}" }, { onSuccess: success, onFailure: error });

I've left a few placeholders here for you to figure out, but that's basically it.

For more information, see the AJAX Toolkit documentation on using Apex from JS.

You might also choose to make a list view version, in which case you'd want to accept a List of Id values instead. Don't forget to query any data you need.

Related Topic