-
ChatterFeed
-
0Best Answers
-
2Likes Received
-
0Likes Given
-
22Questions
-
37Replies
pass lookup inputfield to extension
Hi,
So I have an input field :<b>To: </b> <apex:inputfield value="{!q.contactid}"/><p/>
and in my controller, I have:
public Quote q {get;set;}
and then I would like to present the email address in this outputfield: <b>NAME: </b> <apex:outputtext value="{!q.contact.name}"/><p/>
However this is not working, Please help:
Below is my VF page:
and my extension:
So I have an input field :<b>To: </b> <apex:inputfield value="{!q.contactid}"/><p/>
and in my controller, I have:
public Quote q {get;set;}
and then I would like to present the email address in this outputfield: <b>NAME: </b> <apex:outputtext value="{!q.contact.name}"/><p/>
However this is not working, Please help:
Below is my VF page:
<apex:page standardController="Quote" extensions="email_class"> <apex:form > <apex:pageBlock title="Email Details" id="ed"> <b>To: </b> <apex:inputfield value="{!q.contactid}"/><p/> <apex:actionSupport event="onchange" action="{!Contactpopulated}" rerender="ed"/> <b>NAME: </b> <apex:outputtext value="{!q.contact.email}"/><p/> ....... .......
and my extension:
public class email_class{ Public string ToAddresses {get;set;} Public string CCAddresses {get;set;} Public string quoteId {get;set;} Public string subject {get;set;} public string email_body {get;set;} public string emailTo {get;set;} public string emailCC {get;set;} public Quote q {get;set;} // public Contact ct {get;set;} public string [] ccaddress; public email_class(ApexPages.StandardController controller) { quoteId = ApexPages.currentPage().getParameters().get('id'); Quote q= (Quote)controller.getRecord(); } public void Contactpopulated(){ q.contact=[ Select email, name From contact where id=:q.contactid limit 1]; }
- Sammy7
- March 09, 2017
- Like
- 0
Whats wrong with this code?
I can excute this fine in excute anonymous, but when I put it in the class, I get "Unexpected token: '='" at LINE 5
public class testProduct { public Product2 shipping {get;set;} shipping = [SELECT id, name, productcode from PRODUCT2 where productcode='shipping' limit 1];
- Sammy7
- February 27, 2017
- Like
- 0
System.QueryException: line 1:283 no viable alternative at character '%'
I dont get this error...I tried retyping the quotes. Please help:
System.QueryException: line 1:282 no viable alternative at character '%'
Class.opportunityProductEntryExtension.updateAvailableList: line 119, column 1
Class.opportunityProductEntryTests.theTests: line 53, column 1
System.QueryException: line 1:282 no viable alternative at character '%'
Class.opportunityProductEntryExtension.updateAvailableList: line 119, column 1
Class.opportunityProductEntryTests.theTests: line 53, column 1
public with sharing class opportunityProductEntryExtension { public Opportunity theOpp {get;set;} public String searchString {get;set;} public opportunityLineItem[] shoppingCart {get;set;} public priceBookEntry[] AvailableProducts {get;set;} public Pricebook2 theBook {get;set;} public String toSelect {get; set;} public String toUnselect {get; set;} public Decimal Total {get;set;} public Boolean overLimit {get;set;} public Boolean multipleCurrencies {get; set;} private Boolean forcePricebookSelection = false; private opportunityLineItem[] forDeletion = new opportunityLineItem[]{}; public opportunityProductEntryExtension(ApexPages.StandardController controller) { // Need to know if org has multiple currencies enabled multipleCurrencies = UserInfo.isMultiCurrencyOrganization(); // Get information about the Opportunity being worked on if(multipleCurrencies) theOpp = database.query('select Id, Pricebook2Id, Pricebook2.Name, CurrencyIsoCode from Opportunity where Id = \'' + controller.getRecord().Id + '\' limit 1'); else theOpp = [select Id, Pricebook2Id, PriceBook2.Name from Opportunity where Id = :controller.getRecord().Id limit 1]; // If products were previously selected need to put them in the "selected products" section to start with shoppingCart = [select Id, Quantity, TotalPrice, UnitPrice, Description, PriceBookEntryId, PriceBookEntry.Name, PriceBookEntry.IsActive, PriceBookEntry.Product2Id, PriceBookEntry.Product2.Name, PriceBookEntry.PriceBook2Id from opportunityLineItem where OpportunityId=:theOpp.Id]; // Check if Opp has a pricebook associated yet if(theOpp.Pricebook2Id == null){ Pricebook2[] activepbs = [select Id, Name from Pricebook2 where isActive = true limit 2]; if(activepbs.size() == 2){ forcePricebookSelection = true; theBook = new Pricebook2(); } else{ theBook = activepbs[0]; } } else{ theBook = theOpp.Pricebook2; } if(!forcePricebookSelection) updateAvailableList(); } // this is the 'action' method on the page public PageReference priceBookCheck(){ // if the user needs to select a pricebook before we proceed we send them to standard pricebook selection screen if(forcePricebookSelection){ return changePricebook(); } else{ //if there is only one active pricebook we go with it and save the opp if(theOpp.pricebook2Id != theBook.Id){ try{ theOpp.Pricebook2Id = theBook.Id; update(theOpp); } catch(Exception e){ ApexPages.addMessages(e); } } return null; } } public String getChosenCurrency(){ if(multipleCurrencies) return (String)theOpp.get('CurrencyIsoCode'); else return ''; } public void updateAvailableList() { // We dynamically build a query string and exclude items already in the shopping cart String qString = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.ProductCode, Product2.Family, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and Pricebook2Id = \'' + theBook.Id + '\''; if(multipleCurrencies) qstring += 'and CurrencyIsoCode = \'' + theOpp.get('currencyIsoCode') + '\''; // note that we are looking for the search string entered by the user in the name OR description // modify this to search other fields if desired if(searchString!=null){ qString+= 'and (Product2.Name like \'%' + searchString + '%\' or Product2.ProductCode like \'%' + searchString + '%\')'; } Set<Id> selectedEntries = new Set<Id>(); for(opportunityLineItem d:shoppingCart){ selectedEntries.add(d.PricebookEntryId); } if(selectedEntries.size()>0){ String tempFilter = ' and Id not in ('; for(Id i : selectedEntries){ tempFilter+= '\'' + (String)i + '\','; } String extraFilter = tempFilter.substring(0,tempFilter.length()-1); extraFilter+= ')'; qString+= extraFilter; } qString+= ' order by Product2.Name'; qString+= ' limit 101'; system.debug('qString:' +qString); AvailableProducts = database.query(qString); // We only display up to 100 results... if there are more than we let the user know (see vf page) if(AvailableProducts.size()==101){ AvailableProducts.remove(100); overLimit = true; } else{ overLimit=false; } } public void addToShoppingCart(){ // This function runs when a user hits "select" button next to a product for(PricebookEntry d : AvailableProducts){ if((String)d.Id==toSelect){ shoppingCart.add(new opportunityLineItem(OpportunityId=theOpp.Id, PriceBookEntry=d, PriceBookEntryId=d.Id, UnitPrice=d.UnitPrice)); break; } } updateAvailableList(); } public PageReference removeFromShoppingCart(){ // This function runs when a user hits "remove" on an item in the "Selected Products" section Integer count = 0; for(opportunityLineItem d : shoppingCart){ if((String)d.PriceBookEntryId==toUnselect){ if(d.Id!=null) forDeletion.add(d); shoppingCart.remove(count); break; } count++; } updateAvailableList(); return null; } public PageReference onSave(){ // If previously selected products are now removed, we need to delete them if(forDeletion.size()>0) delete(forDeletion); // Previously selected products may have new quantities and amounts, and we may have new products listed, so we use upsert here try{ if(shoppingCart.size()>0) upsert(shoppingCart); } catch(Exception e){ ApexPages.addMessages(e); return null; } // After save return the user to the Opportunity return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id')); } public PageReference onCancel(){ // If user hits cancel we commit no changes and return them to the Opportunity return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id')); } public PageReference changePricebook(){ // This simply returns a PageReference to the standard Pricebook selection screen // Note that is uses retURL parameter to make sure the user is sent back after they choose PageReference ref = new PageReference('/oppitm/choosepricebook.jsp'); ref.getParameters().put('id',theOpp.Id); ref.getParameters().put('retURL','/apex/opportunityProductEntry?id=' + theOpp.Id); return ref; } }
@istest private class opportunityProductEntryTests { static testMethod void theTests(){ // You really should create test data, but I'm going to query instead // It's my best shot of avoiding a test failure in most orgs // Once you've installed this package though, you might want to write your own tests // or at least customize these ones to make them more applicable to your org OpportunityLineItem oli = [select Id, PricebookEntryId, PricebookEntry.Pricebook2Id, PricebookEntry.Name, PriceBookEntry.Product2Id, OpportunityId, Opportunity.AccountId from OpportunityLineItem limit 1]; //////////////////////////////////////// // test opportunityProductEntry //////////////////////////////////////// // load the page PageReference pageRef = Page.opportunityProductEntry; pageRef.getParameters().put('Id',oli.OpportunityId); Test.setCurrentPageReference(pageRef); // load the extension opportunityProductEntryExtension oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(oli.Opportunity)); // test 'getChosenCurrency' method if(UserInfo.isMultiCurrencyOrganization()) System.assert(oPEE.getChosenCurrency()!=''); else System.assertEquals(oPEE.getChosenCurrency(),''); // we know that there is at least one line item, so we confirm Integer startCount = oPEE.ShoppingCart.size(); system.assert(startCount>0); //test search functionality without finding anything oPEE.searchString = 'michaelforce is a hip cat'; oPEE.updateAvailableList(); system.assert(oPEE.AvailableProducts.size()==0); //test remove from shopping cart oPEE.toUnselect = oli.PricebookEntryId; oPEE.removeFromShoppingCart(); system.assert(oPEE.shoppingCart.size()==startCount-1); //test save and reload extension oPEE.onSave(); oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(oli.Opportunity)); system.assert(oPEE.shoppingCart.size()==startCount-1); // test search again, this time we will find something oPEE.searchString = oli.PricebookEntry.Name; oPEE.updateAvailableList(); system.assert(oPEE.AvailableProducts.size()>0); // test add to Shopping Cart function oPEE.toSelect = oPEE.AvailableProducts[0].Id; oPEE.addToShoppingCart(); system.assert(oPEE.shoppingCart.size()==startCount); // test save method - WITHOUT quanitities and amounts entered and confirm that error message is displayed oPEE.onSave(); system.assert(ApexPages.getMessages().size()>0); opEE.addtoshoppingcart(); // add required info and try save again for(OpportunityLineItem o : oPEE.ShoppingCart){ o.quantity = 5; o.unitprice = 300; } oPEE.onSave(); // query line items to confirm that the save worked opportunityLineItem[] oli2 = [select Id from opportunityLineItem where OpportunityId = :oli.OpportunityId]; system.assert(oli2.size()==startCount); // test on new Opp (no pricebook selected) to make sure redirect is happening Opportunity newOpp = new Opportunity(Name='New Opp',stageName='Pipeline',Amount=10,closeDate=System.Today()+30,AccountId=oli.Opportunity.AccountId); insert(newOpp); oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(newOpp)); System.assert(oPEE.priceBookCheck()!=null); // final quick check of cancel button System.assert(oPEE.onCancel()!=null); //////////////////////////////////////// // test redirect page //////////////////////////////////////// // load the page pageRef = Page.opportunityProductRedirect; pageRef.getParameters().put('Id',oli2[0].Id); Test.setCurrentPageReference(pageRef); // load the extension and confirm that redirect function returns something opportunityProductRedirectExtension oPRE = new opportunityProductRedirectExtension(new ApexPages.StandardController(oli2[0])); System.assert(oPRE.redirect()!=null); } }
- Sammy7
- February 07, 2017
- Like
- 0
Test class for send email fail
Hi,
Im getting the following error and cannot figure out why:
System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email address is invalid: null: [toAddresses, null]
Class.email_class.send: line 48, column 1
Class.TestquoteEmailclass.sendEmailTestMethod: line 47, column 1
Below is my test class:
And my controller:
Any help is appreciated !
Im getting the following error and cannot figure out why:
System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email address is invalid: null: [toAddresses, null]
Class.email_class.send: line 48, column 1
Class.TestquoteEmailclass.sendEmailTestMethod: line 47, column 1
Below is my test class:
@isTest public class TestquoteEmailclass { @isTest static void sendEmailTestMethod(){ Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; PricebookEntry pbe=new PricebookEntry(unitprice=0.01,Product2Id=prod.Id, Pricebook2Id=Test.getStandardPricebookId(), IsActive= true); insert pbe; Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (name='Testopp', Accountid=acc.id, CloseDate= date.today(), StageName='Closed Won', Pricebook2id=Test.getStandardPricebookId()); insert opp; OpportunityLineItem oppLine = new OpportunityLineItem( pricebookentryid=pbe.Id,TotalPrice=2000, Quantity = 2,Opportunityid = opp.Id); insert oppLine; Quote q= new Quote (Name='Testq', Opportunityid=opp.id, QuotetoInvoice__c= True, Pricebook2id=Test.getStandardPricebookId()); insert q; System.currentPagereference().getParameters().put('id',q.id); Attachment objAtt = new Attachment(); objAtt.Name = 'Test'; objAtt.body = Blob.valueof('string'); objAtt.ParentId = q.Id; insert objAtt; ApexPages.StandardController sc =new ApexPages.StandardController(q); email_class ec=new email_class (sc); ec.ToAddresses='test@gmail.com'; ec.CCAddresses='test2@gmail.com'; ec.emailCC= 'test3@gmail.com'; ec.email_body='test1111111'; ec.subject='test22222'; Messaging.InboundEmail email = new Messaging.InboundEmail(); Messaging.InboundEnvelope env = new Messaging.InboundEnvelope(); email.plainTextBody = 'This should become a note'; email.fromAddress ='test@test.com'; String contactEmail = 'jsmith@salesforce.com'; email.ccAddresses = new String[] {'Jon Smith <' + contactEmail + '>'}; email.subject = 'Dummy Account Name 123'; ec.send(); } }
And my controller:
public class email_class{ Public string ToAddresses {get;set;} Public string CCAddresses {get;set;} Public string quoteId {get;set;} Public string subject {get;set;} public string email_body {get;set;} public string emailTo {get;set;} public string emailCC {get;set;} public string [] ccaddress; public email_class(ApexPages.StandardController controller) { quoteId = ApexPages.currentPage().getParameters().get('id'); } Public PageReference send(){ Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); // set the to address mail.setToAddresses(new String[] {emailTo}); // mail.setCCAddresses(new String[] {emailCC}); //set the cc address if(emailCC != null && emailCC.trim() != '') { ccaddress = emailCC.split(',',0); mail.setCCAddresses(ccaddress);} mail.setSubject(subject); mail.setBccSender(false); mail.setUseSignature(false); mail.setPlainTextBody(email_body); List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>(); for (Attachment a : [select Name, Body, BodyLength from Attachment where ParentId = :quoteId]){ // Add to attachment file list Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment(); efa.setFileName(a.Name); efa.setBody(a.Body); fileAttachments.add(efa); } mail.setFileAttachments(fileAttachments);// Send email Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); return null; } }
Any help is appreciated !
- Sammy7
- January 26, 2017
- Like
- 1
Help: Need "SEND EMAIL" button on QUOTE detail page that attaches the attachment from "Notes & Attachment" section
Hi,
I need the ability to send an email from a quote detail page that automatically attaches the file (only one file) under "Notes&Attachment" section.
So there are two ways I envision this:
1) A button that sends email (gets address from "Email" field under Quote detail page) and attaches the file
2) A button that opens up the standard email page with the attachment already attached and I can lookup the contact and write the message and send an email
I have no idea which is easier and what are the steps to accomplish this, so any guidance is appreciated.
Thanks.
I need the ability to send an email from a quote detail page that automatically attaches the file (only one file) under "Notes&Attachment" section.
So there are two ways I envision this:
1) A button that sends email (gets address from "Email" field under Quote detail page) and attaches the file
2) A button that opens up the standard email page with the attachment already attached and I can lookup the contact and write the message and send an email
I have no idea which is easier and what are the steps to accomplish this, so any guidance is appreciated.
Thanks.
- Sammy7
- January 25, 2017
- Like
- 0
Attach a visualforce custom quote page to quotePDFs
Hi,
I overrode the "Createpdf" button on quote page with a custom VF page (Quotecustom). I would like to create another button on quote page that lets me save that pdf as an attachment to the QuotePDF related list.
What are the steps to do this?
I know I need a controller that looks something like this:
THanks.
I overrode the "Createpdf" button on quote page with a custom VF page (Quotecustom). I would like to create another button on quote page that lets me save that pdf as an attachment to the QuotePDF related list.
What are the steps to do this?
I know I need a controller that looks something like this:
public class attachPDFToquote { private final quote q; //quote object //constructor public attachPDFToquote(ApexPages.StandardController standardPageController) { q = (Quote)standardPageController.getRecord(); //instantiate the quote object for the current record } //method called from the Visualforce's action attribute public PageReference attachPDF() { //generate and attach the PDF document PageReference pdfPage = Page.quotecustom; //create a page reference to quote custom Visualforce page Blob pdfBlob = pdfPage.getContent(); //get the output of the page, as displayed to a user in a browser Attachment attach = new Attachment(parentId = q.Id, Name = 'pdfAttachmentDemo.pdf', body = pdfBlob); //create the attachment object insert attach; //insert the attachment //redirect the user PageReference pageWhereWeWantToGo = new ApexPages.StandardController(q).view(); //we want to redirect the User back to the quote detail page pageWhereWeWantToGo.setRedirect(true); //indicate that the redirect should be performed on the client side return pageWhereWeWantToGo; //send the User on their way } }Im confused about the next step...do I have to create another seperate VF page or add the controller as an "extension" to my Quotecustom VF page. Please excuse my misunderstandings as Im new to this.
THanks.
- Sammy7
- December 05, 2016
- Like
- 1
invalid foreign key relationship: access field on custom object with master detail to opportunity
So I have custom object (invoice__c) with master-detail to opportunity. I have a custom field (AF_LastSyncTime__c ) on invoice__c that Im trying to access.
so here is my query:
No error with query, but I get invalid foreign key relationship in the if statement....why is that?
Thanks.
so here is my query:
for (Opportunity opp : [select Id, (select id, AF_LastSyncTime__c from Invoices__r), (select Id, Invoice_No__c, QuotetoInvoice__c, CreatedDate from Quotes order by CreatedDate DESC) from Opportunity where Id IN :oppsId]) { if (opp.Invoices__r.AF_LastSyncTime__c==null) return 'blah blah blah'; }
No error with query, but I get invalid foreign key relationship in the if statement....why is that?
Thanks.
- Sammy7
- November 01, 2016
- Like
- 0
Unknown property 'VisualforceArrayLisy.description'
Hi,
Im new to visualforce and Im trying to understand why I cant iterate through the quote line items using the apex:repeat tag in the below SOQL:
Im new to visualforce and Im trying to understand why I cant iterate through the quote line items using the apex:repeat tag in the below SOQL:
<apex:page controller="myquote" showHeader="false" sidebar="false" > <apex:stylesheet value="{!URLFOR($Resource.advancedpdfresource, 'qstyles.css')}"/> <apex:repeat value="{!quote}" var="qli"> <apex:dataTable value="{!qli}" var="q" > <apex:column style="border: 1px"> <apex:facet name="header">Quote Line Item</apex:facet> <apex:outputText value="{!q.quotelineitems.description}"/> </apex:column> </apex:dataTable> </apex:repeat> </apex:page> <!----Controller-----> public class myquote { List <Quote> quote= [Select id, name, BillingAddress, BillingName, quotenumber,(SELECT id, Description, ListPrice, PricebookEntry.name, PricebookEntry.ProductCode, TotalPrice, Quantity FROM quotelineitems) from QUOTE WHERE id=: ApexPages.CurrentPage().Getparameters().get('id')]; public List<Quote> getquote () { return quote;} }
- Sammy7
- October 19, 2016
- Like
- 0
Steps to generate a custom quote/invoice pdf
Hi guys, the quote template has lots of limitations when it comes to styling; I would like to do something custom and need a step-by-step guide. Basically, I would like a "create quote" button on quote pagelayout that references my visualforce page and creates the pdf.
So I think I need to follow the steps below:
1. Create a custom controller class. Can I do this with standard List controller? Basically, I have to query all the quote and quotelineitems
2. Create a new visual force page using controller from step1, add the proper styling and render as pdf.
3. Create the button on quote with a link to visual force page
Any tips and guides are appreciated.
Thanks.
Did I miss anything?
So I think I need to follow the steps below:
1. Create a custom controller class. Can I do this with standard List controller? Basically, I have to query all the quote and quotelineitems
2. Create a new visual force page using controller from step1, add the proper styling and render as pdf.
3. Create the button on quote with a link to visual force page
Any tips and guides are appreciated.
Thanks.
Did I miss anything?
- Sammy7
- October 17, 2016
- Like
- 0
Allow only sys admin to change stage name validation rule not working
HI,
I have the following validation rule:
AND(
$Profile.Name <> "System Administrator",
ISCHANGED(StageName),
(TEXT(StageName) = "Closed Lost" || TEXT(StageName) = "Closed Won"))
I want only the system admin profile to able to close opportunity. Yet, I logged in as a std user and was able to create a new opportunity and set the stage to closed won and it saved the record....
I have the following validation rule:
AND(
$Profile.Name <> "System Administrator",
ISCHANGED(StageName),
(TEXT(StageName) = "Closed Lost" || TEXT(StageName) = "Closed Won"))
I want only the system admin profile to able to close opportunity. Yet, I logged in as a std user and was able to create a new opportunity and set the stage to closed won and it saved the record....
- Sammy7
- October 13, 2016
- Like
- 0
getting null pointer exception even with seealldate=true for test class on custom setting
Hi ,
I already have the custom setting in my sandbox org and my test class with seealldata=true. So why am I getting this:
EXCEPTION_THROWN|[33]|System.NullPointerException: Attempt to de-reference a null object
When I test the same EXACT test class in my developer org, I get 86% coverage. It drops to 21% in sandbox org....whats going on?
I already have the custom setting in my sandbox org and my test class with seealldata=true. So why am I getting this:
EXCEPTION_THROWN|[33]|System.NullPointerException: Attempt to de-reference a null object
When I test the same EXACT test class in my developer org, I get 86% coverage. It drops to 21% in sandbox org....whats going on?
- Sammy7
- October 06, 2016
- Like
- 0
Help with web service test class
So I have this method that I slightly modified from http://www.valnavjo.com.
All it does is when I press custom buttom "Generate Invoice" it uses a template "Invoice" from quotes template to generate and attach
the invoice pdf to Attachment section of opportunity. I dont know why Im getting only 23% coverage as I invoke the method.
Also, I dont know why it is not creating the attachment in my test class when I check in system assert. Please help.
Below is the method:
global with sharing class InvoicePdfWsSample { /** * Default header height for invoice */ private static final String DEFAULT_INVOICE_HEADER_HEIGHT = '100'; /** * Default footer height for invoice */ private static final String DEFAULT_INVOICE_FOOTER_HEIGHT = '100'; /** * Webservice method that is called from a custom button to generate * an invoice PDF file using quote templates feature. * It generates the invoice based on: * - The synced Quote, or * - The latest Quote * If the Opportunity doesn't have any Quotes, this method doesn't do * anything. * * This method uses PageReference.getContent(). * * @param oppsIdList {List<Id>} list of Opportunity Ids from where the method * will generate the Invoice PDF. * @return {String} with an error message, if any. Blank otherwise. */ webService static String generateInvoicePdf(List<Id> oppsIdList) { try { //From list to set final Set<Id> oppsId = new Set<Id>(oppsIdList); //Get template Id for Invoice and url to hack pdf generation final String invoiceTemplateId = Application_Properties__c.getAll().get('Invoice_Template_Id').value__c; String invoiceHeaderHeight = Application_Properties__c.getAll().get('Invoice_Header_Height').value__c; String invoiceFooterHeight = Application_Properties__c.getAll().get('Invoice_Footer_Height').value__c; final String quoteTemplateDataViewerUrl = Application_Properties__c.getAll().get('Quote_Template_Data_Viewer_URL').value__c; //Pre-validations //Invoice_Template_Id and Quote_Template_Data_Viewer_URL are mandatory if (String.isBlank(invoiceTemplateId) || String.isBlank(quoteTemplateDataViewerUrl)) { String errorMsg = 'Invoice Template Id or Quote Template Data Viewer URL are blank, please review their values in Application Properties custom setting.'; return errorMsg; } //Default values for invoice header/footer height if (String.isBlank(invoiceHeaderHeight)) invoiceHeaderHeight = DEFAULT_INVOICE_HEADER_HEIGHT; if (String.isBlank(invoiceFooterHeight)) invoiceFooterHeight = DEFAULT_INVOICE_FOOTER_HEIGHT; //Iterate over Opps and generate Attachments list final List<Attachment> attList = new List<Attachment>(); for (Opportunity opp : [select Id, (select Id, Invoice_No__c, QuotetoInvoice__c, CreatedDate from Quotes order by CreatedDate DESC) from Opportunity where Id IN :oppsId]) { //No Quotes, no party if (opp.Quotes.isEmpty()) continue; //Synced quote Quote theQuote = null; //Try to get the synced one for (Quote quoteAux : opp.Quotes) { if (quoteAux.Quotetoinvoice__c) { theQuote = quoteAux; } } //No synced Quote, get the last one if (theQuote == null) return 'Select a Quote to Invoice under Quotes section'; PageReference pageRef = new PageReference( quoteTemplateDataViewerUrl.replace('{!QuoteId}', theQuote.Id) .replace('{!InvoiceHeaderHeight}', invoiceHeaderHeight) .replace('{!InvoiceFooterHeight}', invoiceFooterHeight) .replace('{!InvoiceTemplateId}', invoiceTemplateId) ); attList.add( new Attachment( Name = 'Invoice #' + theQuote.Invoice_No__c + '.pdf', Body = pageRef.getContent(), ParentId = opp.Id ) ); } //Create Attachments if (!attList.isEmpty()) insert attList; return ''; } catch (Exception e) { System.debug(LoggingLevel.ERROR, e.getMessage()); final String errorMsg = 'An error has occured while generating the invoice. Details:\n\n' + e.getMessage() + '\n\n' + e.getStackTraceString(); return errorMsg; } } }
and the test class;
@isTest private class TestInvoicepdfclass { @isTest static void testpdfbutton(){ Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book 2009', Description = 'Price Book 2009 Products', IsActive = true ); insert pb; Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; PricebookEntry pbe=new PricebookEntry(unitprice=0.01,Product2Id=prod.Id, Pricebook2Id=Test.getStandardPricebookId(), IsActive= true); insert pbe; // insert opp Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (); opp.name= 'Testopp'; Opp.Accountid= acc.id; opp.CloseDate= date.today(); opp.StageName= 'Closed Won'; opp.Pricebook2id=Test.getStandardPricebookId(); insert opp; OpportunityLineItem oppLine = new OpportunityLineItem( pricebookentryid=pbe.Id,TotalPrice=2000, Quantity = 2,Opportunityid = opp.Id); insert oppLine; // insert quote Quote q= new Quote (); q.Name= 'Testq'; q.OpportunityId= Opp.id; q.quotetoinvoice__C= True; q.REP__C= 'AC' ; q.BillingStreet= '123'; q.BillingCity= 'City'; q.BillingPostalCode= '12345'; q.Pricebook2Id= Test.getStandardPricebookId(); insert q; //add to list List<id> oppids= new List<id> (); oppids.add(opp.Id); // pass the list to the method InvoicepdfWsSample.generateInvoicepdf(oppids); List <Attachment> attlist= [SELECT id, name, parentid From Attachment WHERE parentid IN :oppids]; System.assert (!attlist.isEmpty()); //check if attachment is present } }
- Sammy7
- September 28, 2016
- Like
- 0
Test.getStandardPricebookId() broke overnight?
isTest private class TestInvoicepdfclass { static testmethod void testpdfbutton (){ Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book 2009', Description = 'Price Book 2009 Products', IsActive = true ); insert pb; Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; PricebookEntry pbe=new PricebookEntry(unitprice=0.01,Product2Id=prod.Id, Pricebook2Id=Test.getStandardPricebookId() , IsActive= true); insert pbe; Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (); Opportunity opp2= new Opportunity (); opp.name= 'Testopp'; Opp.Accountid= acc.id; opp.CloseDate= date.today(); opp.StageName= 'Closed Won'; opp.Pricebook2id=Test.getStandardPricebookId(); opp2.name= 'Testopp2'; Opp2.Accountid= acc.id; opp2.CloseDate= date.today(); opp2.StageName= 'Closed Won'; opp2.Pricebook2id=Test.getStandardPricebookId(); insert opp; insert opp2; OpportunityLineItem oppLine = new OpportunityLineItem( pricebookentryid=pbe.Id,TotalPrice=2000, Quantity = 2,Opportunityid = opp.Id); insert oppLine; Quote q= new Quote (); q.Name= 'Testq'; q.OpportunityId= Opp.id; q.quotetoinvoice__C= True; q.REP__C= 'AC' ; q.BillingStreet= '123'; q.BillingCity= 'City'; q.BillingPostalCode= '12345'; q.Pricebook2Id= Test.getStandardPricebookId(); List<id> oppids= new List<id> (); oppids.add(opp.Id); oppids.add(opp2.id); InvoicePdfWsSample.generateInvoicePdf(oppids); } }
I dont understand, Im using this in my test class (above) it was working fine yesterday and today, its giving me this error:
line 9: Method does not exist or incorrect signature: Test.getStandardPricebookId()
Please advice. I'm using the same code in my other test class and it is not prompting any errors.....
- Sammy7
- September 28, 2016
- Like
- 0
Test class for generate invoice pdf
Hi,
I found this nice workaround to use quotetemplate to make invoice pdf from this blog: http://www.valnavjo.com/blog/how-to-create-invoices-using-quote-templates/
But I'm having trouble on how to write a test class for this:
I found this nice workaround to use quotetemplate to make invoice pdf from this blog: http://www.valnavjo.com/blog/how-to-create-invoices-using-quote-templates/
But I'm having trouble on how to write a test class for this:
global with sharing class InvoicePdfWsSample { /** * Default header height for invoice */ private static final String DEFAULT_INVOICE_HEADER_HEIGHT = '100'; /** * Default footer height for invoice */ private static final String DEFAULT_INVOICE_FOOTER_HEIGHT = '100'; /** * Webservice method that is called from a custom button to generate * an invoice PDF file using quote templates feature. * It generates the invoice based on: * - The synced Quote, or * - The latest Quote * If the Opportunity doesn't have any Quotes, this method doesn't do * anything. * * This method uses PageReference.getContent(). * * @param oppsIdList {List<Id>} list of Opportunity Ids from where the method * will generate the Invoice PDF. * @return {String} with an error message, if any. Blank otherwise. */ webService static String generateInvoicePdf(List<Id> oppsIdList) { try { //From list to set final Set<Id> oppsId = new Set<Id>(oppsIdList); //Get template Id for Invoice and url to hack pdf generation final String invoiceTemplateId = Application_Properties__c.getAll().get('Invoice_Template_Id').value__c; String invoiceHeaderHeight = Application_Properties__c.getAll().get('Invoice_Header_Height').value__c; String invoiceFooterHeight = Application_Properties__c.getAll().get('Invoice_Footer_Height').value__c; final String quoteTemplateDataViewerUrl = Application_Properties__c.getAll().get('Quote_Template_Data_Viewer_URL').value__c; //Pre-validations //Invoice_Template_Id and Quote_Template_Data_Viewer_URL are mandatory if (String.isBlank(invoiceTemplateId) || String.isBlank(quoteTemplateDataViewerUrl)) { String errorMsg = 'Invoice Template Id or Quote Template Data Viewer URL are blank, please review their values in Application Properties custom setting.'; return errorMsg; } //Default values for invoice header/footer height if (String.isBlank(invoiceHeaderHeight)) invoiceHeaderHeight = DEFAULT_INVOICE_HEADER_HEIGHT; if (String.isBlank(invoiceFooterHeight)) invoiceFooterHeight = DEFAULT_INVOICE_FOOTER_HEIGHT; //Iterate over Opps and generate Attachments list final List<Attachment> attList = new List<Attachment>(); for (Opportunity opp : [select Id, (select Id, Invoice_No__c, IsSyncing, CreatedDate from Quotes Where QuotetoInvoice__c= True order by CreatedDate DESC) from Opportunity where Id IN :oppsId]) { //No Quotes, no party if (opp.Quotes.isEmpty()) continue; //Synced quote Quote theQuote = null; //Try to get the synced one for (Quote quoteAux : opp.Quotes) { if (quoteAux.IsSyncing) { theQuote = quoteAux; break; } } //No synced Quote, get the last one if (theQuote == null) theQuote = opp.Quotes.get(0); PageReference pageRef = new PageReference( quoteTemplateDataViewerUrl.replace('{!QuoteId}', theQuote.Id) .replace('{!InvoiceHeaderHeight}', invoiceHeaderHeight) .replace('{!InvoiceFooterHeight}', invoiceFooterHeight) .replace('{!InvoiceTemplateId}', invoiceTemplateId) ); attList.add( new Attachment( Name = 'Invoice #' + theQuote.Invoice_No__c + '.pdf', Body = pageRef.getContent(), ParentId = opp.Id ) ); } //Create Attachments if (!attList.isEmpty()) insert attList; return ''; } catch (Exception e) { System.debug(LoggingLevel.ERROR, e.getMessage()); final String errorMsg = 'An error has occured while generating the invoice. Details:\n\n' + e.getMessage() + '\n\n' + e.getStackTraceString(); return errorMsg; } } }
- Sammy7
- September 27, 2016
- Like
- 0
Pricebook difficulty in test class
Hi , this is my first test class and Im not getting how the ids are different in this error. All Im trying to do is create a opp, quote, quotelineitem and close the opp so my trigger fires.
System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: PricebookEntryId (pricebook entry is in a different pricebook than the one assigned to the opportunity): [PricebookEntryId]
System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: PricebookEntryId (pricebook entry is in a different pricebook than the one assigned to the opportunity): [PricebookEntryId]
@isTest private class CreateInvoiceTestClass { @isTest static void insertOpp() { Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book 2009', Description = 'Price Book 2009 Products', IsActive = true ); insert pb; Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; PricebookEntry pbe=new PricebookEntry(unitprice=0.01,Product2Id=prod.Id, Pricebook2Id=Test.getStandardPricebookId(), IsActive= true); insert pbe; Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (); opp.name= 'Testopp'; Opp.Accountid= acc.id; opp.CloseDate= date.today(); opp.StageName= 'Qualification'; opp.Pricebook2id=pb.id; insert opp; OpportunityLineItem oppLine = new OpportunityLineItem( pricebookentryid=pbe.Id,TotalPrice=2000, Quantity = 2,Opportunityid = opp.Id); insert oppLine; Quote q= new Quote (); q.Name= 'Testq'; q.OpportunityId= Opp.id; q.quotetoinvoice__C= TRUE; q.REP__C= 'AC' ; q.BillingStreet= '123'; q.BillingCity= 'City'; q.BillingPostalCode= '12345'; q.Pricebook2Id= pb.id; insert q; QuoteLineItem qli= new QuoteLineItem(Quoteid=q.id, PricebookEntryid= pbe.Id, quantity=2, unitprice=10000); insert qli; opp.StageName= 'Closed Won'; } }
- Sammy7
- September 21, 2016
- Like
- 0
Need help with test class for quote
I am new to test classes, but Im pulling my hair on this one.
Below is my trigger to create an invoice from Quote once opp is closed and quotetoinvoice checkbox is ticked:
trigger CreateInvoice on Opportunity (after update, after insert) {
List<Invoice__c> invoiceList = new List<Invoice__c>();
List<InvoiceLineItem__c> invoiceLineItemList = new List<InvoiceLineItem__c>();
Set<Id> oppIdSet = new Set<Id>();
// We only care about opportunities that are closed won
for(Opportunity o : trigger.new)
{
if (o.stagename=='Closed Won')
{
oppIdSet.add(o.id);
}
}
// Need to grab all the quotes and their subsequent quotelineitems under all the opportunities that fired the trigger, but select quotes that has QuotetoInvoice=True
List<Quote> quoteList = [SELECT id, quotenumber, Accountid, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingName, Shippingname, ShippingStreet, ShippingCity, ShippingPostalCode, ShippingState, REP__c, Totalprice, Opportunityid, name, QuotetoInvoice__c,
(SELECT id, ListPrice, PricebookEntry.name, PricebookEntry.ProductCode, TotalPrice, Quantity FROM quotelineitems)
FROM Quote WHERE Opportunityid in: oppIdSet AND QuotetoInvoice__c=TRUE];
// Create an invoice for each quote
for (Quote q : quoteList)
{
Invoice__c newInvoice = new Invoice__c();
newInvoice.Invoice_number__c=q.quotenumber;
newInvoice.opportunity__c= q.Opportunityid;
newInvoice.Bill_To__c=q.Billingname;
newInvoice.BillingStreet__c=q.Billingstreet;
newInvoice.BillingCity__c= q.BillingCity;
newInvoice.BillingState__c= q.BillingState;
newInvoice.BillingZip__c= q.BillingPostalCode;
newInvoice.Ship_To__c=q.Shippingname;
newInvoice.ShippingStreet__c=q.Shippingstreet;
newInvoice.ShippingCity__c= q.ShippingCity;
newInvoice.ShippingState__c= q.ShippingState;
newInvoice.ShippingZip__c= q.ShippingPostalCode;
newInvoice.Total__c=q.Totalprice;
newInvoice.Customer__c=q.Accountid;
newInvoice.REP__c=q.REP__c;
invoiceList.add(newInvoice);
}
// We need to insert the invoices first, before being able to insert the invoicelineitems under it.
insert invoiceList;
// Construct this set as a copy of the invoiceList so we can remove from it easily later
Set<Invoice__c> invoiceSet = new Set<Invoice__c>(invoiceList);
// Create the invoicelineitems
for (Quote q : quoteList)
{
for (QuoteLineItem qli : q.quotelineitems)
{
InvoiceLineItem__c newInvLineItem = new InvoiceLineItem__c();
newInvLineItem.Invoiceid__c=qli.id;
newInvLineItem.Amount__c = qli.ListPrice;
newInvLineItem.Item__c = qli.PricebookEntry.ProductCode;
newInvLineItem.Description__c= qli.PricebookEntry.name;
newInvLineItem.Quantity__c= qli.quantity;
// We need to relate the invoicelineitem to the correct invoice
for (Invoice__c i : invoiceSet)
{
// Using quote number as an identifier
if (i.Invoice_Number__c == q.quotenumber)
{
newInvLineItem.Invoiceid__c= i.id;
}
}
invoiceLineItemList.add(newInvLineItem);
}
// We need to remove the invoice we just used from the set, just in case there are quotes with duplicate quote numbers.
for (Invoice__c i : invoiceSet)
{
if (i.name == q.name)
{
invoiceSet.remove(i);
}
}
}
insert invoiceLineItemList;
And this is my test class:
Keep getting error: System.QueryException: List has no rows for assignment to SObject, Class.CreateInvoiceTestClass.insertOpp line 18
Please help.
Below is my trigger to create an invoice from Quote once opp is closed and quotetoinvoice checkbox is ticked:
trigger CreateInvoice on Opportunity (after update, after insert) {
List<Invoice__c> invoiceList = new List<Invoice__c>();
List<InvoiceLineItem__c> invoiceLineItemList = new List<InvoiceLineItem__c>();
Set<Id> oppIdSet = new Set<Id>();
// We only care about opportunities that are closed won
for(Opportunity o : trigger.new)
{
if (o.stagename=='Closed Won')
{
oppIdSet.add(o.id);
}
}
// Need to grab all the quotes and their subsequent quotelineitems under all the opportunities that fired the trigger, but select quotes that has QuotetoInvoice=True
List<Quote> quoteList = [SELECT id, quotenumber, Accountid, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingName, Shippingname, ShippingStreet, ShippingCity, ShippingPostalCode, ShippingState, REP__c, Totalprice, Opportunityid, name, QuotetoInvoice__c,
(SELECT id, ListPrice, PricebookEntry.name, PricebookEntry.ProductCode, TotalPrice, Quantity FROM quotelineitems)
FROM Quote WHERE Opportunityid in: oppIdSet AND QuotetoInvoice__c=TRUE];
// Create an invoice for each quote
for (Quote q : quoteList)
{
Invoice__c newInvoice = new Invoice__c();
newInvoice.Invoice_number__c=q.quotenumber;
newInvoice.opportunity__c= q.Opportunityid;
newInvoice.Bill_To__c=q.Billingname;
newInvoice.BillingStreet__c=q.Billingstreet;
newInvoice.BillingCity__c= q.BillingCity;
newInvoice.BillingState__c= q.BillingState;
newInvoice.BillingZip__c= q.BillingPostalCode;
newInvoice.Ship_To__c=q.Shippingname;
newInvoice.ShippingStreet__c=q.Shippingstreet;
newInvoice.ShippingCity__c= q.ShippingCity;
newInvoice.ShippingState__c= q.ShippingState;
newInvoice.ShippingZip__c= q.ShippingPostalCode;
newInvoice.Total__c=q.Totalprice;
newInvoice.Customer__c=q.Accountid;
newInvoice.REP__c=q.REP__c;
invoiceList.add(newInvoice);
}
// We need to insert the invoices first, before being able to insert the invoicelineitems under it.
insert invoiceList;
// Construct this set as a copy of the invoiceList so we can remove from it easily later
Set<Invoice__c> invoiceSet = new Set<Invoice__c>(invoiceList);
// Create the invoicelineitems
for (Quote q : quoteList)
{
for (QuoteLineItem qli : q.quotelineitems)
{
InvoiceLineItem__c newInvLineItem = new InvoiceLineItem__c();
newInvLineItem.Invoiceid__c=qli.id;
newInvLineItem.Amount__c = qli.ListPrice;
newInvLineItem.Item__c = qli.PricebookEntry.ProductCode;
newInvLineItem.Description__c= qli.PricebookEntry.name;
newInvLineItem.Quantity__c= qli.quantity;
// We need to relate the invoicelineitem to the correct invoice
for (Invoice__c i : invoiceSet)
{
// Using quote number as an identifier
if (i.Invoice_Number__c == q.quotenumber)
{
newInvLineItem.Invoiceid__c= i.id;
}
}
invoiceLineItemList.add(newInvLineItem);
}
// We need to remove the invoice we just used from the set, just in case there are quotes with duplicate quote numbers.
for (Invoice__c i : invoiceSet)
{
if (i.name == q.name)
{
invoiceSet.remove(i);
}
}
}
insert invoiceLineItemList;
And this is my test class:
@isTest private class CreateInvoiceTestClass { @isTest static void insertOpp() { Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (); opp.name= 'Testopp'; Opp.Accountid= acc.id; opp.CloseDate= date.today(); opp.StageName= 'Qualification'; insert opp; Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book 2009', Description = 'Price Book 2009 Products', IsActive = true ); insert pb; Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; Pricebook2 standardPB = [select id from Pricebook2 where isStandard=true]; PricebookEntry standardPBE = new PricebookEntry(Pricebook2Id = standardPB.Id, Product2Id = prod.Id, UnitPrice = 1000, IsActive = true); insert standardPBE; PricebookEntry pbe = new PricebookEntry(Pricebook2Id = pb.Id, Product2Id = prod.Id, UnitPrice = 1000, IsActive = true); insert pbe; Quote q= new Quote (); q.Name= 'Testq'; q.OpportunityId= Opp.id; q.quotetoinvoice__C= TRUE; q.REP__C= 'AC' ; q.BillingStreet= '123'; q.BillingCity= 'City'; q.BillingPostalCode= '12345'; q.Pricebook2Id= pb.id; insert q; QuoteLineItem qli= new QuoteLineItem(id=q.Id, Product2id='Product', PricebookEntryid= pbe.Id, quantity=2); insert qli; opp.StageName= 'Closed Won'; } }
Keep getting error: System.QueryException: List has no rows for assignment to SObject, Class.CreateInvoiceTestClass.insertOpp line 18
Please help.
- Sammy7
- September 20, 2016
- Like
- 0
invalid relationship key in opportunity
I want to create an invoice so when my opportunity is closedwon and my custom field QuotetoInvoice on Quote object (is checked) is true
But Im having problem with the conditinal statement.... it says "Invalid foreign key relationship: Opporutnity.quote__r "
for(Opportunity o : trigger.new)
{
if (o.stagename=='Closed Won'&& o.quote__r.QuotetoInvoice__c== TRUE))
{
oppIdSet.add(o.id);
}
}
Please guide me.
But Im having problem with the conditinal statement.... it says "Invalid foreign key relationship: Opporutnity.quote__r "
for(Opportunity o : trigger.new)
{
if (o.stagename=='Closed Won'&& o.quote__r.QuotetoInvoice__c== TRUE))
{
oppIdSet.add(o.id);
}
}
Please guide me.
- Sammy7
- September 19, 2016
- Like
- 0
insert invoice on opportunity from quote line item
Hi,
So I created a custom object Invoice__c and Invoicelineitem__c. Basically, I want to copy all the quote line items to invoice line items.
Below is my code:
trigger Insertnewinvoice on Invoice__c (after insert) {
Invoice__c to=trigger.new[0];
Quote q=[Select id from Quote where id= :to.Quote__c];
list<QuoteLineItem> ql=[select id,ListPrice,PriceBookEntry.Product2Id ,Subtotal,TotalPrice from QuoteLineItem where QuoteId=:q.id];
for(QuoteLineItem qli:ql){
Invoicelineitem__c lm=new Invoicelineitem__c();
lm.List_Price__c=qli.ListPrice;
lm.Product__C=qli.PriceBookEntry.Product2Id;
lm.Order__c=to.id;
insert lm;}}
Why am I getting error: "unexpected token 'Select id from Quote where id' ??
So I created a custom object Invoice__c and Invoicelineitem__c. Basically, I want to copy all the quote line items to invoice line items.
Below is my code:
trigger Insertnewinvoice on Invoice__c (after insert) {
Invoice__c to=trigger.new[0];
Quote q=[Select id from Quote where id= :to.Quote__c];
list<QuoteLineItem> ql=[select id,ListPrice,PriceBookEntry.Product2Id ,Subtotal,TotalPrice from QuoteLineItem where QuoteId=:q.id];
for(QuoteLineItem qli:ql){
Invoicelineitem__c lm=new Invoicelineitem__c();
lm.List_Price__c=qli.ListPrice;
lm.Product__C=qli.PriceBookEntry.Product2Id;
lm.Order__c=to.id;
insert lm;}}
Why am I getting error: "unexpected token 'Select id from Quote where id' ??
- Sammy7
- September 08, 2016
- Like
- 0
getAccount () method to return multiple queries or set?
Hi,
So Im trying to display a custom visualforce page to list three separate accounts (by id and name) and their related contacts list by using a custom controller below.
But I dont know how to get accounts for Acme2 and Acme3 in the class using the same method. Any help is appreciated. Thanks.
and this is my visualpage:
So Im trying to display a custom visualforce page to list three separate accounts (by id and name) and their related contacts list by using a custom controller below.
But I dont know how to get accounts for Acme2 and Acme3 in the class using the same method. Any help is appreciated. Thanks.
public class MyController { public String getName() { return 'MyController'; } public Account getAccount() { return [SELECT id from Account where Name = 'Acme']; } }
and this is my visualpage:
<apex:page controller="MyController" tabStyle="Account"> <apex:pageBlock title="Acme"> <apex:relatedList subject="{!account}" list="Contacts"/> </apex:pageBlock> <apex:pageBlock title="Acme2"> <apex:relatedList subject="{!account}" list="Contacts"/> </apex:pageBlock> <apex:pageBlock title="Acme3"> <apex:relatedList subject="{!account}" list="Contacts"/> </apex:pageBlock> </apex:page>
- Sammy7
- August 16, 2016
- Like
- 0
Insufficient privelages as sys admin
I am creating a VF page in my developer org and getting insufficient privelages page when acessing the related list below on account even though I am the account owner....
<apex:page standardcontroller="Account"> <apex:detail relatedList="true"> <apex:relatedList List="Contacts"/> </apex:detail> </apex:page>
- Sammy7
- August 16, 2016
- Like
- 0
Test class for send email fail
Hi,
Im getting the following error and cannot figure out why:
System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email address is invalid: null: [toAddresses, null]
Class.email_class.send: line 48, column 1
Class.TestquoteEmailclass.sendEmailTestMethod: line 47, column 1
Below is my test class:
And my controller:
Any help is appreciated !
Im getting the following error and cannot figure out why:
System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email address is invalid: null: [toAddresses, null]
Class.email_class.send: line 48, column 1
Class.TestquoteEmailclass.sendEmailTestMethod: line 47, column 1
Below is my test class:
@isTest public class TestquoteEmailclass { @isTest static void sendEmailTestMethod(){ Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; PricebookEntry pbe=new PricebookEntry(unitprice=0.01,Product2Id=prod.Id, Pricebook2Id=Test.getStandardPricebookId(), IsActive= true); insert pbe; Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (name='Testopp', Accountid=acc.id, CloseDate= date.today(), StageName='Closed Won', Pricebook2id=Test.getStandardPricebookId()); insert opp; OpportunityLineItem oppLine = new OpportunityLineItem( pricebookentryid=pbe.Id,TotalPrice=2000, Quantity = 2,Opportunityid = opp.Id); insert oppLine; Quote q= new Quote (Name='Testq', Opportunityid=opp.id, QuotetoInvoice__c= True, Pricebook2id=Test.getStandardPricebookId()); insert q; System.currentPagereference().getParameters().put('id',q.id); Attachment objAtt = new Attachment(); objAtt.Name = 'Test'; objAtt.body = Blob.valueof('string'); objAtt.ParentId = q.Id; insert objAtt; ApexPages.StandardController sc =new ApexPages.StandardController(q); email_class ec=new email_class (sc); ec.ToAddresses='test@gmail.com'; ec.CCAddresses='test2@gmail.com'; ec.emailCC= 'test3@gmail.com'; ec.email_body='test1111111'; ec.subject='test22222'; Messaging.InboundEmail email = new Messaging.InboundEmail(); Messaging.InboundEnvelope env = new Messaging.InboundEnvelope(); email.plainTextBody = 'This should become a note'; email.fromAddress ='test@test.com'; String contactEmail = 'jsmith@salesforce.com'; email.ccAddresses = new String[] {'Jon Smith <' + contactEmail + '>'}; email.subject = 'Dummy Account Name 123'; ec.send(); } }
And my controller:
public class email_class{ Public string ToAddresses {get;set;} Public string CCAddresses {get;set;} Public string quoteId {get;set;} Public string subject {get;set;} public string email_body {get;set;} public string emailTo {get;set;} public string emailCC {get;set;} public string [] ccaddress; public email_class(ApexPages.StandardController controller) { quoteId = ApexPages.currentPage().getParameters().get('id'); } Public PageReference send(){ Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); // set the to address mail.setToAddresses(new String[] {emailTo}); // mail.setCCAddresses(new String[] {emailCC}); //set the cc address if(emailCC != null && emailCC.trim() != '') { ccaddress = emailCC.split(',',0); mail.setCCAddresses(ccaddress);} mail.setSubject(subject); mail.setBccSender(false); mail.setUseSignature(false); mail.setPlainTextBody(email_body); List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>(); for (Attachment a : [select Name, Body, BodyLength from Attachment where ParentId = :quoteId]){ // Add to attachment file list Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment(); efa.setFileName(a.Name); efa.setBody(a.Body); fileAttachments.add(efa); } mail.setFileAttachments(fileAttachments);// Send email Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); return null; } }
Any help is appreciated !
- Sammy7
- January 26, 2017
- Like
- 1
Attach a visualforce custom quote page to quotePDFs
Hi,
I overrode the "Createpdf" button on quote page with a custom VF page (Quotecustom). I would like to create another button on quote page that lets me save that pdf as an attachment to the QuotePDF related list.
What are the steps to do this?
I know I need a controller that looks something like this:
THanks.
I overrode the "Createpdf" button on quote page with a custom VF page (Quotecustom). I would like to create another button on quote page that lets me save that pdf as an attachment to the QuotePDF related list.
What are the steps to do this?
I know I need a controller that looks something like this:
public class attachPDFToquote { private final quote q; //quote object //constructor public attachPDFToquote(ApexPages.StandardController standardPageController) { q = (Quote)standardPageController.getRecord(); //instantiate the quote object for the current record } //method called from the Visualforce's action attribute public PageReference attachPDF() { //generate and attach the PDF document PageReference pdfPage = Page.quotecustom; //create a page reference to quote custom Visualforce page Blob pdfBlob = pdfPage.getContent(); //get the output of the page, as displayed to a user in a browser Attachment attach = new Attachment(parentId = q.Id, Name = 'pdfAttachmentDemo.pdf', body = pdfBlob); //create the attachment object insert attach; //insert the attachment //redirect the user PageReference pageWhereWeWantToGo = new ApexPages.StandardController(q).view(); //we want to redirect the User back to the quote detail page pageWhereWeWantToGo.setRedirect(true); //indicate that the redirect should be performed on the client side return pageWhereWeWantToGo; //send the User on their way } }Im confused about the next step...do I have to create another seperate VF page or add the controller as an "extension" to my Quotecustom VF page. Please excuse my misunderstandings as Im new to this.
THanks.
- Sammy7
- December 05, 2016
- Like
- 1
pass lookup inputfield to extension
Hi,
So I have an input field :<b>To: </b> <apex:inputfield value="{!q.contactid}"/><p/>
and in my controller, I have:
public Quote q {get;set;}
and then I would like to present the email address in this outputfield: <b>NAME: </b> <apex:outputtext value="{!q.contact.name}"/><p/>
However this is not working, Please help:
Below is my VF page:
and my extension:
So I have an input field :<b>To: </b> <apex:inputfield value="{!q.contactid}"/><p/>
and in my controller, I have:
public Quote q {get;set;}
and then I would like to present the email address in this outputfield: <b>NAME: </b> <apex:outputtext value="{!q.contact.name}"/><p/>
However this is not working, Please help:
Below is my VF page:
<apex:page standardController="Quote" extensions="email_class"> <apex:form > <apex:pageBlock title="Email Details" id="ed"> <b>To: </b> <apex:inputfield value="{!q.contactid}"/><p/> <apex:actionSupport event="onchange" action="{!Contactpopulated}" rerender="ed"/> <b>NAME: </b> <apex:outputtext value="{!q.contact.email}"/><p/> ....... .......
and my extension:
public class email_class{ Public string ToAddresses {get;set;} Public string CCAddresses {get;set;} Public string quoteId {get;set;} Public string subject {get;set;} public string email_body {get;set;} public string emailTo {get;set;} public string emailCC {get;set;} public Quote q {get;set;} // public Contact ct {get;set;} public string [] ccaddress; public email_class(ApexPages.StandardController controller) { quoteId = ApexPages.currentPage().getParameters().get('id'); Quote q= (Quote)controller.getRecord(); } public void Contactpopulated(){ q.contact=[ Select email, name From contact where id=:q.contactid limit 1]; }
- Sammy7
- March 09, 2017
- Like
- 0
Whats wrong with this code?
I can excute this fine in excute anonymous, but when I put it in the class, I get "Unexpected token: '='" at LINE 5
public class testProduct { public Product2 shipping {get;set;} shipping = [SELECT id, name, productcode from PRODUCT2 where productcode='shipping' limit 1];
- Sammy7
- February 27, 2017
- Like
- 0
System.QueryException: line 1:283 no viable alternative at character '%'
I dont get this error...I tried retyping the quotes. Please help:
System.QueryException: line 1:282 no viable alternative at character '%'
Class.opportunityProductEntryExtension.updateAvailableList: line 119, column 1
Class.opportunityProductEntryTests.theTests: line 53, column 1
System.QueryException: line 1:282 no viable alternative at character '%'
Class.opportunityProductEntryExtension.updateAvailableList: line 119, column 1
Class.opportunityProductEntryTests.theTests: line 53, column 1
public with sharing class opportunityProductEntryExtension { public Opportunity theOpp {get;set;} public String searchString {get;set;} public opportunityLineItem[] shoppingCart {get;set;} public priceBookEntry[] AvailableProducts {get;set;} public Pricebook2 theBook {get;set;} public String toSelect {get; set;} public String toUnselect {get; set;} public Decimal Total {get;set;} public Boolean overLimit {get;set;} public Boolean multipleCurrencies {get; set;} private Boolean forcePricebookSelection = false; private opportunityLineItem[] forDeletion = new opportunityLineItem[]{}; public opportunityProductEntryExtension(ApexPages.StandardController controller) { // Need to know if org has multiple currencies enabled multipleCurrencies = UserInfo.isMultiCurrencyOrganization(); // Get information about the Opportunity being worked on if(multipleCurrencies) theOpp = database.query('select Id, Pricebook2Id, Pricebook2.Name, CurrencyIsoCode from Opportunity where Id = \'' + controller.getRecord().Id + '\' limit 1'); else theOpp = [select Id, Pricebook2Id, PriceBook2.Name from Opportunity where Id = :controller.getRecord().Id limit 1]; // If products were previously selected need to put them in the "selected products" section to start with shoppingCart = [select Id, Quantity, TotalPrice, UnitPrice, Description, PriceBookEntryId, PriceBookEntry.Name, PriceBookEntry.IsActive, PriceBookEntry.Product2Id, PriceBookEntry.Product2.Name, PriceBookEntry.PriceBook2Id from opportunityLineItem where OpportunityId=:theOpp.Id]; // Check if Opp has a pricebook associated yet if(theOpp.Pricebook2Id == null){ Pricebook2[] activepbs = [select Id, Name from Pricebook2 where isActive = true limit 2]; if(activepbs.size() == 2){ forcePricebookSelection = true; theBook = new Pricebook2(); } else{ theBook = activepbs[0]; } } else{ theBook = theOpp.Pricebook2; } if(!forcePricebookSelection) updateAvailableList(); } // this is the 'action' method on the page public PageReference priceBookCheck(){ // if the user needs to select a pricebook before we proceed we send them to standard pricebook selection screen if(forcePricebookSelection){ return changePricebook(); } else{ //if there is only one active pricebook we go with it and save the opp if(theOpp.pricebook2Id != theBook.Id){ try{ theOpp.Pricebook2Id = theBook.Id; update(theOpp); } catch(Exception e){ ApexPages.addMessages(e); } } return null; } } public String getChosenCurrency(){ if(multipleCurrencies) return (String)theOpp.get('CurrencyIsoCode'); else return ''; } public void updateAvailableList() { // We dynamically build a query string and exclude items already in the shopping cart String qString = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.ProductCode, Product2.Family, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and Pricebook2Id = \'' + theBook.Id + '\''; if(multipleCurrencies) qstring += 'and CurrencyIsoCode = \'' + theOpp.get('currencyIsoCode') + '\''; // note that we are looking for the search string entered by the user in the name OR description // modify this to search other fields if desired if(searchString!=null){ qString+= 'and (Product2.Name like \'%' + searchString + '%\' or Product2.ProductCode like \'%' + searchString + '%\')'; } Set<Id> selectedEntries = new Set<Id>(); for(opportunityLineItem d:shoppingCart){ selectedEntries.add(d.PricebookEntryId); } if(selectedEntries.size()>0){ String tempFilter = ' and Id not in ('; for(Id i : selectedEntries){ tempFilter+= '\'' + (String)i + '\','; } String extraFilter = tempFilter.substring(0,tempFilter.length()-1); extraFilter+= ')'; qString+= extraFilter; } qString+= ' order by Product2.Name'; qString+= ' limit 101'; system.debug('qString:' +qString); AvailableProducts = database.query(qString); // We only display up to 100 results... if there are more than we let the user know (see vf page) if(AvailableProducts.size()==101){ AvailableProducts.remove(100); overLimit = true; } else{ overLimit=false; } } public void addToShoppingCart(){ // This function runs when a user hits "select" button next to a product for(PricebookEntry d : AvailableProducts){ if((String)d.Id==toSelect){ shoppingCart.add(new opportunityLineItem(OpportunityId=theOpp.Id, PriceBookEntry=d, PriceBookEntryId=d.Id, UnitPrice=d.UnitPrice)); break; } } updateAvailableList(); } public PageReference removeFromShoppingCart(){ // This function runs when a user hits "remove" on an item in the "Selected Products" section Integer count = 0; for(opportunityLineItem d : shoppingCart){ if((String)d.PriceBookEntryId==toUnselect){ if(d.Id!=null) forDeletion.add(d); shoppingCart.remove(count); break; } count++; } updateAvailableList(); return null; } public PageReference onSave(){ // If previously selected products are now removed, we need to delete them if(forDeletion.size()>0) delete(forDeletion); // Previously selected products may have new quantities and amounts, and we may have new products listed, so we use upsert here try{ if(shoppingCart.size()>0) upsert(shoppingCart); } catch(Exception e){ ApexPages.addMessages(e); return null; } // After save return the user to the Opportunity return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id')); } public PageReference onCancel(){ // If user hits cancel we commit no changes and return them to the Opportunity return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id')); } public PageReference changePricebook(){ // This simply returns a PageReference to the standard Pricebook selection screen // Note that is uses retURL parameter to make sure the user is sent back after they choose PageReference ref = new PageReference('/oppitm/choosepricebook.jsp'); ref.getParameters().put('id',theOpp.Id); ref.getParameters().put('retURL','/apex/opportunityProductEntry?id=' + theOpp.Id); return ref; } }
@istest private class opportunityProductEntryTests { static testMethod void theTests(){ // You really should create test data, but I'm going to query instead // It's my best shot of avoiding a test failure in most orgs // Once you've installed this package though, you might want to write your own tests // or at least customize these ones to make them more applicable to your org OpportunityLineItem oli = [select Id, PricebookEntryId, PricebookEntry.Pricebook2Id, PricebookEntry.Name, PriceBookEntry.Product2Id, OpportunityId, Opportunity.AccountId from OpportunityLineItem limit 1]; //////////////////////////////////////// // test opportunityProductEntry //////////////////////////////////////// // load the page PageReference pageRef = Page.opportunityProductEntry; pageRef.getParameters().put('Id',oli.OpportunityId); Test.setCurrentPageReference(pageRef); // load the extension opportunityProductEntryExtension oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(oli.Opportunity)); // test 'getChosenCurrency' method if(UserInfo.isMultiCurrencyOrganization()) System.assert(oPEE.getChosenCurrency()!=''); else System.assertEquals(oPEE.getChosenCurrency(),''); // we know that there is at least one line item, so we confirm Integer startCount = oPEE.ShoppingCart.size(); system.assert(startCount>0); //test search functionality without finding anything oPEE.searchString = 'michaelforce is a hip cat'; oPEE.updateAvailableList(); system.assert(oPEE.AvailableProducts.size()==0); //test remove from shopping cart oPEE.toUnselect = oli.PricebookEntryId; oPEE.removeFromShoppingCart(); system.assert(oPEE.shoppingCart.size()==startCount-1); //test save and reload extension oPEE.onSave(); oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(oli.Opportunity)); system.assert(oPEE.shoppingCart.size()==startCount-1); // test search again, this time we will find something oPEE.searchString = oli.PricebookEntry.Name; oPEE.updateAvailableList(); system.assert(oPEE.AvailableProducts.size()>0); // test add to Shopping Cart function oPEE.toSelect = oPEE.AvailableProducts[0].Id; oPEE.addToShoppingCart(); system.assert(oPEE.shoppingCart.size()==startCount); // test save method - WITHOUT quanitities and amounts entered and confirm that error message is displayed oPEE.onSave(); system.assert(ApexPages.getMessages().size()>0); opEE.addtoshoppingcart(); // add required info and try save again for(OpportunityLineItem o : oPEE.ShoppingCart){ o.quantity = 5; o.unitprice = 300; } oPEE.onSave(); // query line items to confirm that the save worked opportunityLineItem[] oli2 = [select Id from opportunityLineItem where OpportunityId = :oli.OpportunityId]; system.assert(oli2.size()==startCount); // test on new Opp (no pricebook selected) to make sure redirect is happening Opportunity newOpp = new Opportunity(Name='New Opp',stageName='Pipeline',Amount=10,closeDate=System.Today()+30,AccountId=oli.Opportunity.AccountId); insert(newOpp); oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(newOpp)); System.assert(oPEE.priceBookCheck()!=null); // final quick check of cancel button System.assert(oPEE.onCancel()!=null); //////////////////////////////////////// // test redirect page //////////////////////////////////////// // load the page pageRef = Page.opportunityProductRedirect; pageRef.getParameters().put('Id',oli2[0].Id); Test.setCurrentPageReference(pageRef); // load the extension and confirm that redirect function returns something opportunityProductRedirectExtension oPRE = new opportunityProductRedirectExtension(new ApexPages.StandardController(oli2[0])); System.assert(oPRE.redirect()!=null); } }
- Sammy7
- February 07, 2017
- Like
- 0
Test class for send email fail
Hi,
Im getting the following error and cannot figure out why:
System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email address is invalid: null: [toAddresses, null]
Class.email_class.send: line 48, column 1
Class.TestquoteEmailclass.sendEmailTestMethod: line 47, column 1
Below is my test class:
And my controller:
Any help is appreciated !
Im getting the following error and cannot figure out why:
System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email address is invalid: null: [toAddresses, null]
Class.email_class.send: line 48, column 1
Class.TestquoteEmailclass.sendEmailTestMethod: line 47, column 1
Below is my test class:
@isTest public class TestquoteEmailclass { @isTest static void sendEmailTestMethod(){ Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; PricebookEntry pbe=new PricebookEntry(unitprice=0.01,Product2Id=prod.Id, Pricebook2Id=Test.getStandardPricebookId(), IsActive= true); insert pbe; Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (name='Testopp', Accountid=acc.id, CloseDate= date.today(), StageName='Closed Won', Pricebook2id=Test.getStandardPricebookId()); insert opp; OpportunityLineItem oppLine = new OpportunityLineItem( pricebookentryid=pbe.Id,TotalPrice=2000, Quantity = 2,Opportunityid = opp.Id); insert oppLine; Quote q= new Quote (Name='Testq', Opportunityid=opp.id, QuotetoInvoice__c= True, Pricebook2id=Test.getStandardPricebookId()); insert q; System.currentPagereference().getParameters().put('id',q.id); Attachment objAtt = new Attachment(); objAtt.Name = 'Test'; objAtt.body = Blob.valueof('string'); objAtt.ParentId = q.Id; insert objAtt; ApexPages.StandardController sc =new ApexPages.StandardController(q); email_class ec=new email_class (sc); ec.ToAddresses='test@gmail.com'; ec.CCAddresses='test2@gmail.com'; ec.emailCC= 'test3@gmail.com'; ec.email_body='test1111111'; ec.subject='test22222'; Messaging.InboundEmail email = new Messaging.InboundEmail(); Messaging.InboundEnvelope env = new Messaging.InboundEnvelope(); email.plainTextBody = 'This should become a note'; email.fromAddress ='test@test.com'; String contactEmail = 'jsmith@salesforce.com'; email.ccAddresses = new String[] {'Jon Smith <' + contactEmail + '>'}; email.subject = 'Dummy Account Name 123'; ec.send(); } }
And my controller:
public class email_class{ Public string ToAddresses {get;set;} Public string CCAddresses {get;set;} Public string quoteId {get;set;} Public string subject {get;set;} public string email_body {get;set;} public string emailTo {get;set;} public string emailCC {get;set;} public string [] ccaddress; public email_class(ApexPages.StandardController controller) { quoteId = ApexPages.currentPage().getParameters().get('id'); } Public PageReference send(){ Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); // set the to address mail.setToAddresses(new String[] {emailTo}); // mail.setCCAddresses(new String[] {emailCC}); //set the cc address if(emailCC != null && emailCC.trim() != '') { ccaddress = emailCC.split(',',0); mail.setCCAddresses(ccaddress);} mail.setSubject(subject); mail.setBccSender(false); mail.setUseSignature(false); mail.setPlainTextBody(email_body); List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>(); for (Attachment a : [select Name, Body, BodyLength from Attachment where ParentId = :quoteId]){ // Add to attachment file list Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment(); efa.setFileName(a.Name); efa.setBody(a.Body); fileAttachments.add(efa); } mail.setFileAttachments(fileAttachments);// Send email Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); return null; } }
Any help is appreciated !
- Sammy7
- January 26, 2017
- Like
- 1
Attach a visualforce custom quote page to quotePDFs
Hi,
I overrode the "Createpdf" button on quote page with a custom VF page (Quotecustom). I would like to create another button on quote page that lets me save that pdf as an attachment to the QuotePDF related list.
What are the steps to do this?
I know I need a controller that looks something like this:
THanks.
I overrode the "Createpdf" button on quote page with a custom VF page (Quotecustom). I would like to create another button on quote page that lets me save that pdf as an attachment to the QuotePDF related list.
What are the steps to do this?
I know I need a controller that looks something like this:
public class attachPDFToquote { private final quote q; //quote object //constructor public attachPDFToquote(ApexPages.StandardController standardPageController) { q = (Quote)standardPageController.getRecord(); //instantiate the quote object for the current record } //method called from the Visualforce's action attribute public PageReference attachPDF() { //generate and attach the PDF document PageReference pdfPage = Page.quotecustom; //create a page reference to quote custom Visualforce page Blob pdfBlob = pdfPage.getContent(); //get the output of the page, as displayed to a user in a browser Attachment attach = new Attachment(parentId = q.Id, Name = 'pdfAttachmentDemo.pdf', body = pdfBlob); //create the attachment object insert attach; //insert the attachment //redirect the user PageReference pageWhereWeWantToGo = new ApexPages.StandardController(q).view(); //we want to redirect the User back to the quote detail page pageWhereWeWantToGo.setRedirect(true); //indicate that the redirect should be performed on the client side return pageWhereWeWantToGo; //send the User on their way } }Im confused about the next step...do I have to create another seperate VF page or add the controller as an "extension" to my Quotecustom VF page. Please excuse my misunderstandings as Im new to this.
THanks.
- Sammy7
- December 05, 2016
- Like
- 1
invalid foreign key relationship: access field on custom object with master detail to opportunity
So I have custom object (invoice__c) with master-detail to opportunity. I have a custom field (AF_LastSyncTime__c ) on invoice__c that Im trying to access.
so here is my query:
No error with query, but I get invalid foreign key relationship in the if statement....why is that?
Thanks.
so here is my query:
for (Opportunity opp : [select Id, (select id, AF_LastSyncTime__c from Invoices__r), (select Id, Invoice_No__c, QuotetoInvoice__c, CreatedDate from Quotes order by CreatedDate DESC) from Opportunity where Id IN :oppsId]) { if (opp.Invoices__r.AF_LastSyncTime__c==null) return 'blah blah blah'; }
No error with query, but I get invalid foreign key relationship in the if statement....why is that?
Thanks.
- Sammy7
- November 01, 2016
- Like
- 0
Unknown property 'VisualforceArrayLisy.description'
Hi,
Im new to visualforce and Im trying to understand why I cant iterate through the quote line items using the apex:repeat tag in the below SOQL:
Im new to visualforce and Im trying to understand why I cant iterate through the quote line items using the apex:repeat tag in the below SOQL:
<apex:page controller="myquote" showHeader="false" sidebar="false" > <apex:stylesheet value="{!URLFOR($Resource.advancedpdfresource, 'qstyles.css')}"/> <apex:repeat value="{!quote}" var="qli"> <apex:dataTable value="{!qli}" var="q" > <apex:column style="border: 1px"> <apex:facet name="header">Quote Line Item</apex:facet> <apex:outputText value="{!q.quotelineitems.description}"/> </apex:column> </apex:dataTable> </apex:repeat> </apex:page> <!----Controller-----> public class myquote { List <Quote> quote= [Select id, name, BillingAddress, BillingName, quotenumber,(SELECT id, Description, ListPrice, PricebookEntry.name, PricebookEntry.ProductCode, TotalPrice, Quantity FROM quotelineitems) from QUOTE WHERE id=: ApexPages.CurrentPage().Getparameters().get('id')]; public List<Quote> getquote () { return quote;} }
- Sammy7
- October 19, 2016
- Like
- 0
Steps to generate a custom quote/invoice pdf
Hi guys, the quote template has lots of limitations when it comes to styling; I would like to do something custom and need a step-by-step guide. Basically, I would like a "create quote" button on quote pagelayout that references my visualforce page and creates the pdf.
So I think I need to follow the steps below:
1. Create a custom controller class. Can I do this with standard List controller? Basically, I have to query all the quote and quotelineitems
2. Create a new visual force page using controller from step1, add the proper styling and render as pdf.
3. Create the button on quote with a link to visual force page
Any tips and guides are appreciated.
Thanks.
Did I miss anything?
So I think I need to follow the steps below:
1. Create a custom controller class. Can I do this with standard List controller? Basically, I have to query all the quote and quotelineitems
2. Create a new visual force page using controller from step1, add the proper styling and render as pdf.
3. Create the button on quote with a link to visual force page
Any tips and guides are appreciated.
Thanks.
Did I miss anything?
- Sammy7
- October 17, 2016
- Like
- 0
Allow only sys admin to change stage name validation rule not working
HI,
I have the following validation rule:
AND(
$Profile.Name <> "System Administrator",
ISCHANGED(StageName),
(TEXT(StageName) = "Closed Lost" || TEXT(StageName) = "Closed Won"))
I want only the system admin profile to able to close opportunity. Yet, I logged in as a std user and was able to create a new opportunity and set the stage to closed won and it saved the record....
I have the following validation rule:
AND(
$Profile.Name <> "System Administrator",
ISCHANGED(StageName),
(TEXT(StageName) = "Closed Lost" || TEXT(StageName) = "Closed Won"))
I want only the system admin profile to able to close opportunity. Yet, I logged in as a std user and was able to create a new opportunity and set the stage to closed won and it saved the record....
- Sammy7
- October 13, 2016
- Like
- 0
getting null pointer exception even with seealldate=true for test class on custom setting
Hi ,
I already have the custom setting in my sandbox org and my test class with seealldata=true. So why am I getting this:
EXCEPTION_THROWN|[33]|System.NullPointerException: Attempt to de-reference a null object
When I test the same EXACT test class in my developer org, I get 86% coverage. It drops to 21% in sandbox org....whats going on?
I already have the custom setting in my sandbox org and my test class with seealldata=true. So why am I getting this:
EXCEPTION_THROWN|[33]|System.NullPointerException: Attempt to de-reference a null object
When I test the same EXACT test class in my developer org, I get 86% coverage. It drops to 21% in sandbox org....whats going on?
- Sammy7
- October 06, 2016
- Like
- 0
Test.getStandardPricebookId() broke overnight?
isTest private class TestInvoicepdfclass { static testmethod void testpdfbutton (){ Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book 2009', Description = 'Price Book 2009 Products', IsActive = true ); insert pb; Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; PricebookEntry pbe=new PricebookEntry(unitprice=0.01,Product2Id=prod.Id, Pricebook2Id=Test.getStandardPricebookId() , IsActive= true); insert pbe; Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (); Opportunity opp2= new Opportunity (); opp.name= 'Testopp'; Opp.Accountid= acc.id; opp.CloseDate= date.today(); opp.StageName= 'Closed Won'; opp.Pricebook2id=Test.getStandardPricebookId(); opp2.name= 'Testopp2'; Opp2.Accountid= acc.id; opp2.CloseDate= date.today(); opp2.StageName= 'Closed Won'; opp2.Pricebook2id=Test.getStandardPricebookId(); insert opp; insert opp2; OpportunityLineItem oppLine = new OpportunityLineItem( pricebookentryid=pbe.Id,TotalPrice=2000, Quantity = 2,Opportunityid = opp.Id); insert oppLine; Quote q= new Quote (); q.Name= 'Testq'; q.OpportunityId= Opp.id; q.quotetoinvoice__C= True; q.REP__C= 'AC' ; q.BillingStreet= '123'; q.BillingCity= 'City'; q.BillingPostalCode= '12345'; q.Pricebook2Id= Test.getStandardPricebookId(); List<id> oppids= new List<id> (); oppids.add(opp.Id); oppids.add(opp2.id); InvoicePdfWsSample.generateInvoicePdf(oppids); } }
I dont understand, Im using this in my test class (above) it was working fine yesterday and today, its giving me this error:
line 9: Method does not exist or incorrect signature: Test.getStandardPricebookId()
Please advice. I'm using the same code in my other test class and it is not prompting any errors.....
- Sammy7
- September 28, 2016
- Like
- 0
Test class for generate invoice pdf
Hi,
I found this nice workaround to use quotetemplate to make invoice pdf from this blog: http://www.valnavjo.com/blog/how-to-create-invoices-using-quote-templates/
But I'm having trouble on how to write a test class for this:
I found this nice workaround to use quotetemplate to make invoice pdf from this blog: http://www.valnavjo.com/blog/how-to-create-invoices-using-quote-templates/
But I'm having trouble on how to write a test class for this:
global with sharing class InvoicePdfWsSample { /** * Default header height for invoice */ private static final String DEFAULT_INVOICE_HEADER_HEIGHT = '100'; /** * Default footer height for invoice */ private static final String DEFAULT_INVOICE_FOOTER_HEIGHT = '100'; /** * Webservice method that is called from a custom button to generate * an invoice PDF file using quote templates feature. * It generates the invoice based on: * - The synced Quote, or * - The latest Quote * If the Opportunity doesn't have any Quotes, this method doesn't do * anything. * * This method uses PageReference.getContent(). * * @param oppsIdList {List<Id>} list of Opportunity Ids from where the method * will generate the Invoice PDF. * @return {String} with an error message, if any. Blank otherwise. */ webService static String generateInvoicePdf(List<Id> oppsIdList) { try { //From list to set final Set<Id> oppsId = new Set<Id>(oppsIdList); //Get template Id for Invoice and url to hack pdf generation final String invoiceTemplateId = Application_Properties__c.getAll().get('Invoice_Template_Id').value__c; String invoiceHeaderHeight = Application_Properties__c.getAll().get('Invoice_Header_Height').value__c; String invoiceFooterHeight = Application_Properties__c.getAll().get('Invoice_Footer_Height').value__c; final String quoteTemplateDataViewerUrl = Application_Properties__c.getAll().get('Quote_Template_Data_Viewer_URL').value__c; //Pre-validations //Invoice_Template_Id and Quote_Template_Data_Viewer_URL are mandatory if (String.isBlank(invoiceTemplateId) || String.isBlank(quoteTemplateDataViewerUrl)) { String errorMsg = 'Invoice Template Id or Quote Template Data Viewer URL are blank, please review their values in Application Properties custom setting.'; return errorMsg; } //Default values for invoice header/footer height if (String.isBlank(invoiceHeaderHeight)) invoiceHeaderHeight = DEFAULT_INVOICE_HEADER_HEIGHT; if (String.isBlank(invoiceFooterHeight)) invoiceFooterHeight = DEFAULT_INVOICE_FOOTER_HEIGHT; //Iterate over Opps and generate Attachments list final List<Attachment> attList = new List<Attachment>(); for (Opportunity opp : [select Id, (select Id, Invoice_No__c, IsSyncing, CreatedDate from Quotes Where QuotetoInvoice__c= True order by CreatedDate DESC) from Opportunity where Id IN :oppsId]) { //No Quotes, no party if (opp.Quotes.isEmpty()) continue; //Synced quote Quote theQuote = null; //Try to get the synced one for (Quote quoteAux : opp.Quotes) { if (quoteAux.IsSyncing) { theQuote = quoteAux; break; } } //No synced Quote, get the last one if (theQuote == null) theQuote = opp.Quotes.get(0); PageReference pageRef = new PageReference( quoteTemplateDataViewerUrl.replace('{!QuoteId}', theQuote.Id) .replace('{!InvoiceHeaderHeight}', invoiceHeaderHeight) .replace('{!InvoiceFooterHeight}', invoiceFooterHeight) .replace('{!InvoiceTemplateId}', invoiceTemplateId) ); attList.add( new Attachment( Name = 'Invoice #' + theQuote.Invoice_No__c + '.pdf', Body = pageRef.getContent(), ParentId = opp.Id ) ); } //Create Attachments if (!attList.isEmpty()) insert attList; return ''; } catch (Exception e) { System.debug(LoggingLevel.ERROR, e.getMessage()); final String errorMsg = 'An error has occured while generating the invoice. Details:\n\n' + e.getMessage() + '\n\n' + e.getStackTraceString(); return errorMsg; } } }
- Sammy7
- September 27, 2016
- Like
- 0
Pricebook difficulty in test class
Hi , this is my first test class and Im not getting how the ids are different in this error. All Im trying to do is create a opp, quote, quotelineitem and close the opp so my trigger fires.
System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: PricebookEntryId (pricebook entry is in a different pricebook than the one assigned to the opportunity): [PricebookEntryId]
System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: PricebookEntryId (pricebook entry is in a different pricebook than the one assigned to the opportunity): [PricebookEntryId]
@isTest private class CreateInvoiceTestClass { @isTest static void insertOpp() { Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book 2009', Description = 'Price Book 2009 Products', IsActive = true ); insert pb; Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; PricebookEntry pbe=new PricebookEntry(unitprice=0.01,Product2Id=prod.Id, Pricebook2Id=Test.getStandardPricebookId(), IsActive= true); insert pbe; Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (); opp.name= 'Testopp'; Opp.Accountid= acc.id; opp.CloseDate= date.today(); opp.StageName= 'Qualification'; opp.Pricebook2id=pb.id; insert opp; OpportunityLineItem oppLine = new OpportunityLineItem( pricebookentryid=pbe.Id,TotalPrice=2000, Quantity = 2,Opportunityid = opp.Id); insert oppLine; Quote q= new Quote (); q.Name= 'Testq'; q.OpportunityId= Opp.id; q.quotetoinvoice__C= TRUE; q.REP__C= 'AC' ; q.BillingStreet= '123'; q.BillingCity= 'City'; q.BillingPostalCode= '12345'; q.Pricebook2Id= pb.id; insert q; QuoteLineItem qli= new QuoteLineItem(Quoteid=q.id, PricebookEntryid= pbe.Id, quantity=2, unitprice=10000); insert qli; opp.StageName= 'Closed Won'; } }
- Sammy7
- September 21, 2016
- Like
- 0
Need help with test class for quote
I am new to test classes, but Im pulling my hair on this one.
Below is my trigger to create an invoice from Quote once opp is closed and quotetoinvoice checkbox is ticked:
trigger CreateInvoice on Opportunity (after update, after insert) {
List<Invoice__c> invoiceList = new List<Invoice__c>();
List<InvoiceLineItem__c> invoiceLineItemList = new List<InvoiceLineItem__c>();
Set<Id> oppIdSet = new Set<Id>();
// We only care about opportunities that are closed won
for(Opportunity o : trigger.new)
{
if (o.stagename=='Closed Won')
{
oppIdSet.add(o.id);
}
}
// Need to grab all the quotes and their subsequent quotelineitems under all the opportunities that fired the trigger, but select quotes that has QuotetoInvoice=True
List<Quote> quoteList = [SELECT id, quotenumber, Accountid, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingName, Shippingname, ShippingStreet, ShippingCity, ShippingPostalCode, ShippingState, REP__c, Totalprice, Opportunityid, name, QuotetoInvoice__c,
(SELECT id, ListPrice, PricebookEntry.name, PricebookEntry.ProductCode, TotalPrice, Quantity FROM quotelineitems)
FROM Quote WHERE Opportunityid in: oppIdSet AND QuotetoInvoice__c=TRUE];
// Create an invoice for each quote
for (Quote q : quoteList)
{
Invoice__c newInvoice = new Invoice__c();
newInvoice.Invoice_number__c=q.quotenumber;
newInvoice.opportunity__c= q.Opportunityid;
newInvoice.Bill_To__c=q.Billingname;
newInvoice.BillingStreet__c=q.Billingstreet;
newInvoice.BillingCity__c= q.BillingCity;
newInvoice.BillingState__c= q.BillingState;
newInvoice.BillingZip__c= q.BillingPostalCode;
newInvoice.Ship_To__c=q.Shippingname;
newInvoice.ShippingStreet__c=q.Shippingstreet;
newInvoice.ShippingCity__c= q.ShippingCity;
newInvoice.ShippingState__c= q.ShippingState;
newInvoice.ShippingZip__c= q.ShippingPostalCode;
newInvoice.Total__c=q.Totalprice;
newInvoice.Customer__c=q.Accountid;
newInvoice.REP__c=q.REP__c;
invoiceList.add(newInvoice);
}
// We need to insert the invoices first, before being able to insert the invoicelineitems under it.
insert invoiceList;
// Construct this set as a copy of the invoiceList so we can remove from it easily later
Set<Invoice__c> invoiceSet = new Set<Invoice__c>(invoiceList);
// Create the invoicelineitems
for (Quote q : quoteList)
{
for (QuoteLineItem qli : q.quotelineitems)
{
InvoiceLineItem__c newInvLineItem = new InvoiceLineItem__c();
newInvLineItem.Invoiceid__c=qli.id;
newInvLineItem.Amount__c = qli.ListPrice;
newInvLineItem.Item__c = qli.PricebookEntry.ProductCode;
newInvLineItem.Description__c= qli.PricebookEntry.name;
newInvLineItem.Quantity__c= qli.quantity;
// We need to relate the invoicelineitem to the correct invoice
for (Invoice__c i : invoiceSet)
{
// Using quote number as an identifier
if (i.Invoice_Number__c == q.quotenumber)
{
newInvLineItem.Invoiceid__c= i.id;
}
}
invoiceLineItemList.add(newInvLineItem);
}
// We need to remove the invoice we just used from the set, just in case there are quotes with duplicate quote numbers.
for (Invoice__c i : invoiceSet)
{
if (i.name == q.name)
{
invoiceSet.remove(i);
}
}
}
insert invoiceLineItemList;
And this is my test class:
Keep getting error: System.QueryException: List has no rows for assignment to SObject, Class.CreateInvoiceTestClass.insertOpp line 18
Please help.
Below is my trigger to create an invoice from Quote once opp is closed and quotetoinvoice checkbox is ticked:
trigger CreateInvoice on Opportunity (after update, after insert) {
List<Invoice__c> invoiceList = new List<Invoice__c>();
List<InvoiceLineItem__c> invoiceLineItemList = new List<InvoiceLineItem__c>();
Set<Id> oppIdSet = new Set<Id>();
// We only care about opportunities that are closed won
for(Opportunity o : trigger.new)
{
if (o.stagename=='Closed Won')
{
oppIdSet.add(o.id);
}
}
// Need to grab all the quotes and their subsequent quotelineitems under all the opportunities that fired the trigger, but select quotes that has QuotetoInvoice=True
List<Quote> quoteList = [SELECT id, quotenumber, Accountid, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingName, Shippingname, ShippingStreet, ShippingCity, ShippingPostalCode, ShippingState, REP__c, Totalprice, Opportunityid, name, QuotetoInvoice__c,
(SELECT id, ListPrice, PricebookEntry.name, PricebookEntry.ProductCode, TotalPrice, Quantity FROM quotelineitems)
FROM Quote WHERE Opportunityid in: oppIdSet AND QuotetoInvoice__c=TRUE];
// Create an invoice for each quote
for (Quote q : quoteList)
{
Invoice__c newInvoice = new Invoice__c();
newInvoice.Invoice_number__c=q.quotenumber;
newInvoice.opportunity__c= q.Opportunityid;
newInvoice.Bill_To__c=q.Billingname;
newInvoice.BillingStreet__c=q.Billingstreet;
newInvoice.BillingCity__c= q.BillingCity;
newInvoice.BillingState__c= q.BillingState;
newInvoice.BillingZip__c= q.BillingPostalCode;
newInvoice.Ship_To__c=q.Shippingname;
newInvoice.ShippingStreet__c=q.Shippingstreet;
newInvoice.ShippingCity__c= q.ShippingCity;
newInvoice.ShippingState__c= q.ShippingState;
newInvoice.ShippingZip__c= q.ShippingPostalCode;
newInvoice.Total__c=q.Totalprice;
newInvoice.Customer__c=q.Accountid;
newInvoice.REP__c=q.REP__c;
invoiceList.add(newInvoice);
}
// We need to insert the invoices first, before being able to insert the invoicelineitems under it.
insert invoiceList;
// Construct this set as a copy of the invoiceList so we can remove from it easily later
Set<Invoice__c> invoiceSet = new Set<Invoice__c>(invoiceList);
// Create the invoicelineitems
for (Quote q : quoteList)
{
for (QuoteLineItem qli : q.quotelineitems)
{
InvoiceLineItem__c newInvLineItem = new InvoiceLineItem__c();
newInvLineItem.Invoiceid__c=qli.id;
newInvLineItem.Amount__c = qli.ListPrice;
newInvLineItem.Item__c = qli.PricebookEntry.ProductCode;
newInvLineItem.Description__c= qli.PricebookEntry.name;
newInvLineItem.Quantity__c= qli.quantity;
// We need to relate the invoicelineitem to the correct invoice
for (Invoice__c i : invoiceSet)
{
// Using quote number as an identifier
if (i.Invoice_Number__c == q.quotenumber)
{
newInvLineItem.Invoiceid__c= i.id;
}
}
invoiceLineItemList.add(newInvLineItem);
}
// We need to remove the invoice we just used from the set, just in case there are quotes with duplicate quote numbers.
for (Invoice__c i : invoiceSet)
{
if (i.name == q.name)
{
invoiceSet.remove(i);
}
}
}
insert invoiceLineItemList;
And this is my test class:
@isTest private class CreateInvoiceTestClass { @isTest static void insertOpp() { Account acc = new Account (name='Acme'); insert acc; Opportunity opp= new Opportunity (); opp.name= 'Testopp'; Opp.Accountid= acc.id; opp.CloseDate= date.today(); opp.StageName= 'Qualification'; insert opp; Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book 2009', Description = 'Price Book 2009 Products', IsActive = true ); insert pb; Product2 prod = new Product2(Name = 'SLA: Bronze', IsActive = true); insert prod; Pricebook2 standardPB = [select id from Pricebook2 where isStandard=true]; PricebookEntry standardPBE = new PricebookEntry(Pricebook2Id = standardPB.Id, Product2Id = prod.Id, UnitPrice = 1000, IsActive = true); insert standardPBE; PricebookEntry pbe = new PricebookEntry(Pricebook2Id = pb.Id, Product2Id = prod.Id, UnitPrice = 1000, IsActive = true); insert pbe; Quote q= new Quote (); q.Name= 'Testq'; q.OpportunityId= Opp.id; q.quotetoinvoice__C= TRUE; q.REP__C= 'AC' ; q.BillingStreet= '123'; q.BillingCity= 'City'; q.BillingPostalCode= '12345'; q.Pricebook2Id= pb.id; insert q; QuoteLineItem qli= new QuoteLineItem(id=q.Id, Product2id='Product', PricebookEntryid= pbe.Id, quantity=2); insert qli; opp.StageName= 'Closed Won'; } }
Keep getting error: System.QueryException: List has no rows for assignment to SObject, Class.CreateInvoiceTestClass.insertOpp line 18
Please help.
- Sammy7
- September 20, 2016
- Like
- 0