diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py
index b6297d153e9..b6a5a03e17f 100644
--- a/addons/account/models/account_bank_statement.py
+++ b/addons/account/models/account_bank_statement.py
@@ -446,6 +446,7 @@ class AccountBankStatementLine(models.Model):
""" Prepare the dict of values to balance the move.
:param recordset move: the account.move to link the move line
+ :param dict move: a dict of vals of a account.move which will be created later
:param float amount: the amount of transaction that wasn't already reconciled
"""
company_currency = self.journal_id.company_id.currency_id
@@ -453,19 +454,23 @@ class AccountBankStatementLine(models.Model):
st_line_currency = self.currency_id or statement_currency
amount_currency = False
st_line_currency_rate = self.currency_id and (self.amount_currency / self.amount) or False
+ if isinstance(move, dict):
+ amount_sum = sum(x[2].get('amount_currency', 0) for x in move['line_ids'])
+ else:
+ amount_sum = sum(x.amount_currency for x in move.line_ids)
# We have several use case here to compare the currency and amount currency of counterpart line to balance the move:
if st_line_currency != company_currency and st_line_currency == statement_currency:
# company in currency A, statement in currency B and transaction in currency B
# counterpart line must have currency B and correct amount is inverse of already existing lines
- amount_currency = -sum([x.amount_currency for x in move.line_ids])
+ amount_currency = -amount_sum
elif st_line_currency != company_currency and statement_currency == company_currency:
# company in currency A, statement in currency A and transaction in currency B
# counterpart line must have currency B and correct amount is inverse of already existing lines
- amount_currency = -sum([x.amount_currency for x in move.line_ids])
+ amount_currency = -amount_sum
elif st_line_currency != company_currency and st_line_currency != statement_currency:
# company in currency A, statement in currency B and transaction in currency C
# counterpart line must have currency B and use rate between B and C to compute correct amount
- amount_currency = -sum([x.amount_currency for x in move.line_ids])/st_line_currency_rate
+ amount_currency = -amount_sum/st_line_currency_rate
elif st_line_currency == company_currency and statement_currency != company_currency:
# company in currency A, statement in currency B and transaction in currency A
# counterpart line must have currency B and amount is computed using the rate between A and B
@@ -474,9 +479,8 @@ class AccountBankStatementLine(models.Model):
# last case is company in currency A, statement in currency A and transaction in currency A
# and in this case counterpart line does not need any second currency nor amount_currency
- return {
+ aml_dict = {
'name': self.name,
- 'move_id': move.id,
'partner_id': self.partner_id and self.partner_id.id or False,
'account_id': amount >= 0 \
and self.statement_id.journal_id.default_credit_account_id.id \
@@ -487,22 +491,72 @@ class AccountBankStatementLine(models.Model):
'currency_id': statement_currency != company_currency and statement_currency.id or (st_line_currency != company_currency and st_line_currency.id or False),
'amount_currency': amount_currency,
}
+ if isinstance(move, self.env['account.move'].__class__):
+ aml_dict['move_id'] = move.id
+ return aml_dict
+ @api.multi
def fast_counterpart_creation(self):
"""This function is called when confirming a bank statement and will allow to automatically process lines without
going in the bank reconciliation widget. By setting an account_id on bank statement lines, it will create a journal
entry using that account to counterpart the bank account
"""
+ payment_list = []
+ move_list = []
+ account_type_receivable = self.env.ref('account.data_account_type_receivable')
+ already_done_stmt_line_ids = [a['statement_line_id'][0] for a in self.env['account.move.line'].read_group([('statement_line_id', 'in', self.ids)], ['statement_line_id'], ['statement_line_id'])]
+ managed_st_line = []
for st_line in self:
# Technical functionality to automatically reconcile by creating a new move line
- if st_line.account_id and not st_line.journal_entry_ids.ids:
- vals = {
+ if st_line.account_id and not st_line.id in already_done_stmt_line_ids:
+ managed_st_line.append(st_line.id)
+ # Create payment vals
+ total = st_line.amount
+ payment_methods = (total > 0) and st_line.journal_id.inbound_payment_method_ids or st_line.journal_id.outbound_payment_method_ids
+ currency = st_line.journal_id.currency_id or st_line.company_id.currency_id
+ partner_type = 'customer' if st_line.account_id.user_type_id == account_type_receivable else 'supplier'
+ payment_list.append({
+ 'payment_method_id': payment_methods and payment_methods[0].id or False,
+ 'payment_type': total > 0 and 'inbound' or 'outbound',
+ 'partner_id': st_line.partner_id.id,
+ 'partner_type': partner_type,
+ 'journal_id': st_line.statement_id.journal_id.id,
+ 'payment_date': st_line.date,
+ 'state': 'reconciled',
+ 'currency_id': currency.id,
+ 'amount': abs(total),
+ 'communication': st_line._get_communication(payment_methods[0] if payment_methods else False),
+ 'name': st_line.statement_id.name or _("Bank Statement %s") % st_line.date,
+ })
+
+ # Create move and move line vals
+ move_vals = st_line._prepare_reconciliation_move(st_line.statement_id.name)
+ aml_dict = {
'name': st_line.name,
'debit': st_line.amount < 0 and -st_line.amount or 0.0,
'credit': st_line.amount > 0 and st_line.amount or 0.0,
'account_id': st_line.account_id.id,
+ 'partner_id': st_line.partner_id.id,
+ 'statement_line_id': st_line.id,
}
- st_line.process_reconciliation(new_aml_dicts=[vals])
+ st_line._prepare_move_line_for_currency(aml_dict, st_line.date or fields.Date.context_today())
+ move_vals['line_ids'] = [(0, 0, aml_dict)]
+ balance_line = self._prepare_reconciliation_move_line(
+ move_vals, -aml_dict['debit'] if st_line.amount < 0 else aml_dict['credit'])
+ move_vals['line_ids'].append((0, 0, balance_line))
+ move_list.append(move_vals)
+
+ # Creates
+ payment_ids = self.env['account.payment'].create(payment_list)
+ for payment_id, move_vals in zip(payment_ids, move_list):
+ for line in move_vals['line_ids']:
+ line[2]['payment_id'] = payment_id.id
+ move_ids = self.env['account.move'].create(move_list)
+ move_ids.post()
+
+ for move, st_line, payment in zip(move_ids, self.browse(managed_st_line), payment_ids):
+ st_line.write({'move_name': move.name})
+ payment.write({'payment_reference': move.name})
def _get_communication(self, payment_method_id):
return self.name or ''
@@ -628,8 +682,6 @@ class AccountBankStatementLine(models.Model):
# Create move line(s). Either matching an existing journal entry (eg. invoice), in which
# case we reconcile the existing and the new move lines together, or being a write-off.
if counterpart_aml_dicts or new_aml_dicts:
- st_line_currency = self.currency_id or statement_currency
- st_line_currency_rate = self.currency_id and (self.amount_currency / self.amount) or False
# Create the move
self.sequence = self.statement_id.line_ids.ids.index(self.id) + 1
@@ -652,32 +704,12 @@ class AccountBankStatementLine(models.Model):
# Complete dicts to create both counterpart move lines and write-offs
to_create = (counterpart_aml_dicts + new_aml_dicts)
- company = self.company_id
date = self.date or fields.Date.today()
for aml_dict in to_create:
aml_dict['move_id'] = move.id
aml_dict['partner_id'] = self.partner_id.id
aml_dict['statement_line_id'] = self.id
- if st_line_currency.id != company_currency.id:
- aml_dict['amount_currency'] = aml_dict['debit'] - aml_dict['credit']
- aml_dict['currency_id'] = st_line_currency.id
- if self.currency_id and statement_currency.id == company_currency.id and st_line_currency_rate:
- # Statement is in company currency but the transaction is in foreign currency
- aml_dict['debit'] = company_currency.round(aml_dict['debit'] / st_line_currency_rate)
- aml_dict['credit'] = company_currency.round(aml_dict['credit'] / st_line_currency_rate)
- elif self.currency_id and st_line_currency_rate:
- # Statement is in foreign currency and the transaction is in another one
- aml_dict['debit'] = statement_currency._convert(aml_dict['debit'] / st_line_currency_rate, company_currency, company, date)
- aml_dict['credit'] = statement_currency._convert(aml_dict['credit'] / st_line_currency_rate, company_currency, company, date)
- else:
- # Statement is in foreign currency and no extra currency is given for the transaction
- aml_dict['debit'] = st_line_currency._convert(aml_dict['debit'], company_currency, company, date)
- aml_dict['credit'] = st_line_currency._convert(aml_dict['credit'], company_currency, company, date)
- elif statement_currency.id != company_currency.id:
- # Statement is in foreign currency but the transaction is in company currency
- prorata_factor = (aml_dict['debit'] - aml_dict['credit']) / self.amount_currency
- aml_dict['amount_currency'] = prorata_factor * self.amount
- aml_dict['currency_id'] = statement_currency.id
+ self._prepare_move_line_for_currency(aml_dict, date)
# Create write-offs
for aml_dict in new_aml_dicts:
@@ -727,6 +759,36 @@ class AccountBankStatementLine(models.Model):
counterpart_moves.assert_balanced()
return counterpart_moves
+ @api.multi
+ def _prepare_move_line_for_currency(self, aml_dict, date):
+ self.ensure_one()
+ company_currency = self.journal_id.company_id.currency_id
+ statement_currency = self.journal_id.currency_id or company_currency
+ st_line_currency = self.currency_id or statement_currency
+ st_line_currency_rate = self.currency_id and (self.amount_currency / self.amount) or False
+ company = self.company_id
+
+ if st_line_currency.id != company_currency.id:
+ aml_dict['amount_currency'] = aml_dict['debit'] - aml_dict['credit']
+ aml_dict['currency_id'] = st_line_currency.id
+ if self.currency_id and statement_currency.id == company_currency.id and st_line_currency_rate:
+ # Statement is in company currency but the transaction is in foreign currency
+ aml_dict['debit'] = company_currency.round(aml_dict['debit'] / st_line_currency_rate)
+ aml_dict['credit'] = company_currency.round(aml_dict['credit'] / st_line_currency_rate)
+ elif self.currency_id and st_line_currency_rate:
+ # Statement is in foreign currency and the transaction is in another one
+ aml_dict['debit'] = statement_currency._convert(aml_dict['debit'] / st_line_currency_rate, company_currency, company, date)
+ aml_dict['credit'] = statement_currency._convert(aml_dict['credit'] / st_line_currency_rate, company_currency, company, date)
+ else:
+ # Statement is in foreign currency and no extra currency is given for the transaction
+ aml_dict['debit'] = st_line_currency._convert(aml_dict['debit'], company_currency, company, date)
+ aml_dict['credit'] = st_line_currency._convert(aml_dict['credit'], company_currency, company, date)
+ elif statement_currency.id != company_currency.id:
+ # Statement is in foreign currency but the transaction is in company currency
+ prorata_factor = (aml_dict['debit'] - aml_dict['credit']) / self.amount_currency
+ aml_dict['amount_currency'] = prorata_factor * self.amount
+ aml_dict['currency_id'] = statement_currency.id
+
def _check_invoice_state(self, invoice):
if invoice.state == 'in_payment' and all([payment.state == 'reconciled' for payment in invoice.mapped('payment_move_line_ids.payment_id')]):
invoice.write({'state': 'paid'})
diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py
index 82de31b482c..096fee365db 100644
--- a/addons/account/models/account_invoice.py
+++ b/addons/account/models/account_invoice.py
@@ -93,11 +93,12 @@ class AccountInvoice(models.Model):
('type', 'in', [TYPE2JOURNAL[ty] for ty in inv_types if ty in TYPE2JOURNAL]),
('company_id', '=', company_id),
]
- journal_with_currency = False
- if self._context.get('default_currency_id'):
- currency_clause = [('currency_id', '=', self._context.get('default_currency_id'))]
- journal_with_currency = self.env['account.journal'].search(domain + currency_clause, limit=1)
- return journal_with_currency or self.env['account.journal'].search(domain, limit=1)
+ company_currency_id = self.env['res.company'].browse(company_id).currency_id.id
+ currency_id = self._context.get('default_currency_id') or company_currency_id
+ currency_clause = [('currency_id', '=', currency_id)]
+ if currency_id == company_currency_id:
+ currency_clause = ['|', ('currency_id', '=', False)] + currency_clause
+ return self.env['account.journal'].search(domain + currency_clause, limit=1)
@api.model
def _default_currency(self):
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index fc844f15c71..546d2687589 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -55,12 +55,14 @@ class AccountMove(models.Model):
if line.account_id.user_type_id.type in ('receivable', 'payable'):
amount = abs(line.debit - line.credit)
total_amount += amount
- for partial_line in (line.matched_debit_ids + line.matched_credit_ids):
- total_reconciled += partial_line.amount
precision_currency = move.currency_id or move.company_id.currency_id
if float_is_zero(total_amount, precision_rounding=precision_currency.rounding):
move.matched_percentage = 1.0
else:
+ for line in move.line_ids:
+ if line.account_id.user_type_id.type in ('receivable', 'payable'):
+ for partial_line in (line.matched_debit_ids + line.matched_credit_ids):
+ total_reconciled += partial_line.amount
move.matched_percentage = total_reconciled / total_amount
@api.multi
@@ -411,6 +413,7 @@ class AccountMove(models.Model):
@api.multi
def _reverse_move(self, date=None, journal_id=None, auto=False):
self.ensure_one()
+ date = date or fields.Date.today()
with self.env.norecompute():
reversed_move = self.copy(default={
'date': date,
@@ -680,8 +683,8 @@ class AccountMoveLine(models.Model):
tax_line_grouping_key = fields.Char(store=False, string='Old Taxes', help="Technical field used to store the old values of fields used to compute tax lines (in account.move form view) between the moment the user changed it and the moment the ORM reflects that change in its one2many")
_sql_constraints = [
- ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry !'),
- ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in accounting entry !'),
+ ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry! Credit or debit should be zero.'),
+ ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in accounting entry! Credit and debit should be positive.'),
]
@api.model
@@ -758,22 +761,21 @@ class AccountMoveLine(models.Model):
In case of full reconciliation, all moves belonging to the reconciliation will belong to the same account_full_reconcile object.
"""
# Get first all aml involved
- part_recs = self.env['account.partial.reconcile'].search(['|', ('debit_move_id', 'in', self.ids), ('credit_move_id', 'in', self.ids)])
- amls = self
- todo = set(part_recs)
+ todo = self.env['account.partial.reconcile'].search_read(['|', ('debit_move_id', 'in', self.ids), ('credit_move_id', 'in', self.ids)], ['debit_move_id', 'credit_move_id'])
+ amls = set(self.ids)
seen = set()
while todo:
- partial_rec = todo.pop()
- seen.add(partial_rec)
- for aml in [partial_rec.debit_move_id, partial_rec.credit_move_id]:
- if aml not in amls:
- amls += aml
- for x in aml.matched_debit_ids | aml.matched_credit_ids:
- if x not in seen:
- todo.add(x)
- partial_rec_ids = [x.id for x in seen]
+ aml_ids = [rec['debit_move_id'][0] for rec in todo if rec['debit_move_id']] + [rec['credit_move_id'][0] for rec in todo if rec['credit_move_id']]
+ amls |= set(aml_ids)
+ seen |= set([rec['id'] for rec in todo])
+ todo = self.env['account.partial.reconcile'].search_read(['&', '|', ('credit_move_id', 'in', aml_ids), ('debit_move_id', 'in', aml_ids), '!', ('id', 'in', list(seen))], ['debit_move_id', 'credit_move_id'])
+
+ partial_rec_ids = list(seen)
if not amls:
return
+ else:
+ amls = self.browse(list(amls))
+
# If we have multiple currency, we can only base ourselve on debit-credit to see if it is fully reconciled
currency = set([a.currency_id for a in amls if a.currency_id.id != False])
multiple_currency = False
diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py
index abc17743e61..614aba000ab 100644
--- a/addons/account/report/account_invoice_report.py
+++ b/addons/account/report/account_invoice_report.py
@@ -96,7 +96,7 @@ class AccountInvoiceReport(models.Model):
sub.payment_term_id, sub.uom_name, sub.currency_id, sub.journal_id,
sub.fiscal_position_id, sub.user_id, sub.company_id, sub.nbr, sub.invoice_id, sub.type, sub.state,
sub.categ_id, sub.date_due, sub.account_id, sub.account_line_id, sub.partner_bank_id,
- sub.product_qty, sub.price_total as price_total, sub.price_average as price_average, sub.amount_total as amount_total,
+ sub.product_qty, sub.price_total as price_total, sub.price_average as price_average, sub.amount_total / COALESCE(cr.rate, 1) as amount_total,
COALESCE(cr.rate, 1) as currency_rate, sub.residual as residual, sub.commercial_partner_id as commercial_partner_id
"""
return select_str
@@ -114,8 +114,7 @@ class AccountInvoiceReport(models.Model):
ai.partner_bank_id,
SUM ((invoice_type.sign_qty * ail.quantity) / COALESCE(u.factor,1) * COALESCE(u2.factor,1)) AS product_qty,
SUM(ail.price_subtotal_signed * invoice_type.sign) AS price_total,
- ai.amount_total_signed / (SELECT count(*) FROM account_invoice_line l where invoice_id = ai.id) *
- count(*) * invoice_type.sign AS amount_total,
+ SUM(ail.price_total * invoice_type.sign_qty) AS amount_total,
SUM(ABS(ail.price_subtotal_signed)) / CASE
WHEN SUM(ail.quantity / COALESCE(u.factor,1) * COALESCE(u2.factor,1)) <> 0::numeric
THEN SUM(ail.quantity / COALESCE(u.factor,1) * COALESCE(u2.factor,1))
diff --git a/addons/account/tests/test_bank_statement_reconciliation.py b/addons/account/tests/test_bank_statement_reconciliation.py
index 0311f278a4b..7957be0b77d 100644
--- a/addons/account/tests/test_bank_statement_reconciliation.py
+++ b/addons/account/tests/test_bank_statement_reconciliation.py
@@ -13,6 +13,8 @@ class TestBankStatementReconciliation(AccountingTestCase):
self.bsl_model = self.env['account.bank.statement.line']
self.reconciliation_widget = self.env['account.reconciliation.widget']
self.partner = self.env['res.partner'].create({'name': 'test'})
+ self.currency_usd_id = self.env.ref("base.USD").id
+ self.currency_euro_id = self.env.ref("base.EUR").id
def test_reconciliation_proposition(self):
rcv_mv_line = self.create_invoice(100)
@@ -108,3 +110,31 @@ class TestBankStatementReconciliation(AccountingTestCase):
})
return bank_stmt_line
+
+ def test_confirm_statement_usd(self):
+ company = self.env.ref('base.main_company')
+ self.cr.execute("UPDATE res_company SET currency_id = %s WHERE id = %s", [self.currency_euro_id, company.id])
+ self.env['res.currency.rate'].search([]).unlink()
+ self.env['res.currency.rate'].create({
+ 'currency_id': self.currency_usd_id,
+ 'rate': 2.0,
+ 'name': '2001-01-01',
+ })
+ bank_journal_usd = self.env['account.journal'].create({
+ 'name': 'Bank US',
+ 'type': 'bank',
+ 'code': 'BNK68',
+ 'currency_id': self.currency_usd_id,
+ })
+ statement = self.bs_model.create({
+ 'journal_id': bank_journal_usd.id,
+ 'balance_end_real': 100,
+ 'line_ids': [(0, 0, {
+ 'name': '_',
+ 'partner_id': self.partner.id,
+ 'amount': 100,
+ 'account_id': bank_journal_usd.default_debit_account_id.id,
+ })],
+ })
+ statement.button_open()
+ statement.button_confirm_bank()
diff --git a/addons/account/wizard/account_invoice_send.py b/addons/account/wizard/account_invoice_send.py
index 54fbd7ff4be..e65b5f0ee89 100644
--- a/addons/account/wizard/account_invoice_send.py
+++ b/addons/account/wizard/account_invoice_send.py
@@ -11,6 +11,7 @@ class AccountInvoiceSend(models.TransientModel):
_description = 'Account Invoice Send'
is_email = fields.Boolean('Email', default=lambda self: self.env.user.company_id.invoice_is_email)
+ invoice_without_email = fields.Text(compute='_compute_invoice_without_email', string='invoice(s) that will not be sent')
is_print = fields.Boolean('Print', default=lambda self: self.env.user.company_id.invoice_is_print)
printed = fields.Boolean('Is Printed', default=False)
invoice_ids = fields.Many2many('account.invoice', 'account_invoice_account_invoice_send_rel', string='Invoices')
@@ -45,6 +46,22 @@ class AccountInvoiceSend(models.TransientModel):
self.composer_id.template_id = self.template_id.id
self.composer_id.onchange_template_id_wrapper()
+ @api.onchange('is_email')
+ def _compute_invoice_without_email(self):
+ for wizard in self:
+ if wizard.is_email and len(wizard.invoice_ids) > 1:
+ invoices = self.env['account.invoice'].search([
+ ('id', 'in', self.env.context.get('active_ids')),
+ ('partner_id.email', '=', False)
+ ])
+ if invoices:
+ wizard.invoice_without_email = "%s\n%s" % (
+ _("The following invoice(s) will not be sent by email, because the customers don't have email address."),
+ "\n".join([i.reference for i in invoices])
+ )
+ else:
+ wizard.invoice_without_email = False
+
@api.multi
def _send_email(self):
if self.is_email:
diff --git a/addons/account/wizard/account_invoice_send_views.xml b/addons/account/wizard/account_invoice_send_views.xml
index 6052c1438d9..648dcdec65d 100644
--- a/addons/account/wizard/account_invoice_send_views.xml
+++ b/addons/account/wizard/account_invoice_send_views.xml
@@ -23,6 +23,9 @@
Create a new employee
diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py
index d3ecb721635..ee837075dd4 100644
--- a/addons/hr_expense/models/hr_expense.py
+++ b/addons/hr_expense/models/hr_expense.py
@@ -799,12 +799,12 @@ class HrExpenseSheet(models.Model):
return self.employee_id.parent_id.user_id
elif self.employee_id.department_id.manager_id.user_id:
return self.employee_id.department_id.manager_id.user_id
- return self.env.user
+ return self.env['res.users']
def activity_update(self):
for expense_report in self.filtered(lambda hol: hol.state == 'submit'):
self.activity_schedule(
'hr_expense.mail_act_expense_approval',
- user_id=expense_report.sudo()._get_responsible_for_approval().id)
+ user_id=expense_report.sudo()._get_responsible_for_approval().id or self.env.user.id)
self.filtered(lambda hol: hol.state == 'approve').activity_feedback(['hr_expense.mail_act_expense_approval'])
self.filtered(lambda hol: hol.state == 'cancel').activity_unlink(['hr_expense.mail_act_expense_approval'])
diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py
index ac8b991c77d..b9fb2650d65 100644
--- a/addons/hr_holidays/models/hr_leave.py
+++ b/addons/hr_holidays/models/hr_leave.py
@@ -842,7 +842,7 @@ class HolidaysRequest(models.Model):
def _get_responsible_for_approval(self):
self.ensure_one()
- responsible = self.env.user
+ responsible = self.env['res.users']
if self.validation_type == 'hr' or (self.validation_type == 'both' and self.state == 'validate1'):
company = self.department_id.company_id if self.holiday_type == 'department' else self.employee_id.company_id
@@ -868,12 +868,12 @@ class HolidaysRequest(models.Model):
elif holiday.state == 'confirm':
holiday.activity_schedule(
'hr_holidays.mail_act_leave_approval',
- user_id=holiday.sudo()._get_responsible_for_approval().id)
+ user_id=holiday.sudo()._get_responsible_for_approval().id or self.env.user.id)
elif holiday.state == 'validate1':
holiday.activity_feedback(['hr_holidays.mail_act_leave_approval'])
holiday.activity_schedule(
'hr_holidays.mail_act_leave_second_approval',
- user_id=holiday.sudo()._get_responsible_for_approval().id)
+ user_id=holiday.sudo()._get_responsible_for_approval().id or self.env.user.id)
elif holiday.state == 'validate':
to_do |= holiday
elif holiday.state == 'refuse':
diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py
index ce96a2fac9b..ab93459622b 100644
--- a/addons/hr_holidays/models/hr_leave_allocation.py
+++ b/addons/hr_holidays/models/hr_leave_allocation.py
@@ -557,7 +557,7 @@ class HolidaysAllocation(models.Model):
return self.employee_id.parent_id.user_id
elif self.department_id.manager_id.user_id:
return self.department_id.manager_id.user_id
- return self.env.user
+ return self.env['res.users']
def activity_update(self):
to_clean, to_do = self.env['hr.leave.allocation'], self.env['hr.leave.allocation']
@@ -567,12 +567,12 @@ class HolidaysAllocation(models.Model):
elif allocation.state == 'confirm':
allocation.activity_schedule(
'hr_holidays.mail_act_leave_allocation_approval',
- user_id=allocation.sudo()._get_responsible_for_approval().id)
+ user_id=allocation.sudo()._get_responsible_for_approval().id or self.env.user.id)
elif allocation.state == 'validate1':
allocation.activity_feedback(['hr_holidays.mail_act_leave_allocation_approval'])
allocation.activity_schedule(
'hr_holidays.mail_act_leave_allocation_second_approval',
- user_id=allocation.sudo()._get_responsible_for_approval().id)
+ user_id=allocation.sudo()._get_responsible_for_approval().id or self.env.user.id)
elif allocation.state == 'validate':
to_do |= allocation
elif allocation.state == 'refuse':
diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py
index 12c81e9d620..4f5bd4abb0b 100644
--- a/addons/http_routing/models/ir_http.py
+++ b/addons/http_routing/models/ir_http.py
@@ -44,7 +44,7 @@ def _guess_mimetype(ext=False, default='text/html'):
return ext is not False and exts.get(ext, default) or exts
-def slugify_one(s, max_length=None):
+def slugify_one(s, max_length=0):
""" Transform a string to a slug that can be used in a url path.
This method will first try to do the job with python-slugify if present.
Otherwise it will process string by stripping leading and ending spaces,
@@ -62,13 +62,12 @@ def slugify_one(s, max_length=None):
except TypeError:
pass
uni = unicodedata.normalize('NFKD', s).encode('ascii', 'ignore').decode('ascii')
- slug_str = re.sub('[\W_]', ' ', uni).strip().lower()
- slug_str = re.sub('[-\s]+', '-', slug_str)
-
- return slug_str[:max_length]
+ slug_str = re.sub(r'[\W_]', ' ', uni).strip().lower()
+ slug_str = re.sub(r'[-\s]+', '-', slug_str)
+ return slug_str[:max_length] if max_length > 0 else slug_str
-def slugify(s, max_length=None, path=False):
+def slugify(s, max_length=0, path=False):
if not path:
return slugify_one(s, max_length=max_length)
else:
diff --git a/addons/l10n_mx/data/account_tag_data.xml b/addons/l10n_mx/data/account_tag_data.xml
index 1e8b23dacda..a025c4dd4e2 100644
--- a/addons/l10n_mx/data/account_tag_data.xml
+++ b/addons/l10n_mx/data/account_tag_data.xml
@@ -2077,212 +2077,230 @@