Release v6.0
This commit is contained in:
parent
dbb30fb088
commit
d4b02a3964
21
__init__.py
21
__init__.py
|
@ -1,16 +1,16 @@
|
|||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.pool import Pool
|
||||
import wage_type
|
||||
import payroll
|
||||
import position
|
||||
import configuration
|
||||
import liquidation
|
||||
import employee
|
||||
import uvt
|
||||
import event_category
|
||||
import account
|
||||
import event
|
||||
from . import wage_type
|
||||
from . import payroll
|
||||
from . import position
|
||||
from . import configuration
|
||||
from . import liquidation
|
||||
from . import employee
|
||||
from . import uvt
|
||||
from . import event_category
|
||||
from . import account
|
||||
from . import event
|
||||
|
||||
|
||||
def register():
|
||||
|
@ -61,6 +61,7 @@ def register():
|
|||
payroll.ExportMovesReport,
|
||||
payroll.PayrollExportReport,
|
||||
liquidation.LiquidationExportReport,
|
||||
wage_type.WageTypeReport,
|
||||
module='staff_payroll_co', type_='report')
|
||||
Pool.register(
|
||||
payroll.PayrollGlobal,
|
||||
|
|
25
account.py
25
account.py
|
@ -7,11 +7,11 @@ from trytond.model import ModelView, fields
|
|||
from trytond.wizard import Wizard, StateView, Button, StateTransition
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.pool import Pool
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext
|
||||
from trytond.modules.staff_payroll.exceptions import MissingPartyWageType
|
||||
|
||||
|
||||
__all__ = ['SeverancePayClearing', 'SeverancePayClearingStart',
|
||||
'SeverancePayClearingDone']
|
||||
|
||||
_ZERO = Decimal('0.0')
|
||||
|
||||
|
||||
|
@ -25,11 +25,11 @@ class SeverancePayClearingStart(ModelView):
|
|||
required=True)
|
||||
severance_pay = fields.Many2One('account.account',
|
||||
'Severance Pay', domain=[
|
||||
('kind', '!=', 'view'),
|
||||
('type', '!=', None),
|
||||
], required=True)
|
||||
counterpart_account = fields.Many2One('account.account',
|
||||
'Counterpart Account', domain=[
|
||||
('kind', '!=', 'view'),
|
||||
('type', '!=', None),
|
||||
], required=True)
|
||||
description = fields.Char('Description', required=True)
|
||||
|
||||
|
@ -55,10 +55,6 @@ class SeverancePayClearing(Wizard):
|
|||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(SeverancePayClearing, cls).__setup__()
|
||||
cls._error_messages.update({
|
||||
'move_created': 'Move %s created. \n',
|
||||
'missing_party': 'Missing party in mandatory wage %s for employee %s',
|
||||
})
|
||||
|
||||
def default_done(self, fields):
|
||||
return {'result': self.result}
|
||||
|
@ -85,7 +81,10 @@ class SeverancePayClearing(Wizard):
|
|||
parties_related = {}
|
||||
for mw in mandatory_wages:
|
||||
if not mw or not mw.party or not mw.employee.party:
|
||||
self.raise_user_error('missing_party', mw.wage_type.name, mw.employee.party.name)
|
||||
raise MissingPartyWageType(
|
||||
gettext('staff_payroll_co.msg_missing_party',
|
||||
wage=mw.wage_type.name,
|
||||
employee=mw.employee.party.name))
|
||||
parties_related[mw.employee.party.id] = mw.party.id
|
||||
|
||||
counterparts = {}
|
||||
|
@ -136,9 +135,9 @@ class SeverancePayClearing(Wizard):
|
|||
for lr in to_reconcile.values():
|
||||
MoveLine.reconcile(lr)
|
||||
|
||||
self.result = self.raise_user_error('move_created',
|
||||
error_args=(move.number,),
|
||||
raise_exception=False)
|
||||
self.result = UserError(
|
||||
gettext('staff_payroll_co.msg_move_created',
|
||||
s=move.number))
|
||||
return 'done'
|
||||
|
||||
|
||||
|
|
|
@ -4,9 +4,6 @@ from trytond.model import fields
|
|||
from trytond.pool import PoolMeta
|
||||
|
||||
|
||||
__all__ = ['Configuration']
|
||||
|
||||
|
||||
class Configuration(metaclass=PoolMeta):
|
||||
__name__ = "staff.configuration"
|
||||
staff_liquidation_sequence = fields.Many2One('ir.sequence',
|
||||
|
@ -17,7 +14,7 @@ class Configuration(metaclass=PoolMeta):
|
|||
uvt_value = fields.Numeric('UVT Value')
|
||||
liquidation_account = fields.Many2One('account.account',
|
||||
'Liquidation Account', domain=[
|
||||
('kind', '=', 'payable'),
|
||||
('type.payable', '=', True),
|
||||
], required=True)
|
||||
payment_partial_sunday = fields.Boolean('Payment Partial Sunday')
|
||||
template_email_confirm = fields.Many2One('email.template', 'Template Email of Confirmation')
|
||||
|
|
53
employee.py
53
employee.py
|
@ -6,9 +6,9 @@ from trytond.transaction import Transaction
|
|||
from trytond.wizard import Wizard, StateView, Button, StateTransition
|
||||
from decimal import Decimal
|
||||
from datetime import datetime
|
||||
from trytond.i18n import gettext
|
||||
from .exceptions import ImportDataEmployeeError
|
||||
|
||||
__all__ = ['Employee', 'UpdateEmployeeStart', 'UpdateEmployee',
|
||||
'MandatoryWage']
|
||||
|
||||
SEX = {
|
||||
'': '',
|
||||
|
@ -76,13 +76,6 @@ class Employee(metaclass=PoolMeta):
|
|||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Employee, cls).__setup__()
|
||||
cls._error_messages.update({
|
||||
'party_not_exists': ('The party with document "%s" not exists!'),
|
||||
'department_not_exists': ('The department with name "%s" not exists!'),
|
||||
'project_not_exists': ('The project with name "%s" not exists!'),
|
||||
'category_not_exists': ('The category with name "%s" not exists!'),
|
||||
'analytic_account_not_exists': ('The analytic account with name "%s" not exists!'),
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def import_data(cls, fields_names, data):
|
||||
|
@ -168,7 +161,8 @@ class Employee(metaclass=PoolMeta):
|
|||
if not banks:
|
||||
party_bank = Party.search([('id_number', '=', row[23])])
|
||||
if not party_bank:
|
||||
cls.raise_user_error('party_not_exists', row[23])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=row[23]))
|
||||
else:
|
||||
bank, = Bank.create([{'party': party_bank[0].id}])
|
||||
else:
|
||||
|
@ -196,15 +190,18 @@ class Employee(metaclass=PoolMeta):
|
|||
|
||||
categories = Category.search([('name', '=', row[6])])
|
||||
if not categories:
|
||||
cls.raise_user_error('category_not_exists', row[6])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_category_not_exists'), s=row[6])
|
||||
category = categories[0]
|
||||
projects = Project.search([('name', '=', row[7])])
|
||||
if not projects:
|
||||
cls.raise_user_error('project_not_exists', row[7])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_project_not_exists'), s=row[7])
|
||||
project = projects[0]
|
||||
departments = Department.search([('name', '=', row[8])])
|
||||
if not departments:
|
||||
cls.raise_user_error('department_not_exists', row[8])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_department_not_exists'), s=row[8])
|
||||
department = departments[0]
|
||||
|
||||
employees = cls.search([('party', '=', party.id)])
|
||||
|
@ -226,7 +223,8 @@ class Employee(metaclass=PoolMeta):
|
|||
('name', '=', row[9]),
|
||||
])
|
||||
if not accounts:
|
||||
cls.raise_user_error('analytic_account_not_exists', row[9])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_analytic_account_not_exists'), s=row[9])
|
||||
|
||||
# mandatory_wages = {
|
||||
# '1': 'ARL CLASE I OPERATIVO',
|
||||
|
@ -269,19 +267,23 @@ class Employee(metaclass=PoolMeta):
|
|||
if wage.type_concept == 'health':
|
||||
parties = Party.search([('id_number', '=', row[16])])
|
||||
if not parties and row[16]:
|
||||
cls.raise_user_error('party_not_exists', row[16])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=row[16]))
|
||||
elif wage.type_concept == 'retirement':
|
||||
parties = Party.search([('id_number', '=', row[17])])
|
||||
if not parties and row[17]:
|
||||
cls.raise_user_error('party_not_exists', row[17])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=row[17]))
|
||||
elif wage.type_concept == 'box_family':
|
||||
parties = Party.search([('id_number', '=', row[18])])
|
||||
if not parties and row[18]:
|
||||
cls.raise_user_error('party_not_exists', row[18])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=row[18]))
|
||||
elif wage.type_concept == 'risk':
|
||||
parties = Party.search([('id_number', '=', row[19])])
|
||||
if not parties and row[19]:
|
||||
cls.raise_user_error('party_not_exists', row[19])
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=row[19]))
|
||||
|
||||
if parties:
|
||||
party_id = parties[0].id
|
||||
|
@ -376,27 +378,32 @@ class Employee(metaclass=PoolMeta):
|
|||
if parties:
|
||||
MandatoryWage.write([line], {'party': parties[0].id})
|
||||
else:
|
||||
Employee.raise_user_error('party_not_exists', value)
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=value))
|
||||
if value:
|
||||
parties = Party.search([('id_number', '=', value)])
|
||||
if parties:
|
||||
MandatoryWage.write([line], {'party': parties[0].id})
|
||||
else:
|
||||
Employee.raise_user_error('party_not_exists', value)
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=value))
|
||||
if value:
|
||||
parties = Party.search([('id_number', '=', value)])
|
||||
if parties:
|
||||
MandatoryWage.write([line], {'party': parties[0].id})
|
||||
else:
|
||||
Employee.raise_user_error('party_not_exists', value)
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=value))
|
||||
if value:
|
||||
parties = Party.search([('id_number', '=', value)])
|
||||
if parties:
|
||||
MandatoryWage.write([line], {'party': parties[0].id})
|
||||
else:
|
||||
Employee.raise_user_error('party_not_exists', value)
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=value))
|
||||
else:
|
||||
Employee.raise_user_error('party_not_exists', value)
|
||||
raise ImportDataEmployeeError(
|
||||
gettext('staff_payroll_co.msg_party_not_exists', s=value))
|
||||
return
|
||||
|
||||
def get_party_bank(self, name=None):
|
||||
|
|
2
event.py
2
event.py
|
@ -4,8 +4,6 @@ from decimal import Decimal
|
|||
from trytond.pool import PoolMeta, Pool
|
||||
from trytond.model import fields
|
||||
|
||||
__all__ = ['Event']
|
||||
|
||||
|
||||
class Event(metaclass=PoolMeta):
|
||||
'Staff Event'
|
||||
|
|
|
@ -4,8 +4,6 @@ from trytond.model import fields
|
|||
from trytond.pool import PoolMeta
|
||||
from trytond.pyson import Eval
|
||||
|
||||
__all__ = ['EventCategory']
|
||||
|
||||
|
||||
STATES_PAYROLL = {'invisible': ~Eval('payroll_effect')}
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.model.exceptions import ValidationError
|
||||
|
||||
|
||||
class ImportDataEmployeeError(ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
class LiquidationEmployeeError(UserError):
|
||||
pass
|
||||
|
||||
|
||||
class LiquidationMoveError(UserError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingSecuenceLiquidation(UserError):
|
||||
pass
|
||||
|
||||
|
||||
class WageTypeConceptError(UserError):
|
||||
pass
|
||||
|
||||
|
||||
class GeneratePayrollError(UserError):
|
||||
pass
|
||||
|
||||
|
||||
class GeneratePayrollMoveError(UserError):
|
||||
pass
|
||||
|
||||
|
||||
class MissingTemplateEmailPayroll(ValidationError):
|
||||
pass
|
|
@ -9,14 +9,9 @@ from trytond.report import Report
|
|||
from trytond.pyson import Eval, If, Bool
|
||||
from trytond.wizard import Wizard, StateView, Button, StateTransition, StateReport
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
__all__ = [
|
||||
'Liquidation', 'Report', 'LiquidationLine', 'LiquidationGroup',
|
||||
'LiquidationLineMoveLine', 'LiquidationLineAdjustment',
|
||||
'LiquidationGroupStart', 'LiquidationAdjustmentStart',
|
||||
'LiquidationAdjustment', 'LiquidationExportStart',
|
||||
'LiquidationExportReport', 'LiquidationExport'
|
||||
]
|
||||
from trytond.i18n import gettext
|
||||
from .exceptions import (LiquidationEmployeeError, MissingSecuenceLiquidation,
|
||||
LiquidationMoveError, WageTypeConceptError)
|
||||
|
||||
STATES = {'readonly': (Eval('state') != 'draft')}
|
||||
|
||||
|
@ -94,7 +89,7 @@ class Liquidation(Workflow, ModelSQL, ModelView):
|
|||
states=STATES, domain=[('employee', '=', Eval('employee'))])
|
||||
account = fields.Many2One('account.account', 'Account',
|
||||
required=True, domain=[
|
||||
('kind', '!=', 'view'),
|
||||
('type', '!=', None),
|
||||
])
|
||||
payrolls = fields.Function(fields.Many2Many('staff.payroll',
|
||||
None, None, 'Payroll', depends=['start_period', 'end_period'],
|
||||
|
@ -109,13 +104,6 @@ class Liquidation(Workflow, ModelSQL, ModelView):
|
|||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Liquidation, cls).__setup__()
|
||||
cls._error_messages.update({
|
||||
'employee_without_salary': ('The employee does not have salary!'),
|
||||
'wrong_start_end': ('The date end can not smaller than date start'),
|
||||
'sequence_missing': ('Sequence liquidation is missing!'),
|
||||
'payroll_not_posted': ('The employee has payrolls does not posted!'),
|
||||
'error_dates': ('The dates for employee is wrong "%s"!'),
|
||||
})
|
||||
cls._transitions |= set((
|
||||
('draft', 'cancel'),
|
||||
('cancel', 'draft'),
|
||||
|
@ -311,7 +299,7 @@ class Liquidation(Workflow, ModelSQL, ModelView):
|
|||
self.write([self], {'move': move.id})
|
||||
for ml in move.lines:
|
||||
if ml.account.id not in grouped.keys() or (
|
||||
ml.account.kind not in ('payable', 'receivable')):
|
||||
ml.account.type.statement not in ('balance')):
|
||||
continue
|
||||
to_reconcile = [ml]
|
||||
to_reconcile.extend(grouped[ml.account.id]['lines'])
|
||||
|
@ -517,7 +505,8 @@ class Liquidation(Workflow, ModelSQL, ModelView):
|
|||
date_start, date_end = self._get_dates()
|
||||
delta = self.getDifference(date_start, date_end)
|
||||
except:
|
||||
# self.raise_user_error('error_dates', self.employee.party.name)
|
||||
raise LiquidationEmployeeError(
|
||||
gettext('staff_payroll_co.msg_error_dates', s=self.employee.party.name))
|
||||
delta = 0
|
||||
return delta
|
||||
|
||||
|
@ -581,13 +570,13 @@ class Liquidation(Workflow, ModelSQL, ModelView):
|
|||
if self.number:
|
||||
return
|
||||
pool = Pool()
|
||||
Sequence = pool.get('ir.sequence')
|
||||
Configuration = pool.get('staff.configuration')
|
||||
configuration = Configuration(1)
|
||||
if not configuration.staff_liquidation_sequence:
|
||||
self.raise_user_error('sequence_missing',)
|
||||
seq = configuration.staff_liquidation_sequence.id
|
||||
self.write([self], {'number': Sequence.get_id(seq)})
|
||||
raise MissingSecuenceLiquidation(
|
||||
gettext('staff_payroll_co.msg_sequence_missing'))
|
||||
seq = configuration.staff_liquidation_sequence.get()
|
||||
self.write([self], {'number': seq})
|
||||
|
||||
def get_sum_operation(self, name):
|
||||
res = []
|
||||
|
@ -642,12 +631,11 @@ class LiquidationLine(ModelSQL, ModelView):
|
|||
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
TableHandler = backend.get('TableHandler')
|
||||
table = TableHandler(cls, module_name)
|
||||
table_h = cls.__table_handler__(module_name)
|
||||
|
||||
# Migration from 4.0: remove hoard_amount
|
||||
if table.column_exist('hoard_amount'):
|
||||
table.drop_column('hoard_amount')
|
||||
if table_h.column_exist('hoard_amount'):
|
||||
table_h.drop_column('hoard_amount')
|
||||
super(LiquidationLine, cls).__register__(module_name)
|
||||
|
||||
def get_party(self, name=None):
|
||||
|
@ -683,7 +671,7 @@ class LiquidationLineAdjustment(ModelSQL, ModelView):
|
|||
account = fields.Many2One('account.account', 'Acount',
|
||||
required=True, domain=[
|
||||
('company', '=', Eval('context', {}).get('company', -1)),
|
||||
('kind', '!=', 'view'),
|
||||
('type', '!=', None),
|
||||
])
|
||||
description = fields.Char('Description', required=True)
|
||||
amount = fields.Numeric('Amount', digits=(10,2), required=True)
|
||||
|
@ -713,7 +701,7 @@ class LiquidationAdjustmentStart(ModelView):
|
|||
account = fields.Many2One('account.account', 'Acount',
|
||||
required=True, domain=[
|
||||
('company', '=', Eval('context', {}).get('company', -1)),
|
||||
('kind', '!=', 'view'),
|
||||
('type', '!=', None),
|
||||
])
|
||||
description = fields.Char('Description', required=True)
|
||||
|
||||
|
@ -736,9 +724,6 @@ class LiquidationAdjustment(Wizard):
|
|||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(LiquidationAdjustment, cls).__setup__()
|
||||
cls._error_messages.update({
|
||||
'liquidation_with_move': ('The liquidation Nro "%s" have move!'),
|
||||
})
|
||||
|
||||
def create_adjustment(self, line):
|
||||
LineAdjustment = Pool().get('staff.liquidation.line_adjustment')
|
||||
|
@ -761,7 +746,8 @@ class LiquidationAdjustment(Wizard):
|
|||
line_created = None
|
||||
if liquidation:
|
||||
if liquidation.move:
|
||||
self.raise_user_error('liquidation_with_move', (liquidation.number))
|
||||
raise LiquidationMoveError(
|
||||
gettext('staff_payroll_co.msg_liquidation_with_move', s=liquidation.number))
|
||||
for line in liquidation.lines:
|
||||
if line.wage.id == self.start.wage_type.id:
|
||||
if line.amount:
|
||||
|
@ -800,7 +786,7 @@ class LiquidationGroupStart(ModelView):
|
|||
description = fields.Char('Description', required=True)
|
||||
account = fields.Many2One('account.account', 'Account', required=True,
|
||||
domain=[
|
||||
('kind', '=', 'payable'),
|
||||
('type.payable', '=', True),
|
||||
('company', '=', Eval('company'))
|
||||
])
|
||||
employees = fields.Many2Many('company.employee', None, None, 'Employee')
|
||||
|
@ -1055,6 +1041,7 @@ class LiquidationExport(Wizard):
|
|||
if self.start.department:
|
||||
department_id = self.start.department.id
|
||||
data = {
|
||||
'ids': [],
|
||||
'company': self.start.company.id,
|
||||
'start_date': self.start.start_date,
|
||||
'end_date': self.start.end_date,
|
||||
|
@ -1077,9 +1064,8 @@ class LiquidationExportReport(Report):
|
|||
return dom_liquidation
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, data):
|
||||
report_context = super(LiquidationExportReport, cls).get_context(
|
||||
records, data)
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
pool = Pool()
|
||||
user = pool.get('res.user')(Transaction().user)
|
||||
Liquidation = pool.get('staff.liquidation')
|
||||
|
@ -1131,7 +1117,6 @@ class LiquidationExportReport(Report):
|
|||
for line in liquidation.lines:
|
||||
if line.wage.type_concept in (payments):
|
||||
concept = line.wage.type_concept
|
||||
print('pasa por aca')
|
||||
else:
|
||||
if line.wage.definition == 'payment' and line.wage_type.receipt:
|
||||
concept = 'others_payments'
|
||||
|
@ -1140,7 +1125,8 @@ class LiquidationExportReport(Report):
|
|||
line.wage.receipt:
|
||||
concept = 'others_deductions'
|
||||
if not concept:
|
||||
liquidation.raise_user_error('type_concept_not_exists', line.wage.name)
|
||||
raise WageTypeConceptError(
|
||||
gettext('staff_payroll_co.msg_type_concept_not_exists', s=line.wage.name))
|
||||
if concept not in parties[employee_id].keys():
|
||||
parties[employee_id][concept] = 0
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data grouped="1">
|
||||
<record model="ir.message" id="msg_party_not_exists">
|
||||
<field name="text">The party with document "%s" not exists!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_department_not_exists">
|
||||
<field name="text">The department with name "%s" not exists!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_project_not_exists">
|
||||
<field name="text">The project with name "%s" not exists</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_category_not_exists">
|
||||
<field name="text">The category with name "%s" not exists!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_analytic_account_not_exists">
|
||||
<field name="text">The analytic account with name "%s" not exists!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_employee_without_salary">
|
||||
<field name="text">The employee does not have salary!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_wrong_start_end">
|
||||
<field name="text">The date end can not smaller than date start</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_sequence_missing">
|
||||
<field name="text">Sequence liquidation is missing!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_payroll_not_posted">
|
||||
<field name="text">The employee has payrolls does not posted!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_error_dates">
|
||||
<field name="text">The dates for employee is wrong "%s"!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_liquidation_with_move">
|
||||
<field name="text">The liquidation Nro "%s" have move!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_type_concept_not_exists">
|
||||
<field name="text">The type concept "(%s)" no exists</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_period_without_contract">
|
||||
<field name="text">The period selected without contract for the employee "(%employee)"!</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_error_report">
|
||||
<field name="text">Error "(%s)"! </field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_template_not_exist">
|
||||
<field name="text">Missing template selection in the configuration</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_provision_missing_account">
|
||||
<field name="text">Missing account debit for provision</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_move_created">
|
||||
<field name="text">Move "%(s)"created. \n</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_missing_party">
|
||||
<field name="text">Missing party in mandatory wage "(%wage)" for employee "(%employee)"</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
77
payroll.py
77
payroll.py
|
@ -14,23 +14,11 @@ from trytond.wizard import (
|
|||
)
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.pyson import Eval
|
||||
from trytond.modules.staff_payroll import Period
|
||||
from trytond.modules.staff_payroll import PayrollReport
|
||||
|
||||
|
||||
__all__ = [
|
||||
'Payroll', 'PayrollGlobalStart', 'PayrollGlobal', 'PayrollGlobalReport',
|
||||
'PayrollPaymentReport', 'PayrollPayment', 'PayrollPaymentStart',
|
||||
'PayrollPaycheckStart', 'PayrollPaycheckReport', 'PayrollPaycheck',
|
||||
'PayrollSheetReport', 'PayrollSheet', 'PayrollLine', 'PayrollSheetStart',
|
||||
'PayrollGroupStart', 'OpenPayrollByPeriodStart', 'PayrollByPeriodDynamic',
|
||||
'OpenPayrollByPeriod', 'PayrollGroup', 'Exo2276Start', 'Exo2276',
|
||||
'Exo2276Report', 'IncomeWithholdings', 'IncomeWithholdingsStart',
|
||||
'ExportMovesReport', 'IncomeWithholdingsReport', 'PayrollExportStart',
|
||||
'PayrollExport', 'PayrollExportReport', 'PayrollSupportDispersionStart',
|
||||
'PayrollSupportDispersion', 'PayrollLineMoveLine', 'PayrollFix',
|
||||
'PayrollsMultiPayment', 'PayrollsMultiPaymentStart',
|
||||
]
|
||||
from trytond.modules.staff_payroll.period import Period
|
||||
from trytond.modules.staff_payroll.payroll import PayrollReport
|
||||
from trytond.i18n import gettext
|
||||
from .exceptions import (GeneratePayrollError, MissingTemplateEmailPayroll,
|
||||
WageTypeConceptError)
|
||||
|
||||
|
||||
STATES = {'readonly': (Eval('state') != 'draft')}
|
||||
|
@ -145,15 +133,6 @@ class Payroll(metaclass=PoolMeta):
|
|||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Payroll, cls).__setup__()
|
||||
cls._error_messages.update({
|
||||
'period_without_contract': (
|
||||
'The period selected without contract for the employee!'
|
||||
),
|
||||
'error_report': ('Error %s !'),
|
||||
'type_concept_not_exists': ('The concept has no type of payment %s'),
|
||||
'template_not_exist': ('Missing template selection in the configuration'),
|
||||
'provision_missing_account': ('Missing account debit for provision'),
|
||||
})
|
||||
|
||||
@fields.depends('end', 'date_effective')
|
||||
def on_change_with_date_effective(self):
|
||||
|
@ -172,7 +151,7 @@ class Payroll(metaclass=PoolMeta):
|
|||
grouped = {line.wage_type.debit_account.id: {'lines': [m for m in line.move_lines]} for line in self.lines if line.wage_type.provision_cancellation}
|
||||
for p in self.move.lines:
|
||||
if p.account.id not in grouped or (
|
||||
p.account.kind not in ('payable', 'receivable')):
|
||||
p.account.type.statement not in ('balance')):
|
||||
continue
|
||||
to_reconcile = [p]
|
||||
to_reconcile.extend(grouped[p.account.id]['lines'])
|
||||
|
@ -232,7 +211,9 @@ class Payroll(metaclass=PoolMeta):
|
|||
if not start_date or not end_date:
|
||||
self.period = None
|
||||
self.description = None
|
||||
self.raise_user_error('period_without_contract')
|
||||
raise GeneratePayrollError(
|
||||
gettext('staff_payroll_co.msg_period_without_contract', employee=self.employee.party.name)
|
||||
)
|
||||
if not self.description and self.period:
|
||||
self.description = self.period.description
|
||||
|
||||
|
@ -774,9 +755,10 @@ class Payroll(metaclass=PoolMeta):
|
|||
if response and response.status_code == 202:
|
||||
self.write([self], {'sended_mail': True})
|
||||
else:
|
||||
raise UserError('No mail sent, check employee email')
|
||||
raise UserError('No mail sent, check employee email', employee=self.employee.party.name)
|
||||
else:
|
||||
self.raise_error('template_not_exist')
|
||||
raise MissingTemplateEmailPayroll(
|
||||
gettext('staff_payroll_co.msg_template_not_exist'))
|
||||
|
||||
|
||||
class PayrollSupportDispersionStart(ModelView):
|
||||
|
@ -865,6 +847,7 @@ class PayrollGlobal(Wizard):
|
|||
if self.start.department:
|
||||
department_id = self.start.department.id
|
||||
data = {
|
||||
'ids': [],
|
||||
'company': self.start.company.id,
|
||||
'start_period': self.start.start_period.id,
|
||||
'end_period': end_period_id,
|
||||
|
@ -887,9 +870,8 @@ class PayrollGlobalReport(Report):
|
|||
return dom_payroll
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, data):
|
||||
report_context = super(PayrollGlobalReport, cls).get_context(
|
||||
records, data)
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
pool = Pool()
|
||||
user = pool.get('res.user')(Transaction().user)
|
||||
Payroll = pool.get('staff.payroll')
|
||||
|
@ -981,7 +963,8 @@ class PayrollGlobalReport(Report):
|
|||
else:
|
||||
concept = line.wage_type.type_concept
|
||||
if not concept:
|
||||
payroll.raise_user_error('type_concept_not_exists', line.wage_type.name)
|
||||
raise WageTypeConceptError(
|
||||
gettext('staff_payroll_co.msg_type_concept_not_exists', s=line.wage_type.name))
|
||||
parties[employee_id][concept] += line.amount
|
||||
parties[employee_id]['worked_days'] += payroll.worked_days
|
||||
parties[employee_id]['gross_payments'] += payroll.gross_payments
|
||||
|
@ -1063,6 +1046,7 @@ class PayrollPayment(Wizard):
|
|||
if self.start.period:
|
||||
period = self.start.period.id
|
||||
data = {
|
||||
'ids': [],
|
||||
'company': self.start.company.id,
|
||||
'period': period,
|
||||
'department': department_id,
|
||||
|
@ -1077,8 +1061,8 @@ class PayrollPaymentReport(Report):
|
|||
__name__ = 'staff.payroll.payment_report'
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, data):
|
||||
report_context = super(PayrollPaymentReport, cls).get_context(records, data)
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
user = Pool().get('res.user')(Transaction().user)
|
||||
Payroll = Pool().get('staff.payroll')
|
||||
Period = Pool().get('staff.payroll.period')
|
||||
|
@ -1155,6 +1139,7 @@ class PayrollPaycheck(Wizard):
|
|||
department_id = self.start.department.id
|
||||
periods = [p.id for p in self.start.periods]
|
||||
data = {
|
||||
'ids': [],
|
||||
'company': self.start.company.id,
|
||||
'periods': periods,
|
||||
'department': department_id,
|
||||
|
@ -1182,8 +1167,8 @@ class PayrollPaycheckReport(Report):
|
|||
return dom_payroll
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, data):
|
||||
report_context = super(PayrollPaycheckReport, cls).get_context(records, data)
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
pool = Pool()
|
||||
Payroll = pool.get('staff.payroll')
|
||||
Period = pool.get('staff.payroll.period')
|
||||
|
@ -1333,6 +1318,7 @@ class PayrollSheet(Wizard):
|
|||
def do_print_(self, action):
|
||||
periods = [p.id for p in self.start.periods]
|
||||
data = {
|
||||
'ids': [],
|
||||
'company': self.start.company.id,
|
||||
'periods': periods,
|
||||
}
|
||||
|
@ -1351,8 +1337,8 @@ class PayrollSheetReport(Report):
|
|||
return dom_payroll
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, data):
|
||||
report_context = super(PayrollSheetReport, cls).get_context(records, data)
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
pool = Pool()
|
||||
user = pool.get('res.user')(Transaction().user)
|
||||
Payroll = pool.get('staff.payroll')
|
||||
|
@ -1701,6 +1687,7 @@ class Exo2276(Wizard):
|
|||
|
||||
def do_print_(self, action):
|
||||
data = {
|
||||
'ids': [],
|
||||
'company': self.start.company.id,
|
||||
'start_period': self.start.start_period.start,
|
||||
'end_period': self.start.end_period.end,
|
||||
|
@ -1955,6 +1942,7 @@ class IncomeWithholdings(Wizard):
|
|||
if self.start.employees:
|
||||
employees = [e.id for e in self.start.employees]
|
||||
data = {
|
||||
'ids': [],
|
||||
'company': self.start.company.id,
|
||||
'start_period': self.start.fiscalyear.start_date,
|
||||
'end_period': self.start.fiscalyear.end_date,
|
||||
|
@ -1982,8 +1970,8 @@ class ExportMovesReport(PayrollReport):
|
|||
__name__ = 'staff_payroll.export_moves.report'
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, data):
|
||||
report_context = super(ExportMovesReport, cls).get_context(records, data)
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
config = Pool().get('staff.configuration')(1)
|
||||
prefix = ''
|
||||
if config:
|
||||
|
@ -2029,6 +2017,7 @@ class PayrollExport(Wizard):
|
|||
department_id = self.start.department.id \
|
||||
if self.start.department else None
|
||||
data = {
|
||||
'ids': [],
|
||||
'company': self.start.company.id,
|
||||
'start_period': self.start.start_period.id,
|
||||
'end_period': self.start.end_period.id,
|
||||
|
@ -2050,8 +2039,8 @@ class PayrollExportReport(Report):
|
|||
return dom_payroll
|
||||
|
||||
@classmethod
|
||||
def get_context(cls, records, data):
|
||||
report_context = super(PayrollExportReport, cls).get_context(records, data)
|
||||
def get_context(cls, records, header, data):
|
||||
report_context = super().get_context(records, header, data)
|
||||
pool = Pool()
|
||||
company = pool.get('company.company')(data['company'])
|
||||
Payroll = pool.get('staff.payroll')
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
from trytond.model import fields
|
||||
from trytond.pool import PoolMeta
|
||||
|
||||
__all__ = ['Position']
|
||||
|
||||
|
||||
class Position(metaclass=PoolMeta):
|
||||
__name__ = 'staff.position'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[tryton]
|
||||
version=5.0.8
|
||||
version=6.0.0
|
||||
depends:
|
||||
company
|
||||
company_department
|
||||
|
|
2
uvt.py
2
uvt.py
|
@ -5,8 +5,6 @@ from trytond.model import ModelView, ModelSQL, fields
|
|||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
__all__ = ['UvtWithholding']
|
||||
|
||||
UVT_SUM_FORMULA = {
|
||||
28: 10,
|
||||
33: 69,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree editable="bottom">
|
||||
<tree editable="1">
|
||||
<field name="account"/>
|
||||
<field name="amount"/>
|
||||
<field name="description"/>
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
from trytond.pool import PoolMeta
|
||||
from trytond.model import fields
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
__all__ = ['WageType']
|
||||
from trytond.report import Report
|
||||
|
||||
ROUND_AMOUNTS = [
|
||||
('', ''),
|
||||
|
@ -64,3 +62,7 @@ class WageType(metaclass=PoolMeta):
|
|||
cursor.execute(
|
||||
'ALTER TABLE staff_wage_type DROP COLUMN IF EXISTS amount_required'
|
||||
)
|
||||
|
||||
|
||||
class WageTypeReport(Report):
|
||||
__name__ = 'staff.wage_type.report'
|
||||
|
|
|
@ -9,5 +9,20 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="inherit" ref="staff_payroll.wage_type_view_form"/>
|
||||
<field name="name">wage_type_form</field>
|
||||
</record>
|
||||
|
||||
<!-- REPORT -->
|
||||
<record model="ir.action.report" id="report_staff_wage_type">
|
||||
<field name="name">Wage Type</field>
|
||||
<field name="model">staff.wage_type</field>
|
||||
<field name="report_name">staff.wage_type.report</field>
|
||||
<field name="report">staff_payroll_co/wagetype.ods</field>
|
||||
<field name="template_extension">ods</field>
|
||||
<field name="translatable">False</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="report_staff_wage_type_keyword">
|
||||
<field name="keyword">form_print</field>
|
||||
<field name="model">staff.wage_type,-1</field>
|
||||
<field name="action" ref="report_staff_wage_type"/>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue