Computer Associates Plans To Release Agile Development Tool On Force.com Platform
Today, at Dreamforce 2009, Computer Associates plans to release CA Agile Planner(http://www.ca.com/agile), a tool to manage agile development teams.
CA Agile Planner will be integrated with CA Clarity PPM (http://www.ca.com/ppm).
Although it was not clear how much of the demonstrated app will run on Force.com and how much will run on the CA servers (though it appeared to be 100% on Force.com), it was clear that the application was accessed via a force.com URL.
For more information, see http://www.ca.com/agile.
A release date for the product was not mentioned, but the earliest planned release of any newly-announced feature thus far is Spring 2010, so one might assume that this will not be available until then.
New Developer Library Released
Today, Developer Force (http://developer.force.com) released its new library. Here are a few of them. All can be found at http://wiki.developerforce.com/index.php/Documentation.
Workbook
http://www.salesforce.com/us/developer/docs/workbook/index.htm
Fundamentals
http://www.salesforce.com/us/developer/docs/fundamentals/index.htm
Cookbook
http://www.salesforce.com/us/developer/docs/cookbook/index.htm
Apex Advanced Code Example
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_shopping_cart_example.htm
https://sites.secure.force.com/appexchange/listingDetail?listingId=a0N30000001saDCEAY
And many more to come!
A Mention in the Developers Challenge
The salesforce.com Developer Force Challenge has concluded, and the team of Force Squared and The Enforcer won a mention!
Our Daily Shinro site was listed “for sheer exuberance!”
I’m really proud of the site, though the lion’s share of the kudos go to John for the concept and site design. I just coded whatever he told me to code; he’s the creative one!
So if anyone is looking for a custom Force.com Site or website integration to Salesforce, contact us and let’s discuss your needs!
Overload Apex Class to be Controller AND Extension
Wow - today brought an interesting discovery. Here's the situation:
Coding the new premium version of Mass Update Contacts (details to come), I replaced the two parts of the page with Apex Components. This will allow the app to support custom address fields and international address formats.
I didn't want to write one ControllerExtension for the main page, a CustomController for the view section component, and another CustomController for the pageblocktable component. So here is the overloaded class constructor. Note that this works because an extension passes the StandardController to the constructor, and a CustomController passes nothing:
public with sharing class VersatileClass {
private Account account;
public VersatileClass(){
system.debug('OPERATING AS CONTROLLER');
if(System.currentPageReference().getParameters().get('id')==null){
//Include error checking here
} else{
string AId = System.currentPageReference().getParameters().get('id');
account = [select id, name from Account where id = :AId];
//And whatever else you want to do
}
}
public VersatileClass(ApexPages.StandardController controller) {
system.debug('OPERATING AS EXTENSION');
if(System.currentPageReference().getParameters().get('id')==null){
//Include error checking here
} else{
this.account = (Account)controller.getRecord();
//And whatever else you want to do
}
}
}
Enjoy! This should save people a lot of time.
Email Inbox Version 2
Well, it took about ten minutes from the release of Email Inbox Version 1 for people to request additional features, screenshots, etc. Version 2 includes some neat icons, and this post has the multiple-times-requested screenshots we promised.
First, a teaser screenshot. (There's a better one below the code.)

Here's the updated Visualforce code:
<apex:page controller="EmailMessageController" action="{!ViewData}">
<apex:sectionHeader title="Email Messages" subtitle=""></apex:sectionHeader>
<apex:pageblock id="emailblock">
<apex:facet name="header">
<apex:form >
<apex:panelGrid styleClass="list"
columnClasses="pbTitle,pbButton,pbHelp" columns="3" border="0"
cellpadding="0" cellspacing="0">
<apex:outputLabel ><h3>Messages</h3></apex:outputLabel>
<apex:commandButton value=" Refresh " styleClass="btn"
action="{!ViewData}" rerender="emailblock"></apex:commandButton>
<apex:SelectList value="{!wheretext}" size="1" id="controllerselectlist">
<apex:actionSupport event="onchange" action="{!ViewData}"
reRender="emailblock"></apex:actionSupport>
<apex:selectOptions value="{!views}" />
</apex:SelectList>
</apex:panelGrid>
</apex:form>
</apex:facet>
<apex:form >
<apex:pageblocktable value="{!Messages}" var="e" id="emailtable"
bgcolor="#F3F3EC" styleClass="list" rowClasses="dataRow"
onRowMouseOver="hiOn(this);" onRowMouseOut="hiOff(this);">
<apex:column >
<apex:facet name="header">
<apex:commandLink action="{!ViewData}"
value="{!$ObjectType.EmailMessage.fields.Subject.label}{!IF(sortExpression=='Subject',
IF(sortDirection='ASC','▼','▲'),'')}">
<apex:param value="Subject" name="column"
assignTo="{!sortExpression}"></apex:param>
</apex:commandLink>
</apex:facet>
<apex:outputLink value="/{!e.Id}" target="_blank">{!e.Subject}</apex:outputLink>
</apex:column>
<apex:column >
<apex:facet name="header">
{!$ObjectType.Contact.fields.Name.label}
</apex:facet>
<apex:outputLink value="/{!e.Parent.ContactId}" target="_blank"
rendered="{!IF(e.Parent.ContactId != '',true,false)}">{!e.FromName}</apex:outputLink>
<apex:outputtext value="{!e.FromName}"
rendered="{!IF(e.Parent.ContactId != '',false,true)}" />
</apex:column>
<apex:column >
<apex:facet name="header">
{!$ObjectType.Account.fields.Name.label}
</apex:facet>
<apex:outputLink value="/{!e.Parent.AccountId}" target="_blank">{!e.Parent.Account.Name}</apex:outputLink>
</apex:column>
<apex:column value="{!e.FromAddress}">
<apex:facet name="header">
<apex:commandLink action="{!ViewData}"
value="{!$ObjectType.EmailMessage.fields.FromAddress.label}{!IF(sortExpression=='FromAddress',
IF(sortDirection='ASC','▼','▲'),'')}">
<apex:param value="FromAddress" name="column"
assignTo="{!sortExpression}"></apex:param>
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{!e.Status}">
<apex:facet name="header">
<apex:commandLink action="{!ViewData}"
value="{!$ObjectType.EmailMessage.fields.Status.label}{!IF(sortExpression=='Status',
IF(sortDirection='ASC','▼','▲'),'')}">
<apex:param value="Status" name="column"
assignTo="{!sortExpression}"></apex:param>
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column value="{!e.MessageDate}">
<apex:facet name="header">
<apex:commandLink action="{!ViewData}"
value="{!$ObjectType.EmailMessage.fields.MessageDate.label}{!IF(sortExpression=='MessageDate',
IF(sortDirection='ASC','▼','▲'),'')}">
<apex:param value="MessageDate" name="column"
assignTo="{!sortExpression}"></apex:param>
</apex:commandLink>
</apex:facet>
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink action="{!ViewData}"
value="Inbound/Outbound{!IF(sortExpression=='Incoming',
IF(sortDirection='ASC','▼','▲'),'')}">
<apex:param value="Incoming" name="column"
assignTo="{!sortExpression}"></apex:param>
</apex:commandLink>
</apex:facet>
<apex:image url="/img/emailInbound.gif" rendered="{!e.Incoming}" />
<apex:image url="/img/emailOutbound.gif" rendered="{!NOT(e.Incoming)}" />
<!--<apex:outputfield value="{!e.Incoming}" rendered="{!NOT(e.Incoming)}" />-->
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink action="{!ViewData}"
value="Attachment{!IF(sortExpression=='HasAttachment',
IF(sortDirection='ASC','▼','▲'),'')}">
<apex:param value="HasAttachment" name="column"
assignTo="{!sortExpression}"></apex:param>
</apex:commandLink>
</apex:facet>
<apex:image url="/img/emailHasAttach.gif" rendered="{!e.HasAttachment}"/>
<apex:outputfield value="{!e.HasAttachment}" rendered="{!NOT(e.HasAttachment)}" />
</apex:column>
<apex:column >
<apex:facet name="header">
<apex:commandLink action="{!ViewData}"
value="{!$ObjectType.Case.fields.CaseNumber.label}{!IF(sortExpression=='ParentId',
IF(sortDirection='ASC','▼','▲'),'')}">
<apex:param value="ParentId" name="column"
assignTo="{!sortExpression}"></apex:param>
</apex:commandLink>
</apex:facet>
<apex:outputLink value="/{!e.ParentId}">{!e.Parent.CaseNumber}</apex:outputLink>
</apex:column>
<apex:column value="{!e.ToAddress}">
<apex:facet name="header">
<apex:commandLink action="{!ViewData}"
value="{!$ObjectType.EmailMessage.fields.ToAddress.label}{!IF(sortExpression=='ToAddress',
IF(sortDirection='ASC','▼','▲'),'')}">
<apex:param value="ToAddress" name="column"
assignTo="{!sortExpression}"></apex:param>
</apex:commandLink>
</apex:facet>
</apex:column>
</apex:pageblocktable>
</apex:form>
</apex:pageblock>
</apex:page>
The Apex controller code has not changed from Version 1.
Here's the screenshot, which includes some emails from around the Salesforce ecosystem:
- Salesforce will search ANY Email field to match an incoming email to a Contact. (nice job, Salesforce!) - We know because Simon Fell's Contact.Email is sfell at salesforce.com, and his Contact.Secondary_Email__c is simon at fell.com in the sandbox. Ditto (with her own email addresses) for Irene Brodt.
- Auto-response emails will be included. We turned off auto-response after a few emails came in.
- Though the Email Address field is coded just to show the field value, Salesforce includes the Gmail link. (We assume that's because we activated the integration, but we may be wrong. Has anyone not activated that?)
- We did not (yet) implement the super Email/Web2Case trigger code that Marco Casalaina posted in the Salesforce Support Blog, but if we had, then every email in the list would be associated with a Contact. (Example: Michael Smith of Force2b.net, who will be a Contact from now on!)





