Browsed by
Tag: project

Starting Your Own IT Business In India?

Starting Your Own IT Business In India?

This is the Current State Of Processes Around It!

I recently started working on a foreign software development contract. It seems that to ‘earn’ via such a contract, you need to have a business entity of sorts. I had to undergo a long, painful process riddled with unknowns and uncertainties to establish one and raise my invoices. Here is a brief of my understanding of the process and various norms and laws. I do not claim that the material below is correct, it is only how I understood it and would recommend you to not follow this blindly. You should, as I have, take help of professionals in this area (Chartered Accountants or CA, Company Secretary or CS and lawyers) before you proceed and form your own understanding. This is write up is merely a record of things I went through.

GST and stuff

  • First things first, link your mobile number (and email id) to Aadhaar number. By the way, linking your aadhaar to mobile and mobile to aadhaar are two different things. First keeps your mobile working. Second allows your to verify your Aadhaar number when asked for. Those who have registered for Aadhaar in the recent times, might already have their number linked. You can verify this on the Aadhaar portal. This currently is a big pain as all the private e-Seva Kendra are closed and government centres are flooded. Solutions:
    • Get in a queue at a bank or post office where they are still modifying Aadhaar at about 5 am on a Monday to get your appointment for modification. You have to then be present with all (don’t know which all) possible documents at the time and date of your appointment to get the modifications done. Else, get a new token by standing in queue.
    • Go to a remote village’s regional office to get it modified.
  • Register your business. In any way possible, but do register. Proprietorship is probably the easiest way to go forward, in a proprietorship, you and the business are the same entities and are inter-changeable.
    • It is good to name the business. Even if you name it as your name, i.e “Nikhil Wanpal” in my case. CA/CS would suggest to add something like “& co” or “& associates” etc in the name for clarity and avoiding confusion in legal matters. But this will bite us back when opening current account. If you decide to go for a proprietorship, here are the documents required:
      • Self signed copy of pan and Aadhaar of owner of business
      • Copy of latest electricity bill of premises
      • Copy of NOC for use of premises
      • Photo of name plate along with owner (Of course we cannot create a board, so take print out paste on your home door and take your photo in front of it)
      • Mobile no and email ID
      • Brief business activity
    • Many other forms exist: OPC, Partnership, LLP and pvt ltd. Choose one with least hassles. All other forms, either require another person to be part of the business and hence a dependency or else require a repetitive documentation to be maintained like BOD meeting MOMs. Also, when your business is a separate entity, you have a separate PAN and you need to be extra careful when making transactions, even by mistake, making a business transaction with your personal card (or vise a versa), linked to your personal PAN can be an issue. You need to ensure you carefully use correct cards for correct type of expenses. This is not an issue for larger organisations where there are people managing purchases and granting expense claims, but for a single person working, to me, this seemed like an unnecessary hassle.
  • Get your Shop Act License. This step is same as above, basically, a shop act is how you register a proprietorship. Shop act license is a license from government to perform business, and is ideal for shops/merchants and works well for us as small businesses as well. There were amendments to this license, in Dec 2017. The portal to avail the license was closed till 22 Feb, 18 for modifications. And when the portal opened, it opened with a new format of the license. Under the new act, a shop with less than 9 employees does not need the license, if you apply it does not need verification, nor does it need renewal of license. This is a good change for us, but is a pain since it is not yet propagated through the system.
  • Get your rubber stamps. Required on almost all documents you sign. A designation/authority stamp, an address stamp and a round stamp are minimum of those required. Also, buy a blue/violet stamp-pad.
  • Get your Udyog Aadhaar. This is a new self declaration of business required since Jan, 18. It is a supportive document for shop act license. Having a valid mobile number linked to your Aadhaar is mandatory to get this. In theory, this could ease your current account pains.
  • Get your GSTIN. GST is mandatory for business in India, especially if your turnover is more than 20 lakh in a financial year. You have to file GST for every month, by 20th of next month. If you can get the name of the business in the GST, it can help simplify further processes. GSTIN and PAN are linked to entities, and in proprietorship there is only but one entity, you. So your GSTIN will be linked to your PAN. There is no easy way to get a GST number for your business, unless you go for a ‘Company’ registration. Apparently, there is a way to add a business name in your personal GST. But as it happens, what if I choose to open a another business? Or rename my existing business? GST modification is not on-line yet and requires physical document submission. I did not know this, I got GST way before shop act and so my certificate does not have the name of the proprietorship in it.
  • Open a current account in the name of the business. Apparently, we, the IT professionals, do not fall under the group of professions that are allowed to do business using a savings account and hence a current account is mandatory, do not yet know of the implications. Now this part is tricky:
    • Shop act is no longer mandatory for business smaller than 9 employees, and hence the format is modified and no longer includes an expiry nor verification stamp.
    • Udyog Aadhaar is not a registration, but a self declaration (which is also what the new shop act has functionally become, given there is no verification).
    • Unfortunately, banks have not yet received a “Government Mandate” to use this shop act and hence this document is not considered as a legal / valid doc to open a current account. I have visited and inquired with these banks already, all would say they will open the current account, sure, but when you show them the shop act they will not recognise it and ask for a ‘real shop act’. List of banks I have visited: ICICI, Axis, SBI (they almost kicked me out), Saraswat cooperative bank, Maharashtra bank, Kotak Mahindra, PNB (total 7). A local cooperative bank was the only one that could recognise the new format and open a current account for me. (This issue may be limited to Maharashtra region)
    • In the last couple weeks, I have heard of HDFC bank offering a current account with a declaration from a practising CA along with other documents. I have not verified this.
    • From this step onward you need your stamps everywhere.
  • Get a registered digital signature. Contact a Company Secretary who can get this for you. Go for longest term and both signing and encrypting capabilities. Format for IEC has changed, it is now an online document and does not have a physical stamp or signature. Officials may have to be convinced for this. Required Documents: Refer next point, documents list is inclusive of both.
  • Get your IEC issued by DGFT. IEC stands for an Import-Export Code. We need this to make our export of software legal. To be able to get IEC, we need the digital signature and company name. IEC cannot be issued in the name of an individual. A CS can do this for you. It requires the form to be filled physically then submitted online and then offline, physically at their office. IEC requires a cancelled cheque in the name of the business, is the reason why you need a current account in the name of the business in the first place. Go for export permission for everything, because you can: manufacture, retail and service. Needs verification: Even if you do not fit the requirement to get GST, you still likely need to get IEC to make your export of software/service legal. Required Documents:
    • Photograph (3x3cms) of Applicant
    • Copy of PAN card and Aadhaar Card of applicant
    • Cancelled Cheque bearing the applicant Entity name, IFSC code
    • Mail ID and Contact no. of applicant
    • Copy of PAN Card of company, if applicable
    • Digital Signature of applicant with password
    • Copy of COI, MOA and AOA of Company, if applicable
    • Confirm any one of the business activity for IEC. (Merchant Cum Manufacturer Cum Service Provider)
  • Get your LOU/LUT: Letter of Undertaking. (Officially called LUT on the GST portal) This says that you are doing an export and are not liable for any GST, and if you are you would pay it. This does not exempt you from filing GST, but the direct payment of it from your income. You still have to file your GSTs and declare expenses and GST you have paid. Unless you have LUT, you have to submit your income and pay (18%) GST on it. Then you can request a refund later, when you get your LUT. My CA was generous here and suggested I also grant him a letter of authority, so I would not have to go to the GST office stand in queue myself. It takes 2 days for Digital Certificate and 2-3 days for IEC to be generated. The process for LUT has changed and the submission is now online. The same documents above are to be scanned and uploaded to the portal. Also, there is no longer a physical document or any document provided for LUT. An acknowledgement number is generated when uploaded documents are accepted. This generation of acknowledgement number is considered as ‘acceptance’ and ‘grant/approval’ of LUT, and you Ack number itself is your LUT number. This is communicated via government circular (# 40/14/2018-GST) dated 6th April. This may be a hassle, if your client does not accept or is unaware of the new LUT process. In either case, you also need a LUT declaration on your invoices.You should not have any income in the duration from when you get your GST to the time you get your LUT, in other words, get . Required Documents:
    • Form No RFD-11 on firms letter head.
    • LUT on Rs 500/- stamp paper
    • Copy of GST registration certificate duly self attested.
    • Copy of Import Export Code certificate issued by DGFT.
    • Declaration on your letterhead that you are not liable for any contravention under GST act.
    • Copy of address proof of your entity duly self attested.
    • Copy of your PAN and address proof duly self attested
    • Authority letter in favour of CA on Rs 500/- stamp paper to represent on your behalf.

Pro-tip: Close your stamp pad and pack your stamps immediately after use, to avoid damaging your documents. 😉

Generating Invoices

Once you have all the docs setup, all income has to be justified with a GST Invoice letter, generated, signed, stamped and sent to the client on or before the date of payment. There are many formats floating around for GST invoices, there is also a government issued format, but there is nothing I could readily use. There are companies like Zoho who have an invoicing software with GST support. There are many other But I found it unnecessary when raising so few invoices for my purposes, I went with a Google Sheets, created a custom format which includes all the fields required in official government format and is more suited for our (IT) business.

Here is the link. Feel free to copy and use it for your own business purposes. I would love a shout-out if it helped though. 🙂

The invoice is marked with text where you need to modify and fill in values relevant to you, like your business name, client name, GSTIN etc. Follow the text steps in the invoice itself to get your own personal invoice. If you are billing hourly, you might want to fill in hours, minutes and hourly rate and use this formula in amount field:

=(SUM(F17*60+G17)/60)*H17

It converts the hours into minutes, adds the minutes, converts them back into hours in decimal and multiplies by hourly rate to calculate total amount. No other change should be required. When looking for SAC/HSN codes, I found 2 that could apply to regular IT development and have included them both in the template.

Filing Income Tax Returns

Someone might suggest you something apparently amazing to save tax, something called ‘presumptive tax’. In my view and understanding, there are a lot of practical issues with this scheme.

  • Presumptive tax is a self declared expense/income from your turnover without being forced to audit your business.
  • The allowed percent is 50% for an individual/proprietorship/professional. (8% for business)
  • It means: you can self-declare 50% losses/expenses, without any documentation or computation of income or balance sheet and it would still be considered a legal tax filing under presumptive taxation. i.e. you would be liable for tax only on 50% of the income.
  • You should actually have that much business expense. Using this scheme for invasion of tax is not advisable.

There may be people who would suggest otherwise and it might sound good. Here are some thoughts for those who intend to follow this route:

  • You cannot use the extra money in any form. If you are found to have invested, say 1 lakh in a mutual fund and income tax office asks for an explanation say 5 years later, you would have no way to proving legal income.
  • Say you falsely claimed 50% as a business expense, (and used it for personal expense) it would be illogical, since it is expected to have happened from the remaining 50% of your income.
  • Say are doing nothing illegal, and your actual expense is 50%. This scheme is new, and hence there is little prior knowledge or cases to show what can be done to ‘escape’ from such inquiries if they happen and hence I (and my CA) are not in favour.
  • Needs verification: This scheme locks you in for 5 years, i.e. you cannot change the way you show expense for 5 years once you opt for this.
  • All banks and legal firms ask for balance sheet and computation of income of minimum 3 financial years (more on this below).
  • That being said, you cannot get any loan for the next up to 8 (5+3) years since you have no (or not enough) balance sheets to show. You cannot keep a balance sheet or computation when filing under presumptive tax, as presumptive tax scheme exist to exempt you from having to maintain balance sheets. If you have balance sheets, which means you have kept books of accounts which means you cannot opt for presumptive tax.
  • Under presumptive tax, even if a bank agrees to give you loan, it will be only on your 50% income.

I would rather show actual expenses and depreciation of business assets the traditional way. Well (Unfortunately) for us IT folks, the income is almost always via bank transfers, and the expenses are limited and again mostly via bank/card payments and so almost everything is anyways documented. It means I end up paying a lot more tax as opposed to filing under presumptive tax, but I am okay with it.

Some Points on Loan applications

As the situation was for me, I also had to apply for a loan. Ah, that in itself is a long story but some takeaways are:

  • As a business person, you cannot get a loan unless you have been in business for a minimum of 3 years and the business has been ‘in business’ for 2 years.
  • You need to present books of accounts, balance sheets, and computation of income for each business year of the last 3 years and the current year. The sheets and books for current year will be tentative, but that is still okay.
  • Your income for granting loan is considered as ~70% of average of the last 3 years of income. Bank may add higher ‘safety’ margins on it as they see fit.
  • If a bank grants you loan, you will always have a rate of interest at least 0.2% higher than the normal interest.

 

Again, iterating that the process and steps documented above are what I had to go through. There were a whole lot of unknowns and uncertainties that I had to go through to come to these conclusions and what you see above are the conclusions alone. One of the primary reason for the unknowns was that the processes had changed very recently, (I was almost always one of the first clients of the CA/CS/lawyers I was consulting since the change in process as if my timing matched with the changes!) causing uncertainties. But almost all the changes are of making the processes offline -> online, complex -> simplified, physical -> automated, multiple approvals -> less or no approvals; which I see as a positive thing, leaving aside the fact that I was caught in the transition. I hope when you need to implement this, the processes will have been simplified further!

A Guess-The-Color-Code Game: ColorCode

A Guess-The-Color-Code Game: ColorCode

This post was written ~6 years ago, a lot of things in the world of browsers have changed since, the game may no longer work/look correctly.

A game with unknown name!
That is what it was when I started working on it…
I played this game first as a board game, on a very very old board, with no reference to the name. It was to be played by two players.
The other day, my younger sisters friends had come home, they brought with them a board game to play. It belonged to her mom (so old). No one knew the name, but it was just plain fun to play.

We decided to implement it in code. And here it is.. A digital version of the game.
But what to name it? First we thought of naming it colour-seq, but some amount of Googling revealed that there exist many versions of this game in digital format already and they are called ColorCode. So thats what it is! 🙂

Game objective:
Its simple, match the same colour sequence with same colours as the computer had in his mind.

Game rules:

  • The computer decides a sequence of the colours (in mind!)
  • The player puts the pegs in the holes and tries to arrive at the same sequence.
  • Computer will indicate on every entry how many of the colours the player missed and how many positions were incorrect.
  • You can choose from 3 different difficulty levels:
    • Easy: 4 colours,4 positions (no chance to choose a wrong color), 10 attempts
    • Medium: 5 colours, 4 positions, 10 attempts.
    • Hard: 6 colours, 4 positions and 10 attempts.
  • You can also select if you want numbers to be  displayed on the pegs along with the colours to identify them.

How to play:

  • Once you choose the options, you will see the game board.
  • Drag and drop the coloured pegs from the right hand side floating bar onto the central part of the board with 4 holes (not holes, but, u get it, right?)
  • You can rearrange the colour sequence.
  • Once you are satisfied, press the submit button.
  • Computer will match the code you entered with the one it had in mind and will answer in a colour code.
  • On the left part, where you see the holes arranged in two columns:
    • If a position turns orange, there is a colour in wrong position.
    • If a position turns black, there is a wrong colour.
    • Counting the number of black squares, you know how many colours were wrong. (i.e. you selected the colour but computer did not, choose another.)
    • Counting the number of orange squares, you know how many colours were in wrong position (i.e. the colour is correct, but not is correct position, rearrange.)
  • Starting with a guess for the first attempt, it goes all Logic from there on..
Known issues:
  • The floating bar has a little glitch, it floats a little weird sometimes.

Future enhancements

  • Forgot to mention, have not tested the code on Internet explorer at all. Will do the testing and required fixing once I find a windows machine. Till then, please use firefox or chrome.
  • I plan to make it more customisable: allow for choosing colours, columns and attempts manually.
  • Make them circles.
  • Remove the hiding plate above to reveal the code in computer’s mind.
  • What if computer never told you the colour was wrong..? Thinking… 😀

Well, a note:
I know its all JavaScript and all the geeks will simply turn on their firebug to check what the colour sequence is. But please don’t, otherwise, there is no fun! But if you just could not convince your conscience, let me tell you I have taken care not to spoil the fun for you. The colour code the computer remembers is actually salted, hashed number and not the simple colour name you might make some guess at.. The salt is randomly generated on every new game. Just to help you take a firm stand against your disobedient mind! (Oh I know, its still not difficult to crack it, but worth the effort! 🙂 )

So what are you waiting for? Hit the ‘Start the game’ button!

If you find more glitches and bugs please note them in the comments. And feel free to tell me you enjoy it! 😀

Just another object-oriented approach to jQuery plugins

Just another object-oriented approach to jQuery plugins

It has been almost a year since I have been working primarily in JavaScript. During this time I have written three jQuery plugins and loads of other scripts.This is the story of how my approach to writing jQuery plugins has evolved.

I was working on my first plugin, which was supposed to be a large (in LOC) and went through the authoring mentioned on the jQuery site. In the beginning- it was great, a few exposed methods, well organized code, private functions, everything looked pretty. Soon the code reached some 1000 lines and it started becoming messy for me. To clarify, I am basically a java developer. I accept that the coding practices will obviously differ in every language, but for me, object oriented approach to code seems much more understandable and tidier than ‘functions everywhere’ thing!

I began searching for object oriented approaches people take in writing jQuery plugins. There are many, but mostly at the cost of some other flexibility. Some approaches allow only one public method, claiming only one namespace is must but more control was needed in the calendar. Some allow complete public access to the options object, but additional control was needed. There were one time calculations based on options that were necessary for the required functionality. Now making the options object public won’t give me that control, will it? But apart from that, I could not understand the requirement of making it fully public. Pardon me, this statement is not to question those who follow these approaches, but this is what was thought.

A better approach was needed, where all the flexibility of making it a ‘functions everywhere’ is retained and a little more organization is achieved in the code. So there emerged a merger. A merger that:

  • Allows multiple methods to be made available.
  • Claims only one namespace.
  • Does not make options simply public.
  • Keeps a context, maintains a state.
  • And follows every other requirement mentioned as a guideline while writing plugins by the jQuery authors.
That merger has now evolved into a simple, precise plugin template! All you need is a case-sensitive, replace-all and you are ready with a working plugin, set with the basic features ready for more, organized plugin…
Here’s the code:
/**
* Plugin comments
*/
(function($, undefined){
var MyPlugin = function(element, options){

/*
* *************************** Variables ***************************
*/
var defaults = {
defaultValue : '2'
}; //default options

/*
* *************************** Plugin Functions ***************************
*/

/*
* Initializes plugin.
*/
function initialize(options){
extendOptions(options);
sl.log("Got Options- initialize: ");
sl.log(options);
}

/*
* Updates plugin.
*/
function update(options){
sl.log("Got Options- update: ");
sl.log(options);
}

/*
* Destroy plugin changes
*/
function destroy(options){
// Remove all added classes.
// Remove all bound methods.

// Remove plugin data
element.removeData('myplugin');
}

/*
* Updates plugin options after plugin has been initialized.
*/
function setOptions(options){
extendOptions(options);
}

//expose plugin functions
this.initialize = initialize;
this.update = update;
this.destroy = destroy;
this.setOptions = setOptions;

/*
* *************************** Utility Methods ***************************
*/
/*
* Extend the default options using the passed options.
*/
function extendOptions(options){
if (options) {
$.extend(true, defaults, options);
}
}
};

var mP = $.myPlugin = {version: "0.01"};
$.fn.myPlugin = function(options){
var args = arguments; // full argument array passed to the plugin.

// Available methods in plugin
var pMethods = {
init : function(options){
// Get the plugin data
if (this.data('myplugin')) return;
// Initialize the plugin
var myplugin = new MyPlugin(this, options);
// Add plugin data to the element
this.data('myplugin', myplugin);
myplugin.initialize(options);
},
update : function(options){
// Get the plugin data
var myplugin = this.data('myplugin');
if (!myplugin) return; // do nothing if plugin is not instantiated.

myplugin.update(options);
},
destroy : function(options){
// Get the plugin data
var myplugin = this.data('myplugin');
if (!myplugin) return; // do nothing if plugin is not instantiated.

// destroy data and revert all plguin changes.
myplugin.destroy(options);
},
setOptions : function(options){
// Get the plugin data
var myplugin = this.data('myplugin');
if (!myplugin) return; // do nothing if plugin is not instantiated.

// Update the plugin options
myplugin.setOptions(options);
}
};

// For each element, check and invoke appropriate method passing the options object
return this.each(function(i, tElement){
var element = $(tElement);

if (pMethods[options]){
pMethods[options].call(element, args[1]);
} else if (typeof options === 'object' || !options){
pMethods['init'].call(element, args[0]);
} else {
$.error( 'Method ' + options + ' does not exist in jQuery.myplugin' );
}
});
};
})(jQuery);
Now what you need to get going is the replace-all, this is what you replace:

MyPlugin : PluginName
myPlugin : Plugin JQuery Method Name/pluginName
myplugin : Data Name/Variable Name
mp       : pN
pMethods : pluginNameMethods
defaults : defaulsObjectName

That’s it!
You are ready with a working plugin!
Oh yes, that sl there in the code is actually the SmartLogger. Read about it here.
This is a quick post and I plan to update the post with more explanation of the code, do visit again!

Let me know how you find it in the comments.

Habit-Firebug Saver: SmartLogger

Habit-Firebug Saver: SmartLogger

How many of the web developers do not depend on Firebug or the chrome’s console… Just wondering..

BTW, its plain fun to work with firebug, makes life a lot easier.. Its a different matter all together that the other browser that you have to develop for does not have a powerful enough tool. (Name deliberately avoided to avoid the eminent flame-war!) Yes the current versions have a quite powerful debug and development tools but (hopefully) few developers working on products still have to consider some 10 year old versions (namely 6, 6.5 and 7). Ah, the pain.. Anyways, we are not discussing that..

What we are talking about is the issues that we face when testing our changes to a thousand lines JavaScript code on multiple browsers, especially after we are accustomed to the ease of firebug. 🙂

I spent much of my time commenting my console.log() statements before I could dare to open the page in IE. Well, fear not, the days have passed! The pain drove me to write a logger object that can not only sense presence of console object but can do much more than that, like ability to assert, selective logging and more..

I call it the SmartLogger.

//Global Logger Object, for use during development, configurable logger.
var SmartLogger = function(options) {

var sl = {}; // Logger Object

// Accepting passed params.
options = options || {};
sl.enableLogger = options.enableLogger!==undefined?options.enableLogger:true;
sl.enableAssert = options.enableAssert!==undefined?options.enableAssert:true;
sl.loggerOutput = options.loggerOutput!==undefined?options.loggerOutput:undefined; //'console', 'alert', undefined
sl.selectiveEnable = options.selectiveEnable!==undefined?options.selectiveEnable:'';
sl.selectiveDisable = options.selectiveDisable!==undefined?options.selectiveDisable:'';

// Logger properties
sl.name = "SmartLogger";
sl.whoami = function(){ return "SmartLogger_"+sl.enableLogger+"_"+sl.enableAssert+"_"+sl.loggerOutput+"_"+sl.selectiveEnable+"_"+sl.selectiveDisable;}
sl.version = '0.7';

// Checks if console object is defined. Checked only at the time of instantiation.
var hasConsole = (typeof console === "object");

// Checks if logging should be done to console.
function logToConsole(){
if (sl.loggerOutput){
if (sl.loggerOutput === 'console') return true;
} else {
if(hasConsole) return true;
}
return false;
}

// Handles the logging intelligence
function handleLogging(logMethod, logString, strId){
if(!sLog(strId)) {return;}
// Decides if to log and logs or alerts appropriately.
if(sl.enableLogger){
if (logToConsole()){ // && hasConsole
if(hasConsole)console[logMethod](logString);
} else {
alert(logString);
}
}
};

// Handles the selective logging functionality
function sLog(strId){
var allowLog = true;
if (sl.selectiveEnable) {
allowLog = strId === sl.selectiveEnable;
} else if (sl.selectiveDisable) {
allowLog = !(strId === sl.selectiveDisable);
}

return allowLog;
};

// Returns a formatted object structure with current values to complete depth.
function printString(obj, name, str, strEnd){
var stringified;
name = name?name:"Object",
str = str?str:"";
strEnd = strEnd?strEnd:"";
stringified = str+name+" : {n";
for (var a in obj){
if (typeof obj[a] === 'object'){
stringified+= printString(obj[a],a,"t",",");
} else {
stringified+= str+"t"+a +" : "+obj[a]+",n";
}
}
stringified += str+"}"+strEnd+"n";
return stringified;
};

// Exposed methods of the object
//log a string to console/alert
sl.log = function(str, strId){
handleLogging('log', str, strId);
};

//debug logging a string to console/alert
sl.debug = function(str, strId){
handleLogging('debug', str, strId);
};

//write an information string to console/alert
sl.info = function(str, strId){
handleLogging('info', str, strId);
};

//throw error string to console/alert
sl.error = function(str, strId){
handleLogging('error', str, strId);
};

//Assert an assumption
sl.assert = function(str, strId){
if(sl.enableAssert){
handleLogging('log', 'Assumption: true', strId);
if(!str){
handleLogging('error', 'Assumption failed!', strId);
debugger;
}
}
};

// Logs the formatted object structure with current values to console/alert
sl.stringToConsole = function(obj, str){
sl.log(printString(obj, str));
};

return sl;
};

var sl = new SmartLogger();

Features:

  • Multiple logging profiles can be maintained at the same time with different properties.
var sl = new SmartLogger();
var sl2 = new SmartLogger({selectiveEnable: 'block1'});
  • Proprieties can be set at the time of instantiation or even later.
var sl = new SmartLogger();
sl.loggerOutput = 'console';
var sl2 = new SmartLogger({loggerOutput: 'console'});
  • name, version number and whoami to identify the logger with a string of its current properties.
var sl = new SmartLogger();
sl.name // SmartLogger.
sl.version // 0.7
sl.whoamI() // Returns a string of its properties with the name of the object in a specific sequence:
// "SmartLogger_"+ enableLogger +"_"+ enableAssert+"_"+ loggerOutput+"_"+ selectiveEnable+"_"+ selectiveDisable;
// Example: SmartLogger_true_true_console__b
// We will see what these properties are in some time..
  • Enable or disable logging altogether: enableLogger controls if the statements should ever be logged.
var sl = new SmartLogger();
sl.log('gets logged');
sl.enableLogger = false;
sl.log('never gets logged');
  • Intelligently decides where the logging statements should go…
sl.loggerOutput = undefined; //default
/* Decides based on presence of 'console' object.
If console is present statements will be logged to console,
else like in case of IE, will be 'alerted' to the user.
Now at times this can get messy, with loads of log statements alerting on our face..
But wait, we have ways to handle that.*/

sl.loggerOutput = 'console';
// Plain instruction, no intelligence, all statements will always go to console.
// If console is not present statements will just be eaten-up.

sl.loggerOutput = 'alert';
// Another plain instruction, all statements will always be alerted.
// Will not bother to check if console exists or not.
  • Log formatted objects to console. Now you wont need that much with firebug but to see the entire contents of the object, well formatted you can just say stringToConsole.
// Just a sample object with unknown properties.
var obj = {prop1: 'value',functProp:function(){return "this is a function that returns me!";}, propObj:{prop2:'value2'}};
sl.stringToConsole(obj); // You say this.

// On console or in the alert prompt, you get this
Object : {
prop1 : value,
functProp : function () {
return "this is a function that returns me!";
},
propObj : {
prop2 : value2,
},
}
  • Assert your assumptions. Checks that the assumption is true, if yes, logs so. If assumption fails, will write out an error on the console and invoke the debugger so the user can check in the stack exactly where the assumption failed and why.
sl.assert(Obj.str===Obj2.str)
sl.assert(1==1); // logs 'Assumption: true' to console.
sl.assert(1==2); // Logs error 'Assumption: failed!' and invoke debugger to the assert line in SmartLogger.

//Now you can go and check in the stack and watch to panels to check value and call stack.
  • Has a wrapper for 4 of the logging APIs from firebug and adding new is not much of a task. What it already has:
    • log
    • debug
    • info
    • error
  • Has ability of selective logging.
Now this thing is a live saver. The properties selectiveEnable and selectiveDisable control what statements to log. While these are not mandatory inputs to all the wrappers but I suggest you set them always. These are logging context that can be used to selectively enable logs for only partial of the code, the code that currently interests you..
// Suppose we were working on a defect number 101 and now we are developing a functionality for
// automating welcome messages to users and are asked to urgently fix defect 203.
// Ah, complex scenario, but it will only help understand the purpose.

// When we are working on defect 101, we had the logger configured as statements as:
sl.log("reached here"); // worst way to log: who knows wheres here! but just an example.

// Now we are working on the functionality and
// we would not want those 10 logging statements added while we were working on the defect.
// We can remove them or simply enable the 'selective logger'!
sl.selectiveEnable = 'welcomer';
sl.log("fetching message", "welcomer");
// And voila, only the 'welcomer' messages will be logged.

// Now we get the next urgent defect.
sl.selectiveEnable = 'defect203';
sl.log("value in Obj1.str"+Obje1.str, "defect203");
// We get only the defect203 logs!

// Now some of our new changes depend on the changes we made in defect101, but we cant get the logs from those..
// What do we do? If someone did not enable selective logger and removed the statements, please add them back (:p),
// remove statements for 'welcomer' functionality. Or simply, disable 'welcomer' messages..!
sl.selectiveEnable = '';
sl.selectiveDisable = 'welcomer';
sl.log("value in Obj1.str"+Obje1.str, "defect203");
sl.log("value in Obj2.varInt1"+Obj2.varInt1, "defect101");
// Ha ha! Log statements for 'welcomer' gone and we get the rest!
While using the SmartLogger, I suggest you always pass the string identifier, so that you can control the logs at any point of time later.

What can you expect next in SmartLogger:

  • Use assert from firebug itself.
  • Check that the function exists in the logger before calling it.
  • Make the selective logger take arrays.
  • In stringToConsole, handle functions too to remove that glitch in no closing bracket.

Let me know what you think about the SmartLogger, if you would like any additions to its behaviour and also if you find any defects in the comments below.