Understanding leads, accounts, opportunities and contacts in CRM world

If you are new to the CRM (Customer Relationship Management) world, it is entirely possible that you get confused in the soup of terminology presented to you. How is a lead different from an opportunity? What is the relationship between an account and a contact? In this post, I will try to shed some light on the important concepts in CRM using examples.


If you got a business card at a conference or a trade show, and want to follow up with the person on a future sale, that person is called a lead. This is an unqualified contact, since that person has not yet explicitly showed an intention to purchase your product/service. Such leads could come through  various sources – website signups, Facebook ads, purchasing a email list etc. It is important to track the lead source in the CRM, to measure the effectiveness of your various ad campaigns. A lead becomes a contact associated with an opportunity when it has a high possibility of getting through. Depending on your industry, you can set the criteria to advance the lead. For instance, you could set the criteria as promote a lead when the person returns your call and conveys that s/he is in the market for the product.

Leads can be classified into cold, warm and hot leads based on the probability of the lead converting into a future sale. A cold lead is a person you have randomly picked from a phone book. It is quite unlikely that this person will buy from you and you have to pursue many cold leads before you find an opportunity. Warm lead could be someone who has attended your webinar or subscribed to your newsletter. You have to do some work to complete a sale. A hot lead is somebody who is on market for your product and has very high probability of becoming an opportunity.


An account is an entity (individual or an enterprise) with whom you have an existing business relationship. The relationship could be a channel partner, supplier, customer, re-seller etc. Most CRM tools let you track the type of account and also let you segment them into different categories (poor customer, great customer, average customer, etc). It is very important to track all the interactions with the accounts, as a part of customer service management.


Contact is an individual who is associated with an account or an opportunity. So, how is a contact different from an account? Here is an example. If you are selling goods to Target Inc, then you add Target as your account, while the manager at the purchase department and the VP of marketing can be added to your contacts. Contact always reaches a real individual, while account could be a business entity. Typically there are 1 or more contacts that are tied to an account.


An opportunity could be associated with a contact, when it has a strong prospect of completing the sale. If your accounts purchase from you repeatedly, you can also associate them with an opportunity as they have a high chance of buying from you in the future. Opportunity records tracks the size of the deal (in terms of revenue), probability of closing the deal, followup activity you need to do etc. You can also record the deals that are won, lost and open.

Tracking the opportunities will help you better forecast your financial future and track what went wrong when a deal falls through. For instance, if you are in talks with a local financial provider for selling your analytics software, you can track the probability of closing the deal and other aspects of the deal at various stages of the talks. This can become a template for your future deals.


This atricle has been taken from here, and as usual placed on this blog for my own reference which is quicker than forgetting about it and having to search for it again: http://project-management.com/understanding-leads-accounts-opportunities-and-contacts-in-crm-world/

Full guide on db replication via SSH tunnel

All commands in red must be replaced with actual values used in your environment.


Configuring MySQL replication leaves port 3306 open to the Internet and data between the replication servers is not encrypted. Using SSH tunneling MySQL replication data can be transferred through the SSH connection. This method doesn’t need any additional ports to be opened in the firewall. For this article:

  • The master IP is
  • The slave IP is

Commands to be entered in the master are marked (master) and commands for slave are marked (slave).

It is assumed that you’ve read this article on MySQL replication.

Step 1: Setup SSH Tunneling

Create a user and assign a password. This user will be used to create the SSH tunnel: (master)

The tunneluser must be allowed to connect only from the slave server so it must be entered in the/etc/ssh/sshd_config file as an allowed user. (master)

Since allowed users are being defined, users not in this list will be denied access, so add the administrative users who will use SSH to login to this VPS. (master)

Restart the SSH server: (master)

The steps to generate a SSH key are mentioned in this article but I’ll repeat the commands here. (slave)

Sample output:

Do NOT enter a passphrase because this key will be used to automatically establish a SSH tunnel which will not be possible if it contains a passphrase. Copy the public key to the master server. (slave)

Sample output:

The tunneluser user will be used only for tunneling and not for administration so change the shell tonologin and remove the password. (master)

Debian and Ubuntu users replace /sbin/nologin with /usr/sbin/nologin.

Create a SSH tunnel using the following command. (slave)

The tunnel has been created, so accessing port 33061 at localhost will connect the slave to the master via SSH. The -f parameter runs this command in the background and the -N parameter means “Do not execute a command” since the tunneluser has a nologin shell.

Step 2: Configuring the replication settings on the MASTER

Open up the mysql configuration file on the master server.

Once inside that file, we need to make a few changes.

The first step is to find the section that looks like this, binding the server to the local host… and… leave it :).  If you were setting up db replication without an ssh tunnel this might be different.

The next configuration change refers to the server-id, located in the [mysqld] section. You can choose any number for this spot (it may just be easier to start with 1), but the number must be unique and cannot match any other server-id in your replication group. I’m going to go ahead and call this one 1.

Move on to the log_bin line. This is where the real details of the replication are kept. The slave is going to copy all of the changes that are registered in the log. For this step we simply need to uncomment the line that refers to log_bin:

Finally, we need to designate the database that will be replicated on the slave server. You can include more than one database by repeating this line for all of the databases you will need. Just replace the name below with the name of the database you wish to replicate.

After you make all of the changes, go ahead and save and exit out of the configuration file.

Refresh MySQL.

The next steps will take place in the MySQL shell, itself (NB we are still on the master server here).

We need to grant privileges to the slave. You can use this line to name your slave and set up their password. The command should be in this format:

Follow up with:

Switch to your database

Following that, lock the database to prevent any new changes:

Then type in:

You will see a table that should look something like this:

This is the position from which the slave database will start replicating. Record these numbers, they are needed later.

If you make any new changes in the same window, the database will automatically unlock. For this reason, you should open the new tab or window and continue with the next steps there.

Proceeding the with the database still locked, export your database using mysqldump in the new window (make sure you are typing this command in the bash shell, not in MySQLshell).

Now, returning to your your original window, unlock the databases (making them writeable again). Finish up by exiting the shell.

Now you are all done with the configuration of the the master database.


Step Three—Configure the Slave Database

Once you have configured the master database. You can put it aside for a while, and we will now begin to configure the slave database.

Log into your slave server, open up the MySQL shell and create the new database that you will be replicating from the master (then exit):

Get the database dump from the master server to the slave server

With the database dump now on the slave server, import it into the database you just created:

We’re nearly there now…

Now we need to configure the slave configuration in the same way as we did the master:

We have to make sure that we have a few things set up in this configuration. The first is the server-id. This number, as mentioned before needs to be unique. Since it is set on the default (still 1), be sure to change it’s something different.

NB the replay log probably wont already exist in the my.cnf file… so you will have to create it.

Restart MySQL once again:


Step Four — Setting it all off!

The next step is to enable the replication from within the MySQL shell.

Open up the the MySQL shell once again and type in the following details, replacing the values to match your information:

The only thing we need to change here is the value of ‘MASTER_LOG_FILE’ and the value of ‘MASTER_LOG_POS’. These tell the slave where to start replication from.

Now.. Activate the slave server:

And you’re done.

Additional info:

To view the status of the slave. From the slave server, log into the mysql shell and run

The \G rearranges the text to make it more readable.

You can always test the connectivity of the slave to the master via the ssh tunnel with this command:


MySQL replication has a lot different options, and this was just a brief overview.

If you have any further questions about the specific capabilities of MySQL, feel free to post your questions in our Q&A Forum and we’ll be happy to answer them.


This guide has been put together for my own use/reference. The content originates from:



CMS Content Organization Structures: Trees vs Facets vs Tags

Trees are the oldest of the methods mentioned above. The reason for this is likely that they work great in the physical world, ie. good old paper books, as they require no content duplication. That is, every piece of information is placed in exactly one place. The fact that trees have been around so long also gives them one distinct advantage: everyone knows how they work. Facets and tags, however, very much leverage the new possibilities of the digital age in that content can easily live in several places at once. But just because trees predate the digital age does not make them a dinosaur waiting for extinction. Let us first look at some of the advantages and disadvantages of facets and tags.


My personal takeaway is that any CMS managing any sizeable amount of data needs to support trees. Anything else will lead to an unmanageable mess. However, systems with smaller sets of content, especially with a smaller group of authors, can get away with tagging as well. Facetting only really works well with a system that stores content that is highly structured at least on a per node type basis. In this spirit, I maintain that repository as a service providers will need to provide full support for trees, both to structure as well as visualized content, in order to become able to handle larger volumes of data. Faceting will also need to be provided if they intend to make inroads from doing more than just serving large chunks of text and media content.

Upgrading Mysql to 5.7.* on Ubuntu 14

First backup all your databases:

JavaScript Closures

Taken from: http://stackoverflow.com/questions/111102/how-do-javascript-closures-work

JavaScript Closures for Dummies

Submitted by Morris on Tue, 2006-02-21 10:19. Community-edited since.

Closures Are Not Magic

This page explains closures so that a programmer can understand them — using working JavaScript code. It is not for gurus or functional programmers.

Closures are not hard to understand once the core concept is grokked. However, they are impossible to understand by reading any academic papers or academically oriented information about them!

This article is intended for programmers with some programming experience in a mainstream language, and who can read the following JavaScript function:

An Example of a Closure

Two one sentence summaries:

  • a closure is the local variable for a function — kept alive after the function has returned, or
  • a closure is a stack-frame which is not deallocated when the function returns (as if a ‘stack-frame’ were malloc’ed instead of being on the stack!).

The following code returns a reference to a function:

Most JavaScript programmers will understand how a reference to a function is returned to a variable (say2) in the above code. If you don’t, then you need to before you can learn closures. A C programmer would think of the function as returning a pointer to a function, and that the variables say and say2 were each a pointer to a function.

There is a critical difference between a C pointer to a function and a JavaScript reference to a function. In JavaScript, you can think of a function reference variable as having both a pointer to a function as well as a hidden pointer to a closure.

The above code has a closure because the anonymous function function() { console.log(text); } is declared inside another function, sayHello2() in this example. In JavaScript, if you use the function keyword inside another function, you are creating a closure.

In C and most other common languages, after a function returns, all the local variables are no longer accessible because the stack-frame is destroyed.

In JavaScript, if you declare a function within another function, then the local variables can remain accessible after returning from the function you called. This is demonstrated above, because we call the function say2() after we have returned from sayHello2(). Notice that the code that we call references the variable text, which was a local variable of the function sayHello2().

Looking at the output of say2.toString(), we can see that the code refers to the variable text. The anonymous function can reference text which holds the value 'Hello Bob' because the local variables of sayHello2() are kept in a closure.

The magic is that in JavaScript a function reference also has a secret reference to the closure it was created in — similar to how delegates are a method pointer plus a secret reference to an object.

More examples

For some reason, closures seem really hard to understand when you read about them, but when you see some examples you can click to how they work (it took me a while).
I recommend working through the examples carefully until you understand how they work. If you start using closures without fully understanding how they work, you would soon create some very weird bugs!

Example 3

This example shows that the local variables are not copied — they are kept by reference. It is kind of like keeping a stack-frame in memory when the outer function exits!

Example 4

All three global functions have a common reference to the same closure because they are all declared within a single call to setupSomeGlobals().

The three functions have shared access to the same closure — the local variables of setupSomeGlobals() when the three functions were defined.

Note that in the above example, if you call setupSomeGlobals() again, then a new closure (stack-frame!) is created. The old gLogNumber, gIncreaseNumber, gSetNumber variables are overwritten with new functions that have the new closure. (In JavaScript, whenever you declare a function inside another function, the inside function(s) is/are recreated again each time the outside function is called.)

Example 5

This one is a real gotcha for many people, so you need to understand it. Be very careful if you are defining a function within a loop: the local variables from the closure do not act as you might first think.

The line result.push( function() {console.log(item + ' ' + list[i])} adds a reference to an anonymous function three times to the result array. If you are not so familiar with anonymous functions think of it like:

Note that when you run the example, "item2 undefined" is alerted three times! This is because just like previous examples, there is only one closure for the local variables for buildList. When the anonymous functions are called on the line fnlist[j](); they all use the same single closure, and they use the current value for i and item within that one closure (where i has a value of 3 because the loop had completed, and item has a value of 'item2'). Note we are indexing from 0 hence item has a value of item2. And the i++ will increment i to the value 3.

Example 6

This example shows that the closure contains any local variables that were declared inside the outer function before it exited. Note that the variable alice is actually declared after the anonymous function. The anonymous function is declared first; and when that function is called it can access the alice variable because alice is in the same scope (JavaScript does variable hoisting).
Also sayAlice()() just directly calls the function reference returned from sayAlice() — it is exactly the same as what was done previously, but without the temporary variable.

Tricky: note also that the say variable is also inside the closure, and could be accessed by any other function that might be declared within sayAlice(), or it could be accessed recursively within the inside function.

Example 7

This final example shows that each call creates a separate closure for the local variables. There is not a single closure per function declaration. There is a closure for each call to a function.


If everything seems completely unclear then the best thing to do is to play with the examples. Reading an explanation is much harder than understanding examples.
My explanations of closures and stack-frames, etc. are not technically correct — they are gross simplifications intended to help understanding. Once the basic idea is grokked, you can pick up the details later.

Final points:

  • Whenever you use function inside another function, a closure is used.
  • Whenever you use eval() inside a function, a closure is used. The text you eval can reference local variables of the function, and within eval you can even create new local variables by using eval('var foo = …')
  • When you use new Function(…) (the Function constructor) inside a function, it does not create a closure. (The new function cannot reference the local variables of the outer function.)
  • A closure in JavaScript is like keeping a copy of all the local variables, just as they were when a function exited.
  • It is probably best to think that a closure is always created just on entry to a function, and the local variables are added to that closure.
  • A new set of local variables is kept every time a function with a closure is called (given that the function contains a function declaration inside it, and a reference to that inside function is either returned or an external reference is kept for it in some way).
  • Two functions might look like they have the same source text, but have completely different behaviour because of their ‘hidden’ closure. I don’t think JavaScript code can actually find out if a function reference has a closure or not.
  • If you are trying to do any dynamic source code modifications (for example: myFunction = Function(myFunction.toString().replace(/Hello/,'Hola'));), it won’t work if myFunction is a closure (of course, you would never even think of doing source code string substitution at runtime, but…).
  • It is possible to get function declarations within function declarations within functions — and you can get closures at more than one level.
  • I think normally a closure is the term for both the function along with the variables that are captured. Note that I do not use that definition in this article!
  • I suspect that closures in JavaScript differ from those normally found in functional languages.



If you have just learned closures (here or elsewhere!), then I am interested in any feedback from you about any changes you might suggest that could make this article clearer. Send an email to morrisjohns.com (morris_closure @). Please note that I am not a guru on JavaScript — nor on closures.

Original post by Morris can be found in the Internet Archive.

Flexible angularJs ui-router