[MERGE] merge with latest stable
[odoo/odoo.git] / addons / hr_payroll / hr_payroll.py
index 0079d23..2f50321 100644 (file)
@@ -6,16 +6,16 @@
 #    d$
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
+#    it under the terms of the GNU Affero General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
+#    GNU Affero General Public License for more details.
 #
-#    You should have received a copy of the GNU General Public License
+#    You should have received a copy of the GNU Affero General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
@@ -27,8 +27,9 @@ from datetime import timedelta
 
 import netsvc
 from osv import fields, osv
-from tools import config
+import tools
 from tools.translate import _
+import decimal_precision as dp
 
 def prev_bounds(cdate=False):
     when = date.fromtimestamp(time.mktime(time.strptime(cdate,"%Y-%m-%d")))
@@ -52,8 +53,9 @@ class hr_contract_wage_type(osv.osv):
 
     _inherit = 'hr.contract.wage.type'
     _columns = {
-        'type' : fields.selection([('basic','Basic'), ('gross','Gross'), ('net','Net')], 'Type', required=True),
+        'type': fields.selection([('basic','Basic'), ('gross','Gross'), ('net','Net')], 'Type', required=True),
     }
+
 hr_contract_wage_type()
 
 class hr_passport(osv.osv):
@@ -86,7 +88,7 @@ class hr_payroll_structure(osv.osv):
     - Allowlance
     - Deductions
     """
-    
+
     _name = 'hr.payroll.structure'
     _description = 'Salary Structure'
     _columns = {
@@ -113,15 +115,12 @@ class hr_payroll_structure(osv.osv):
 
         @return: returns a id of newly created record
         """
-        if context is None:
-            context = {}
         code = self.browse(cr, uid, id, context=context).code
         default = {
             'code':code+"(copy)",
             'company_id':self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
         }
-        res_id = super(hr_payroll_structure, self).copy(cr, uid, id, default, context=context)
-        return res_id
+        return super(hr_payroll_structure, self).copy(cr, uid, id, default, context=context)
 
 hr_payroll_structure()
 
@@ -130,12 +129,16 @@ class hr_contract(osv.osv):
     Employee contract based on the visa, work permits
     allowas to configure different Salary structure
     """
-    
-    def compute_basic(self, cr, uid, ids, context={}):
+
+    def compute_basic(self, cr, uid, ids, context=None):
         res = {}
+        if context is None:
+            context = {}
         ids += context.get('employee_structure', [])
-        
-        for contract in self.browse(cr, uid, ids, context):
+
+        slip_line_pool = self.pool.get('hr.payslip.line')
+
+        for contract in self.browse(cr, uid, ids, context=context):
             all_per = 0.0
             ded_per = 0.0
             all_fix = 0.0
@@ -151,20 +154,19 @@ class hr_contract(osv.osv):
             if contract.wage_type_id.type == 'basic':
                 obj['basic'] = contract.wage
                 update['basic'] = contract.wage
-            
+
             sal_type = contract.wage_type_id.type
-            function = contract.struct_id.id
+#            function = contract.struct_id.id
             lines = contract.struct_id.line_ids
             if not contract.struct_id:
                 res[contract.id] = obj['basic']
-                continue 
-            
+                continue
+
             ad = []
-            c_type = {}
             for line in lines:
                 cd = line.code.lower()
                 obj[cd] = line.amount or 0.0
-            
+
             for line in lines:
                 if line.category_id.code in ad:
                     continue
@@ -175,7 +177,7 @@ class hr_contract(osv.osv):
                     exp = line.category_id.condition
                     calculate = eval(exp, obj)
                 except Exception, e:
-                    raise osv.except_osv(_('Variable Error !'), _('Variable Error : %s ' % (e)))
+                    raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
 
                 if not calculate:
                     continue
@@ -183,14 +185,14 @@ class hr_contract(osv.osv):
                 percent = 0.0
                 value = 0.0
                 base = False
-                company_contrib = 0.0
+#                company_contrib = 0.0
                 base = line.category_id.base
 
                 try:
                     #Please have a look at the configuration guide.
                     amt = eval(base, obj)
                 except Exception, e:
-                    raise osv.except_osv(_('Variable Error !'), _('Variable Error : %s ' % (e)))
+                    raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
 
                 if sal_type in ('gross', 'net'):
                     if line.amount_type == 'per':
@@ -228,19 +230,24 @@ class hr_contract(osv.osv):
                     per = (all_per - ded_per)
                 else:
                     per = all_per
-                if per <=0 :
+                if per <=0:
                     per *= -1
                 final = (per * 100) + 100
                 basic = (sal * 100) / final
             else:
                 basic = contract.wage
-            
+
             res[contract.id] = basic
 
         return res
-    
+
+    def check_vals(self, val1, val2):
+        if val1 == val2 and val1 == 0:
+            return True
+        return False
+
     def _calculate_salary(self, cr, uid, ids, field_names, arg, context=None):
-        res = self.compute_basic(cr, uid, ids, context)
+        res = self.compute_basic(cr, uid, ids, context=context)
         vals = {}
         for rs in self.browse(cr, uid, ids, context=context):
             allow = 0.0
@@ -251,8 +258,14 @@ class hr_contract(osv.osv):
                 obj['gross'] = rs.wage
             if rs.wage_type_id.type == 'net':
                 obj['net'] = rs.net
-            
+
             if not rs.struct_id:
+                if self.check_vals(obj['basic'], obj['gross']):
+                    obj['gross'] = obj['basic'] = obj['net']
+                elif self.check_vals(obj['gross'], obj['net']):
+                    obj['gross']= obj['net'] = obj['basic']
+                elif self.check_vals(obj['net'], obj['basic']):
+                    obj['net'] = obj['basic'] = obj['gross']
                 record = {
                     'advantages_gross':0.0,
                     'advantages_net':0.0,
@@ -262,19 +275,19 @@ class hr_contract(osv.osv):
                 }
                 vals[rs.id] = record
                 continue
-                
+
             for line in rs.struct_id.line_ids:
                 amount = 0.0
                 if line.amount_type == 'per':
                     try:
                         amount = line.amount * eval(str(line.category_id.base), obj)
                     except Exception, e:
-                        raise osv.except_osv(_('Variable Error !'), _('Variable Error : %s ' % (e)))
+                        raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
                 elif line.amount_type in ('fix', 'func'):
                     amount = line.amount
                 cd = line.category_id.code.lower()
                 obj[cd] = amount
-                
+
                 if line.type == 'allowance':
                     allow += amount
                 elif line.type == 'deduction':
@@ -288,9 +301,9 @@ class hr_contract(osv.osv):
             record = {
                 'advantages_gross':round(allow),
                 'advantages_net':round(deduct),
-                'basic':res[rs.id],
-                'gross':round(res[rs.id] + allow),
-                'net':round(res[rs.id] + allow - deduct)
+                'basic':obj['basic'],
+                'gross':round(obj['basic'] + allow),
+                'net':round(obj['basic'] + allow - deduct)
             }
             vals[rs.id] = record
 
@@ -298,13 +311,12 @@ class hr_contract(osv.osv):
 
     _inherit = 'hr.contract'
     _description = 'Employee Contract'
-
     _columns = {
-        'permit_no':fields.char('Work Permit No', size=256, required=False, readonly=False),
-        'passport_id':fields.many2one('hr.passport', 'Passport', required=False),
-        'visa_no':fields.char('Visa No', size=64, required=False, readonly=False),
+        'permit_no': fields.char('Work Permit No', size=256, required=False, readonly=False),
+        'passport_id': fields.many2one('hr.passport', 'Passport No', required=False),
+        'visa_no': fields.char('Visa No', size=64, required=False, readonly=False),
         'visa_expire': fields.date('Visa Expire Date'),
-        'struct_id' : fields.many2one('hr.payroll.structure', 'Salary Structure'),
+        'struct_id': fields.many2one('hr.payroll.structure', 'Salary Structure'),
         'working_days_per_week': fields.integer('Working Days', help="No of Working days / week for an employee"),
         'basic': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Basic Salary', digits=(14,2)),
         'gross': fields.function(_calculate_salary, method=True, store=True, multi='dc', type='float', string='Gross Salary', digits=(14,2)),
@@ -321,6 +333,7 @@ class payroll_register(osv.osv):
     """
     Payroll Register
     """
+
     _name = 'hr.payroll.register'
     _description = 'Payroll Register'
 
@@ -381,8 +394,6 @@ class payroll_register(osv.osv):
     def compute_sheet(self, cr, uid, ids, context=None):
         emp_pool = self.pool.get('hr.employee')
         slip_pool = self.pool.get('hr.payslip')
-        func_pool = self.pool.get('hr.payroll.structure')
-        slip_line_pool = self.pool.get('hr.payslip.line')
         wf_service = netsvc.LocalService("workflow")
         if context is None:
             context = {}
@@ -411,9 +422,15 @@ class payroll_register(osv.osv):
         self.write(cr, uid, ids, {'state':'draft', 'number':number}, context=context)
         return True
 
+    def set_to_draft(self, cr, uid, ids, context=None):
+        self.write(cr, uid, ids, {'state':'draft'}, context=context)
+        return True
+
+    def cancel_sheet(self, cr, uid, ids, context=None):
+        self.write(cr, uid, ids, {'state':'cancel'}, context=context)
+        return True
+
     def verify_sheet(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         slip_pool = self.pool.get('hr.payslip')
 
         for id in ids:
@@ -431,15 +448,13 @@ class payroll_register(osv.osv):
         advice_line_pool = self.pool.get('hr.payroll.advice.line')
         sequence_pool = self.pool.get('ir.sequence')
         users_pool = self.pool.get('res.users')
-        if context is None:
-            context = {}
 
         for id in ids:
             sids = slip_pool.search(cr, uid, [('register_id','=',id), ('state','=','hr_check')], context=context)
             wf_service = netsvc.LocalService("workflow")
             for sid in sids:
                 wf_service.trg_validate(uid, 'hr.payslip', sid, 'final_verify_sheet', cr)
-        
+
         company_name = users_pool.browse(cr, uid, uid, context=context).company_id.name
         for reg in self.browse(cr, uid, ids, context=context):
             advice = {
@@ -448,10 +463,10 @@ class payroll_register(osv.osv):
                 'register_id':reg.id
             }
             pid = advice_pool.create(cr, uid, advice, context=context)
-            
+
             for slip in reg.line_ids:
                 if not slip.employee_id.bank_account_id:
-                    raise osv.except_osv(_('Error !'), _('Please define bank account for the %s employee' % (slip.employee_id.name)))
+                    raise osv.except_osv(_('Error !'), _('Please define bank account for the %s employee') % (slip.employee_id.name))
                 pline = {
                     'advice_id':pid,
                     'name':slip.employee_id.bank_account_id.acc_number,
@@ -481,9 +496,9 @@ class payroll_advice(osv.osv):
     '''
     Bank Advice Note
     '''
+
     _name = 'hr.payroll.advice'
     _description = 'Bank Advice Note'
-
     _columns = {
         'register_id':fields.many2one('hr.payroll.register', 'Payroll Register', required=False),
         'name':fields.char('Name', size=2048, required=True, readonly=False),
@@ -509,27 +524,19 @@ class payroll_advice(osv.osv):
     }
 
     def confirm_sheet(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         self.write(cr, uid, ids, {'state':'confirm'}, context=context)
         return True
 
     def set_to_draft(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         self.write(cr, uid, ids, {'state':'draft'}, context=context)
         return True
 
     def cancel_sheet(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         self.write(cr, uid, ids, {'state':'cancel'}, context=context)
         return True
 
     def onchange_company_id(self, cr, uid, ids, company_id=False, context=None):
         res = {}
-        if context is None:
-            context = {}
         if company_id:
             company = self.pool.get('res.company').browse(cr, uid, company_id, context=context)
             if company.partner_id.bank_ids:
@@ -543,9 +550,9 @@ class payroll_advice_line(osv.osv):
     '''
     Bank Advice Lines
     '''
+
     _name = 'hr.payroll.advice.line'
     _description = 'Bank Advice Lines'
-
     _columns = {
         'advice_id':fields.many2one('hr.payroll.advice', 'Bank Advice', required=False),
         'name':fields.char('Bank Account A/C', size=64, required=True, readonly=False),
@@ -561,8 +568,6 @@ class payroll_advice_line(osv.osv):
     def onchange_employee_id(self, cr, uid, ids, ddate, employee_id, context=None):
         vals = {}
         slip_pool = self.pool.get('hr.payslip')
-        if context is None:
-            context = {}
         if employee_id:
             dates = prev_bounds(ddate)
             sids = False
@@ -581,10 +586,11 @@ class contrib_register(osv.osv):
     '''
     Contribution Register
     '''
+
     _name = 'hr.contibution.register'
     _description = 'Contribution Register'
 
-    def _total_contrib(self, cr, uid, ids, field_names, arg, context={}):
+    def _total_contrib(self, cr, uid, ids, field_names, arg, context=None):
         line_pool = self.pool.get('hr.contibution.register.line')
 
         res = {}
@@ -620,12 +626,11 @@ class contrib_register_line(osv.osv):
     '''
     Contribution Register Line
     '''
+
     _name = 'hr.contibution.register.line'
     _description = 'Contribution Register Line'
 
     def _total(self, cr, uid, ids, field_names, arg, context=None):
-        if context is None:
-            context = {}
         res={}
         for line in self.browse(cr, uid, ids, context=context):
             res[line.id] = line.emp_deduction + line.comp_deduction
@@ -655,10 +660,9 @@ class payment_category(osv.osv):
 
     _name = 'hr.allounce.deduction.categoty'
     _description = 'Allowance Deduction Heads'
-
     _columns = {
-        'name':fields.char('Categoty Name', size=64, required=True, readonly=False),
-        'code':fields.char('Categoty Code', size=64, required=True, readonly=False),
+        'name':fields.char('Category Name', size=64, required=True, readonly=False),
+        'code':fields.char('Category Code', size=64, required=True, readonly=False),
         'type':fields.selection([
             ('allowance','Allowance'),
             ('deduction','Deduction'),
@@ -696,7 +700,6 @@ class company_contribution(osv.osv):
 
     _name = 'company.contribution'
     _description = "Company Contribution"
-
     _columns = {
         'category_id':fields.many2one('hr.allounce.deduction.categoty', 'Heads', required=False),
         'name':fields.char('Name', size=256, required=True, readonly=False),
@@ -718,7 +721,7 @@ class company_contribution(osv.osv):
             ('per','Percentage'),
             ('func','Function Calculation'),
         ],'Amount Type', select=True),
-        'contribute_per':fields.float('Contribution', digits=(16, 4), help='Define Company contribution ratio 1.00=100% contribution, If Employee Contribute 5% then company will and here 0.50 defined then company will contribute 50% on employee 5% contribution'),
+        'contribute_per':fields.float('Contribution', digits=(16, 4), help='Define Company contribution ratio 1.00=100% contribution.'),
         'company_id':fields.many2one('res.company', 'Company', required=False),
         'active':fields.boolean('Active', required=False),
         'note': fields.text('Description'),
@@ -731,7 +734,7 @@ class company_contribution(osv.osv):
                 self.pool.get('res.users').browse(cr, uid, uid,
                     context=context).company_id.id,
     }
-    
+
     def _execute_function(self, cr, uid, id, value, context=None):
         """
         self: pointer to self object
@@ -739,8 +742,6 @@ class company_contribution(osv.osv):
         uid: user id of current executer
         """
         line_pool = self.pool.get('company.contribution.line')
-        if context is None:
-            context = {}
         res = 0
         ids = line_pool.search(cr, uid, [('category_id','=',id), ('to_val','>=',value),('from_val','<=',value)], context=context)
         if not ids:
@@ -750,9 +751,9 @@ class company_contribution(osv.osv):
         else:
             res = line_pool.browse(cr, uid, ids, context=context)[0].value
         return res
-        
-    def compute(self, cr, uid, id, value, context={}):
-        contrib = self.browse(cr, uid, id, context)
+
+    def compute(self, cr, uid, id, value, context=None):
+        contrib = self.browse(cr, uid, id, context=context)
         if contrib.amount_type == 'fix':
             return contrib.contribute_per
         elif contrib.amount_type == 'per':
@@ -768,9 +769,8 @@ class company_contribution_line(osv.osv):
     """
 
     _name = 'company.contribution.line'
-    _description = 'Allowance Deduction Categoty'
+    _description = 'Allowance Deduction Category'
     _order = 'sequence'
-
     _columns = {
         'contribution_id':fields.many2one('company.contribution', 'Contribution', required=False),
         'name':fields.char('Name', size=64, required=False, readonly=False),
@@ -785,8 +785,8 @@ class company_contribution_line(osv.osv):
 company_contribution_line()
 
 class hr_holidays_status(osv.osv):
-    _inherit = "hr.holidays.status"
 
+    _inherit = "hr.holidays.status"
     _columns = {
         'company_id':fields.many2one('res.company', 'Company', required=False),
         'type':fields.selection([
@@ -810,13 +810,13 @@ class hr_payslip(osv.osv):
     '''
     Pay Slip
     '''
+
     _name = 'hr.payslip'
     _description = 'Pay Slip'
 
     def _calculate(self, cr, uid, ids, field_names, arg, context=None):
         slip_line_obj = self.pool.get('hr.payslip.line')
-        if context is None:
-            context = {}
+        register_pool = self.pool.get('company.contribution')
         res = {}
         for rs in self.browse(cr, uid, ids, context=context):
             allow = 0.0
@@ -833,7 +833,7 @@ class hr_payslip(osv.osv):
                     try:
                         amount = line.amount * eval(str(line.category_id.base), obj)
                     except Exception, e:
-                        raise osv.except_osv(_('Variable Error !'), _('Variable Error : %s ' % (e)))
+                        raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
                 elif line.amount_type in ('fix', 'func'):
                     amount = line.amount
                 cd = line.category_id.code.lower()
@@ -853,15 +853,20 @@ class hr_payslip(osv.osv):
                     others += amount
                 elif line.type == 'otherpay':
                     others += amount
-                slip_line_obj.write(cr, uid, [line.id], {'total':amount}, context=context)
+
+                company_contrib = 0.0
+                for contrib_line in line.category_id.contribute_ids:
+                    company_contrib += register_pool.compute(cr, uid, contrib_line.id, amount, context)
+
+                slip_line_obj.write(cr, uid, [line.id], {'total':amount, 'company_contrib':company_contrib}, context=context)
 
             record = {
-                'allounce':round(allow),
-                'deduction':round(deduct),
-                'grows':round(rs.basic + allow),
-                'net':round(rs.basic + allow - deduct),
+                'allounce':allow,
+                'deduction':deduct,
+                'grows':rs.basic + allow,
+                'net':rs.basic + allow - deduct,
                 'other_pay':others,
-                'total_pay':round(rs.basic + allow - deduct)
+                'total_pay':rs.basic + allow - deduct
             }
             res[rs.id] = record
         return res
@@ -882,15 +887,15 @@ class hr_payslip(osv.osv):
             ('done','Paid Salary'),
             ('cancel','Reject'),
         ],'State', select=True, readonly=True),
-        'basic_before_leaves': fields.float('Basic Salary', readonly=True,  digits=(16, 2)),
-        'leaves': fields.float('Leave Deductions', readonly=True,  digits=(16, 2)),
-        'basic': fields.float('Net Basic', readonly=True,  digits=(16, 2)),
-        'grows': fields.function(_calculate, method=True, store=True, multi='dc', string='Gross Salary', type='float', digits=(16, 2)),
-        'net': fields.function(_calculate, method=True, store=True, multi='dc', string='Net Salary', digits=(16, 2)),
-        'allounce': fields.function(_calculate, method=True, store=True, multi='dc', string='Allowance', digits=(16, 2)),
-        'deduction': fields.function(_calculate, method=True, store=True, multi='dc', string='Deduction', digits=(16, 2)),
-        'other_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Others', digits=(16, 2)),
-        'total_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Total Payment', digits=(16, 2)),
+        'basic_before_leaves': fields.float('Basic Salary', readonly=True,  digits_compute=dp.get_precision('Account')),
+        'leaves': fields.float('Leave Deductions', readonly=True,  digits_compute=dp.get_precision('Account')),
+        'basic': fields.float('Net Basic', readonly=True,  digits_compute=dp.get_precision('Account')),
+        'grows': fields.function(_calculate, method=True, store=True, multi='dc', string='Gross Salary', digits_compute=dp.get_precision('Account')),
+        'net': fields.function(_calculate, method=True, store=True, multi='dc', string='Net Salary', digits_compute=dp.get_precision('Account')),
+        'allounce': fields.function(_calculate, method=True, store=True, multi='dc', string='Allowance', digits_compute=dp.get_precision('Account')),
+        'deduction': fields.function(_calculate, method=True, store=True, multi='dc', string='Deduction', digits_compute=dp.get_precision('Account')),
+        'other_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Others', digits_compute=dp.get_precision('Account')),
+        'total_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Total Payment', digits_compute=dp.get_precision('Account')),
         'line_ids':fields.one2many('hr.payslip.line', 'slip_id', 'Payslip Line', required=False, readonly=True, states={'draft': [('readonly', False)]}),
         'company_id':fields.many2one('res.company', 'Company', required=False, readonly=True, states={'draft': [('readonly', False)]}),
         'holiday_days': fields.float('No of Leaves', readonly=True),
@@ -911,8 +916,6 @@ class hr_payslip(osv.osv):
     }
 
     def copy(self, cr, uid, id, default=None, context=None):
-        if context is None:
-            context = {}
         company_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
         default = {
             'line_ids': False,
@@ -939,40 +942,29 @@ class hr_payslip(osv.osv):
             slip_move.create(cr, uid, res)
 
     def set_to_draft(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         self.write(cr, uid, ids, {'state':'draft'}, context=context)
         return True
 
     def cancel_sheet(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         self.write(cr, uid, ids, {'state':'cancel'}, context=context)
         return True
 
     def account_check_sheet(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         self.write(cr, uid, ids, {'state':'accont_check'}, context=context)
         return True
 
     def hr_check_sheet(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         self.write(cr, uid, ids, {'state':'hr_check'}, context=context)
         return True
 
     def process_sheet(self, cr, uid, ids, context=None):
-        if context is None:
-            context = {}
         self.write(cr, uid, ids, {'paid':True, 'state':'done'}, context=context)
         return True
-    
-    def verify_sheet(self, cr, uid, ids, context={}):
-        payslip_pool = self.pool.get('hr.payslip.line')
+
+    def verify_sheet(self, cr, uid, ids, context=None):
         register_pool = self.pool.get('company.contribution')
         register_line_pool = self.pool.get('hr.contibution.register.line')
-        
+
         for slip in self.browse(cr, uid, ids, context=context):
             base = {
                 'basic':slip.basic,
@@ -995,13 +987,11 @@ class hr_payslip(osv.osv):
                             'total':line.total + line.total
                         }
                         register_line_pool.create(cr, uid, reg_line)
-                        
+
         self.write(cr, uid, ids, {'state':'confirm'}, context=context)
         return True
 
     def get_contract(self, cr, uid, employee, date, context=None):
-        if context is None:
-            context = {}
         sql_req= '''
             SELECT c.id as id, c.wage as wage, struct_id as function
             FROM hr_contract c
@@ -1032,8 +1022,6 @@ class hr_payslip(osv.osv):
 
         @return: return a result
         """
-        if context is None:
-            context = {}
         result = []
 
         dates = prev_bounds(slip.date)
@@ -1050,12 +1038,9 @@ class hr_payslip(osv.osv):
         return result
 
     def compute_sheet(self, cr, uid, ids, context=None):
-        emp_pool = self.pool.get('hr.employee')
-        slip_pool = self.pool.get('hr.payslip')
         func_pool = self.pool.get('hr.payroll.structure')
         slip_line_pool = self.pool.get('hr.payslip.line')
         holiday_pool = self.pool.get('hr.holidays')
-        contract_obj = self.pool.get('hr.contract')
         sequence_obj = self.pool.get('ir.sequence')
         if context is None:
             context = {}
@@ -1063,14 +1048,14 @@ class hr_payslip(osv.osv):
 
         #Check for the Holidays
         def get_days(start, end, month, year, calc_day):
-            count = 0
             import datetime
+            count = 0
             for day in range(start, end):
                 if datetime.date(year, month, day).weekday() == calc_day:
                     count += 1
             return count
 
-        for slip in self.browse(cr, uid, ids, context=context):            
+        for slip in self.browse(cr, uid, ids, context=context):
             old_slip_ids = slip_line_pool.search(cr, uid, [('slip_id','=',slip.id)], context=context)
             slip_line_pool.unlink(cr, uid, old_slip_ids, context=context)
             update = {}
@@ -1080,7 +1065,7 @@ class hr_payslip(osv.osv):
                 update.update({
                     'basic': round(0.0),
                     'basic_before_leaves': round(0.0),
-                    'name':'Salary Slip of %s for %s' % (slip.employee_id.name, ttyme.strftime('%B-%Y')),
+                    'name':'Salary Slip of %s for %s' % (slip.employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))),
                     'state':'draft',
                     'contract_id':False,
                     'company_id':slip.employee_id.company_id.id
@@ -1096,10 +1081,9 @@ class hr_payslip(osv.osv):
                 func = func_pool.read(cr, uid, function, ['line_ids'], context=context)
                 lines = slip_line_pool.browse(cr, uid, func['line_ids'], context=context)
 
-            lines += slip.employee_id.line_ids
+            #lines += slip.employee_id.line_ids
 
             ad = []
-            lns = {}
             all_per = 0.0
             ded_per = 0.0
             all_fix = 0.0
@@ -1116,7 +1100,6 @@ class hr_payslip(osv.osv):
                 obj['basic'] = contract.wage
                 update['basic'] = contract.wage
 
-            c_type = { }
             for line in lines:
                 cd = line.code.lower()
                 obj[cd] = line.amount or 0.0
@@ -1131,7 +1114,7 @@ class hr_payslip(osv.osv):
                     exp = line.category_id.condition
                     calculate = eval(exp, obj)
                 except Exception, e:
-                    raise osv.except_osv(_('Variable Error !'), _('Variable Error : %s ' % (e)))
+                    raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
 
                 if not calculate:
                     continue
@@ -1139,14 +1122,14 @@ class hr_payslip(osv.osv):
                 percent = 0.0
                 value = 0.0
                 base = False
-                company_contrib = 0.0
+#                company_contrib = 0.0
                 base = line.category_id.base
 
                 try:
                     #Please have a look at the configuration guide.
                     amt = eval(base, obj)
                 except Exception, e:
-                    raise osv.except_osv(_('Variable Error !'), _('Variable Error : %s ' % (e)))
+                    raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
 
                 if sal_type in ('gross', 'net'):
                     if line.amount_type == 'per':
@@ -1192,7 +1175,7 @@ class hr_payslip(osv.osv):
                     per = (all_per - ded_per)
                 else:
                     per = all_per
-                if per <=0 :
+                if per <=0:
                     per *= -1
                 final = (per * 100) + 100
                 basic = (sal * 100) / final
@@ -1205,11 +1188,22 @@ class hr_payslip(osv.osv):
                 'number':number,
                 'basic': round(basic),
                 'basic_before_leaves': round(basic),
-                'name':'Salary Slip of %s for %s' % (slip.employee_id.name, ttyme.strftime('%B-%Y')),
+                'name':'Salary Slip of %s for %s' % (slip.employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))),
                 'state':'draft',
                 'contract_id':contract.id,
                 'company_id':slip.employee_id.company_id.id
             })
+
+            for line in slip.employee_id.line_ids:
+                vals = {
+                    'amount':line.amount,
+                    'slip_id':slip.id,
+                    'employee_id':False,
+                    'function_id':False,
+                    'base':base
+                }
+                slip_line_pool.copy(cr, uid, line.id, vals, {})
+
             self.write(cr, uid, [slip.id], update, context=context)
 
         for slip in self.browse(cr, uid, ids, context=context):
@@ -1234,8 +1228,8 @@ class hr_payslip(osv.osv):
             paid_leave = 0.0
             for hday in holiday_pool.browse(cr, uid, leave_ids, context=context):
                 if not hday.holiday_status_id.head_id:
-                    raise osv.except_osv(_('Error !'), _('Please check configuration of %s, payroll head is missing' % (hday.holiday_status_id.name)))
-                    
+                    raise osv.except_osv(_('Error !'), _('Please check configuration of %s, payroll head is missing') % (hday.holiday_status_id.name))
+
                 res = {
                     'slip_id':slip.id,
                     'name':hday.holiday_status_id.name + '-%s' % (hday.number_of_days),
@@ -1256,7 +1250,7 @@ class hr_payslip(osv.osv):
 #                    res['type'] = 'allowance'
 #                    leave += days
 #                    total += perday * days
-                
+
                 elif hday.holiday_status_id.type == 'halfpaid':
                     paid_leave += (days / 2)
                     res['name'] = hday.holiday_status_id.name + '-%s/2' % (days)
@@ -1273,7 +1267,7 @@ class hr_payslip(osv.osv):
 
                 slip_line_pool.create(cr, uid, res, context=context)
             basic = basic - total
-            leaves = total
+#            leaves = total
             update.update({
                 'basic':basic,
                 'basic_before_leaves': round(basic_before_leaves),
@@ -1290,11 +1284,11 @@ class hr_payslip_line(osv.osv):
     '''
     Payslip Line
     '''
+
     _name = 'hr.payslip.line'
     _description = 'Payslip Line'
 
     def onchange_category(self, cr, uid, ids, category_id):
-        seq = 0
         res = {
         }
         if category_id:
@@ -1320,7 +1314,7 @@ class hr_payslip_line(osv.osv):
         'employee_id':fields.many2one('hr.employee', 'Employee', required=False),
         'name':fields.char('Name', size=256, required=True, readonly=False),
         'base':fields.char('Formula', size=1024, required=False, readonly=False),
-        'code':fields.char('Code', size=64, required=False, readonly=False),        
+        'code':fields.char('Code', size=64, required=False, readonly=False),
         'category_id':fields.many2one('hr.allounce.deduction.categoty', 'Category', required=True),
         'type':fields.selection([
             ('allowance','Allowance'),
@@ -1340,7 +1334,7 @@ class hr_payslip_line(osv.osv):
             ('func','Function Value'),
         ],'Amount Type', select=True, required=True),
         'amount': fields.float('Amount / Percentage', digits=(16, 4)),
-        'total': fields.float('Sub Total', readonly=True, digits=(16, 4)),
+        'total': fields.float('Sub Total', readonly=True, digits_compute=dp.get_precision('Account')),
         'company_contrib': fields.float('Company Contribution', readonly=True, digits=(16, 4)),
         'sequence': fields.integer('Sequence'),
         'note':fields.text('Description'),
@@ -1352,8 +1346,6 @@ class hr_payslip_line(osv.osv):
     }
 
     def execute_function(self, cr, uid, id, value, context=None):
-        if context is None:
-            context = {}
         line_pool = self.pool.get('hr.payslip.line.line')
         res = 0
         ids = line_pool.search(cr, uid, [('slipline_id','=',id), ('from_val','<=',value), ('to_val','>=',value)], context=context)
@@ -1371,10 +1363,10 @@ class hr_payslip_line_line(osv.osv):
     '''
     Function Line
     '''
+
     _name = 'hr.payslip.line.line'
     _description = 'Function Line'
     _order = 'sequence'
-
     _columns = {
         'slipline_id':fields.many2one('hr.payslip.line', 'Slip Line', required=False),
         'name':fields.char('Name', size=64, required=False, readonly=False),
@@ -1392,15 +1384,69 @@ class hr_employee(osv.osv):
     '''
     Employee
     '''
+
     _inherit = 'hr.employee'
     _description = 'Employee'
 
+    def _calculate_salary(self, cr, uid, ids, field_names, arg, context=None):
+        vals = {}
+        slip_line_pool = self.pool.get('hr.payslip.line')
+
+        for employee in self.browse(cr, uid, ids, context=context):
+            if not employee.contract_id:
+                vals[employee.id] = {'basic':0.0, 'gross':0.0, 'net':0.0, 'advantages_gross':0.0, 'advantages_net':0.0}
+                continue
+
+            basic = employee.contract_id.basic
+            gross = employee.contract_id.gross
+            net = employee.contract_id.net
+            allowance = employee.contract_id.advantages_gross
+            deduction = employee.contract_id.advantages_net
+
+            obj = {
+                'basic':basic,
+                'gross':gross,
+                'net':net
+            }
+            for line in employee.line_ids:
+                base = line.category_id.base
+                try:
+                    amt = eval(base, obj)
+                except Exception, e:
+                    raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
+                amount = 0.0
+                if line.amount_type == 'per':
+                    amount = amt * line.amount
+                elif line.amount_type == 'func':
+                    amount = slip_line_pool.execute_function(cr, uid, line.id, amt, context)
+                elif line.amount_type == 'fix':
+                    amount = line.amount
+
+                if line.type == 'allowance':
+                    allowance += amount
+                elif line.type == 'deduction':
+                    deduction += amount
+
+            vals[employee.id] = {
+                'basic':basic,
+                'advantages_gross':allowance,
+                'gross':basic + allowance,
+                'advantages_net':deduction,
+                'net':basic + allowance - deduction
+            }
+        return vals
+
     _columns = {
-        'passport_id':fields.many2one('hr.passport', 'Passport', required=False, domain="[('employee_id','=',active_id), ('address_id','=',address_home_id)]", help="Employee Passport Information"),
-        'bank_account_id':fields.many2one('res.partner.bank', 'Bank Account', domain="[('partner_id','=',partner_id)]", help="Employee bank salary account"),
+        'passport_id':fields.many2one('hr.passport', 'Passport No', required=False, domain="[('employee_id','=',active_id), ('address_id','=',address_home_id)]", help="Employee Passport Information"),
         'line_ids':fields.one2many('hr.payslip.line', 'employee_id', 'Salary Structure', required=False),
         'slip_ids':fields.one2many('hr.payslip', 'employee_id', 'Payslips', required=False, readonly=True),
-        'otherid': fields.char('Other Id', size=64)
+        'otherid': fields.char('Other Id', size=64),
+
+        'basic': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Basic Salary', digits=(14,2)),
+        'gross': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Gross Salary', digits=(14,2)),
+        'net': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Net Salary', digits=(14,2)),
+        'advantages_net': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Deductions', digits=(14,2)),
+        'advantages_gross': fields.function(_calculate_salary, method=True, multi='dc', type='float', string='Allowances', digits=(14,2)),
     }
 hr_employee()