About Modern Customizations

This page is the place to go when in doubt how to build a customization using the new tools in Lime Server. It is important to understand that there is no simple 1-1 mapping between legacy tools and the new tools. Therefore, you may have to design customizations differently when using the new tools. Because of this, examples are used here instead of just explanations what each new tool is.

Before we dig in to examples, here is a list with short descriptions of the tools at hand.

A way to expand the standard REST API. You are free to define how the payload and the returned output should look. This makes it very useful for more complex situations.

Has three major purposes:

  1. Provides hooks where you can write your own code that should be executed whenever an object is created, updated (both handled in the same hook) or deleted. For example whenever a deal is saved you want it to automatically recalculate some properties on the object. This is possible both before the data is saved in the database and after.
  2. Add functions keeping business logic on the object. For example, add a function to check off a helpdesk ticket. This can then be called from all places where it should be possible to do so, e.g., Actionpad link in the desktop client, link in the web client, other website showing tickets, an integration towards another system etc.
  3. Take care of complex Object Access logic.

Not that commonly used. Is for situations where you want to react on things that has already happened in Lime CRM but without the possibility to change any data in Lime CRM or retrieve supplemental data from Lime CRM except for the data already included in the event provided.

This is the tool for building GUI things for the Web Client.

Documentation is found on Github.

Will be used as long as the desktop client is used since it (and only it) can catch events for when things happen in the desktop client GUI. But keep VBA usage to a minimum. Do not do things here that can be done in other places, is a good motto.

The Actionpads in the desktop client are built on Lime Bootstrap. Both simpler things and more advanced things that requires javascript and CSS coding (where you build a Lime Bootstrap app). But make sure to use the REST API and custom endpoints where possible instead of saving data through VBA.

Background

The customer has a website that needs to fetch data from Lime CRM. It also needs to save data back into Lime CRM.

Legacy

Both fetching data and saving data could be done using the Lime CRM Soap Webservice. Either by using the standard Soap Webservice or by having a SQL procedure that was called through the Soap Webservice.

Modern

Either the standard REST API or custom endpoints should be used (or a combination of both). Which to choose depends on two things:

  1. How advanced the need is.
  2. Where the logic should be implemented.

In some cases the things that should be retrieved from or updated in Lime CRM are the same as in some other cases, or are considered very general for a specific Limetype. For example when you need to check off a helpdesk ticket. In those cases that could be implemented as a function on a Custom Limeobject.

Background

The customer wants to have the total number of participants that have accepted in an integer field on the campaign card. They need the field and not just a visualization in the Actionpad on the campaign card to be able to use it in filters.

Legacy

SQL Expression on the integer field. That is however performance heavy if showing the field in lists.

Could also be done in csp_afterupdate, triggering on updated participant cards. Some troublesome things there is that you would also have to consider cases when a participant card is deleted where it was not so easy to find which campaign card it once had belonged to. Same issue with participant cards that were moved to another campaign card, where you would have to update both involved campaign cards.

Some might use the SQL for Update on the integer field. This would however only be triggered to reevaluate when either new participants were added or existing were deleted or unlinked from the campaign card. So to cover situations where the status was changed from “Invited” to “Accepted” you would have to put code in csp_afterupdate as well.

Modern

  1. Add a function on the Custom Limeobject for campaign that calculates the number of participants that have status Accepted on the specific campaign and saves it in the integer field.
  2. Use a Custom Limeobject and the hooks after update and after delete on participant. A major improvement compared with the legacy tools is that here, you will have easy access to the data both before and after the update. Which makes it possible to handle situations where a participant was moved to another campaign. From these hooks, call the function added on the Custom Limeobject for campagin.

Similar Examples

  • Keep the Sales Trend option field on a company updated when invoice or invoicerow information is updated.

Background

Some Lime Bootstrap app needs aggregated or in other ways special data that is not available on the Active Inspector.

Legacy

Two options:

  1. Fetch data using VBA.
  2. Write a SQL procedure that returns an XML that will be transformed into JSON by Lime Bootstrap.

Your javascript code will have to consider cases where the JSON will have a single object/value instead of an array with objects/values.

Modern

Write a custom endpoint and call that from the Lime Bootstrap app.

Background

When creating/updating/deleting data of a specific Limetype, that information should be sent to another system or an integration platform.

Legacy

Not possible to do in real-time (without using CLR procedures). Something close would be to create an SSIS package that uses SQL to filter out information that has been updated since the last time it was run. A script component would then be used to call the other system. The SSIS package could be scheduled to run every minute or so, using the SQL Server Agent.

Modern

Use the Event Handler to react on updates on desired objects. For each updated object, call the receiving system. If the call succeeds the event is acknowledged and if it fails it should be handled in a suitable way (for example put back on the queue, put on a failed queue or similar).

Background

A customer creates a lot of quotes from templates in Lime CRM. As we all know, documents created from templates in Lime CRM have their filename set to the name of the template. On the document card they have the regular comment field which also adds the deal name and deal number to the comment field automatically if it is of type Quote. Therefore, they want the filename of the generated quote to be equal to the content of the comment field whenever they are creating a new quote.

Legacy

Put code that fixes this in csp_afterupdate.

Modern

Add code that handles this in the Custom Limeobject for document.

Background

A customer has a custom built e-signing service where you send a .pdf file together with your email and password and it returns a signed version. This should be called from the Actionpad on the document card. The signed version of the document should also be stored next to the original document (on the same deal for example).

Legacy

Use a combination of javascript in the Lime Bootstrap app and VBA to deal with the records and call the service.

Modern

Let the Lime Bootstrap app take care of the GUI things and have it call a custom endpoint when the signing call should be made and new records are created etc.

The GUI will basically be a send button and an input to enter your password. It will send the document card id and the password to the custom endpoint. The endpoint verifies file type, user, and a few more things before getting the file from the database and the email from the user session. The file is sent to the e-signing service and (hopefully) signed successfully. Then, a new document record is created, having its properties copied from the original document, and the newly signed file is added to it. Finally, the new iddocument is returned so that the Lime Bootstrap app can offer the user the option to open the document card for the signed document.

Having the frontend and backend things separated like this also makes it easier with the future transition to the web client.

Background

Some common examples:

  • Keep the full name of a person or coworker updated based on separate input fields for first name and last name.
  • Save a timestamp to a field when a deal changes status into for example Won.
  • Set the weighted value on a deal based when the probability and value fields are changed.

Legacy

Use SQL for update.

Modern

Use Custom Limeobject. Remember to put things that might need to be called from other customizations as well in separate functions.

Background

Whenever a new card of Limetype x is created, also create a history note and attach to it.

Legacy

Either in VBA (would of course only work in the desktop client) or in csp_afterupdate.

Modern

Use Custom Limeobject and the before update hook. Have it create a new history object, attach it to the newly created object of Limetype x and add it to the uow (unit of work). That way it will not be saved unless the whole transaction is completed.

Coming: With the possibility to add asynchronous tasks, this could be done in the after update hook instead. Then the user will not have to wait for it to complete, which will be especially good when more time consuming things should be done.

Background

Whenever a deal is set to status Won, send an email to the responsible coworker's manager.

Legacy

Either in VBA (would of course only work in the desktop client) or in csp_afterupdate using DB Mail.

Modern

Use our Python lib for sending emails easily, traml, and call it from the Custom Limeobject for deal. (traml can be used synchronously as it takes care of sending the email asynchronously).

Background

An object in the Web Client should be sent to another system. For example, an ERP system or a credit rating supplier.

Legacy

This was not possible before!

Modern

Create a Web Component and a Custom Endpoint. Let the typescript code in the Web Component handle the GUI and the call to the Custom Endpoint. The Custom Endpoint will handle any manipulation of data and the actual call to the other system. Remember to put any functionality that is general for the object on the Custom Limeobject for that object so it is gathered in one place and also reusable in other customizations.

Note that the same Custom Endpoint can be called from an LBS app in the Desktop Client if the same functionality should be available there.

  • Last modified: 3 years ago
  • by Tomas Eketorp