Subject
Challenge
- Create ‘Meeting’ object
- Create ‘Meeting’ to ‘Contact’ relation
- Create ‘Meeting’ to ‘User’ relation
Now looking at the list above I have to correct myself. I’ll be creating appointments for 2 persons, one being an appointment owner and another one being an appointment contact. Think of it as you (appointment owner) are going to visit a customer (appointment contact).
perl
as a scripting language. I especially like it for client-side development, but it’s not so often used in connection with SugarCRM, which is written in php
. So, googling is of a limited help here looking for examples.Platform/Tools
- First of all, SugarCRM CE (Community Edition) version 6.5.16
- ActiveState perl (v5.14.2) on Windows 7
- And also one nice perl module Net::SugarCRM found on CPAN (version 2.17738).
Solution
Simple create appointment
Using Net::SugarCRM
module this goes pretty straightforward:
use Net::SugarCRM; use DateTime; use Data::Random qw(:all); ... my $s = Net::SugarCRM::Links->new(url=>$url, restuser=>$login, restpasswd=> $pass); ... my $meeting_entry = { date_start => DateTime->now()->date() . ' ' .DateTime->now()->time(), assigned_user_id => $user_id, duration_minutes => '60', description => join(' ',rand_words( size => 5)), name => join(' ',rand_words( )), status => 'Planned', parent_type => 'Contacts', parent_id => $contact_id, }; my $meeting_id = $s->create_module_entry('Meetings',$meeting_entry);
This will return the id of the new appointment, we just created. $user_id
is the id of the appointment owner (myself) and $client_id
is the id of the client, I’m going to meet.
Please also note the usage of DateTime
and Data::Random
to fill the content automatically with some random values.
It was very simple so far, but this is not all. Appointments are created, but not properly assigned. If we go to SugarCRM user interface, we won’t see these appointments in user’s calendar and also won’t see them in the list of activities for particular contacts. To solve this we will need to create relationships.
Extend Net::SugarCRM to handle relationships
Unfortunately Net::SugarCRM
doesn’t offer a generic function to create relationships between objects (modules) in SugarCRM. Here I just decided to extend it via my own module Net::SugarCRM::Links
having one additional method to support relationship creation.
package Net::SugarCRM::Links; use parent Net::SugarCRM; ... sub create_module_links { my ($self, $module, $module_id, $link_field_name, $related_ids, $attributes) = @_; foreach my $required_attr (@{$self->required_attr->{$module}}) { $self->log->logconfess("No $required_attr attribute. Not creating links in $module for: ".Dumper($attributes)) if (!exists($$attributes{$required_attr}) || !defined($$attributes{$required_attr}) || $$attributes{$required_attr} eq ''); } my $rest_data = '{"session": "'.$self->sessionid.'", "module_name": "'.$module . '", "module_id": "' . $module_id . '", "link_field_name": "' . $link_field_name. '", "related_ids": ' . encode_json($related_ids) . ', "name_value_list": '. encode_json($attributes). '}'; my $response = $self->_rest_request('set_relationship', $rest_data); $self->log->info( "Successfully created link in <".encode_json($attributes)."> with sessionid ".$self->sessionid."\n"); $self->log->debug("Link created in module $module was:".Dumper($response)); #return $response->{id}; return $response; }
The above code is almost “Copy&Paste” from the parent’s method create_module_entry
with very few changes.
Line 14 creates a different REST request string and in the call _rest_reqeust
in line 19 we use set_relationship
from SugarCRM REST API.
Please note that I kept the code to check for required attributes (line 7), but it has no practical meaning. To get any use of it one would need to add additional modules and attributes in the parent’s class required_attr
array. This exercise is left to the reader.
Add links to Contact and User
There are two many-to-many relationships we would need to create using the above Net::SugarCRM::Links
module. Nothing too special with that, just review the code below.
use Net::SugarCRM::Links; my $link_entry = { module => 'Meetings', meeting_id => $meeting_id, module => 'Contacts', contact_id => $contact_list[$i]->{'id'} }; my $out = $s->create_module_links('Meetings',$meeting_id,'contacts',[$contact_id],$link_entry); my $user_link_entry = { meeting_id => $meeting_id, user_id => $user_id, accept_status => 'accept', required => 1 }; $out = $s->create_module_links('Meetings',$meeting_id,'users',[$user_id],$user_link_entry);
I intentionally don’t include error handling here to keep is simple, basically you are advised to traverse through the output of the create_module_links
method, this works as documented in the API documentation. In particular you will see how many relationships are created, deleted and failed.
Please observe the 3-d argument to the method create_module_links
above in lines 10 and 19. This is what the API documentation describes as
link_field_name -- name of the link field which relates to the other module for which the relationship needs to be generated.
And this is a nice pitfall. My first understanding was that this should be something like ‘meetings_contacts’ as a field name and it took a while before I realized that this should be just a module name to which we are creating our relationships.
Discussion
And finally when we go to a particular contact, we see all these meeting listed in the Activities section:

Caveats
accept_status
update didn’t work and the meeting owner could change the status directly in UI.