diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py index 2695db40ee6..553b6080cc6 100644 --- a/addons/account/models/account_bank_statement.py +++ b/addons/account/models/account_bank_statement.py @@ -637,9 +637,12 @@ class AccountBankStatementLine(models.Model): # Create The payment payment = self.env['account.payment'] + partner_id = self.partner_id or (aml_dict.get('move_line') and aml_dict['move_line'].partner_id) or self.env['res.partner'] if abs(total)>0.00001: payment_vals = self._prepare_payment_vals(total) - if self.partner_id and len(account_types) == 1: + if not payment_vals['partner_id']: + payment_vals['partner_id'] = partner_id.id + if payment_vals['partner_id'] and len(account_types) == 1: payment_vals['partner_type'] = 'customer' if account_types == receivable_account_type else 'supplier' payment = payment.create(payment_vals) diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index 897da38b719..4f221aba093 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -1621,12 +1621,14 @@ class AccountInvoice(models.Model): fmt = partial(formatLang, invoice.with_context(lang=invoice.partner_id.lang).env, currency_obj=currency) res = {} for line in invoice.tax_line_ids: - res.setdefault(line.tax_id.tax_group_id, {'base': 0.0, 'amount': 0.0}) - res[line.tax_id.tax_group_id]['amount'] += line.amount_total - res[line.tax_id.tax_group_id]['base'] += line.base - res = sorted(res.items(), key=lambda l: l[0].sequence) + tax = line.tax_id + group_key = (tax.tax_group_id, tax.amount_type, tax.amount) + res.setdefault(group_key, {'base': 0.0, 'amount': 0.0}) + res[group_key]['amount'] += line.amount_total + res[group_key]['base'] += line.base + res = sorted(res.items(), key=lambda l: l[0][0].sequence) invoice.amount_by_group = [( - r[0].name, r[1]['amount'], r[1]['base'], + r[0][0].name, r[1]['amount'], r[1]['base'], fmt(r[1]['amount']), fmt(r[1]['base']), len(res), ) for r in res] diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py index f815820da4a..afc9a6cec49 100644 --- a/addons/account/models/account_journal_dashboard.py +++ b/addons/account/models/account_journal_dashboard.py @@ -172,7 +172,7 @@ class account_journal(models.Model): LEFT JOIN account_move move ON aml.move_id = move.id WHERE aml.account_id in %%s AND move.date <= %%s AND move.state = 'posted';""" % (amount_field,) - self.env.cr.execute(query, (account_ids, fields.Date.today(),)) + self.env.cr.execute(query, (account_ids, fields.Date.context_today(self),)) query_results = self.env.cr.dictfetchall() if query_results and query_results[0].get('sum') != None: account_sum = query_results[0].get('sum') diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py index 7646343f7a4..dfc2b605790 100644 --- a/addons/account/models/account_payment.py +++ b/addons/account/models/account_payment.py @@ -236,10 +236,14 @@ class account_abstract_payment(models.AbstractModel): currency = self.currency_id or self.journal_id.currency_id or self.journal_id.company_id.currency_id or invoices and invoices[0].currency_id # Avoid currency rounding issues by summing the amounts according to the company_currency_id before + invoice_datas = invoices.read_group( + [('id', 'in', invoices.ids)], + ['currency_id', 'type', 'residual_signed'], + ['currency_id', 'type'], lazy=False) total = 0.0 - groups = groupby(invoices, lambda i: i.currency_id) - for payment_currency, payment_invoices in groups: - amount_total = sum([MAP_INVOICE_TYPE_PAYMENT_SIGN[i.type] * i.residual_signed for i in payment_invoices]) + for invoice_data in invoice_datas: + amount_total = MAP_INVOICE_TYPE_PAYMENT_SIGN[invoice_data['type']] * invoice_data['residual_signed'] + payment_currency = self.env['res.currency'].browse(invoice_data['currency_id'][0]) if payment_currency == currency: total += amount_total else: diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py index b3e7dbf6cc3..83aa46b8e0d 100644 --- a/addons/account/models/account_reconcile_model.py +++ b/addons/account/models/account_reconcile_model.py @@ -574,7 +574,7 @@ class AccountReconcileModel(models.Model): if line_residual > total_residual: amount_percentage = (total_residual / line_residual) * 100 else: - amount_percentage = (line_residual / total_residual) * 100 + amount_percentage = (line_residual / total_residual) * 100 if total_residual else 0 return amount_percentage >= self.match_total_amount_param @api.multi diff --git a/addons/account/models/reconciliation_widget.py b/addons/account/models/reconciliation_widget.py index 8369d69e9b3..875a346dabd 100644 --- a/addons/account/models/reconciliation_widget.py +++ b/addons/account/models/reconciliation_widget.py @@ -143,11 +143,12 @@ class AccountReconciliation(models.AbstractModel): else: aml_ids = matching_amls[line.id]['aml_ids'] bank_statements_left += line.statement_id + target_currency = line.currency_id or line.journal_id.currency_id or line.journal_id.company_id.currency_id amls = aml_ids and self.env['account.move.line'].browse(aml_ids) line_vals = { 'st_line': self._get_statement_line(line), - 'reconciliation_proposition': aml_ids and self._prepare_move_lines(amls) or [], + 'reconciliation_proposition': aml_ids and self._prepare_move_lines(amls, target_currency=target_currency, target_date=line.date) or [], 'model_id': matching_amls[line.id].get('model') and matching_amls[line.id]['model'].id, 'write_off': matching_amls[line.id].get('status') == 'write_off', } @@ -486,21 +487,12 @@ class AccountReconciliation(models.AbstractModel): ('payment_id', '<>', False) ] - # Black lines = unreconciled & (not linked to a payment or open balance created by statement - domain_matching = [('reconciled', '=', False)] - if partner_id: - domain_matching = expression.AND([ - domain_matching, - [('account_id.internal_type', 'in', ['payable', 'receivable'])] - ]) - else: - # TODO : find out what use case this permits (match a check payment, registered on a journal whose account type is other instead of liquidity) - domain_matching = expression.AND([ - domain_matching, - [('account_id.reconcile', '=', True)] - ]) + # default domain matching + domain_matching = expression.AND([ + [('reconciled', '=', False)], + [('account_id.reconcile', '=', True)] + ]) - # Let's add what applies to both domain = expression.OR([domain_reconciliation, domain_matching]) if partner_id: domain = expression.AND([domain, [('partner_id', '=', partner_id)]]) diff --git a/addons/account/tests/test_reconciliation_widget.py b/addons/account/tests/test_reconciliation_widget.py index 7b5f21ee325..a24cec75ca5 100644 --- a/addons/account/tests/test_reconciliation_widget.py +++ b/addons/account/tests/test_reconciliation_widget.py @@ -2,6 +2,7 @@ import logging import odoo.tests import time import requests +from odoo.addons.account.tests.test_reconciliation import TestReconciliation _logger = logging.getLogger(__name__) @@ -27,3 +28,29 @@ class TestUi(odoo.tests.HttpCase): self.phantom_js(prep.url.replace('http://localhost','').replace('?','#'), "odoo.__DEBUG__.services['web_tour.tour'].run('bank_statement_reconciliation')", "odoo.__DEBUG__.services['web_tour.tour'].tours.bank_statement_reconciliation.ready", login="admin") + + +@odoo.tests.tagged('post_install', '-at_install') +class TestReconciliationWidget(TestReconciliation): + + def test_statement_suggestion_other_currency(self): + # company currency is EUR + # payment in USD + invoice = self.create_invoice(invoice_amount=50, currency_id=self.currency_usd_id) + + # journal currency in USD + bank_stmt = self.acc_bank_stmt_model.create({ + 'journal_id': self.bank_journal_usd.id, + 'date': time.strftime('%Y-07-15'), + 'name': 'payment %s' % invoice.number, + }) + + bank_stmt_line = self.acc_bank_stmt_line_model.create({'name': 'payment', + 'statement_id': bank_stmt.id, + 'partner_id': self.partner_agrolait_id, + 'amount': 50, + 'date': time.strftime('%Y-07-15'), + }) + + result = self.env['account.reconciliation.widget'].get_bank_statement_line_data(bank_stmt_line.ids) + self.assertEqual(result['lines'][0]['reconciliation_proposition'][0]['amount_str'], '$ 50.00') \ No newline at end of file diff --git a/addons/account/views/account_move_views.xml b/addons/account/views/account_move_views.xml index 6f59fe7320d..251fa4a8da5 100644 --- a/addons/account/views/account_move_views.xml +++ b/addons/account/views/account_move_views.xml @@ -276,7 +276,7 @@
- +
@@ -549,4 +549,4 @@ sequence="1"/> - \ No newline at end of file + diff --git a/addons/account/views/account_payment_view.xml b/addons/account/views/account_payment_view.xml index 135c735eecc..7dbbd1aa023 100644 --- a/addons/account/views/account_payment_view.xml +++ b/addons/account/views/account_payment_view.xml @@ -71,7 +71,7 @@
- +
diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml index 75140895390..bd55957c7c1 100644 --- a/addons/account/views/report_invoice.xml +++ b/addons/account/views/report_invoice.xml @@ -84,7 +84,7 @@ - + diff --git a/addons/analytic/models/analytic_account.py b/addons/analytic/models/analytic_account.py index 187d53d1ad7..91815380304 100644 --- a/addons/analytic/models/analytic_account.py +++ b/addons/analytic/models/analytic_account.py @@ -160,7 +160,10 @@ class AccountAnalyticAccount(models.Model): if operator == 'ilike' and not (name or '').strip(): domain = [] else: - domain = ['|', '|', ('code', operator, name), ('name', operator, name), ('partner_id.name', operator, name)] + # `partner_id` is in auto_join and the searches using ORs with auto_join fields doesn't work + # we have to cut the search in two searches ... https://github.com/odoo/odoo/issues/25175 + partner_ids = self.env['res.partner']._search([('name', operator, name)], limit=limit, access_rights_uid=name_get_uid) + domain = ['|', '|', ('code', operator, name), ('name', operator, name), ('partner_id', 'in', partner_ids)] analytic_account_ids = self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid) return self.browse(analytic_account_ids).name_get() diff --git a/addons/auth_signup/models/res_partner.py b/addons/auth_signup/models/res_partner.py index 85d6d732055..db66467d7dd 100644 --- a/addons/auth_signup/models/res_partner.py +++ b/addons/auth_signup/models/res_partner.py @@ -27,16 +27,16 @@ class ResPartner(models.Model): signup_token = fields.Char(copy=False, groups="base.group_erp_manager") signup_type = fields.Char(string='Signup Token Type', copy=False, groups="base.group_erp_manager") signup_expiration = fields.Datetime(copy=False, groups="base.group_erp_manager") - signup_valid = fields.Boolean(compute='_compute_signup_valid', compute_sudo=True, string='Signup Token is Valid') + signup_valid = fields.Boolean(compute='_compute_signup_valid', string='Signup Token is Valid') signup_url = fields.Char(compute='_compute_signup_url', string='Signup URL') @api.multi @api.depends('signup_token', 'signup_expiration') def _compute_signup_valid(self): dt = now() - for partner in self: - partner.signup_valid = bool(partner.signup_token) and \ - (not partner.signup_expiration or dt <= partner.signup_expiration) + for partner, partner_sudo in zip(self, self.sudo()): + partner.signup_valid = bool(partner_sudo.signup_token) and \ + (not partner_sudo.signup_expiration or dt <= partner_sudo.signup_expiration) @api.multi def _compute_signup_url(self): diff --git a/addons/base_automation/data/base_automation_demo.xml b/addons/base_automation/data/base_automation_demo.xml index 3e864e34565..7ddc3a74581 100644 --- a/addons/base_automation/data/base_automation_demo.xml +++ b/addons/base_automation/data/base_automation_demo.xml @@ -84,4 +84,19 @@ record['name'] = record.name + 'X' + + Template Automation + + <div>Email automation</div> + + + Base Automation: test send an email + + + email + on_write + + [('deadline', '!=', False)] + [('deadline', '=', False)] + diff --git a/addons/base_automation/models/base_automation.py b/addons/base_automation/models/base_automation.py index ab460f1e875..e2620d202e7 100644 --- a/addons/base_automation/models/base_automation.py +++ b/addons/base_automation/models/base_automation.py @@ -164,14 +164,17 @@ class BaseAutomation(models.Model): return records def _filter_post(self, records): + return self._filter_post_export_domain(records)[0] + + def _filter_post_export_domain(self, records): """ Filter the records that satisfy the postcondition of action ``self``. """ if self.filter_domain and records: domain = [('id', 'in', records.ids)] + safe_eval(self.filter_domain, self._get_eval_context()) - return records.search(domain) + return records.search(domain), domain else: - return records + return records, None - def _process(self, records): + def _process(self, records, domain_post=None): """ Process action ``self`` on the ``records`` that have not been done yet. """ # filter out the records on which self has already been done action_done = self._context['__action_done'] @@ -198,7 +201,12 @@ class BaseAutomation(models.Model): for record in records: # we process the action if any watched field has been modified if self._check_trigger_fields(record): - ctx = {'active_model': record._name, 'active_ids': record.ids, 'active_id': record.id} + ctx = { + 'active_model': record._name, + 'active_ids': record.ids, + 'active_id': record.id, + 'domain_post': domain_post, + } self.action_server_id.with_context(**ctx).run() def _check_trigger_fields(self, record): @@ -274,7 +282,8 @@ class BaseAutomation(models.Model): _write.origin(records, vals, **kw) # check postconditions, and execute actions on the records that satisfy them for action in actions.with_context(old_values=old_values): - action._process(action._filter_post(pre[action])) + records, domain_post = action._filter_post_export_domain(pre[action]) + action._process(records, domain_post=domain_post) return True return _write diff --git a/addons/base_automation/tests/test_base_automation.py b/addons/base_automation/tests/test_base_automation.py index 6b34c65c6a7..97fcb2d1827 100644 --- a/addons/base_automation/tests/test_base_automation.py +++ b/addons/base_automation/tests/test_base_automation.py @@ -1,5 +1,6 @@ # # -*- coding: utf-8 -*- # # Part of Odoo. See LICENSE file for full copyright and licensing details. +from unittest.mock import patch from odoo.tests import common @@ -9,13 +10,14 @@ class base_automation_test(common.TransactionCase): def setUp(self): super(base_automation_test, self).setUp() - self.user_admin = self.env.ref('base.user_root') + self.user_root = self.env.ref('base.user_root') + self.user_admin = self.env.ref('base.user_admin') self.user_demo = self.env.ref('base.user_demo') def create_lead(self, **kwargs): vals = { 'name': "Lead Test", - 'user_id': self.user_admin.id, + 'user_id': self.user_root.id, } vals.update(kwargs) return self.env['base.automation.lead.test'].create(vals) @@ -27,7 +29,7 @@ class base_automation_test(common.TransactionCase): """ lead = self.create_lead(state='open') self.assertEqual(lead.state, 'open') - self.assertEqual(lead.user_id, self.user_admin, "Responsible should not change on creation of Lead with state 'open'.") + self.assertEqual(lead.user_id, self.user_root, "Responsible should not change on creation of Lead with state 'open'.") def test_01_check_to_state_draft_post(self): """ @@ -49,15 +51,15 @@ class base_automation_test(common.TransactionCase): """ lead = self.create_lead(state='open') self.assertEqual(lead.state, 'open', "Lead state should be 'open'") - self.assertEqual(lead.user_id, self.user_admin, "Responsible should not change on creation of Lead with state 'open'.") + self.assertEqual(lead.user_id, self.user_root, "Responsible should not change on creation of Lead with state 'open'.") # change state to pending and check that responsible has not changed lead.write({'state': 'pending'}) self.assertEqual(lead.state, 'pending', "Lead state should be 'pending'") - self.assertEqual(lead.user_id, self.user_admin, "Responsible should not change on creation of Lead with state from 'draft' to 'open'.") + self.assertEqual(lead.user_id, self.user_root, "Responsible should not change on creation of Lead with state from 'draft' to 'open'.") # change state to done and check that responsible has not changed lead.write({'state': 'done'}) self.assertEqual(lead.state, 'done', "Lead state should be 'done'") - self.assertEqual(lead.user_id, self.user_admin, "Responsible should not chang on creation of Lead with state from 'pending' to 'done'.") + self.assertEqual(lead.user_id, self.user_root, "Responsible should not chang on creation of Lead with state from 'pending' to 'done'.") def test_03_check_from_draft_to_done_without_steps(self): """ @@ -70,7 +72,7 @@ class base_automation_test(common.TransactionCase): """ lead = self.create_lead(state='open') self.assertEqual(lead.state, 'open', "Lead state should be 'open'") - self.assertEqual(lead.user_id, self.user_admin, "Responsible should not change on creation of Lead with state 'open'.") + self.assertEqual(lead.user_id, self.user_root, "Responsible should not change on creation of Lead with state 'open'.") # change state to done and check that responsible has changed lead.write({'state': 'done'}) self.assertEqual(lead.state, 'done', "Lead state should be 'done'") @@ -85,7 +87,7 @@ class base_automation_test(common.TransactionCase): partner.write({'customer': False}) lead = self.create_lead(state='open', partner_id=partner.id) self.assertFalse(lead.customer, "Customer field should updated to False") - self.assertEqual(lead.user_id, self.user_admin, "Responsible should not change on creation of Lead with state from 'draft' to 'open'.") + self.assertEqual(lead.user_id, self.user_root, "Responsible should not change on creation of Lead with state from 'draft' to 'open'.") # change partner, recompute on lead should trigger the rule partner.write({'customer': True}) self.assertTrue(lead.customer, "Customer field should updated to True") @@ -101,15 +103,52 @@ class base_automation_test(common.TransactionCase): self.assertFalse(lead.deadline, 'There should not be a deadline defined') # change priority and user; this triggers deadline recomputation, and # the server action should set the boolean field to True - lead.write({'priority': True, 'user_id': self.user_admin.id}) + lead.write({'priority': True, 'user_id': self.user_root.id}) self.assertTrue(lead.deadline, 'Deadline should be defined') self.assertTrue(lead.is_assigned_to_admin, 'Lead should be assigned to admin') + def test_11b_recomputed_field(self): + mail_automation = self.env.ref('base_automation.test_rule_on_write_recompute_send_email') + send_mail_count = 0 + + def _patched_get_actions(*args, **kwargs): + obj = args[0] + if '__action_done' not in obj._context: + obj = obj.with_context(__action_done={}) + return mail_automation.with_env(obj.env) + + def _patched_send_mail(*args, **kwargs): + nonlocal send_mail_count + send_mail_count += 1 + + patchers = [ + patch('odoo.addons.base_automation.models.base_automation.BaseAutomation._get_actions', _patched_get_actions), + patch('odoo.addons.mail.models.mail_template.MailTemplate.send_mail', _patched_send_mail), + ] + + patchers[0].start() + + lead = self.create_lead() + self.assertFalse(lead.priority) + self.assertFalse(lead.deadline) + + patchers[1].start() + + lead.write({'priority': True}) + + self.assertTrue(lead.priority) + self.assertTrue(lead.deadline) + + for patcher in patchers: + patcher.stop() + + self.assertEqual(send_mail_count, 1) + def test_12_recursive(self): """ Check that a rule is executed recursively by a secondary change. """ lead = self.create_lead(state='open') self.assertEqual(lead.state, 'open') - self.assertEqual(lead.user_id, self.user_admin) + self.assertEqual(lead.user_id, self.user_root) # change partner; this should trigger the rule that modifies the state partner = self.env.ref('base.res_partner_1') lead.write({'partner_id': partner.id}) diff --git a/addons/base_import/static/csv/o2m_customers_contacts.csv b/addons/base_import/static/csv/o2m_customers_contacts.csv index bf142142d3c..d29a600f18b 100644 --- a/addons/base_import/static/csv/o2m_customers_contacts.csv +++ b/addons/base_import/static/csv/o2m_customers_contacts.csv @@ -1,9 +1,9 @@ Name,Is a company,Related company,Address type,Customer,Supplier,Street,ZIP,City,State,Country -Aurora Shelves,1,,,1,0,25 Pacific Road,95101,San José,CA,United States -Roger Martins,0,Aurora Shelves,Invoice address,1,0,27 Pacific Road,95102,San José,CA,United States -House Sales Direct,1,,,1,0,104 Saint Mary Avenue,94059,Redwood,CA,United States -Yvan Holiday,0,House Sales Direct,Contact,1,0,104 Saint Mary Avenue,94060,Redwood,CA,United States -Jack Unsworth,0,House Sales Direct,Invoice address,1,0,227 Jackson Road,94061,Redwood,CA,United States -Michael Mason,0,,,1,0,16 5th Avenue,94104,San Francisco,CA,United States -International Wood,1,,,1,0,748 White House Boulevard,20004,Washington,DC,United States -Sharon Pecker,0,International Wood,Invoice address,1,0,755 White House Boulevard,20005,Washington,DC,United States +Aurora Shelves,1,,,1,0,25 Pacific Road,95101,San José,California,United States +Roger Martins,0,Aurora Shelves,Invoice address,1,0,27 Pacific Road,95102,San José,California,United States +House Sales Direct,1,,,1,0,104 Saint Mary Avenue,94059,Redwood,California,United States +Yvan Holiday,0,House Sales Direct,Contact,1,0,104 Saint Mary Avenue,94060,Redwood,California,United States +Jack Unsworth,0,House Sales Direct,Invoice address,1,0,227 Jackson Road,94061,Redwood,California,United States +Michael Mason,0,,,1,0,16 5th Avenue,94104,San Francisco,California,United States +International Wood,1,,,1,0,748 White House Boulevard,20004,Washington,D.C.,United States +Sharon Pecker,0,International Wood,Invoice address,1,0,755 White House Boulevard,20005,Washington,D.C.,United States diff --git a/addons/crm/models/crm_team.py b/addons/crm/models/crm_team.py index 30d7cc945ea..a101fb26848 100644 --- a/addons/crm/models/crm_team.py +++ b/addons/crm/models/crm_team.py @@ -31,7 +31,10 @@ class Team(models.Model): compute='_compute_overdue_opportunities', string='Overdue Opportunities Revenues') - alias_user_id = fields.Many2one(domain=lambda self: [ + # Since we are in a _inherits case, this is not an override + # but a plain definition of a field + # So we need to reset the property related of that field + alias_user_id = fields.Many2one('res.users', related='alias_id.alias_user_id', inherited=True, domain=lambda self: [ ('groups_id', 'in', self.env.ref('sales_team.group_sale_salesman_all_leads').id)]) def _compute_unassigned_leads_count(self): diff --git a/addons/event_sale/models/sale_order.py b/addons/event_sale/models/sale_order.py index 1b15093de03..fac1730bead 100644 --- a/addons/event_sale/models/sale_order.py +++ b/addons/event_sale/models/sale_order.py @@ -73,6 +73,11 @@ class SaleOrderLine(models.Model): if self.event_ticket_id and (not self.event_id or self.event_id != self.event_ticket_id.event_id): self.event_ticket_id = None + @api.onchange('product_uom', 'product_uom_qty') + def product_uom_change(self): + if not self.event_ticket_id: + super(SaleOrderLine, self).product_uom_change() + @api.onchange('event_ticket_id') def _onchange_event_ticket_id(self): company = self.event_id.company_id or self.env.user.company_id diff --git a/addons/gamification/data/gamification_karma_rank_data.xml b/addons/gamification/data/gamification_karma_rank_data.xml index 2a5ad0231fe..3833dd24b7e 100644 --- a/addons/gamification/data/gamification_karma_rank_data.xml +++ b/addons/gamification/data/gamification_karma_rank_data.xml @@ -1,20 +1,75 @@ - - - - - 2500 - - - 2500 - + + + + 2500 + + + 2500 + - - - Newbie -

You just began the adventure! Welcome!

- 1 - -
-
-
\ No newline at end of file + + + Newbie +

You just began the adventure! Welcome!

+ +
+
Reach the next rank to show the rest of the world you exist!
+ +
+
+ 1 + +
+ + + Student +

You're a young padawan now. May the force be with you!

+ +
+
Reach the next rank to improve your status.
+ +
+
+ 100 + +
+ + + Bachelor +

You love learning things. Curiosity is a good way to progress.

+ +
+
Reach the next rank and become a Master!
+ +
+
+ 500 + +
+ + + Master +

You know what you are talking about. People learn from you.

+ +
+
Reach the next rank and become a powerful user!
+ +
+
+ 2000 + +
+ + + Doctor +

You have reached the last rank. Congratulations!

+ +
+
You have reached the last rank. Congratulations!
+
+
+ 10000 + +
+
diff --git a/addons/gamification/data/gamification_karma_rank_demo.xml b/addons/gamification/data/gamification_karma_rank_demo.xml index 26c639a8cc9..c2d81ebbcc7 100644 --- a/addons/gamification/data/gamification_karma_rank_demo.xml +++ b/addons/gamification/data/gamification_karma_rank_demo.xml @@ -10,51 +10,39 @@ - Student -

You begin to understand things ! Keep going!

-
-
Reach the next rank and gain a very nice mug !
- -
- 100 - +
+
Reach the next rank and gain a very nice mug !
+ +
+
- Bachelor -

Hey ! You're not so dumb after all !

-
-
Reach the next rank and gain a very magic wand !
- -
- 500 - +
+
Reach the next rank and gain a very magic wand !
+ +
+
- Master -

You're good ! Really Good !

-
-
Reach the next rank and gain a very nice hat !
- -
- 2000 - +
+
Reach the next rank and gain a very nice hat !
+ +
+
- Doctor -

Ok, RESPECT !

-
-
Reach the next rank and gain a week-end with a unicorn !
- -
- 10000 - +
+
Reach the next rank and gain a week-end with a unicorn !
+ +
+
diff --git a/addons/gamification/models/badge.py b/addons/gamification/models/badge.py index 849f1744f46..f092a6dd522 100644 --- a/addons/gamification/models/badge.py +++ b/addons/gamification/models/badge.py @@ -259,7 +259,7 @@ class GamificationBadge(models.Model): elif self.rule_auth == 'users' and self.env.user not in self.rule_auth_user_ids: return self.USER_NOT_VIP elif self.rule_auth == 'having': - all_user_badges = self.env['gamification.badge.user'].search([('user_id', '=', self.env.uid)]) + all_user_badges = self.env['gamification.badge.user'].search([('user_id', '=', self.env.uid)]).mapped('badge_id') if self.rule_auth_badge_ids - all_user_badges: return self.BADGE_REQUIRED diff --git a/addons/gamification/models/res_users.py b/addons/gamification/models/res_users.py index 8f59f6c7591..f556dcc514a 100644 --- a/addons/gamification/models/res_users.py +++ b/addons/gamification/models/res_users.py @@ -47,9 +47,10 @@ class Users(models.Model): @api.multi def write(self, vals): + result = super(Users, self).write(vals) if 'karma' in vals: self._recompute_rank() - return super(Users, self).write(vals) + return result @api.multi def add_karma(self, karma): @@ -72,13 +73,16 @@ class Users(models.Model): self.env['gamification.karma.rank'].search([], order="karma_min DESC")] for user in self: old_rank = user.rank_id - for i in range(0, len(ranks)): - if user.karma >= ranks[i]['karma_min']: - user.write({ - 'rank_id': ranks[i]['rank'].id, - 'next_rank_id': ranks[i - 1]['rank'].id if i > 0 else False - }) - break + if user.karma == 0 and ranks: + user.write({'next_rank_id': ranks[-1]['rank'].id}) + else: + for i in range(0, len(ranks)): + if user.karma >= ranks[i]['karma_min']: + user.write({ + 'rank_id': ranks[i]['rank'].id, + 'next_rank_id': ranks[i - 1]['rank'].id if 0 < i else False + }) + break if old_rank != user.rank_id: user._rank_changed() diff --git a/addons/gamification/static/img/rank_misc_world.png b/addons/gamification/static/img/rank_misc_world.png new file mode 100644 index 00000000000..087b7e7bd1d Binary files /dev/null and b/addons/gamification/static/img/rank_misc_world.png differ diff --git a/addons/hr/models/hr.py b/addons/hr/models/hr.py index 209235ff42b..7ce2db69071 100644 --- a/addons/hr/models/hr.py +++ b/addons/hr/models/hr.py @@ -360,13 +360,13 @@ class Employee(models.Model): self = self.sudo(real_user) return self - def _message_log(self, body='', subject=False, message_type='notification', **kwargs): - return super(Employee, self._post_author()).message_post(body=body, subject=subject, message_type=message_type, **kwargs) + def _message_log(self, *args, **kwargs): + return super(Employee, self._post_author())._message_log(*args, **kwargs) @api.multi @api.returns('mail.message', lambda value: value.id) - def message_post(self, **kwargs): - return super(Employee, self._post_author()).message_post(**kwargs) + def message_post(self, *args, **kwargs): + return super(Employee, self._post_author()).message_post(*args, **kwargs) class Department(models.Model): diff --git a/addons/hr_fleet/controllers/i18n/az.po b/addons/hr_fleet/controllers/i18n/az.po deleted file mode 100644 index 23fa2458e4d..00000000000 --- a/addons/hr_fleet/controllers/i18n/az.po +++ /dev/null @@ -1,115 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * crm_project -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~11.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 13:17+0000\n" -"PO-Revision-Date: 2018-08-24 09:17+0000\n" -"Language-Team: Azerbaijani (https://www.transifex.com/odoo/teams/41243/az/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: az\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: crm_project -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_view_form -msgid "" -"Convert To\n" -" Task" -msgstr "" - -#. module: crm_project -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_convert2task_view_form -msgid "Cancel" -msgstr "" - -#. module: crm_project -#: model:ir.actions.act_window,name:crm_project.crm_lead_convert2task_action -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_convert2task_view_form -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_view_form -msgid "Convert to Task" -msgstr "" - -#. module: crm_project -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_convert2task_view_form -msgid "Create Task" -msgstr "" - -#. module: crm_project -#: selection:crm.lead.convert2task,action:0 -msgid "Create a new customer" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__create_uid -msgid "Created by" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__create_date -msgid "Created on" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__partner_id -msgid "Customer" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__display_name -msgid "Display Name" -msgstr "" - -#. module: crm_project -#: selection:crm.lead.convert2task,action:0 -msgid "Do not link to a customer" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__id -msgid "ID" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task____last_update -msgid "Last Modified on" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__write_date -msgid "Last Updated on" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__lead_id -msgid "Lead" -msgstr "" - -#. module: crm_project -#: model:ir.model,name:crm_project.model_crm_lead_convert2task -msgid "Lead convert to Task" -msgstr "" - -#. module: crm_project -#: selection:crm.lead.convert2task,action:0 -msgid "Link to an existing customer" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__project_id -msgid "Project" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__action -msgid "Related Customer" -msgstr "" diff --git a/addons/hr_fleet/controllers/i18n/fil.po b/addons/hr_fleet/controllers/i18n/fil.po deleted file mode 100644 index f3c56bf488c..00000000000 --- a/addons/hr_fleet/controllers/i18n/fil.po +++ /dev/null @@ -1,115 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * crm_project -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~11.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-21 13:17+0000\n" -"PO-Revision-Date: 2018-08-24 09:17+0000\n" -"Language-Team: Filipino (https://www.transifex.com/odoo/teams/41243/fil/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: fil\n" -"Plural-Forms: nplurals=2; plural=(n == 1 || n==2 || n==3) || (n % 10 != 4 || n % 10 != 6 || n % 10 != 9);\n" - -#. module: crm_project -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_view_form -msgid "" -"Convert To\n" -" Task" -msgstr "" - -#. module: crm_project -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_convert2task_view_form -msgid "Cancel" -msgstr "" - -#. module: crm_project -#: model:ir.actions.act_window,name:crm_project.crm_lead_convert2task_action -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_convert2task_view_form -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_view_form -msgid "Convert to Task" -msgstr "" - -#. module: crm_project -#: model_terms:ir.ui.view,arch_db:crm_project.crm_lead_convert2task_view_form -msgid "Create Task" -msgstr "" - -#. module: crm_project -#: selection:crm.lead.convert2task,action:0 -msgid "Create a new customer" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__create_uid -msgid "Created by" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__create_date -msgid "Created on" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__partner_id -msgid "Customer" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__display_name -msgid "Display Name" -msgstr "" - -#. module: crm_project -#: selection:crm.lead.convert2task,action:0 -msgid "Do not link to a customer" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__id -msgid "ID" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task____last_update -msgid "Last Modified on" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__write_date -msgid "Last Updated on" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__lead_id -msgid "Lead" -msgstr "" - -#. module: crm_project -#: model:ir.model,name:crm_project.model_crm_lead_convert2task -msgid "Lead convert to Task" -msgstr "" - -#. module: crm_project -#: selection:crm.lead.convert2task,action:0 -msgid "Link to an existing customer" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__project_id -msgid "Project" -msgstr "" - -#. module: crm_project -#: model:ir.model.fields,field_description:crm_project.field_crm_lead_convert2task__action -msgid "Related Customer" -msgstr "" diff --git a/addons/hr_gamification/wizard/gamification_badge_user_wizard.py b/addons/hr_gamification/wizard/gamification_badge_user_wizard.py index 4e486a0e048..7c4c174129f 100644 --- a/addons/hr_gamification/wizard/gamification_badge_user_wizard.py +++ b/addons/hr_gamification/wizard/gamification_badge_user_wizard.py @@ -10,7 +10,7 @@ class GamificationBadgeUserWizard(models.TransientModel): employee_id = fields.Many2one('hr.employee', string='Employee', required=True) user_id = fields.Many2one('res.users', string='User', related='employee_id.user_id', - store=False, readonly=True) + store=False, readonly=True, compute_sudo=True) @api.multi def action_grant_badge(self): diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index 459bd63b3df..200d7937d1c 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -111,13 +111,12 @@ class HolidaysRequest(models.Model): "\nThe status is 'Approved', when time off request is approved by manager.") payslip_status = fields.Boolean('Reported in last payslips', help='Green this button when the time off has been taken into account in the payslip.') report_note = fields.Text('HR Comments') - user_id = fields.Many2one('res.users', string='User', related='employee_id.user_id', related_sudo=True, store=True, default=lambda self: self.env.uid, readonly=True) + user_id = fields.Many2one('res.users', string='User', related='employee_id.user_id', related_sudo=True, compute_sudo=True, store=True, default=lambda self: self.env.uid, readonly=True) # leave type configuration holiday_status_id = fields.Many2one( "hr.leave.type", string="Time Off Type", required=True, readonly=True, states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, domain=[('valid', '=', True)]) - leave_type_request_unit = fields.Selection(related='holiday_status_id.request_unit', readonly=True) validation_type = fields.Selection('Validation Type', related='holiday_status_id.validation_type', readonly=False) # HR data employee_id = fields.Many2one( diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py index 8ac1d7d10bd..da978c4ae60 100644 --- a/addons/hr_holidays/models/hr_leave_allocation.py +++ b/addons/hr_holidays/models/hr_leave_allocation.py @@ -252,7 +252,7 @@ class HolidaysAllocation(models.Model): if self.env.user.employee_ids: self.department_id = self.department_id or self.env.user.employee_ids[0].department_id self.employee_id = None - elif self.holiday_type == 'category': + else: self.employee_id = None self.department_id = None diff --git a/addons/hr_holidays/report/hr_leave_reports.xml b/addons/hr_holidays/report/hr_leave_reports.xml index 90e1affc20c..f7da796a104 100644 --- a/addons/hr_holidays/report/hr_leave_reports.xml +++ b/addons/hr_holidays/report/hr_leave_reports.xml @@ -77,7 +77,7 @@
- +
diff --git a/addons/hr_holidays/security/hr_holidays_security.xml b/addons/hr_holidays/security/hr_holidays_security.xml index 1d534a94648..8bc6852d3fe 100644 --- a/addons/hr_holidays/security/hr_holidays_security.xml +++ b/addons/hr_holidays/security/hr_holidays_security.xml @@ -8,6 +8,7 @@ Team Approver + @@ -48,7 +49,7 @@ Time Off: approver: write on employee's time off in his team - [('employee_id.leave_manager_id', '=' , user.id), ('holiday_type', '=', 'employee')] + ['&', ('holiday_type', '=', 'employee'), '|', ('employee_id.leave_manager_id', '=' , user.id), ('employee_id.parent_id.user_id', '=' , user.id)] @@ -123,6 +124,16 @@ + + Allocations: Team Leader: read employee's allocations in his team + + ['|', ('employee_id.leave_manager_id', '=' , user.id), ('employee_id.parent_id.user_id', '=' , user.id)] + + + + + + Time Off Resources: Approver diff --git a/addons/hr_holidays/tests/common.py b/addons/hr_holidays/tests/common.py index 0f9c6f1cc89..510c6883b41 100644 --- a/addons/hr_holidays/tests/common.py +++ b/addons/hr_holidays/tests/common.py @@ -23,6 +23,9 @@ class TestHrHolidaysBase(common.TransactionCase): self.user_hrmanager_2 = mail_new_test_user(self.env, login='florence', groups='base.group_user,hr_holidays.group_hr_holidays_manager') self.user_hrmanager_2_id = self.user_hrmanager_2.id + self.user_team_leader = mail_new_test_user(self.env, login='arthur', groups='base.group_user,hr_holidays.group_hr_holidays_team_leader') + self.user_team_leader_id = self.user_team_leader.id + # Hr Data Department = self.env['hr.department'].with_context(tracking_disable=True) diff --git a/addons/hr_holidays/tests/test_access_rights.py b/addons/hr_holidays/tests/test_access_rights.py index ca651a69010..00ac2856d20 100644 --- a/addons/hr_holidays/tests/test_access_rights.py +++ b/addons/hr_holidays/tests/test_access_rights.py @@ -362,6 +362,37 @@ class TestLeavesRights(TestHrHolidaysBase): self.employee_leave.sudo(self.user_hruser).action_approve() self.employee_leave.sudo(self.user_hrmanager_id).action_validate() + # ---------------------------------------- + # Validation: team leader + # ---------------------------------------- + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_leave_validation_team_leader_other(self): + """ Team Leader validates its employee's leave only""" + self.leave_type.write({'allocation_type': 'fixed'}) + self.env['hr.leave.allocation'].create({ + 'holiday_status_id': self.leave_type.id, + 'employee_id': self.employee_emp.id, + 'number_of_days': 10, + }).action_approve() + with self.assertRaises(AccessError): + self.employee_leave.sudo(self.user_team_leader).action_approve() + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_leave_validation_team_leader(self): + """ Team Leader validates its employee's leave""" + self.leave_type.write({'allocation_type': 'fixed'}) + + # set the team leader + self.employee_emp.leave_manager_id = self.user_team_leader + + self.env['hr.leave.allocation'].create({ + 'holiday_status_id': self.leave_type.id, + 'employee_id': self.employee_emp.id, + 'number_of_days': 10, + }).action_approve() + self.employee_leave.sudo(self.user_team_leader).action_approve() + class TestMultiCompany(TestHrHolidaysBase): diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py index 67d468b0a44..ea025d571cd 100644 --- a/addons/hr_holidays/tests/test_leave_requests.py +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -138,7 +138,7 @@ class TestLeaveRequests(TestHrHolidaysBase): 'number_of_days': 1, }) - @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail', 'odoo.models') def test_accrual_validity_time_not_valid(self): """ Employee ask leav during a not valid validity time """ with self.assertRaises(ValidationError): diff --git a/addons/hr_payroll/models/hr_benefit.py b/addons/hr_payroll/models/hr_benefit.py index 6c3367fd3aa..f75e115108d 100644 --- a/addons/hr_payroll/models/hr_benefit.py +++ b/addons/hr_payroll/models/hr_benefit.py @@ -275,9 +275,9 @@ class HrBenefit(models.Model): }] self.env['resource.calendar.attendance'].create(vals_list) - @api.model - def action_validate(self, ids): - benefits = self.env['hr.benefit'].search([('id', 'in', ids), ('state', '!=', 'validated')]) + @api.multi + def action_validate(self): + benefits = self.filtered(lambda benefit: benefit.state != 'validated') benefits.write({'display_warning': False}) if not benefits._check_if_error(): benefits.write({'state': 'validated'}) @@ -311,4 +311,4 @@ class Contacts(models.Model): _sql_constraints = [ ('user_id_employee_id_unique', 'UNIQUE(user_id,employee_id)', 'You cannot have twice the same employee.') - ] \ No newline at end of file + ] diff --git a/addons/hr_payroll/tests/test_benefit.py b/addons/hr_payroll/tests/test_benefit.py index 083a9c287ac..3100ff6db43 100644 --- a/addons/hr_payroll/tests/test_benefit.py +++ b/addons/hr_payroll/tests/test_benefit.py @@ -1,10 +1,8 @@ # # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from datetime import datetime import pytz from dateutil.relativedelta import relativedelta -from odoo import exceptions from odoo.fields import Datetime, Date from odoo.tests.common import tagged from odoo.addons.hr_payroll.tests.common import TestPayslipBase @@ -130,7 +128,7 @@ class TestBenefit(TestPayslipBase): 'date_stop': end, 'benefit_type_id': self.benefit_type.id, }) - benefit.action_validate(benefit.ids) + benefit.action_validate() benefits = self.env['hr.benefit'].search([('employee_id', '=', self.richard_emp.id)]) self.assertTrue(all((b.state == 'validated' for b in benefits)), "Benefits should be approved") self.assertEqual(len(benefits), 3, "Benefit should be split in three") @@ -204,7 +202,7 @@ class TestBenefit(TestPayslipBase): 'date_start': start, 'date_stop': end, }) - benef.action_validate(benef.ids) + benef.action_validate() calendar_leave = self.env['resource.calendar.leaves'].search([('name', '=', 'Richard leave from benef')]) self.assertTrue(calendar_leave, "It should have created a leave in the calendar") self.assertEqual(calendar_leave.benefit_type_id, benef.benefit_type_id, "It should have the same benefit type") @@ -220,7 +218,7 @@ class TestBenefit(TestPayslipBase): 'date_start': start, 'date_stop': end + relativedelta(hours=5), }) - benef2 = self.env['hr.benefit'].create({ + self.env['hr.benefit'].create({ 'name': '2', 'employee_id': self.richard_emp.id, 'benefit_type_id': self.env.ref('hr_payroll.benefit_type_attendance').id, @@ -228,7 +226,7 @@ class TestBenefit(TestPayslipBase): 'date_start': start + relativedelta(hours=3), 'date_stop': end, }) - self.assertFalse(benef1.action_validate(benef1.ids), "It should not validate benefits conflicting with others") + self.assertFalse(benef1.action_validate(), "It should not validate benefits conflicting with others") self.assertTrue(benef1.display_warning) self.assertNotEqual(benef1.state, 'validated') @@ -241,7 +239,7 @@ class TestBenefit(TestPayslipBase): 'date_start': self.start, 'date_stop': self.end, }) - leave_1 = self.env['hr.leave'].create({ + self.env['hr.leave'].create({ 'name': 'Doctor Appointment', 'employee_id': self.richard_emp.id, 'holiday_status_id': self.leave_type.id, @@ -249,7 +247,7 @@ class TestBenefit(TestPayslipBase): 'date_to': self.start + relativedelta(days=1), 'number_of_days': 2, }) - self.assertFalse(benef1.action_validate(benef1.ids),"It should not validate benefits conflicting with non approved leaves") + self.assertFalse(benef1.action_validate(), "It should not validate benefits conflicting with non approved leaves") self.assertTrue(benef1.display_warning) def test_validate_undefined_benefit(self): @@ -260,7 +258,7 @@ class TestBenefit(TestPayslipBase): 'date_start': self.start, 'date_stop': self.end, }) - self.assertFalse(benef1.action_validate(benef1.ids),"It should not validate benefits without a type") + self.assertFalse(benef1.action_validate(), "It should not validate benefits without a type") def test_approve_leave_benefit(self): start = self.to_datetime_tz('2015-11-01 09:00:00') @@ -273,7 +271,7 @@ class TestBenefit(TestPayslipBase): 'date_to': start + relativedelta(days=1), 'number_of_days': 2, }) - benef = self.env['hr.benefit'].create({ + self.env['hr.benefit'].create({ 'name': '1', 'employee_id': self.richard_emp.id, 'contract_id': self.richard_emp.contract_id.id, @@ -299,7 +297,7 @@ class TestBenefit(TestPayslipBase): self.assertTrue(new_benef, "It should have created a benefit for the last two days") self.assertTrue(new_leave_benef, "It should have created a leave benefit for the first day") - self.assertTrue(benef.action_validate((new_benef | new_leave_benef).ids), "It should be able to validate the benefits") + self.assertTrue((new_benef | new_leave_benef).action_validate(), "It should be able to validate the benefits") def test_refuse_leave_benefit(self): start = self.to_datetime_tz('2015-11-01 09:00:00') @@ -321,7 +319,7 @@ class TestBenefit(TestPayslipBase): 'date_stop': end, 'leave_id': leave.id }) - benef.action_validate(benef.ids) + benef.action_validate() self.assertTrue(benef.display_warning, "It should have an error (conflicting leave to approve") leave.action_refuse() self.assertFalse(benef.display_warning, "It should not have an error") @@ -342,7 +340,7 @@ class TestBenefit(TestPayslipBase): 'date_start': start, 'date_stop': end, }) - benef.action_validate(benef.ids) + benef.action_validate() data = self.richard_emp._get_benefit_days_data(self.benefit_type, self.start, self.end) self.assertEqual(data['hours'], 7.0) @@ -358,7 +356,7 @@ class TestBenefit(TestPayslipBase): 'date_start': start, 'date_stop': end, }) - leave_benef.action_validate(leave_benef.ids) + leave_benef.action_validate() data = self.richard_emp._get_benefit_days_data(self.benefit_type_leave, self.start, self.end) self.assertEqual(data['hours'], 5.0, "It should equal the number of hours richard should have worked") @@ -374,7 +372,7 @@ class TestBenefit(TestPayslipBase): 'date_start': start, 'date_stop': end, }) - leave_benef.action_validate(leave_benef.ids) + leave_benef.action_validate() data = self.richard_emp._get_benefit_days_data(self.benefit_type_leave, self.start, self.end) self.assertEqual(data['hours'], 0.0, "It should equal the number of hours richard should have worked") @@ -390,7 +388,7 @@ class TestBenefit(TestPayslipBase): 'date_start': start, 'date_stop': end, }) - leave_benef.action_validate(leave_benef.ids) + leave_benef.action_validate() payslip_wizard = self.env['hr.payslip.employees'].create({'employee_ids': [(4, self.richard_emp.id)]}) payslip_wizard.with_context({'default_date_start': Date.to_string(start), 'default_date_end': Date.to_string(end)}).compute_sheet() payslip = self.env['hr.payslip'].search([('employee_id', '=', self.richard_emp.id)]) @@ -414,7 +412,7 @@ class TestBenefit(TestPayslipBase): 'date_start': start, 'date_stop': end, }) - benef.action_validate(benef.ids) + benef.action_validate() payslip_wizard = self.env['hr.payslip.employees'].create({'employee_ids': [(4, self.richard_emp.id)]}) payslip_wizard.with_context({ 'default_date_start': Date.to_string(start), diff --git a/addons/hr_skills/static/src/js/resume_widget.js b/addons/hr_skills/static/src/js/resume_widget.js index 4249fca884b..7bb2023b76f 100644 --- a/addons/hr_skills/static/src/js/resume_widget.js +++ b/addons/hr_skills/static/src/js/resume_widget.js @@ -90,7 +90,7 @@ var AbstractGroupedOne2ManyRenderer = ListRenderer.extend({ return qweb.render('hr_trash_button'); }, - _renderAddItemButton(group) { + _renderAddItemButton: function (group) { return qweb.render(this.addLineButtonTemplate, { context: JSON.stringify(this._getCreateLineContext(group)), }); @@ -141,8 +141,8 @@ var ResumeLineRenderer = AbstractGroupedOne2ManyRenderer.extend({ var date_start = data.date_start && data.date_start.format(dateFormat) || ""; var date_end = data.date_end && data.date_end.format(dateFormat) || _t("Current"); return _.extend(data, { - date_start, - date_end, + date_start: date_start, + date_end: date_end, }); }, diff --git a/addons/l10n_be_hr_payroll/views/res_config_settings_views.xml b/addons/l10n_be_hr_payroll/views/res_config_settings_views.xml index f65c72e610e..947cfbb98f7 100644 --- a/addons/l10n_be_hr_payroll/views/res_config_settings_views.xml +++ b/addons/l10n_be_hr_payroll/views/res_config_settings_views.xml @@ -18,52 +18,52 @@