~unifield-team/unifield-wm/us-826

634.5.3 by Olivier DOSSMANN
UF-822 [ADD] Payroll entries
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
##############################################################################
4
#
5
#    OpenERP, Open Source Management Solution
6
#    Copyright (C) 2012 TeMPO Consulting, MSF. All Rights Reserved
7
#    Developer: Olivier DOSSMANN
8
#
9
#    This program is free software: you can redistribute it and/or modify
10
#    it under the terms of the GNU Affero General Public License as
11
#    published by the Free Software Foundation, either version 3 of the
12
#    License, or (at your option) any later version.
13
#
14
#    This program is distributed in the hope that it will be useful,
15
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
#    GNU Affero General Public License for more details.
18
#
19
#    You should have received a copy of the GNU Affero General Public License
20
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
#
22
##############################################################################
23
24
from osv import osv
25
from osv import fields
26
from decimal_precision import get_precision
27
from time import strftime
634.5.10 by Olivier DOSSMANN
UF-822 [ADD] Add analytic distribution on payroll entries
28
from lxml import etree
634.5.17 by Olivier DOSSMANN
UF-822 [ADD] Block payroll entries creation
29
from tools.translate import _
634.5.3 by Olivier DOSSMANN
UF-822 [ADD] Payroll entries
30
31
class hr_payroll(osv.osv):
32
    _name = 'hr.payroll.msf'
33
    _description = 'Payroll'
34
726 by jf
uF-822 UF-824 [DEV] Homere interface
35
    def _get_analytic_state(self, cr, uid, ids, name, args, context=None):
634.5.11 by Olivier DOSSMANN
UF-822 [ADD] Add analytic distribution on payroll lines
36
        """
37
        Get state of distribution:
38
         - if compatible with the line, then "valid"
39
         - if no distribution on the line, then "none"
40
         - all other case are "invalid"
41
        """
42
        if isinstance(ids, (int, long)):
43
            ids = [ids]
44
        # Prepare some values
45
        res = {}
46
        # Search MSF Private Fund element, because it's valid with all accounts
47
        try:
48
            fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 
49
            'analytic_account_msf_private_funds')[1]
50
        except ValueError:
51
            fp_id = 0
52
        # Browse all given lines
53
        for line in self.browse(cr, uid, ids, context=context):
54
            res[line.id] = 'invalid'
55
            if line.cost_center_id and line.funding_pool_id:
56
                if line.funding_pool_id.id == fp_id:
57
                    res[line.id] = 'valid'
58
                    continue
59
                if line.account_id.id in [x.id for x in line.funding_pool_id.account_ids] and line.cost_center_id.id in [x.id for x in line.funding_pool_id.cost_center_ids]:
60
                    res[line.id] = 'valid'
61
                    continue
62
            elif line.cost_center_id and not line.funding_pool_id:
63
                res[line.id] = 'valid'
64
                continue
65
            else:
66
                res[line.id] = 'none'
67
        return res
68
726 by jf
uF-822 UF-824 [DEV] Homere interface
69
    def _get_third_parties(self, cr, uid, ids, field_name=None, arg=None, context=None):
634.5.21 by Olivier DOSSMANN
UF-822 [ADD] Third parties for payroll entries
70
        """
71
        Get "Third Parties" following other fields
72
        """
73
        res = {}
634.5.24 by Olivier DOSSMANN
UF-822 [ADD] Improve Employee identification id display for payroll entries
74
        for line in self.browse(cr, uid, ids):
634.5.21 by Olivier DOSSMANN
UF-822 [ADD] Third parties for payroll entries
75
            if line.employee_id:
76
                res[line.id] = {'third_parties': 'hr.employee,%s' % line.employee_id.id}
77
                res[line.id] = 'hr.employee,%s' % line.employee_id.id
78
            elif line.journal_id:
79
                res[line.id] = 'account.journal,%s' % line.transfer_journal_id.id
80
            elif line.partner_id:
81
                res[line.id] = 'res.partner,%s' % line.partner_id.id
82
            else:
83
                res[line.id] = False
84
        return res
85
726 by jf
uF-822 UF-824 [DEV] Homere interface
86
    def _get_employee_identification_id(self, cr, uid, ids, field_name=None, arg=None, context=None):
634.5.24 by Olivier DOSSMANN
UF-822 [ADD] Improve Employee identification id display for payroll entries
87
        """
88
        Get employee identification number if employee id is given
89
        """
90
        res = {}
91
        for line in self.browse(cr, uid, ids):
92
            res[line.id] = ''
93
            if line.employee_id:
94
                res[line.id] = line.employee_id.identification_id
95
        return res
96
634.5.3 by Olivier DOSSMANN
UF-822 [ADD] Payroll entries
97
    _columns = {
634.5.14 by Olivier DOSSMANN
UF-822 [ADD] All fields for payroll entries are readonly except analytic fields
98
        'date': fields.date(string='Date', required=True, readonly=True),
891.1.20 by Olivier DOSSMANN
UF-1089 [ADD] document date on payroll import and validation
99
        'document_date': fields.date(string='Document Date', required=True, readonly=True),
634.5.14 by Olivier DOSSMANN
UF-822 [ADD] All fields for payroll entries are readonly except analytic fields
100
        'account_id': fields.many2one('account.account', string="Account", required=True, readonly=True),
101
        'period_id': fields.many2one('account.period', string="Period", required=True, readonly=True),
102
        'employee_id': fields.many2one('hr.employee', string="Employee", readonly=True),
103
        'partner_id': fields.many2one('res.partner', string="Partner", readonly=True),
104
        'journal_id': fields.many2one('account.journal', string="Journal", readonly=True),
634.5.24 by Olivier DOSSMANN
UF-822 [ADD] Improve Employee identification id display for payroll entries
105
        'employee_id_number': fields.function(_get_employee_identification_id, method=True, type='char', size=255, string='Employee ID', readonly=True),
634.5.14 by Olivier DOSSMANN
UF-822 [ADD] All fields for payroll entries are readonly except analytic fields
106
        'name': fields.char(string='Description', size=255, readonly=True),
107
        'ref': fields.char(string='Reference', size=255, readonly=True),
634.5.7 by Olivier DOSSMANN
UF-822 [ADD] Change some payroll entry fields in order not to be modified by users
108
        'amount': fields.float(string='Amount', digits_compute=get_precision('Account'), readonly=True),
109
        'currency_id': fields.many2one('res.currency', string="Currency", required=True, readonly=True),
110
        'state': fields.selection([('draft', 'Draft'), ('valid', 'Validated')], string="State", required=True, readonly=True),
634.5.10 by Olivier DOSSMANN
UF-822 [ADD] Add analytic distribution on payroll entries
111
        'cost_center_id': fields.many2one('account.analytic.account', string="Cost Center", required=True, domain="[('category','=','OC'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
112
        'funding_pool_id': fields.many2one('account.analytic.account', string="Funding Pool", domain="[('category', '=', 'FUNDING'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
113
        'free1_id': fields.many2one('account.analytic.account', string="Free 1", domain="[('category', '=', 'FREE1'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
114
        'free2_id': fields.many2one('account.analytic.account', string="Free 2", domain="[('category', '=', 'FREE2'), ('type', '!=', 'view'), ('state', '=', 'open')]"),
634.5.11 by Olivier DOSSMANN
UF-822 [ADD] Add analytic distribution on payroll lines
115
        'analytic_state': fields.function(_get_analytic_state, type='selection', method=True, readonly=True, string="Distribution State",
116
            selection=[('none', 'None'), ('valid', 'Valid'), ('invalid', 'Invalid')], help="Give analytic distribution state"),
634.5.21 by Olivier DOSSMANN
UF-822 [ADD] Third parties for payroll entries
117
        'partner_type': fields.function(_get_third_parties, type='reference', method=True, string="Third Parties", readonly=True,
118
            selection=[('res.partner', 'Partner'), ('account.journal', 'Journal'), ('hr.employee', 'Employee'), ('account.bank.statement', 'Register')]),
634.5.93 by Olivier DOSSMANN
UF-822 [ADD] Permit to import payroll from some fields
119
        'field': fields.char(string='Field', readonly=True, size=255, help="Field this line come from in Homère."),
634.5.3 by Olivier DOSSMANN
UF-822 [ADD] Payroll entries
120
    }
121
122
    _order = 'employee_id, date desc'
123
124
    _defaults = {
634.5.21 by Olivier DOSSMANN
UF-822 [ADD] Third parties for payroll entries
125
        'date': lambda *a: strftime('%Y-%m-%d'),
891.1.20 by Olivier DOSSMANN
UF-1089 [ADD] document date on payroll import and validation
126
        'document_date': lambda *a: strftime('%Y-%m-%d'),
634.5.3 by Olivier DOSSMANN
UF-822 [ADD] Payroll entries
127
        'state': lambda *a: 'draft',
128
    }
129
634.5.10 by Olivier DOSSMANN
UF-822 [ADD] Add analytic distribution on payroll entries
130
    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
131
        """
132
        Change funding pool domain in order to include MSF Private fund
133
        """
134
        if not context:
135
            context = {}
136
        view = super(hr_payroll, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
137
        if view_type == 'tree':
138
            form = etree.fromstring(view['arch'])
139
            data_obj = self.pool.get('ir.model.data')
140
            try:
141
                oc_id = data_obj.get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_project')[1]
142
            except ValueError:
143
                oc_id = 0
144
            # Change OC field
145
            fields = form.xpath('/tree//field[@name="cost_center_id"]')
146
            for field in fields:
147
                field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), ('id', 'child_of', [%s])]" % oc_id)
148
            # Change FP field
149
            try:
150
                fp_id = data_obj.get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1]
151
            except ValueError:
152
                fp_id = 0
153
            fp_fields = form.xpath('/tree//field[@name="funding_pool_id"]')
154
            for field in fp_fields:
155
                field.set('domain', "[('type', '!=', 'view'), ('state', '=', 'open'), '|', '&', ('cost_center_ids', '=', cost_center_id), ('account_ids', '=', account_id), ('id', '=', %s)]" % fp_id)
156
            view['arch'] = etree.tostring(form)
157
        return view
158
726 by jf
uF-822 UF-824 [DEV] Homere interface
159
    def create(self, cr, uid, vals, context=None):
634.5.15 by Olivier DOSSMANN
UF-822 [ADD] Create a description for expense account with "Salary Month Year"
160
        """
634.5.43 by Olivier DOSSMANN
UF-822 [ADD] Delete some useless code
161
        Raise an error if creation don't become from an import or a YAML.
634.5.45 by Olivier DOSSMANN
UF-822 [ADD] Default analytic distribution for new payroll entries
162
        Add default analytic distribution for those that doesn't have anyone.
634.5.15 by Olivier DOSSMANN
UF-822 [ADD] Create a description for expense account with "Salary Month Year"
163
        """
164
        if not context:
165
            context = {}
634.5.17 by Olivier DOSSMANN
UF-822 [ADD] Block payroll entries creation
166
        if not context.get('from', False) and not context.get('from') in ['yaml', 'csv_import']:
167
            raise osv.except_osv(_('Error'), _('You are not able to create payroll entries.'))
634.5.45 by Olivier DOSSMANN
UF-822 [ADD] Default analytic distribution for new payroll entries
168
        if not vals.get('cost_center_id', False):
169
            try:
170
                dummy_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_project_dummy')[1]
171
            except:
172
                dummy_id = 0
173
            if dummy_id:
174
                vals.update({'cost_center_id': dummy_id,})
175
        if not vals.get('funding_pool_id', False):
176
            try:
177
                fp_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'analytic_distribution', 'analytic_account_msf_private_funds')[1]
726 by jf
uF-822 UF-824 [DEV] Homere interface
178
            except ValueError:
634.5.45 by Olivier DOSSMANN
UF-822 [ADD] Default analytic distribution for new payroll entries
179
                fp_id = 0
180
            if fp_id:
181
                vals.update({'funding_pool_id': fp_id,})
634.5.15 by Olivier DOSSMANN
UF-822 [ADD] Create a description for expense account with "Salary Month Year"
182
        return super(osv.osv, self).create(cr, uid, vals, context)
183
634.5.3 by Olivier DOSSMANN
UF-822 [ADD] Payroll entries
184
hr_payroll()
185
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: