function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ken KoellnerKen Koellner 

Site written in VF and access to standard objects with Public Access Profile.

I see that I can't grant the public access profile for a Site update on Contact or create/update on most standard objects.

 

If I write a site in VF and declare my controllers WITHOUT SHARING, would VF pages be allowed to create and update records in Object like Opportunity.

 

I'd like to write a Sites application where invited customers could use a wizard in VF to put together their own cost proposal and the controller would save the records in Opportunity and OpportunityLineItem. 

 

But I don't want to design it if the controller won't be all to insert the records.  If that's the case, I'll have to save to alternate objects.

 

-Ken

 

Ken KoellnerKen Koellner

I did a bit of playing with some test code so see if I could update Opportunity and OLI from a VF page on an SF Sites application.  Controller declared without sharing.

 

It turns out the inputField tags I coded when viewed internally via .../apex/pageName.page work as expected.

 

When I via it using public access via the Sites URL, the same fields are read-only, even though the Public Access profile has write access to the field.  I believe they are read only because the record exists.  If I declared a New Opportunity rather than read an existing one, then they were writable.  But, I had a save but that runs and action method and that has some assignments to change some field values and then save the record.  Those updates do get persisted.

 

So I'm thinking you could do updates if you declared alternate input tags on your page and then copied the data from those fields to your real sObjects.

 

Anyone else have any thoughts on the subject?

 

 

I sure do wish SF didn't have all these restrictions so you didn't have to use tricks and jump through hoops to get certaion functionality.

 

-Ken

 

Ken KoellnerKen Koellner

I coded an example.  (pasting a screen shot is too big so here is a link to one -- VF Site Screen Shot)

 

In this page, the bottom section has an Opportunity and OpportunityLineItem objects that don't yet exist.  They were created via New in the controller and don't have Ids.  These fields are writable.

 

In the top sections, existing records are read.  Here nothing is writable except the first OLI.  That is because I nulled out the ID field in this record.  That leads me to believe that I can work around the no update Opportunity restriction on Sites by caching the IDs in an alternate data structure, nulling out the IDs in the objects before displaying the page, and then putting the IDs back before issue an Update DML.  Why is all that necessary????

 

 

 

 

Ken KoellnerKen Koellner
public without sharing class KKTestSiteController {
	
	Id oppId;
	public Opportunity opp {get; set;}
	public list<OpportunityLineItem> oliList {get; set;}
	public Opportunity opp2 {get; set;}
	public list<OpportunityLineItem> oliList2 {get; set;}
	
	public KKTestSiteController () {
	 	oppId = ApexPages.currentPage().getParameters().get('oppId');
	 	if (oppId == null) {
	 		opp = new Opportunity();
	 		return;
	 	}
	 	opp = [select id, ATTN_To__c 
	 					from Opportunity
	 					where id = :oppId];
 		oliList = [select short_product_code__c, quantity, description
 					from OpportunityLineItem
 					where OpportunityId = :oppId ];
 		if (!oliList.isEmpty()) {
 			oliList[0].id = null;
 		}			
 		opp2 = new Opportunity();
 		oliList2 = new list<OpportunityLineItem>();
 		for (integer i=0; i<5; i++) {
 			OpportunityLineItem oli = new OpportunityLineItem();
 			oli.quantity = 1;
 			oliList2.add(oli);
 		}		
	 					
	}

	public PageReference saveIt() {
		try {
			opp.attn_to__c = System.now().format();
			update opp;
			for (OpportunityLineItem oli : oliList) { 
				oli.Quantity = oli.quantity + 1.00;
			}
			update oliList;
		} Catch (Exception ex) {
			ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, ex.getMessage()));
		}
		ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.INFO, 'Updated to ' + opp.attn_to__c + '.'));
		return null;
	}
	
}

 

<apex:page controller="KKTestSiteController" cache="false" tabstyle="Opportunity">
<apex:form >
<apex:pageBlock > 
<apex:pageMessages />
<apex:pageBlockButtons location="both"> 

<apex:commandButton value="save" action="{!saveIt}"/>

</apex:pageBlockButtons>


<apex:pageBlockSection title="update section" columns="1">

<apex:inputField value="{!opp.ATTN_To__c}"/> 
<apex:pageBlockTable value="{!oliList}" var="item">
	 <apex:column >
	   <apex:inputField value="{!item.description}"/>  
	 </apex:column>
	 <apex:column >
	   <apex:inputField value="{!item.quantity}"/> 
	 </apex:column>
</apex:pageBlockTable>
</apex:pageBlockSection>

<apex:pageBlockSection title="new section (not persisted)" columns="1">

<apex:inputField value="{!opp2.ATTN_To__c}"/> 
<apex:pageBlockTable value="{!oliList2}" var="item">
	 <apex:column >
	   <apex:inputField value="{!item.description}"/> 
	 </apex:column>
	 <apex:column >
	   <apex:inputField value="{!item.quantity}"/> 
	 </apex:column>
</apex:pageBlockTable>
</apex:pageBlockSection>

</apex:pageBlock>
</apex:form>
</apex:page>

 

nathaForcenathaForce
Hi Ken,

Are you planning on using a customer portal? When I once worked on a project for an online university, we also wanted to use Opportunities along with a customer portal, but the way salesforce views it, customers should not have access to the Opportunity object. The object could be accessible when using Partner Portal only.

I would suggest to look more into it, and also look into what Communities offer (the new version of a customer portal, which includes chatter).

Nathalie