How can i set the required fields of a Salesforce object? - salesforce

I have a Salesforce object, lets say Contact.
If I try to set the Name field by using code:
Contact testAccount = new Contact();
testAccount.Name ='TestAccountContact';
insert testAccount;
It gives an error:
Line: 2, Column: 20
Field is not writeable: Contact.Name
By navigating the object through Salesforce I find that Name is a combination of FirstName, LastName.
How can I determine if the field is writeable and if not get the componenets of that field that together represent it. In this case FirstName and LastName cconcatenated makes up Name.

Contact/Lead/User Name is special field which Salesforce composes in runtime depending on what's in the data and who's looking. Source fields can be:
Salutation (Mr, Mrs...)
FirstName
MiddleName (if you have them enabled)
LastName
Suffix (if you have them enabled)
"Who's looking"? There are cultures that use "LastName FirstName", commonly referred to as CJK (Chinese,Japanese,Korean) but also Hungarian for example. This is defined by user's locale.
To check if field can be written to on insert use "describe" calls, specifically isCreateable.
System.debug(Schema.sObjectType.Contact.fields.Name.isCreateable()); // false
For practical purposes - try to not to use Contact.Name too much in Apex or reports for example. You'll forget this quirk and 2 years later will get a "funny" bug report that for some user report that goes Name equals to John Doe doesn't return any results for certain user and you'll go all "works for me".

Related

Why Lead.Name is null

I have assigned values to a Lead record. I looked at the same record via regular UI Listview and the field Name is ok (concatenation of FirstName and LastName). However the System.debug shows "null". Why this discrepancy?
Lead myLead = new Lead();
myLead.Company = 'Tesla Motors';
myLead.LastName = 'Musk';
myLead.FirstName = 'TechnoKing';
System.debug('Here is the new Lead: ' + myLead.Company + ' and Lead Name: ' + myLead.Name );
Name is special field calculated at runtime when you view a saved record. You'd need to insert it and query the value. 2 reasons:
For you it might be natural to go "FirstName LastName" but there are cultures that prefer "LastName FirstName". Chinese/Japanese/Korean (often abbreviated to CJK). And bit closer to home - Hungarian for example, I kid you not. See the list at https://help.salesforce.com/articleView?id=sf.admin_supported_locales.htm&type=5. So Lead.Name, Contact.Name, User.Name is special, it's not a real field, it depends who's looking.
"Name" is a bigger concept than just "John Doe". It can include Salutation (Mr, Ms etc), Middle name (if you enabled that in setup, even suffixes. https://help.salesforce.com/articleView?id=000332623&type=1&mode=1 So it's 1 data source to keep in mind when composing at runtime.

Django Model ValueError

I'm accessing emails in my email server, taking the body of each email and then applying regular expressions to find the data necessary to populate my Django model.
This all works fine except for one field, which is linked as a foreign key to another model field. Despite the value in my email being the same as the one in listed in my other model, it fails....
The error:
ValueError: Cannot assign "'Humanities'": "Subject.faculty" must be a "Faculty" instance.
For example, say each school subject has to be part of a faculty. When populating the database via a form, for the Subject's faculty field I drop down the menu to a list of faculty values/instances as there is a foreign key relationship defined in my model i.e. for the faculty field I can choose from Humanities, Art, Design Technology etc.
But when I find the value 'Humanities' in my email and try to add it to the database model, I get the error above.
Anyone shed any light on this? Am I being stupid or is it more than a ValueError as to me, the values are the same in both cases
Thank you
More code as requested:
class Faculty(models.Model):
name = models.CharField(primary_key=True, max_length=50)
leader = models.CharField(max_length=50)
email = models.EmailField()
mailing_list = models.ManyToManyField("Contact", null=True)
class Subject(models.Model):
name = models.CharField(max_length=50)
faculty = models.ForeignKey(Faculty, to_field="name")
faculty_head = models.CharField(max_length=50)
It sounds like you are trying to assign a string "Humantities" to a ForeignKey relationship. This doesn't make sense. You need to either find or create the actual Faculty object with the name "Humanities" and assign it to the Subject. Something like this in your view (depending on how your form is set up):
if form.is_valid():
faculty_str = form.cleaned_data['faculty']
(faculty, was_created) = Faculty.objects.get_or_create(name=faculty_str, ...)
# It's hard to tell if you are using a ModelForm or just a normal Form. Anyway, assume we already have access to the Subject object
subject.faculty = faculty
subject.save()
get_or_create()
Your value is 'Humanities' perhaps you mean to search for Humanities (without quotes).
You need to create a Faculty instance first.
faculty = Faculty(name='', leader='', email='')
faculty.save()
subject.faculty = faculty
subject.save()

How to create autocomplete with GAE?

I use jQuery UI autocomplete widget. Also I have GAE datastore:
class Person(db.Model):
# key_name contains person id in format 'lastname-firstname-middlename-counter',
# counter and leading dash are omitted, if counter=0
first_name = db.StringProperty()
last_name = db.StringProperty()
middle_name = db.StringProperty()
How can I search the person in the autocomplete widget, when user can input there surname, first name and/or middle name?
So, I am getting user input string as self.request.get('term'). How should I search for the same in my datastore (since I need to look at each field and probably for combined value of 3 fields)? How to optimize such query?
I am also not clear what should be the reply format. jQuery doc says:
A data source can be:
an Array with local data
a String, specifying a URL
a Callback
The local data can be a simple Array of Strings, or it contains
Objects for each item in the array, with either a label or value
property or both.
There are a few neat tricks here. Consider this augmented model:
class Person(db.Model):
first_name = db.StringProperty()
last_name = db.StringProperty()
middle_name = db.StringProperty()
names_lower = db.StringListProperty()
You'll need to keep names_lower in sync with the real fields, e.g.:
p.names_lower = [p.first_name.lower(), p.last_name.lower(),
p.middle_name.lower()]
You can do this more elegantly with a DerivedProperty.
And now, your query:
term = self.request.get('term').lower()
query = Person.all()
query.filter('names_lower >=', term)
query.filter('names_lower <=', unicode(term) + u"\ufffd")
This gives you:
Matching on all 3 properties with one index
Case insensitive matches
Wildcard suffix matches
So a query for "smi" will return any person with any name starting with "smi" in any case.
Copying lower-cased names to a ListProperty enables case-insensitive matching, and allows us to search all 3 fields with one query. "\ufffd" is the highest possible unicode character, so it's the upper limit for our substring match. If for some reason you want an exact match, filter for 'names_lower =', term instead.
Edit:
How should I search for the same in my datastore (since I need to look
at each field and probably for combined value of 3 fields)? How to
optimize such query?
This is already accounted for in the original solution. By taking the 3 fields and copying them to a single ListProperty, we're essentially creating a single index with multiple entries per person. If we have a person named Bob J Smith, he'll have 3 hits in our index:
names_lower = bob
names_lower = j
names_lower = smith
This eliminates the need to run distinct queries on each field.
I am also not clear what should be the reply format.
Read the docs carefully. Formatting output for jQuery should be pretty straightforward. Your data source will be a string specifying a URL, and you'll want to format the response as JSON.
Basically agreeing on everything Drew wrote I post a link to my blog with rather elaborate example for auto-completing selecting keywords when searching for information in the datastore.
All done in GAE with Python and using YUI3 instead of jQuery (plugging in jQuery or any other library instead would be trivial).
Shortly, the idea is that datastore contains set of documents that are indexed using keywords (using Relation Index Entity). And when user enters words to search for, the system autocompletes them with the keywords from those documents.

VisualForce(APEX): Update record with known ID

This is an APEX code related question and is specific to a VisualForce controller class.
Question
I am trying to update a record with a known AccountId. However, when I set the ID in the sObject declaration SalesForce is appending the string "IAR" to the end of the ID!
Can someone please let me know what I am doing that is wrong and if I am going about this in the wrong way than what is the correct way to update a record from a custom method, outside of quicksave() or update().
Description
So basically, the user will come to this page with the id encoded and it will either have an id or a level. This is handled by the function decode() which takes a string; "id" / "level". I then create an Account variable "acc" which will be used to store all of the Account information before we insert or update it with the statement "insert acc;". Since, I cannot set the ID for "acc" with "acc.id = salesForceID" I have decided to set it when "acc" is created. The following APEX code occurs in the constructor when it is declaring the "acc" variable.
URL Variable Passed
/application?id=001Q000000OognA
APEX Controller Class (Abridged)
salesForceID = decode('id');
debug1 = 'salesForceID: ' + salesForceID;
acc = new Account(id = salesForceID);
debug2 = 'Account ID: ' + acc.id;
Debug Output
salesForceID: 001Q000000OognA
Account ID: 001Q000000OognAIAR
Comments
I apologise for the brevity of the code given, this is for security reasons. I am basically trying to set the ID of the acc before I insert/upsert/update it. I appreciate any explanations for why it could be appending "IAR" and or any alternate ways to update a record given an input AccountId. I do understand that if you pass the id in as a URL variable that SalesForce will automatically do this for you. However, I am passing more than one variable to the page as there are three separate use cases.
Thanks for your help.
001Q000000OognA is the "standard" 15-character Salesforce ID. 15-character ID's are case-sensitive.
001Q000000OognAIAR is the case-insensitive 18-character version of that ID.
Either one is fine. You do not need to worry about the difference. If for some reason you really need to use the 15-character version in parameters etc, you can safely truncate the last 3 digits.
More information here: http://www.salesforce.com/us/developer/docs/api/Content/field_types.htm

Creating "complex forms" in FileMaker - is it even possible?

I have been asked to look into FileMaker for creating a pretty simple database app. The application will handle contact information, some information about events hosted by the organization and - and this is where I'm currently struggling - RSVP information that link the contacts and events, as well as stores some data about payment.
What I would like to use is some kind of form where the user gets to search for a contact (any combo of first/last name) and an event (any combo of name/date), select each from two respective lists (where all other information is displayed as well, to distinguish the results), add some extra information and hit submit.
The closest I've gotten so far is a form where the user can enter a ContactId and EventId manually, which means that he/she first has to go to another view, search for the records, and copy/paste the id numbers.
Is there really no way to get closer to my vision using FileMaker?
Would a better option be to build a new, custom app using for example C# and MsSQL?
If so, how do I sell this to my contractor? As this would in that case be my first commercial application, there is obviously a "safety factor" that speaks in favor of an established product. And then we haven't even mentioned that the cost would probably increase, as developing a new app from scratch would take much longer time.
Note: I have no previous experience with FileMaker. I've tried to read the documentation, but I haven't been able to find any tutorials that take me closer to my specific needs. I'm fairly experienced in MsSQL, so I do know this and that about database management in general - just not in FileMaker.
There are loads of ways to do it. This is a quick way to get it to work.
Let's say you have two tables like this:
Contacts Events
-------- --------
ContactID EventID
FirstName EventDate
LastName EventDetails
Create a new link table between them that also stores the extra RSVP information you want.
RSVP
--------
fk_ContactID
fk_EventID
PaymentInfo
Create a FORM table
FORM
--------
ContactSearch
cContactMatch = Calculation, If(isEmpty(ContactSearch) ; "ALL" ; ContactSearch)
EventSearch
cEventMatch = Calculation, If(isEmpty(EventSearch) ; "ALL" ; EventSearch)
Add the following fields to the Contacts and Events tables:
Contacts
--------
cMatchField = Calculation, Stored, (FirstName + NEWLINE + LastName + NEWLINE + ALL + NEWLINE + Firstname LastName)
Events
--------
cMatchField = Calculation, Stored, (EventDate + NEWLINE + EventDetails + NEWLINE + ALL)
This means that the cMatchField for Contacts will look something like this:
John
Smith
John Smith
ALL
In the relationship diagram, connect the tables like this:
FORM
--------
cContactMatch = CONTACTS/cMatchText
cEventMatch = EVENTS/cMatchText
Create a layout called FORM based on the FORM table.
Add the fields ContactSearch and EventSearch to the layout. Add the PaymentInfo field.
Add two PORTALS to the layout, one for the Contacts table, one for the Events.
By default you should see all the records in each of these portals.
Write a script, or use a script trigger, that refreshes the layout whenever one of those search fields is Exited/Modified. This should refresh the portals and show you the related records you're interested in.
Add a button to each row in the portals and call a script that sets a global variable to that portal rows ID.
For example:
Script: Set Selected Contact ID
Set Variable ($$ContactID ; Contacts::ContactID)
Script Set Selected Event ID
Set Variable ($$EventID ; Events::EventID)
Add another button to the layout and a new script.
Script: Create RSVP
# Check that a contact and event have been selected
If(isEmpty($$ContactID) or isEmpty($$EventID)
Exit Script
End If
# Get the payment info that has been entered
Set Variable ($PaymentInfo ; FORM::PaymentInfo)
# Create the RSVP Link record
Go To Layout(RSVP)
Create New Record
Set Field(fk_ContactID ; $$ContactID)
Set Field(fk_EventID ; $$EventID)
Set Field(PaymentInfo ; $PaymentInfo)
Commit Records
Go to Layout (Original Layout)
# Clear the search fields
Set Field(PaymentInfo; "")
Set Field(ContactSearch; "")
Set Field(EventSearch; "")
Set Variable($$ContactID; "")
Set Variable($$EventID; "")
Commit Records
Refresh Screen
Phew.
And you should be back, ready to search for Contacts, Events, and "Submit" the form to create more RSVPs.
FileMaker is fun, eh?

Resources