/** @module General Ledger Model */
'use strict';

var logger = require(process.env.LOGGER)('General Ledger Model');

var _ = require('lodash');

var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

var GeneralLedgerSchema = new Schema({

	name: {
		type: String,
		trim: true,
		default: '',
		required : true
	},

	description: {
		type: String,
		trim: true,
		default: ''
	},

	closed: {
		type: Boolean,
		default: false
	},

	meta: {
		created: Date,
		creationUser : String,
		updated: Date,
		updatedUser : String
	}

});


// Virtuals ===================================================================

GeneralLedgerSchema.virtual('netWorth').get(function() {

	logger.debug('Computing the net worth');

	var netWorth = 0;

	var conditions = {
		generalLedger : this._id,
		$or : [
			{ type : 'asset' },
			{ type : 'liability' }
		]
	};

	logger.debug('Finding all accounts of the general ledger');

	mongoose.model('Account').find(conditions, function(err, accounts) {

		logger.debug('accounts.length : ' + accounts.length);
		if (!err && accounts.length){

			_.forIn(accounts, function(account) {
				account = account.toObject({ virtuals: true });
				logger.debug('account.balance.own : ' + account.balance.own);
				if (account.type === 'asset') {
					netWorth += account.balance.own;
				} else if (account.type === 'liability') {
					netWorth -= account.balance.own;
				}
			});

		}

		logger.debug('Net worth : ' + netWorth);
		return netWorth;

	});


});

// Pre processing methods =====================================================

GeneralLedgerSchema.pre('save', function(next) {

	logger.debug('====== New General Ledger saving =========================');

	logger.debug('Name : ' + this.name);

	// meta dates management

	var today = new Date();

	if (!this.meta.created) {
		this.meta.created = today;
	}

	this.meta.updated = today;

	logger.debug('');

	next();

});

// Post processing methods ====================================================

GeneralLedgerSchema.post('save', function(account) {

	logger.debug('====== New General Ledger saved ==========================');
	logger.debug('_id : ' + account._id);
	logger.debug('Name : ' + account.name);
	logger.debug('');

});


// Model export ===============================================================

module.exports = mongoose.model('GeneralLedger', GeneralLedgerSchema);
/** @module General Ledger Model */
'use strict';

var logger = require(process.env.LOGGER)('General Ledger Model');

var _ = require('lodash');
var async = require('async');

var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

var GeneralLedgerSchema = new Schema({

	name: {
		type: String,
		trim: true,
		default: '',
		required : true
	},

	description: {
		type: String,
		trim: true,
		default: ''
	},

	closed: {
		type: Boolean,
		default: false
	},

	meta: {
		created: Date,
		creationUser : String,
		updated: Date,
		updatedUser : String
	}

});


GeneralLedgerSchema.methods.getNetWorth = function(callback) {

	var name = this.name;
	var _id = this._id;

	logger.debug('Computing the net worth of ' + name);

	var netWorth = 0;

	var conditions = {
		generalLedger : _id,
		$or : [
			{ type : 'asset' },
			{ type : 'liability' }
		]
	};

	mongoose.model('Account').find(conditions, function(err, accounts) {

		if (err) {

			logger.error('Error while getting the accounts of ' + name);
			callback(err);

		} else if (accounts.length){

			var accountsArray = [];

			_.forIn(accounts, function(account) {
				accountsArray.push(account);
			});

			async.each(accountsArray, function(account, asyncCallback) {

				var accountObject = account.toObject();
				var type = accountObject.type;

				account.getOwnBalance(function(err, ownBalance) {

					if (err) {

						logger.error('Error while getting the own balance of ' + accountObject.name);
						asyncCallback(err);

					} else {

						if (type === 'asset'){
							netWorth += ownBalance;
						} else if (type === 'liability') {
							netWorth -= ownBalance;
						}

						asyncCallback(null);

					}

				});

			}, function(err){

				if (err) {

					logger.error('Error while getting the own balance of one account of ' + name);
					callback(err);

				} else {

					callback(null, netWorth);

				}

			});

		} else {

			callback('No accounts found for this general ledger', null);

		}

	});

};

// Pre processing methods =====================================================

GeneralLedgerSchema.pre('save', function(next) {

	// meta dates management --------------------------------------------------

	var today = new Date();

	if (!this.meta.created) {
		this.meta.created = today;
	}

	this.meta.updated = today;

	next();

});

// Post processing methods ====================================================

GeneralLedgerSchema.post('save', function(generalLedger) {

	logger.debug('Saved general ledger ' + generalLedger.name + ' with _id ' + generalLedger._id);

});


// Model export ===============================================================

module.exports = mongoose.model('GeneralLedger', GeneralLedgerSchema);
Update the getNetWorth method by using the getBalance of accounts