Adding and Removing Teams Within Sugar

From time to time you will need to change the teams on a records, via code, probably from a logic hook. This sounds easy but I had quite a lot of difficulty with it. I’ll give you what I learned

Firstly, Sugar have documented here very well, but there are aspects to it that just don’t work. Note that the code snippets below all come from the Sugar site, with a few modifications.

From their examples I found the following.

1. It is imperative that the primary team (team_id) be one of the teams to be included. If you are removing the primary team from the list of teams, make sure you allocate a new primary_team, and save the record, before you start adding and removing teams.

The code below shows setting a new primary team, and saving the record.

2. Use replace(), not add() and remove() as suggested in the Sugar article.

I had all sorts of problems using add(0 and remove(). When I turned to replace(), everything worked fine. I’m using Professional 6.5.14, so it may have been corrected in later editions.

The following is all you need, just replacing the array with all the teams you want included.

With the above you don’t need to worry about TeamSets at all.

Let me know if you have any comments or suggestions.

 

 

 

 

Adding Javscript to SugarCRM UI

I had a case where the logic needed for a calculated field within Sugar was just too complicated for Formula Editor. Even if I had managed to get it working it would have been hard to modify in future.

So I started looking round for ways to use Javascript for this type of client validation, and I found that it was very easy to implement. Although my requirement was just to produce a calculated field, I started to think of all sorts of things you could do with Javascript, including  using Ajax to retrieve and display data, and to  do all sorts of validation, and other changes to the UI

For the present it is just the calculated field. The following a the few simple steps you need to follow. In this example I’ve assumed you are working with opportunities. The same logic would apply to any other module just as easily.

1. Add a reference to the javascript file you are going to add

Add the following at the end of custom/modules/Opportunities/metadata/editviewsdef.php

 2. Add the javascript file

custom/modules/Opportunities/recalculateAmount.js

What the above is doing is using JQuery to add a function that gets called whenever the ‘description’ file changes. When this happens, the field ‘next_step’ has its value changed, and an alert box is shown.

While this functionality if obviously of no value, you can do any logic and updating you like here. Also, we are using the JQuery function ‘change’ (which is just Javascript’s ‘onchange’ function), but of course you can use any of the JQuery trigger functions here.

3. Quick Repair, then browser refresh

This is needed to implement the new logic.

That is it really. One quirk I found was with multiple dependent drop-down lists where there were three levels. It seems that if more than one drop down list has it’s value change, only the first of them calls the Javascript on change. I need to investigate this further, but for now just be warned.

I would appreciate any comments of suggestions.

 

When Sugar User Interface Goes Wrong

When you work with Module Builder and Studio, usually things go well. The only thing to remember is that once you start using Studio to amend things, you can’t go back to Module Builder. If you do you loose the Studio amendments, and that is really how it should work.

My problem today came from exporting customization from a development instance of Sugar and loading it into the production instance. I’ve done this many times, as a means of migrating custom fields, layouts and code (logic hooks). This time it didn’t work, and I’m not sure why. Certainly the manifest file of the exported module looked a mess, so it it is not surprising that it caused all sort or problems.

I’m not going to bore you with going through all the steps I had to take, but I would like to document the few general rules that I found applied. These need more testing out, so don’t depend on them 100%. If I have any wrong, or missed anything, please let me know.

1.    If custom fields don’t appear in the fields_meta_data table in the database, nothing else will solve your problems.

2. When you edit any vardef type fields, always do a Quick Repair afterwards. There is no need to clear cache or log off or anything else.

3. Sometimes you need to go into Studio, and save an deploy each of DetailView, EditView etc, to correct some type of problems.

I’ll add some more notes here from time to time, but I would be interested if you have any further suggestions or ideas.

 

Adding Fields To An Existing Module Without Using Module Builder

I had the need to take an existing module that had been built earlier with Module Builder, but needed some fields added. In fact there were a large number to add, so much in fact that I didn’t fancy entering them one by one in Module Builder.

As all were very similar fields I thought I should be able to edit files within the module directly. As it turned out this was quite possible.

The steps I went through were as follows.

1. Obtain the existing module. This is a zip file you can locate in the upload/modules directory

2. Unzip this file

3. Edit the vardefs file for the module you want to add fields to. If the module was Test, the file would be SugarModules/modules/Test/vardefs.php

When you look at this file you will see the format of the various fields. Just add and edit as needed.

Note you may wish to edit the language files as well, though I didn’t.

4. Zip up the folder again. Something like the following

zip -r ../test.zip *

Will give you a file test.zip that you can upload.

If the module exists, you will need to uninstall the previous version first. You can conserve the data.

5. Use Module Loader to install the modules.

That’s it. Most times you won’t want to do it this way, but in my case I needed to duplicate 5 fields 15 times. An horrible job in Module Builder.

 

 

SugarCRM Offline Client Written Using HTML5 and JQuery – Part 1

I’ve spent some time recently working with HTML5 and thought it might be fun to use its local database capabilities to build an offline client for Sugar, especially for mobile. I know Sugar have offline apps, but they cost money and are rather inflexible. It would be good to build a framework that allowed bespoke offline applications to be built to meet clients specific needs.

Two ideas came to mind, but there are sure to be many more. Firstly, collecting leads at a business show is often done on tablets. This should be possible offline, with the stored results sent to Sugar once an internet connection becomes available.

The other possibility is simply to hold data from Sugar for offline viewing. This could be client and contact details, and maybe product details or sales history.

I know this functionality is well short of the two way syncing that can be provided by some apps, but that is much more difficult to accomplish, so that will have to wait for another day.

I’m keen to know what the capabilities and limitations are for HTML5 databases. How do they handle hundreds of thousands of records. One of my first tests will be to load large data sets from Sugar and see how they go.

Well so far I have in place the various elements needed, as follows.

1. User Interface

As these will be mainly mobile solutions I thought it best to start with JQuery Mobile to handle the user interface. This will give me mobile capabilities with very little work.

2. Internal Database

I’ve tried creating databases, and adding and reading records.

3. Communicating With Sugar

I’ve used web services to access Sugar many times from PHP, mainly for integration processes, but never from a browser. The JQuery Ajax capability is easy to use, but getting the parameters configured in JSON is a bit tricky. I can now read and insert records into Sugar, though there is more to do.

Well that’s the start. In Part 2 I’ll put all the bits together.

I would be interested to hear any comments or suggestions.

 

 

Sugar Integration Without Last Modified Dates

Integration with Sugar is very common where details from a remote system needs to be made available to Sugar users.

The usual way to transfer data is to ask the remote system for all records that were recently created or modified after a specific date and time. This means that only a small number of records needs to be imported each time the integration process runs.

Of course this depends on the remote system being able to provide recent data, either by direct database access or via web services. What do you do when the remote system doesn’t record the last modification date?

One answer is to (as  I have implemented once) just copy all the records each time the integration runs. This has many disadvantages, including the extra band width and processing time, and the fact that last modification dates of the data in Sugar become meaningless.

There is a simple solution to this which involves setting up a new table to record the changes and additions. Ideally this is held in the remote system, but if you don’t have suitable access to it, you can hold the table with the integration process or within Sugar.

This table includes one record for each record in the remote system being integrated. The one table can handle records for any number of remotes system tables. It includes four columns as follows

Table name – name of the table in remote system
Primary key for the table in the remote system
A text field – see below
A modified date/time

The text field is a JSON string of an array of the remote systems record.

The process reads all records from the required tables in the remote system. For each it used the table name and primary key value to see if the record exists in our integration table. If not it creates one with the current date/time.

If it finds the record, it compares the JSON encoded array of values, with the equivalent from the just read remote system record. If they differ (i.e.. if any of the fields within the remote record have changed since the last time the integration process ran, the integration table is updated with the new JSAON value and the date/time is set.

The Sugar integration can use this integration table any time it likes, with SQL something like.

This approach does take more disk space but allow you to structure date with last modified date/time.

Another big advantage is in terms of creating web service API for others to access your system. You could create a single table like this, and make it the only database table accessible by your API. That would simplify the API and ensure that API methods didn’t have to work on your live tables, just the single integration table. Of course this only applies if the API are read only.

Another advantage is that in creating this single integration table, you could include details from more than one table. An example might be the you include the account name along with contact details.

I have implemented all the above in PHP, and applied it to a live Sugar database. I know Sugar records last modified date/time but I’m doing it as test and it proves to run very quickly. It reads lots but only inserts or updates a relatively small number.

I am interested to hear your opinions on this approach and would be happy to share my code. Any feedback would be welcome.

Update 10th July 2017

I just had another Sugar integration process that needed this approach. It worked very well, and was really the best approach where you don’t have a modified date. Instead of retaining the actual data, I created and saved a hash value, as the data was quite large

 

 

 

 

 

Ways To Change Sugar UI

When you use Studio you can only build user interfaces of a predetermined layout, with predetermined elements. To go beyond the standard involves coding, but what options do you have?

I’m no expert but I have worked with a number of approaches which I had described below. As you can see, these are very much a work in progress.

1. Amend vardefs files

You can edit these directly. I will add an example later.

2. Use Logic Hook with after_ui_frame

This will add code after the UI has been loaded into the browser. You can’t just add text as I have done as there is no way of knowing where it will arrive in the page. It would be better to set the inner HTML, or add a javascript file, or style sheet.

I haven’t explored these but you can see that this does give you the scope to change or add to the UI

In the following example I have added code to the  file custom/modules/Accounts/logic_hooks.php

And included ExtraUIStuff.php in the same directory, as follows.

 

3. Add new Smarty files

This is the most flexible. I will add a section here to describe what is needed and what can be achieved.

See the following link, until I can test and add my own code.

http://www.dobre.name/sugarcrm/adding-header-or-footer-to-editview-in-sugarcrm.html

More to follow…..

 

Debugging Web Services

Debugging normal  PHP web applications is pretty straight forward. I use Eclipse but almost all IDEs have some means of setting break points and seeing the value of variables. I know some people put print or log statements in their code but this is much more time consuming than just setting a breakpoint and looking at the variables there, and maybe steping forward to see how the script runs.

I would be interested to hear if others usually use IDEs like Eclipse and debug in this way. I would hate to work without it. I even use it to check a newly written script or one that I have taken over responsibility for. Stepping through the processing can help you spot problems very easily.

Now all that is ok for a simple script or web application, but what about the server end of a web service? Normally the server runs in response to a client call. The client request may be quite complex, so how do you debug the server side?

Well my answer is to log the client request as it is received by the server as follows. Add this code to the very top of your server entry point, then have the client make its request. The server will log the request then carry on to produce a result (or not if there is some bug you want to fix).

To debug the server side, replace the above code with the following.

That’s it!. Now you can debug the server side without needing a client to make a request. The server entry point thinks it is getting a request from a client, but really it is just coming from the log file.

Now all this might seem trivial or obvious, but it took me a while to work this out when I had my first web service server to debug. Suddenly I’m just debugging a stand alone script rather than a server than depends on an external client request.

I would be very interested to see if this is useful to anyone.

 

 

 

 

Creating Custom Web Services In SugarCRM

I have been using web services to access Sugar for sometime now, for purposes of integration and for accessing data from a portal. While it is reasonably well documented, there are restrictions, and last week I cam across a requirement I just couldn’t meet with the standard web services methods. It was time to explore custom web services.

When I did, I suddenly realised that it was very simple to implement, and allowed me to push much of the business logic back into the server where it belongs. I could create a new method that had all sorts of complex logic,and expose the results via web services.

Now I did think that this might restrict the ability of the client software; any time it needs to access a Sugar instance, that instance needs the custom web service installed. By zipping up the custom web service as a loadable module (a topic I’ll discuss in the future as it is a very easy and powerful way to deploy any sort of customisation) this objection was quickly overcome. In any cases I would normally have access to the server when doing this type of work.

So, I have included a trivial method here, just to prove that I can. I think you will see that just about anything can go into such a method, allowing the web service to provide complex functionality to its client.

Before tackling that, lets see how the standard web service works. We will look at the version 4.1REST option from Sugar PRO 6.5.13.

service/v4_1/rest.php

You can try this in a browser directly, as follows (your url will be slightly different)

http://localhost/sugarPro6.5.13/service/v4_1/rest.php

This will show you documentation of the standard Sugar methods you can call, and their parameters.

Custom Web Service

Now our custom web service is to reside at custom/service so that it its upgrade safe. Lets look at the code, and compare it with the standard Sugar version above.

You will see we just extend the standard classes and create our own. These are below (MySugarRestService.php and MySugarRestServiceImp.php, though we could do without the first)

and MySugarRestServiceImpl.php below. You can see how it extends the Sugar class and adds a new method (getContactDetails).

Note that the method just returns hard coded values.

Accessing The Web Service

To prove that it works you need some a client. The following is very basic code to act as a client calling our new method. In a later post I will show more examples of client code, but for now this is enough to get started.

When you run that client you get the following response.

Which are just the hard coded value set in our server method.

I think that is enough to get started. I haven’t shown the login process, or how values can be retrieved from Sugar. All will have to wait for a new post.

Please contact me if you have any questions.

 

 

Strange PHP

This is post I thought I would start as I come across weird PHP code from time to time and I thought I would like to record it. When we are new at a language we struggle to find ways to achieve results and sometimes this leads to some quirky code. I’m sure others could find examples in my code.

1. Iterating though an array

instead of

 

 

Posted in PHP