[FIX] P3: remove pycompat.{keys,items,values} helpers
Now that we're closer to switching to P3 for good, these helpers have outlived their usefulness, and mostly add noise. All remaining dict.iter*() or dict.view*() must be converted to the normal keys(), values() or items() calls. Whenever the result is likely to be used for more than the scope of a loop, or when the dict needs to be modified during iteration, the calls must be wrapped in a ``list()``, to protect the new P3 semantics. Those cases are very exceptional. Also removed some dead code or improved the API to remove unnecessary conversions.
This commit is contained in:
@@ -5,7 +5,7 @@ import math
|
||||
|
||||
from odoo.osv import expression
|
||||
from odoo.tools.float_utils import float_round as round
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, pycompat
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
@@ -395,7 +395,7 @@ class AccountInvoice(models.Model):
|
||||
'_onchange_partner_id': ['account_id', 'payment_term_id', 'fiscal_position_id', 'partner_bank_id'],
|
||||
'_onchange_journal_id': ['currency_id'],
|
||||
}
|
||||
for onchange_method, changed_fields in pycompat.items(onchanges):
|
||||
for onchange_method, changed_fields in onchanges.items():
|
||||
if any(f not in vals for f in changed_fields):
|
||||
invoice = self.new(vals)
|
||||
getattr(invoice, onchange_method)()
|
||||
@@ -516,7 +516,7 @@ class AccountInvoice(models.Model):
|
||||
tax_grouped = invoice.get_taxes_values()
|
||||
|
||||
# Create new tax lines
|
||||
for tax in pycompat.values(tax_grouped):
|
||||
for tax in tax_grouped.values():
|
||||
account_invoice_tax.create(tax)
|
||||
|
||||
# dummy write on self to trigger recomputations
|
||||
@@ -535,7 +535,7 @@ class AccountInvoice(models.Model):
|
||||
def _onchange_invoice_line_ids(self):
|
||||
taxes_grouped = self.get_taxes_values()
|
||||
tax_lines = self.tax_line_ids.filtered('manual')
|
||||
for tax in pycompat.values(taxes_grouped):
|
||||
for tax in taxes_grouped.values():
|
||||
tax_lines += tax_lines.new(tax)
|
||||
self.tax_line_ids = tax_lines
|
||||
return
|
||||
@@ -886,7 +886,7 @@ class AccountInvoice(models.Model):
|
||||
else:
|
||||
line2[tmp] = l
|
||||
line = []
|
||||
for key, val in pycompat.items(line2):
|
||||
for key, val in line2.items():
|
||||
line.append((0, 0, val))
|
||||
return line
|
||||
|
||||
@@ -1079,7 +1079,7 @@ class AccountInvoice(models.Model):
|
||||
result = []
|
||||
for line in lines:
|
||||
values = {}
|
||||
for name, field in pycompat.items(line._fields):
|
||||
for name, field in line._fields.items():
|
||||
if name in MAGIC_COLUMNS:
|
||||
continue
|
||||
elif field.type == 'many2one':
|
||||
@@ -1249,7 +1249,7 @@ class AccountInvoice(models.Model):
|
||||
for line in self.tax_line_ids:
|
||||
res.setdefault(line.tax_id.tax_group_id, 0.0)
|
||||
res[line.tax_id.tax_group_id] += line.amount
|
||||
res = sorted(pycompat.items(res), key=lambda l: l[0].sequence)
|
||||
res = sorted(res.items(), key=lambda l: l[0].sequence)
|
||||
res = [(l[0].name, l[1]) for l in res]
|
||||
return res
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ from odoo.exceptions import UserError
|
||||
|
||||
import logging
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
def migrate_set_tags_and_taxes_updatable(cr, registry, module):
|
||||
@@ -327,7 +325,7 @@ class AccountChartTemplate(models.Model):
|
||||
|
||||
# writing account values after creation of accounts
|
||||
company.transfer_account_id = account_template_ref[transfer_account_id.id]
|
||||
for key, value in pycompat.items(generated_tax_res['account_dict']):
|
||||
for key, value in generated_tax_res['account_dict'].items():
|
||||
if value['refund_account_id'] or value['account_id'] or value['cash_basis_account']:
|
||||
AccountTaxObj.browse(key).write({
|
||||
'refund_account_id': account_ref.get(value['refund_account_id'], False),
|
||||
|
||||
@@ -5,7 +5,7 @@ from operator import itemgetter
|
||||
import time
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, pycompat
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.base.res.res_partner import WARNING_MESSAGE, WARNING_HELP
|
||||
|
||||
@@ -73,7 +73,7 @@ class AccountFiscalPosition(models.Model):
|
||||
ref_dict = {}
|
||||
for line in self.account_ids:
|
||||
ref_dict[line.account_src_id] = line.account_dest_id
|
||||
for key, acc in list(pycompat.items(accounts)):
|
||||
for key, acc in accounts.items():
|
||||
if acc in ref_dict:
|
||||
accounts[key] = ref_dict[acc]
|
||||
return accounts
|
||||
@@ -293,7 +293,7 @@ class ResPartner(models.Model):
|
||||
""" % where_clause
|
||||
self.env.cr.execute(query, where_clause_params)
|
||||
price_totals = self.env.cr.dictfetchall()
|
||||
for partner, child_ids in pycompat.items(all_partners_and_children):
|
||||
for partner, child_ids in all_partners_and_children.items():
|
||||
partner.total_invoiced = sum(price['total'] for price in price_totals if price['partner_id'] in child_ids)
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import time
|
||||
from odoo import api, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class ReportFinancial(models.AbstractModel):
|
||||
@@ -28,7 +27,7 @@ class ReportFinancial(models.AbstractModel):
|
||||
if where_clause.strip():
|
||||
wheres.append(where_clause.strip())
|
||||
filters = " AND ".join(wheres)
|
||||
request = "SELECT account_id as id, " + ', '.join(pycompat.values(mapping)) + \
|
||||
request = "SELECT account_id as id, " + ', '.join(mapping.values()) + \
|
||||
" FROM " + tables + \
|
||||
" WHERE account_id IN %s " \
|
||||
+ filters + \
|
||||
@@ -55,26 +54,26 @@ class ReportFinancial(models.AbstractModel):
|
||||
if report.type == 'accounts':
|
||||
# it's the sum of the linked accounts
|
||||
res[report.id]['account'] = self._compute_account_balance(report.account_ids)
|
||||
for value in pycompat.values(res[report.id]['account']):
|
||||
for value in res[report.id]['account'].values():
|
||||
for field in fields:
|
||||
res[report.id][field] += value.get(field)
|
||||
elif report.type == 'account_type':
|
||||
# it's the sum the leaf accounts with such an account type
|
||||
accounts = self.env['account.account'].search([('user_type_id', 'in', report.account_type_ids.ids)])
|
||||
res[report.id]['account'] = self._compute_account_balance(accounts)
|
||||
for value in pycompat.values(res[report.id]['account']):
|
||||
for value in res[report.id]['account'].values():
|
||||
for field in fields:
|
||||
res[report.id][field] += value.get(field)
|
||||
elif report.type == 'account_report' and report.account_report_id:
|
||||
# it's the amount of the linked report
|
||||
res2 = self._compute_report_balance(report.account_report_id)
|
||||
for key, value in pycompat.items(res2):
|
||||
for key, value in res2.items():
|
||||
for field in fields:
|
||||
res[report.id][field] += value[field]
|
||||
elif report.type == 'sum':
|
||||
# it's the sum of the children of this account.report
|
||||
res2 = self._compute_report_balance(report.children_ids)
|
||||
for key, value in pycompat.items(res2):
|
||||
for key, value in res2.items():
|
||||
for field in fields:
|
||||
res[report.id][field] += value[field]
|
||||
return res
|
||||
@@ -86,11 +85,11 @@ class ReportFinancial(models.AbstractModel):
|
||||
res = self.with_context(data.get('used_context'))._compute_report_balance(child_reports)
|
||||
if data['enable_filter']:
|
||||
comparison_res = self.with_context(data.get('comparison_context'))._compute_report_balance(child_reports)
|
||||
for report_id, value in pycompat.items(comparison_res):
|
||||
for report_id, value in comparison_res.items():
|
||||
res[report_id]['comp_bal'] = value['balance']
|
||||
report_acc = res[report_id].get('account')
|
||||
if report_acc:
|
||||
for account_id, val in pycompat.items(comparison_res[report_id].get('account')):
|
||||
for account_id, val in comparison_res[report_id].get('account').items():
|
||||
report_acc[account_id]['comp_bal'] = val['balance']
|
||||
|
||||
for report in child_reports:
|
||||
@@ -115,7 +114,7 @@ class ReportFinancial(models.AbstractModel):
|
||||
|
||||
if res[report.id].get('account'):
|
||||
sub_lines = []
|
||||
for account_id, value in pycompat.items(res[report.id]['account']):
|
||||
for account_id, value in res[report.id]['account'].items():
|
||||
#if there are accounts to display, we add them to the lines with a level equals to their level in
|
||||
#the COA + 1 (to avoid having them with a too low level that would conflicts with the level of data
|
||||
#financial reports for Assets, liabilities...)
|
||||
|
||||
@@ -2,8 +2,6 @@ from odoo.addons.account.tests.account_test_classes import AccountingTestCase
|
||||
import time
|
||||
import unittest
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class TestReconciliation(AccountingTestCase):
|
||||
|
||||
@@ -339,8 +337,8 @@ class TestReconciliation(AccountingTestCase):
|
||||
self.assertTrue(exchange_loss_line, 'There should be one move line of 0.01 EUR in credit')
|
||||
# The journal items of the reconciliation should have their debit and credit total equal
|
||||
# Besides, the total debit and total credit should be 60.61 EUR (2.00 USD)
|
||||
self.assertEquals(sum(res['debit'] for res in pycompat.values(result)), 60.61)
|
||||
self.assertEquals(sum(res['credit'] for res in pycompat.items(result)), 60.61)
|
||||
self.assertEquals(sum(res['debit'] for res in result.values()), 60.61)
|
||||
self.assertEquals(sum(res['credit'] for res in result.items()), 60.61)
|
||||
counterpart_exchange_loss_line = None
|
||||
for line in exchange_loss_line.move_id.line_id:
|
||||
if line.account_id.id == self.account_fx_expense_id:
|
||||
|
||||
@@ -7,7 +7,7 @@ from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DF, pycompat
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DF
|
||||
from odoo.tools import float_compare, float_is_zero
|
||||
|
||||
|
||||
@@ -374,7 +374,7 @@ class AccountAssetAsset(models.Model):
|
||||
vals = self.onchange_category_id_values(self.category_id.id)
|
||||
# We cannot use 'write' on an object that doesn't exist yet
|
||||
if vals:
|
||||
for k, v in pycompat.items(vals['value']):
|
||||
for k, v in vals['value'].items():
|
||||
setattr(self, k, v)
|
||||
|
||||
def onchange_category_id_values(self, category_id):
|
||||
@@ -583,7 +583,7 @@ class AccountAssetDepreciationLine(models.Model):
|
||||
message = ''
|
||||
if message_description:
|
||||
message = '<span>%s</span>' % message_description
|
||||
for name, values in pycompat.items(tracked_values):
|
||||
for name, values in tracked_values.items():
|
||||
message += '<div> • <b>%s</b>: ' % name
|
||||
message += '%s</div>' % values
|
||||
return message
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
from odoo import fields, models, api, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class AccountVoucher(models.Model):
|
||||
@@ -358,7 +357,7 @@ class AccountVoucherLine(models.Model):
|
||||
self.company_id.id,
|
||||
self.voucher_id.currency_id.id,
|
||||
self.voucher_id.voucher_type)
|
||||
for fname, fvalue in pycompat.items(onchange_res['value']):
|
||||
for fname, fvalue in onchange_res['value'].items():
|
||||
setattr(self, fname, fvalue)
|
||||
|
||||
def _get_account(self, product, fpos, type):
|
||||
|
||||
@@ -8,7 +8,6 @@ from odoo.addons.auth_signup.models.res_users import SignupError
|
||||
from odoo.addons.web.controllers.main import ensure_db, Home
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.http import request
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -106,7 +105,7 @@ class AuthSignupHome(Home):
|
||||
try:
|
||||
# retrieve the user info (name, login or email) corresponding to a signup token
|
||||
token_infos = request.env['res.partner'].sudo().signup_retrieve_info(qcontext.get('token'))
|
||||
for k, v in pycompat.items(token_infos):
|
||||
for k, v in token_infos.items():
|
||||
qcontext.setdefault(k, v)
|
||||
except:
|
||||
qcontext['error'] = _("Invalid signup token")
|
||||
|
||||
@@ -8,8 +8,6 @@ from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from odoo import api, exceptions, fields, models, _
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class SignupError(Exception):
|
||||
pass
|
||||
|
||||
@@ -5,7 +5,6 @@ import re
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
STREET_FIELDS = ('street_name', 'street_number', 'street_number2')
|
||||
|
||||
@@ -135,7 +134,7 @@ class Partner(models.Model):
|
||||
vals[field_name] = street_raw
|
||||
# assign the values to the fields
|
||||
# /!\ Note that a write(vals) would cause a recursion since it would bypass the cache
|
||||
for k, v in pycompat.items(vals):
|
||||
for k, v in vals.items():
|
||||
partner[k] = v
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import api, fields, models, SUPERUSER_ID
|
||||
from odoo.modules.registry import Registry
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -264,7 +263,7 @@ class BaseAutomation(models.Model):
|
||||
if res:
|
||||
if 'value' in res:
|
||||
res['value'].pop('id', None)
|
||||
self.update({key: val for key, val in pycompat.items(res['value']) if key in self._fields})
|
||||
self.update({key: val for key, val in res['value'].items() if key in self._fields})
|
||||
if 'domain' in res:
|
||||
result.setdefault('domain', {}).update(res['domain'])
|
||||
if 'warning' in res:
|
||||
|
||||
@@ -8,7 +8,6 @@ import uuid
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -194,7 +193,7 @@ class BaseGengoTranslations(models.TransientModel):
|
||||
term_ids.write(vals)
|
||||
jobs = response.get('jobs', [])
|
||||
if jobs:
|
||||
for t_id, job in pycompat.items(jobs):
|
||||
for t_id, job in jobs.items():
|
||||
self._update_terms_job(job)
|
||||
|
||||
return
|
||||
|
||||
@@ -42,7 +42,7 @@ FILE_TYPE_DICT = {
|
||||
}
|
||||
EXTENSIONS = {
|
||||
'.' + ext: handler
|
||||
for mime, (ext, handler, req) in pycompat.items(FILE_TYPE_DICT)
|
||||
for mime, (ext, handler, req) in FILE_TYPE_DICT.items()
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ class Import(models.TransientModel):
|
||||
}]
|
||||
model_fields = Model.fields_get()
|
||||
blacklist = models.MAGIC_COLUMNS + [Model.CONCURRENCY_CHECK_FIELD]
|
||||
for name, field in pycompat.items(model_fields):
|
||||
for name, field in model_fields.items():
|
||||
if name in blacklist:
|
||||
continue
|
||||
# an empty string means the field is deprecated, @deprecated must
|
||||
@@ -127,7 +127,7 @@ class Import(models.TransientModel):
|
||||
continue
|
||||
# states = {state: [(attr, value), (attr2, value2)], state2:...}
|
||||
if not any(attr == 'readonly' and value is False
|
||||
for attr, value in itertools.chain.from_iterable(pycompat.values(states))):
|
||||
for attr, value in itertools.chain.from_iterable(states.values())):
|
||||
continue
|
||||
field_value = {
|
||||
'id': name,
|
||||
@@ -595,7 +595,7 @@ class Import(models.TransientModel):
|
||||
def _parse_import_data(self, data, import_fields, options):
|
||||
# Get fields of type date/datetime
|
||||
all_fields = self.env[self.res_model].fields_get()
|
||||
for name, field in pycompat.items(all_fields):
|
||||
for name, field in all_fields.items():
|
||||
if field['type'] in ('date', 'datetime') and name in import_fields:
|
||||
# Parse date
|
||||
index = import_fields.index(name)
|
||||
|
||||
@@ -19,8 +19,6 @@ from odf import opendocument
|
||||
from odf.table import Table, TableRow, TableCell
|
||||
from odf.text import P
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class ODSReader(object):
|
||||
|
||||
@@ -97,4 +95,4 @@ class ODSReader(object):
|
||||
return self.SHEETS[name]
|
||||
|
||||
def getFirstSheet(self):
|
||||
return next(iter(pycompat.values(self.SHEETS)))
|
||||
return next(iter(self.SHEETS.values()))
|
||||
|
||||
@@ -9,7 +9,7 @@ from os.path import join as opj
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.modules import load_information_from_description_file
|
||||
from odoo.tools import convert_file, exception_to_unicode, pycompat
|
||||
from odoo.tools import convert_file, exception_to_unicode
|
||||
from odoo.tools.osutil import tempdir
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -119,6 +119,6 @@ class IrModule(models.Model):
|
||||
finally:
|
||||
addons.module.ad_paths.remove(module_dir)
|
||||
r = ["Successfully imported module '%s'" % mod for mod in success]
|
||||
for mod, error in pycompat.items(errors):
|
||||
for mod, error in errors.items():
|
||||
r.append("Error while importing module '%s': %r" % (mod, error))
|
||||
return '\n'.join(r), module_names
|
||||
|
||||
@@ -470,7 +470,7 @@ class Alarm(models.Model):
|
||||
name = fields.Char('Name', required=True)
|
||||
type = fields.Selection([('notification', 'Notification'), ('email', 'Email')], 'Type', required=True, default='email')
|
||||
duration = fields.Integer('Remind Before', required=True, default=1)
|
||||
interval = fields.Selection(list(pycompat.items(_interval_selection)), 'Unit', required=True, default='hours')
|
||||
interval = fields.Selection(list(_interval_selection.items()), 'Unit', required=True, default='hours')
|
||||
duration_minutes = fields.Integer('Duration in minutes', compute='_compute_duration_minutes', store=True, help="Duration in minutes")
|
||||
|
||||
@api.onchange('duration', 'interval')
|
||||
@@ -1292,7 +1292,7 @@ class Meeting(models.Model):
|
||||
@api.multi
|
||||
def _get_message_unread(self):
|
||||
id_map = {x: calendar_id2real_id(x) for x in self.ids}
|
||||
real = self.browse(set(pycompat.values(id_map)))
|
||||
real = self.browse(set(id_map.values()))
|
||||
super(Meeting, real)._get_message_unread()
|
||||
for event in self:
|
||||
if event.id == id_map[event.id]:
|
||||
@@ -1304,7 +1304,7 @@ class Meeting(models.Model):
|
||||
@api.multi
|
||||
def _get_message_needaction(self):
|
||||
id_map = {x: calendar_id2real_id(x) for x in self.ids}
|
||||
real = self.browse(set(pycompat.values(id_map)))
|
||||
real = self.browse(set(id_map.values()))
|
||||
super(Meeting, real)._get_message_needaction()
|
||||
for event in self:
|
||||
if event.id == id_map[event.id]:
|
||||
|
||||
@@ -5,7 +5,6 @@ import pytz
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.addons.mail.models.mail_template import format_tz
|
||||
from odoo.exceptions import AccessError, UserError, ValidationError
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.translate import html_translate
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
@@ -389,7 +388,7 @@ class EventRegistration(models.Model):
|
||||
'partner_id': partner_id.id,
|
||||
'event_id': event_id and event_id.id or False,
|
||||
}
|
||||
data.update({key: value for key, value in pycompat.items(registration) if key in self._fields})
|
||||
data.update({key: value for key, value in registration.items() if key in self._fields})
|
||||
return data
|
||||
|
||||
@api.one
|
||||
|
||||
@@ -6,8 +6,6 @@ from odoo.exceptions import UserError
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class FleetVehicleCost(models.Model):
|
||||
_name = 'fleet.vehicle.cost'
|
||||
@@ -264,7 +262,7 @@ class FleetVehicleLogContract(models.Model):
|
||||
res[contract.vehicle_id.id] = 1
|
||||
|
||||
Vehicle = self.env['fleet.vehicle']
|
||||
for vehicle, value in pycompat.items(res):
|
||||
for vehicle, value in res.items():
|
||||
Vehicle.browse(vehicle).message_post(body=_('%s contract(s) need(s) to be renewed and/or closed!') % value)
|
||||
return contracts.write({'state': 'toclose'})
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ class Goal(models.Model):
|
||||
for goal in self:
|
||||
goals_by_definition.setdefault(goal.definition_id, []).append(goal)
|
||||
|
||||
for definition, goals in pycompat.items(goals_by_definition):
|
||||
for definition, goals in goals_by_definition.items():
|
||||
goals_to_write = {}
|
||||
if definition.computation_mode == 'manually':
|
||||
for goal in goals:
|
||||
@@ -307,9 +307,9 @@ class Goal(models.Model):
|
||||
subqueries.setdefault((start_date, end_date), {}).update({goal.id:safe_eval(definition.batch_user_expression, {'user': goal.user_id})})
|
||||
|
||||
# the global query should be split by time periods (especially for recurrent goals)
|
||||
for (start_date, end_date), query_goals in pycompat.items(subqueries):
|
||||
for (start_date, end_date), query_goals in subqueries.items():
|
||||
subquery_domain = list(general_domain)
|
||||
subquery_domain.append((field_name, 'in', list(set(pycompat.values(query_goals)))))
|
||||
subquery_domain.append((field_name, 'in', list(set(query_goals.values()))))
|
||||
if start_date:
|
||||
subquery_domain.append((field_date_name, '>=', start_date))
|
||||
if end_date:
|
||||
@@ -353,7 +353,7 @@ class Goal(models.Model):
|
||||
|
||||
goals_to_write.update(goal._get_write_values(new_value))
|
||||
|
||||
for goal, values in pycompat.items(goals_to_write):
|
||||
for goal, values in goals_to_write.items():
|
||||
if not values:
|
||||
continue
|
||||
goal.write(values)
|
||||
|
||||
@@ -12,7 +12,7 @@ import pytz
|
||||
from werkzeug import urls
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.tools import exception_to_unicode, pycompat
|
||||
from odoo.tools import exception_to_unicode
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -25,15 +25,13 @@ class Meta(type):
|
||||
""" This Meta class allow to define class as a structure, and so instancied variable
|
||||
in __init__ to avoid to have side effect alike 'static' variable """
|
||||
def __new__(typ, name, parents, attrs):
|
||||
methods = {k: v for k, v in pycompat.items(attrs)
|
||||
if callable(v)}
|
||||
attrs = {k: v for k, v in pycompat.items(attrs)
|
||||
if not callable(v)}
|
||||
methods = {k: v for k, v in attrs.items() if callable(v)}
|
||||
attrs = {k: v for k, v in attrs.items() if not callable(v)}
|
||||
|
||||
def init(self, **kw):
|
||||
for key, val in pycompat.items(attrs):
|
||||
for key, val in attrs.items():
|
||||
setattr(self, key, val)
|
||||
for key, val in pycompat.items(kw):
|
||||
for key, val in kw.items():
|
||||
assert key in attrs
|
||||
setattr(self, key, val)
|
||||
|
||||
@@ -161,7 +159,7 @@ class SyncOperation(object):
|
||||
def __init__(self, src, info, **kw):
|
||||
self.src = src
|
||||
self.info = info
|
||||
for key, val in pycompat.items(kw):
|
||||
for key, val in kw.items():
|
||||
setattr(self, key, val)
|
||||
|
||||
def __str__(self):
|
||||
@@ -689,7 +687,7 @@ class GoogleCalendar(models.AbstractModel):
|
||||
|
||||
my_google_attendees = CalendarAttendee.with_context(context_novirtual).search([
|
||||
('partner_id', '=', my_partner_id),
|
||||
('google_internal_event_id', 'in', pycompat.keys(all_event_from_google))
|
||||
('google_internal_event_id', 'in', all_event_from_google.keys())
|
||||
])
|
||||
my_google_att_ids = my_google_attendees.ids
|
||||
|
||||
@@ -753,7 +751,7 @@ class GoogleCalendar(models.AbstractModel):
|
||||
ev_to_sync.OE.status = event.active
|
||||
ev_to_sync.OE.synchro = att.oe_synchro_date
|
||||
|
||||
for event in pycompat.values(all_event_from_google):
|
||||
for event in all_event_from_google.values():
|
||||
event_id = event.get('id')
|
||||
base_event_id = event_id.rsplit('_', 1)[0]
|
||||
|
||||
@@ -788,7 +786,7 @@ class GoogleCalendar(models.AbstractModel):
|
||||
# DO ACTION #
|
||||
######################
|
||||
for base_event in event_to_synchronize:
|
||||
event_to_synchronize[base_event] = sorted(pycompat.items(event_to_synchronize[base_event]), key=operator.itemgetter(0))
|
||||
event_to_synchronize[base_event] = sorted(event_to_synchronize[base_event].items(), key=operator.itemgetter(0))
|
||||
for current_event in event_to_synchronize[base_event]:
|
||||
self.env.cr.commit()
|
||||
event = current_event[1] # event is an Sync Event !
|
||||
|
||||
@@ -7,7 +7,6 @@ from odoo import api, fields, models
|
||||
from odoo import tools, _
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.modules.module import get_module_resource
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -250,7 +249,7 @@ class Employee(models.Model):
|
||||
if auto_follow_fields is None:
|
||||
auto_follow_fields = ['user_id']
|
||||
user_field_lst = []
|
||||
for name, field in pycompat.items(self._fields):
|
||||
for name, field in self._fields.items():
|
||||
if name in auto_follow_fields and name in updated_fields and field.comodel_name == 'res.users':
|
||||
user_field_lst.append(name)
|
||||
return user_field_lst
|
||||
|
||||
@@ -5,7 +5,7 @@ import re
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import email_split, float_is_zero, pycompat
|
||||
from odoo.tools import email_split, float_is_zero
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
@@ -243,7 +243,7 @@ class HrExpense(models.Model):
|
||||
expense.sheet_id.write({'account_move_id': move.id})
|
||||
if expense.payment_mode == 'company_account':
|
||||
expense.sheet_id.paid_expense_sheets()
|
||||
for move in pycompat.values(move_group_by_sheet):
|
||||
for move in move_group_by_sheet.values():
|
||||
move.post()
|
||||
return True
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ import babel
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class HrPayslip(models.Model):
|
||||
_name = 'hr.payslip'
|
||||
@@ -205,7 +203,7 @@ class HrPayslip(models.Model):
|
||||
}
|
||||
|
||||
res.append(attendances)
|
||||
res.extend(pycompat.values(leaves))
|
||||
res.extend(leaves.values())
|
||||
return res
|
||||
|
||||
@api.model
|
||||
@@ -369,7 +367,7 @@ class HrPayslip(models.Model):
|
||||
#blacklist this rule and its children
|
||||
blacklist += [id for id, seq in rule._recursive_search_of_rules()]
|
||||
|
||||
return [value for code, value in pycompat.items(result_dict)]
|
||||
return list(result_dict.values())
|
||||
|
||||
# YTI TODO To rename. This method is not really an onchange, as it is not in any view
|
||||
# employee_id and contract_id could be browse records
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class PayslipDetailsReport(models.AbstractModel):
|
||||
_name = 'report.hr_payroll.report_payslipdetails'
|
||||
@@ -38,9 +36,9 @@ class PayslipDetailsReport(models.AbstractModel):
|
||||
result.setdefault(x[2], {})
|
||||
result[x[2]].setdefault(x[1], [])
|
||||
result[x[2]][x[1]].append(x[0])
|
||||
for payslip_id, lines_dict in pycompat.items(result):
|
||||
for payslip_id, lines_dict in result.items():
|
||||
res.setdefault(payslip_id, [])
|
||||
for rule_categ_id, line_ids in pycompat.items(lines_dict):
|
||||
for rule_categ_id, line_ids in lines_dict.items():
|
||||
rule_categories = RuleCateg.browse(rule_categ_id)
|
||||
lines = PayslipLine.browse(line_ids)
|
||||
level = 0
|
||||
@@ -70,9 +68,9 @@ class PayslipDetailsReport(models.AbstractModel):
|
||||
result.setdefault(line.slip_id.id, {})
|
||||
result[line.slip_id.id].setdefault(line.register_id, line)
|
||||
result[line.slip_id.id][line.register_id] |= line
|
||||
for payslip_id, lines_dict in pycompat.items(result):
|
||||
for payslip_id, lines_dict in result.items():
|
||||
res.setdefault(payslip_id, [])
|
||||
for register, lines in pycompat.items(lines_dict):
|
||||
for register, lines in lines_dict.items():
|
||||
res[payslip_id].append({
|
||||
'register_name': register.name,
|
||||
'total': sum(lines.mapped('total')),
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
from datetime import datetime
|
||||
|
||||
from odoo import api, fields, models, tools, SUPERUSER_ID
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.translate import _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
@@ -251,7 +250,7 @@ class Applicant(models.Model):
|
||||
self = self.with_context(default_department_id=vals.get('department_id'))
|
||||
if vals.get('job_id') or self._context.get('default_job_id'):
|
||||
job_id = vals.get('job_id') or self._context.get('default_job_id')
|
||||
for key, value in pycompat.items(self._onchange_job_id_internal(job_id)['value']):
|
||||
for key, value in self._onchange_job_id_internal(job_id)['value'].items():
|
||||
if key not in vals:
|
||||
vals[key] = value
|
||||
if vals.get('user_id'):
|
||||
|
||||
@@ -6,8 +6,6 @@ import re
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from odoo import api, fields, models, modules, tools
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class ImLivechatChannel(models.Model):
|
||||
""" Livechat Channel
|
||||
@@ -96,7 +94,7 @@ class ImLivechatChannel(models.Model):
|
||||
for record in self:
|
||||
dt = fields.Datetime.to_string(datetime.utcnow() - timedelta(days=7))
|
||||
repartition = record.channel_ids.rating_get_grades([('create_date', '>=', dt)])
|
||||
total = sum(pycompat.values(repartition))
|
||||
total = sum(repartition.values())
|
||||
if total > 0:
|
||||
happy = repartition['great']
|
||||
record.rating_percentage_satisfaction = ((happy*100) / total) if happy > 0 else 0
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class ChannelPartner(models.Model):
|
||||
_inherit = 'mail.channel.partner'
|
||||
@@ -78,7 +76,7 @@ class MailChannel(models.Model):
|
||||
last_msg = self.env['mail.message'].search([("channel_ids", "in", [channel.id])], limit=1)
|
||||
if last_msg:
|
||||
channel_infos_dict[channel.id]['last_message_date'] = last_msg.date
|
||||
return list(pycompat.values(channel_infos_dict))
|
||||
return list(channel_infos_dict.values())
|
||||
|
||||
@api.model
|
||||
def channel_fetch_slot(self):
|
||||
|
||||
@@ -5,8 +5,6 @@ from datetime import date
|
||||
|
||||
from odoo import api, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class EmployeesYearlySalaryReport(models.AbstractModel):
|
||||
_name = 'report.l10n_in_hr_payroll.report_hryearlysalary'
|
||||
@@ -99,7 +97,7 @@ class EmployeesYearlySalaryReport(models.AbstractModel):
|
||||
|
||||
def salary_list(self, salaries):
|
||||
cat_salary_all = []
|
||||
for category_name, amount in pycompat.items(salaries):
|
||||
for category_name, amount in salaries.items():
|
||||
cat_salary = []
|
||||
total = 0.0
|
||||
cat_salary.append(category_name)
|
||||
|
||||
@@ -59,7 +59,7 @@ class LuxTaxGenerator:
|
||||
if tax_code in tax_codes:
|
||||
raise RuntimeError('duplicate tax code %s' % tax_code)
|
||||
tax_codes[tax_code] = row['id']
|
||||
writer.writerow([pycompat.to_text(v) for v in pycompat.values(row)])
|
||||
writer.writerow([pycompat.to_text(v) for v in row.values()])
|
||||
|
||||
# read taxes and add leaf tax codes
|
||||
new_tax_codes = {} # id: parent_code
|
||||
@@ -162,7 +162,7 @@ class LuxTaxGenerator:
|
||||
cur_seq = seq
|
||||
writer.writerow([
|
||||
pycompat.to_text(v)
|
||||
for v in list(pycompat.values(row))[3:]
|
||||
for v in list(row.values())[3:]
|
||||
] + [cur_seq])
|
||||
|
||||
def fiscal_pos_map_to_csv(self):
|
||||
@@ -173,7 +173,7 @@ class LuxTaxGenerator:
|
||||
keys = next(fiscal_pos_map_iterator)
|
||||
writer.writerow(keys)
|
||||
for row in fiscal_pos_map_iterator:
|
||||
writer.writerow([pycompat.to_text(s) for s in pycompat.values(row)])
|
||||
writer.writerow([pycompat.to_text(s) for s in row.values()])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -12,7 +12,7 @@ from werkzeug import urls, utils
|
||||
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.tools import ustr, pycompat
|
||||
from odoo.tools import ustr
|
||||
|
||||
URL_REGEX = r'(\bhref=[\'"](?!mailto:)([^\'"]+)[\'"])'
|
||||
|
||||
@@ -165,7 +165,7 @@ class link_tracker(models.Model):
|
||||
create_vals['url'] = VALIDATE_URL(vals['url'])
|
||||
|
||||
search_domain = []
|
||||
for fname, value in pycompat.items(create_vals):
|
||||
for fname, value in create_vals.items():
|
||||
search_domain.append((fname, '=', value))
|
||||
|
||||
result = self.search(search_domain, limit=1)
|
||||
|
||||
@@ -10,8 +10,6 @@ from odoo import api, fields, models, _
|
||||
from odoo.exceptions import AccessError, ValidationError
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class LunchOrder(models.Model):
|
||||
"""
|
||||
@@ -26,10 +24,10 @@ class LunchOrder(models.Model):
|
||||
prev_order = self.env['lunch.order.line'].search([('user_id', '=', self.env.uid), ('product_id.active', '!=', False)], limit=20, order='id desc')
|
||||
# If we return return prev_order.ids, we will have duplicates (identical orders).
|
||||
# Therefore, this following part removes duplicates based on product_id and note.
|
||||
return list(pycompat.values({
|
||||
return list({
|
||||
(order.product_id, order.note): order.id
|
||||
for order in prev_order
|
||||
}))
|
||||
}.values())
|
||||
|
||||
user_id = fields.Many2one('res.users', 'User', readonly=True,
|
||||
states={'new': [('readonly', False)]},
|
||||
@@ -88,10 +86,10 @@ class LunchOrder(models.Model):
|
||||
prev_order = self.env['lunch.order.line'].search([('user_id', '=', self.env.uid), ('product_id.active', '!=', False)], limit=20, order='date desc, id desc')
|
||||
# If we use prev_order.ids, we will have duplicates (identical orders).
|
||||
# Therefore, this following part removes duplicates based on product_id and note.
|
||||
self.previous_order_ids = list(pycompat.values({
|
||||
self.previous_order_ids = list({
|
||||
(order.product_id, order.note): order.id
|
||||
for order in prev_order
|
||||
}))
|
||||
}.values())
|
||||
|
||||
if self.previous_order_ids:
|
||||
lunch_data = {}
|
||||
|
||||
@@ -9,7 +9,7 @@ import uuid
|
||||
from odoo import _, api, fields, models, modules, tools
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import ormcache, pycompat
|
||||
from odoo.tools import ormcache
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
|
||||
@@ -619,7 +619,7 @@ class Channel(models.Model):
|
||||
channel = channels_preview[message['id']]
|
||||
del(channel['message_id'])
|
||||
channel['last_message'] = message
|
||||
return list(pycompat.values(channels_preview))
|
||||
return list(channels_preview.values())
|
||||
|
||||
#------------------------------------------------------
|
||||
# Commands
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class Followers(models.Model):
|
||||
@@ -42,7 +41,7 @@ class Followers(models.Model):
|
||||
using the subtypes given in the parameters
|
||||
"""
|
||||
res_model_id = self.env['ir.model']._get(res_model).id
|
||||
force_mode = force or (all(data for data in pycompat.values(partner_data)) and all(data for data in pycompat.values(channel_data)))
|
||||
force_mode = force or (all(partner_data.values()) and all(channel_data.values()))
|
||||
generic = []
|
||||
specific = {}
|
||||
existing = {} # {res_id: follower_ids}
|
||||
@@ -71,13 +70,13 @@ class Followers(models.Model):
|
||||
|
||||
if force_mode:
|
||||
employee_pids = self.env['res.users'].sudo().search([('partner_id', 'in', list(partner_data)), ('share', '=', False)]).mapped('partner_id').ids
|
||||
for pid, data in pycompat.items(partner_data):
|
||||
for pid, data in partner_data.items():
|
||||
if not data:
|
||||
if pid not in employee_pids:
|
||||
partner_data[pid] = external_default_subtypes.ids
|
||||
else:
|
||||
partner_data[pid] = default_subtypes.ids
|
||||
for cid, data in pycompat.items(channel_data):
|
||||
for cid, data in channel_data.items():
|
||||
if not data:
|
||||
channel_data[cid] = default_subtypes.ids
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ from email.utils import formataddr
|
||||
from odoo import _, api, fields, models
|
||||
from odoo import tools
|
||||
from odoo.addons.base.ir.ir_mail_server import MailDeliveryException
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -205,7 +204,7 @@ class MailMail(models.Model):
|
||||
groups[mail.mail_server_id.id].append(mail.id)
|
||||
sys_params = self.env['ir.config_parameter'].sudo()
|
||||
batch_size = int(sys_params.get_param('mail.session.batch.size', 1000))
|
||||
for server_id, record_ids in pycompat.items(groups):
|
||||
for server_id, record_ids in groups.items():
|
||||
for mail_batch in tools.split_every(batch_size, record_ids):
|
||||
yield server_id, mail_batch
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ from email.utils import formataddr
|
||||
from odoo import _, api, fields, models, modules, SUPERUSER_ID, tools
|
||||
from odoo.exceptions import UserError, AccessError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
_image_dataurl = re.compile(r'(data:image/[a-z]+?);base64,([a-z0-9+/]{3,}=*)([\'"])', re.I)
|
||||
@@ -282,7 +281,7 @@ class Message(models.Model):
|
||||
partners = self.env['res.partner'].sudo()
|
||||
attachments = self.env['ir.attachment']
|
||||
trackings = self.env['mail.tracking.value']
|
||||
for key, message in pycompat.items(message_tree):
|
||||
for key, message in message_tree.items():
|
||||
if message.author_id:
|
||||
partners |= message.author_id
|
||||
if message.subtype_id and message.partner_ids: # take notified people of message with a subtype
|
||||
@@ -446,7 +445,7 @@ class Message(models.Model):
|
||||
def _find_allowed_doc_ids(self, model_ids):
|
||||
IrModelAccess = self.env['ir.model.access']
|
||||
allowed_ids = set()
|
||||
for doc_model, doc_dict in pycompat.items(model_ids):
|
||||
for doc_model, doc_dict in model_ids.items():
|
||||
if not IrModelAccess.check(doc_model, 'read', False):
|
||||
continue
|
||||
allowed_ids |= self._find_allowed_model_wise(doc_model, doc_dict)
|
||||
@@ -607,17 +606,17 @@ class Message(models.Model):
|
||||
# Author condition (READ, WRITE, CREATE (private))
|
||||
author_ids = []
|
||||
if operation == 'read' or operation == 'write':
|
||||
author_ids = [mid for mid, message in pycompat.items(message_values)
|
||||
author_ids = [mid for mid, message in message_values.items()
|
||||
if message.get('author_id') and message.get('author_id') == self.env.user.partner_id.id]
|
||||
elif operation == 'create':
|
||||
author_ids = [mid for mid, message in pycompat.items(message_values)
|
||||
author_ids = [mid for mid, message in message_values.items()
|
||||
if not message.get('model') and not message.get('res_id')]
|
||||
|
||||
# Parent condition, for create (check for received notifications for the created message parent)
|
||||
notified_ids = []
|
||||
if operation == 'create':
|
||||
# TDE: probably clean me
|
||||
parent_ids = [message.get('parent_id') for mid, message in pycompat.items(message_values)
|
||||
parent_ids = [message.get('parent_id') for message in message_values.values()
|
||||
if message.get('parent_id')]
|
||||
self._cr.execute("""SELECT DISTINCT m.id, partner_rel.res_partner_id, channel_partner.partner_id FROM "%s" m
|
||||
LEFT JOIN "mail_message_res_partner_rel" partner_rel
|
||||
@@ -630,37 +629,37 @@ class Message(models.Model):
|
||||
ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = (%%s)
|
||||
WHERE m.id = ANY (%%s)""" % self._table, (self.env.user.partner_id.id, self.env.user.partner_id.id, parent_ids,))
|
||||
not_parent_ids = [mid[0] for mid in self._cr.fetchall() if any([mid[1], mid[2]])]
|
||||
notified_ids += [mid for mid, message in pycompat.items(message_values)
|
||||
notified_ids += [mid for mid, message in message_values.items()
|
||||
if message.get('parent_id') in not_parent_ids]
|
||||
|
||||
# Recipients condition, for read and write (partner_ids) and create (message_follower_ids)
|
||||
other_ids = set(self.ids).difference(set(author_ids), set(notified_ids))
|
||||
model_record_ids = _generate_model_record_ids(message_values, other_ids)
|
||||
if operation in ['read', 'write']:
|
||||
notified_ids = [mid for mid, message in pycompat.items(message_values) if message.get('notified')]
|
||||
notified_ids = [mid for mid, message in message_values.items() if message.get('notified')]
|
||||
elif operation == 'create':
|
||||
for doc_model, doc_ids in pycompat.items(model_record_ids):
|
||||
for doc_model, doc_ids in model_record_ids.items():
|
||||
followers = self.env['mail.followers'].sudo().search([
|
||||
('res_model', '=', doc_model),
|
||||
('res_id', 'in', list(doc_ids)),
|
||||
('partner_id', '=', self.env.user.partner_id.id),
|
||||
])
|
||||
fol_mids = [follower.res_id for follower in followers]
|
||||
notified_ids += [mid for mid, message in pycompat.items(message_values)
|
||||
notified_ids += [mid for mid, message in message_values.items()
|
||||
if message.get('model') == doc_model and message.get('res_id') in fol_mids]
|
||||
|
||||
# CRUD: Access rights related to the document
|
||||
other_ids = other_ids.difference(set(notified_ids))
|
||||
model_record_ids = _generate_model_record_ids(message_values, other_ids)
|
||||
document_related_ids = []
|
||||
for model, doc_ids in pycompat.items(model_record_ids):
|
||||
for model, doc_ids in model_record_ids.items():
|
||||
DocumentModel = self.env[model]
|
||||
mids = DocumentModel.browse(doc_ids).exists()
|
||||
if hasattr(DocumentModel, 'check_mail_message_access'):
|
||||
DocumentModel.check_mail_message_access(mids.ids, operation) # ?? mids ?
|
||||
else:
|
||||
self.env['mail.thread'].check_mail_message_access(mids.ids, operation, model_name=model)
|
||||
document_related_ids += [mid for mid, message in pycompat.items(message_values)
|
||||
document_related_ids += [mid for mid, message in message_values.items()
|
||||
if message.get('model') == model and message.get('res_id') in mids.ids]
|
||||
|
||||
# Calculate remaining ids: if not void, raise an error
|
||||
|
||||
@@ -379,7 +379,7 @@ class MailTemplate(models.Model):
|
||||
'user': self.env.user,
|
||||
'ctx': self._context, # context kw would clash with mako internals
|
||||
}
|
||||
for res_id, record in pycompat.items(res_to_rec):
|
||||
for res_id, record in res_to_rec.items():
|
||||
variables['object'] = record
|
||||
try:
|
||||
render_result = template.render(variables)
|
||||
@@ -391,7 +391,7 @@ class MailTemplate(models.Model):
|
||||
results[res_id] = render_result
|
||||
|
||||
if post_process:
|
||||
for res_id, result in pycompat.items(results):
|
||||
for res_id, result in results.items():
|
||||
results[res_id] = self.render_post_process(result)
|
||||
|
||||
return multi_mode and results or results[res_ids[0]]
|
||||
@@ -412,7 +412,7 @@ class MailTemplate(models.Model):
|
||||
self.ensure_one()
|
||||
|
||||
langs = self.render_template(self.lang, self.model, res_ids)
|
||||
for res_id, lang in pycompat.items(langs):
|
||||
for res_id, lang in langs.items():
|
||||
if lang:
|
||||
template = self.with_context(lang=lang)
|
||||
else:
|
||||
@@ -431,11 +431,11 @@ class MailTemplate(models.Model):
|
||||
|
||||
if self.use_default_to or self._context.get('tpl_force_default_to'):
|
||||
default_recipients = self.env['mail.thread'].message_get_default_recipients(res_model=self.model, res_ids=res_ids)
|
||||
for res_id, recipients in pycompat.items(default_recipients):
|
||||
for res_id, recipients in default_recipients.items():
|
||||
results[res_id].pop('partner_to', None)
|
||||
results[res_id].update(recipients)
|
||||
|
||||
for res_id, values in pycompat.items(results):
|
||||
for res_id, values in results.items():
|
||||
partner_ids = values.get('partner_ids', list())
|
||||
if self._context.get('tpl_partners_only'):
|
||||
mails = tools.email_split(values.pop('email_to', '')) + tools.email_split(values.pop('email_cc', ''))
|
||||
@@ -474,11 +474,11 @@ class MailTemplate(models.Model):
|
||||
|
||||
# templates: res_id -> template; template -> res_ids
|
||||
templates_to_res_ids = {}
|
||||
for res_id, template in pycompat.items(res_ids_to_templates):
|
||||
for res_id, template in res_ids_to_templates.items():
|
||||
templates_to_res_ids.setdefault(template, []).append(res_id)
|
||||
|
||||
results = dict()
|
||||
for template, template_res_ids in pycompat.items(templates_to_res_ids):
|
||||
for template, template_res_ids in templates_to_res_ids.items():
|
||||
Template = self.env['mail.template']
|
||||
# generate fields value for all res_ids linked to the current template
|
||||
if template.lang:
|
||||
@@ -488,7 +488,7 @@ class MailTemplate(models.Model):
|
||||
generated_field_values = Template.render_template(
|
||||
getattr(template, field), template.model, template_res_ids,
|
||||
post_process=(field == 'body_html'))
|
||||
for res_id, field_value in pycompat.items(generated_field_values):
|
||||
for res_id, field_value in generated_field_values.items():
|
||||
results.setdefault(res_id, dict())[field] = field_value
|
||||
# compute recipients
|
||||
if any(field in fields for field in ['email_to', 'partner_to', 'email_cc']):
|
||||
|
||||
@@ -26,7 +26,6 @@ from werkzeug import url_encode
|
||||
|
||||
from odoo import _, api, exceptions, fields, models, tools
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.pycompat import text_type
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
|
||||
@@ -239,7 +238,7 @@ class MailThread(models.AbstractModel):
|
||||
|
||||
# auto_subscribe: take values and defaults into account
|
||||
create_values = dict(values)
|
||||
for key, val in pycompat.items(self._context):
|
||||
for key, val in self._context.items():
|
||||
if key.startswith('default_') and key[8:] not in create_values:
|
||||
create_values[key[8:]] = val
|
||||
thread.message_auto_subscribe(list(create_values), values=create_values)
|
||||
@@ -389,7 +388,7 @@ class MailThread(models.AbstractModel):
|
||||
always tracked fields and modified on_change fields
|
||||
"""
|
||||
tracked_fields = []
|
||||
for name, field in pycompat.items(self._fields):
|
||||
for name, field in self._fields.items():
|
||||
if getattr(field, 'track_visibility', False):
|
||||
tracked_fields.append(name)
|
||||
|
||||
@@ -417,10 +416,10 @@ class MailThread(models.AbstractModel):
|
||||
|
||||
@api.multi
|
||||
def _message_track_post_template(self, tracking):
|
||||
if not any(change for rec_id, (change, tracking_value_ids) in pycompat.items(tracking)):
|
||||
if not any(change for rec_id, (change, tracking_value_ids) in tracking.items()):
|
||||
return True
|
||||
templates = self._track_template(tracking)
|
||||
for field_name, (template, post_kwargs) in pycompat.items(templates):
|
||||
for field_name, (template, post_kwargs) in templates.items():
|
||||
if not template:
|
||||
continue
|
||||
if isinstance(template, pycompat.string_types):
|
||||
@@ -451,7 +450,7 @@ class MailThread(models.AbstractModel):
|
||||
display_values_ids = []
|
||||
|
||||
# generate tracked_values data structure: {'col_name': {col_info, new_value, old_value}}
|
||||
for col_name, col_info in pycompat.items(tracked_fields):
|
||||
for col_name, col_info in tracked_fields.items():
|
||||
track_visibility = getattr(self._fields[col_name], 'track_visibility', 'onchange')
|
||||
initial_value = initial[col_name]
|
||||
new_value = getattr(self, col_name)
|
||||
@@ -817,7 +816,7 @@ class MailThread(models.AbstractModel):
|
||||
def message_capable_models(self):
|
||||
""" Used by the plugin addon, based for plugin_outlook and others. """
|
||||
ret_dict = {}
|
||||
for model_name, model in pycompat.items(self.env):
|
||||
for model_name, model in self.env.items():
|
||||
if hasattr(model, "message_process") and hasattr(model, "message_post"):
|
||||
ret_dict[model_name] = model._description
|
||||
return ret_dict
|
||||
@@ -2057,7 +2056,7 @@ class MailThread(models.AbstractModel):
|
||||
if auto_follow_fields is None:
|
||||
auto_follow_fields = ['user_id']
|
||||
user_field_lst = []
|
||||
for name, field in pycompat.items(self._fields):
|
||||
for name, field in self._fields.items():
|
||||
if name in auto_follow_fields and name in updated_fields and getattr(field, 'track_visibility', False) and field.comodel_name == 'res.users':
|
||||
user_field_lst.append(name)
|
||||
return user_field_lst
|
||||
@@ -2153,10 +2152,10 @@ class MailThread(models.AbstractModel):
|
||||
for partner in to_add_users.mapped('partner_id'):
|
||||
new_partners.setdefault(partner.id, None)
|
||||
|
||||
for pid, subtypes in pycompat.items(new_partners):
|
||||
for pid, subtypes in new_partners.items():
|
||||
subtypes = list(subtypes) if subtypes is not None else None
|
||||
self.message_subscribe(partner_ids=[pid], subtype_ids=subtypes, force=(subtypes != None))
|
||||
for cid, subtypes in pycompat.items(new_channels):
|
||||
for cid, subtypes in new_channels.items():
|
||||
subtypes = list(subtypes) if subtypes is not None else None
|
||||
self.message_subscribe(channel_ids=[cid], subtype_ids=subtypes, force=(subtypes != None))
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
import logging
|
||||
import threading
|
||||
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.misc import split_every
|
||||
|
||||
from odoo import _, api, fields, models, registry, SUPERUSER_ID
|
||||
@@ -175,7 +174,7 @@ class Partner(models.Model):
|
||||
|
||||
emails = self.env['mail.mail']
|
||||
recipients_nbr, recipients_max = 0, 50
|
||||
for email_type, recipient_template_values in pycompat.items(recipients):
|
||||
for email_type, recipient_template_values in recipients.items():
|
||||
if recipient_template_values['followers']:
|
||||
# generate notification email content
|
||||
template_fol_values = dict(base_template_ctx, **recipient_template_values) # fixme: set button_unfollow to none
|
||||
|
||||
@@ -140,7 +140,7 @@ class MailComposer(models.TransientModel):
|
||||
for mid, rmod, rid in self._cr.fetchall():
|
||||
message_values[mid] = {'model': rmod, 'res_id': rid}
|
||||
# remove from the set to check the ids that mail_compose_message accepts
|
||||
author_ids = [mid for mid, message in pycompat.items(message_values)
|
||||
author_ids = [mid for mid, message in message_values.items()
|
||||
if message.get('model') and not message.get('res_id')]
|
||||
self = self.browse(list(set(self.ids) - set(author_ids))) # not sure slef = ...
|
||||
|
||||
@@ -248,7 +248,7 @@ class MailComposer(models.TransientModel):
|
||||
for res_ids in sliced_res_ids:
|
||||
batch_mails = Mail
|
||||
all_mail_values = wizard.get_mail_values(res_ids)
|
||||
for res_id, mail_values in pycompat.items(all_mail_values):
|
||||
for res_id, mail_values in all_mail_values.items():
|
||||
if wizard.composition_mode == 'mass_mail':
|
||||
batch_mails |= Mail.create(mail_values)
|
||||
else:
|
||||
@@ -338,7 +338,7 @@ class MailComposer(models.TransientModel):
|
||||
def onchange_template_id_wrapper(self):
|
||||
self.ensure_one()
|
||||
values = self.onchange_template_id(self.template_id.id, self.composition_mode, self.model, self.res_id)['value']
|
||||
for fname, value in pycompat.items(values):
|
||||
for fname, value in values.items():
|
||||
setattr(self, fname, value)
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -9,7 +9,6 @@ import re
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
@@ -466,7 +465,7 @@ class MarketingCampaignWorkitem(models.Model):
|
||||
matching_workitems = []
|
||||
for id, res_id, model in res:
|
||||
workitem_map.setdefault(model, {}).setdefault(res_id, set()).add(id)
|
||||
for model, id_map in pycompat.items(workitem_map):
|
||||
for model, id_map in workitem_map.items():
|
||||
Model = self.env[model]
|
||||
condition_name[0] = Model._rec_name
|
||||
condition = [('id', 'in', list(id_map)), condition_name]
|
||||
|
||||
@@ -5,7 +5,6 @@ from dateutil import relativedelta
|
||||
import datetime
|
||||
|
||||
from odoo import api, exceptions, fields, models, _
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class MrpWorkcenter(models.Model):
|
||||
@@ -74,7 +73,7 @@ class MrpWorkcenter(models.Model):
|
||||
if res_group['state'] in ('pending', 'ready', 'progress'):
|
||||
result_duration_expected[res_group['workcenter_id'][0]] += res_group['duration_expected']
|
||||
for workcenter in self:
|
||||
workcenter.workorder_count = sum(count for state, count in pycompat.items(result[workcenter.id]) if state not in ('done', 'cancel'))
|
||||
workcenter.workorder_count = sum(count for state, count in result[workcenter.id].items() if state not in ('done', 'cancel'))
|
||||
workcenter.workorder_pending_count = result[workcenter.id].get('pending', 0)
|
||||
workcenter.workcenter_load = result_duration_expected[workcenter.id]
|
||||
workcenter.workorder_ready_count = result[workcenter.id].get('ready', 0)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class MakeInvoice(models.TransientModel):
|
||||
@@ -25,7 +24,7 @@ class MakeInvoice(models.TransientModel):
|
||||
# but that second call will not do anything, since the repairs are already invoiced.
|
||||
repairs.action_repair_invoice_create()
|
||||
return {
|
||||
'domain': [('id', 'in', list(pycompat.values(new_invoice)))],
|
||||
'domain': [('id', 'in', list(new_invoice.values()))],
|
||||
'name': 'Invoices',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
|
||||
@@ -10,7 +10,7 @@ import requests
|
||||
|
||||
from odoo import api, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import html2plaintext, pycompat
|
||||
from odoo.tools import html2plaintext
|
||||
|
||||
from ..py_etherpad import EtherpadLiteClient
|
||||
|
||||
@@ -106,7 +106,7 @@ class PadCommon(models.AbstractModel):
|
||||
|
||||
# In case the pad is created programmatically, the content is not filled in yet since it is
|
||||
# normally initialized by the JS layer
|
||||
for k, field in pycompat.items(self._fields):
|
||||
for k, field in self._fields.items():
|
||||
if hasattr(field, 'pad_content_field') and k not in vals:
|
||||
ctx = {
|
||||
'model': self._name,
|
||||
@@ -121,7 +121,7 @@ class PadCommon(models.AbstractModel):
|
||||
def _set_pad_value(self, vals):
|
||||
|
||||
# Update the pad if the `pad_content_field` is modified
|
||||
for k, field in pycompat.items(self._fields):
|
||||
for k, field in self._fields.items():
|
||||
if hasattr(field, 'pad_content_field') and vals.get(field.pad_content_field) and self[k]:
|
||||
company = self.env.user.sudo().company_id
|
||||
myPad = EtherpadLiteClient(company.pad_key, company.pad_server + '/api')
|
||||
@@ -129,7 +129,7 @@ class PadCommon(models.AbstractModel):
|
||||
myPad.setText(path, (html2plaintext(vals[field.pad_content_field]).encode('utf-8')))
|
||||
|
||||
# Update the `pad_content_field` if the pad is modified
|
||||
for k, v in list(pycompat.items(vals)):
|
||||
for k, v in vals.items():
|
||||
field = self._fields[k]
|
||||
if hasattr(field, 'pad_content_field'):
|
||||
vals[field.pad_content_field] = self.pad_get_content(v)
|
||||
@@ -139,7 +139,7 @@ class PadCommon(models.AbstractModel):
|
||||
self.ensure_one()
|
||||
if not default:
|
||||
default = {}
|
||||
for k, field in pycompat.items(self._fields):
|
||||
for k, field in self._fields.items():
|
||||
if hasattr(field, 'pad_content_field'):
|
||||
pad = self.pad_generate_url()
|
||||
default[k] = pad.get('url')
|
||||
|
||||
@@ -5,7 +5,7 @@ import logging
|
||||
import datetime
|
||||
|
||||
from odoo import api, exceptions, fields, models, _
|
||||
from odoo.tools import consteq, float_round, image_resize_images, ustr, pycompat
|
||||
from odoo.tools import consteq, float_round, image_resize_images, ustr
|
||||
from odoo.addons.base.module import module
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
@@ -169,7 +169,7 @@ class PaymentAcquirer(models.Model):
|
||||
""" If the field has 'required_if_provider="<provider>"' attribute, then it
|
||||
required if record.provider is <provider>. """
|
||||
for acquirer in self:
|
||||
if any(getattr(f, 'required_if_provider', None) == acquirer.provider and not acquirer[k] for k, f in pycompat.items(self._fields)):
|
||||
if any(getattr(f, 'required_if_provider', None) == acquirer.provider and not acquirer[k] for k, f in self._fields.items()):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ from odoo import api, fields, models, tools, _
|
||||
from odoo.addons.payment.models.payment_acquirer import ValidationError
|
||||
from odoo.addons.payment_adyen.controllers.main import AdyenController
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -52,7 +50,7 @@ class AcquirerAdyen(models.Model):
|
||||
def signParams(parms):
|
||||
signing_string = ':'.join(
|
||||
escapeVal(v)
|
||||
for v in chain(pycompat.keys(parms), pycompat.values(parms))
|
||||
for v in chain(parms.keys(), parms.values())
|
||||
)
|
||||
hm = hmac.new(hmac_key, signing_string.encode('utf-8'), hashlib.sha256)
|
||||
return base64.b64encode(hm.digest())
|
||||
@@ -81,7 +79,7 @@ class AcquirerAdyen(models.Model):
|
||||
|
||||
hmac_key = binascii.a2b_hex(self.adyen_skin_hmac_key.encode('ascii'))
|
||||
raw_values = {k: values.get(k.encode('ascii'), '') for k in keys if k in values}
|
||||
raw_values_ordered = OrderedDict(sorted(pycompat.items(raw_values), key=lambda t: t[0]))
|
||||
raw_values_ordered = OrderedDict(sorted(raw_values.items(), key=lambda t: t[0]))
|
||||
|
||||
return signParams(raw_values_ordered)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import odoo
|
||||
from odoo.addons.payment.models.payment_acquirer import ValidationError
|
||||
from odoo.addons.payment.tests.common import PaymentAcquirerCommon
|
||||
from odoo.addons.payment_authorize.controllers.main import AuthorizeController
|
||||
from odoo.tools import mute_logger, pycompat
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
@odoo.tests.common.at_install(True)
|
||||
@@ -91,7 +91,7 @@ class AuthorizeForm(AuthorizeCommon):
|
||||
tree = objectify.fromstring(res)
|
||||
self.assertEqual(tree.get('action'), 'https://test.authorize.net/gateway/transact.dll', 'Authorize: wrong form POST url')
|
||||
for el in tree.iterfind('input'):
|
||||
values = list(pycompat.values(el.attrib))
|
||||
values = list(el.attrib.values())
|
||||
if values[1] in ['submit', 'x_fp_hash', 'return_url', 'x_state', 'x_ship_to_state']:
|
||||
continue
|
||||
self.assertEqual(
|
||||
|
||||
@@ -6,7 +6,6 @@ import werkzeug
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -27,6 +26,6 @@ class BuckarooController(http.Controller):
|
||||
""" Buckaroo."""
|
||||
_logger.info('Buckaroo: entering form_feedback with post data %s', pprint.pformat(post)) # debug
|
||||
request.env['payment.transaction'].sudo().form_feedback(post, 'buckaroo')
|
||||
post = {key.upper(): value for key, value in pycompat.items(post)}
|
||||
post = {key.upper(): value for key, value in post.items()}
|
||||
return_url = post.get('ADD_RETURNDATA') or '/'
|
||||
return werkzeug.utils.redirect(return_url)
|
||||
|
||||
@@ -8,7 +8,6 @@ from odoo import api, fields, models, _
|
||||
from odoo.addons.payment.models.payment_acquirer import ValidationError
|
||||
from odoo.addons.payment_buckaroo.controllers.main import BuckarooController
|
||||
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.float_utils import float_compare
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -21,7 +20,7 @@ def normalize_keys_upper(data):
|
||||
convert everything to upper case to be able to easily detected the presence
|
||||
of a parameter by checking the uppercase key only
|
||||
"""
|
||||
return {key.upper(): val for key, val in pycompat.items(data)}
|
||||
return {key.upper(): val for key, val in data.items()}
|
||||
|
||||
|
||||
class AcquirerBuckaroo(models.Model):
|
||||
@@ -73,7 +72,7 @@ class AcquirerBuckaroo(models.Model):
|
||||
del values[key]
|
||||
break
|
||||
|
||||
items = sorted(pycompat.items(values), key=lambda pair: pair[0].lower())
|
||||
items = sorted(values.items(), key=lambda pair: pair[0].lower())
|
||||
sign = ''.join('%s=%s' % (k, urls.url_unquote_plus(v)) for k, v in items)
|
||||
else:
|
||||
sign = ''.join('%s=%s' % (k, get_value(k)) for k in keys)
|
||||
|
||||
@@ -15,7 +15,7 @@ from odoo import api, fields, models, _
|
||||
from odoo.addons.payment.models.payment_acquirer import ValidationError
|
||||
from odoo.addons.payment_ogone.controllers.main import OgoneController
|
||||
from odoo.addons.payment_ogone.data import ogone
|
||||
from odoo.tools import float_round, DEFAULT_SERVER_DATE_FORMAT, pycompat
|
||||
from odoo.tools import float_round, DEFAULT_SERVER_DATE_FORMAT
|
||||
from odoo.tools.float_utils import float_compare, float_repr
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
@@ -142,7 +142,7 @@ class PaymentAcquirerOgone(models.Model):
|
||||
]
|
||||
return key.upper() in keys
|
||||
|
||||
items = sorted((k.upper(), v) for k, v in pycompat.items(values))
|
||||
items = sorted((k.upper(), v) for k, v in values.items())
|
||||
sign = ''.join('%s=%s%s' % (k, v, key) for k, v in items if v and filter_key(k))
|
||||
sign = sign.encode("utf-8")
|
||||
shasign = sha1(sign).hexdigest()
|
||||
|
||||
@@ -8,7 +8,7 @@ import psycopg2
|
||||
import pytz
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.tools import float_is_zero, pycompat
|
||||
from odoo.tools import float_is_zero
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.http import request
|
||||
from odoo.addons import decimal_precision as dp
|
||||
@@ -333,7 +333,7 @@ class PosOrder(models.Model):
|
||||
|
||||
# round tax lines per order
|
||||
if rounding_method == 'round_globally':
|
||||
for group_key, group_value in pycompat.items(grouped_data):
|
||||
for group_key, group_value in grouped_data.items():
|
||||
if group_key[0] == 'tax':
|
||||
for line in group_value:
|
||||
line['credit'] = cur.round(line['credit'])
|
||||
@@ -351,7 +351,7 @@ class PosOrder(models.Model):
|
||||
order.write({'state': 'done', 'account_move': move.id})
|
||||
|
||||
all_lines = []
|
||||
for group_key, group_data in pycompat.items(grouped_data):
|
||||
for group_key, group_data in grouped_data.items():
|
||||
for value in group_data:
|
||||
all_lines.append((0, 0, value),)
|
||||
if move: # In case no order was changed
|
||||
@@ -1032,7 +1032,7 @@ class ReportSaleDetails(models.AbstractModel):
|
||||
'total_paid': user_currency.round(total),
|
||||
'payments': payments,
|
||||
'company_name': self.env.user.company_id.name,
|
||||
'taxes': list(pycompat.values(taxes)),
|
||||
'taxes': list(taxes.values()),
|
||||
'products': sorted([{
|
||||
'product_id': product.id,
|
||||
'product_name': product.name,
|
||||
@@ -1041,7 +1041,7 @@ class ReportSaleDetails(models.AbstractModel):
|
||||
'price_unit': price_unit,
|
||||
'discount': discount,
|
||||
'uom': product.uom_id.name
|
||||
} for (product, price_unit, discount), qty in pycompat.items(products_sold)], key=lambda l: l['product_name'])
|
||||
} for (product, price_unit, discount), qty in products_sold.items()], key=lambda l: l['product_name'])
|
||||
}
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -90,7 +90,7 @@ class Pricelist(models.Model):
|
||||
results = {}
|
||||
for pricelist in pricelists:
|
||||
subres = pricelist._compute_price_rule(products_qty_partner, date=date, uom_id=uom_id)
|
||||
for product_id, price in pycompat.items(subres):
|
||||
for product_id, price in subres.items():
|
||||
results.setdefault(product_id, {})
|
||||
results[product_id][pricelist.id] = price
|
||||
return results
|
||||
@@ -254,11 +254,11 @@ class Pricelist(models.Model):
|
||||
self.ensure_one()
|
||||
return {
|
||||
product_id: res_tuple[0]
|
||||
for product_id, res_tuple in pycompat.items(self._compute_price_rule(
|
||||
for product_id, res_tuple in self._compute_price_rule(
|
||||
list(pycompat.izip(products, quantities, partners)),
|
||||
date=date,
|
||||
uom_id=uom_id
|
||||
))
|
||||
).items()
|
||||
}
|
||||
|
||||
def get_product_price(self, product, quantity, partner, date=False, uom_id=False):
|
||||
@@ -280,7 +280,7 @@ class Pricelist(models.Model):
|
||||
@api.multi
|
||||
def price_get(self, prod_id, qty, partner=None):
|
||||
""" Multi pricelist, mono product - returns price per pricelist """
|
||||
return {key: price[0] for key, price in pycompat.items(self.price_rule_get(prod_id, qty, partner=partner))}
|
||||
return {key: price[0] for key, price in self.price_rule_get(prod_id, qty, partner=partner).items()}
|
||||
|
||||
@api.multi
|
||||
def price_rule_get_multi(self, products_by_qty_by_partner):
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import datetime
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class StockProductionLot(models.Model):
|
||||
@@ -54,5 +53,5 @@ class StockProductionLot(models.Model):
|
||||
@api.onchange('product_id')
|
||||
def _onchange_product(self):
|
||||
dates_dict = self._get_dates()
|
||||
for field, value in pycompat.items(dates_dict):
|
||||
for field, value in dates_dict.items():
|
||||
setattr(self, field, value)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
import time
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
@@ -139,6 +138,6 @@ class ProductProduct(models.Model):
|
||||
res[val.id]['expected_margin'] = res[val.id]['sale_expected'] - res[val.id]['normal_cost']
|
||||
res[val.id]['total_margin_rate'] = res[val.id]['turnover'] and res[val.id]['total_margin'] * 100 / res[val.id]['turnover'] or 0.0
|
||||
res[val.id]['expected_margin_rate'] = res[val.id]['sale_expected'] and res[val.id]['expected_margin'] * 100 / res[val.id]['sale_expected'] or 0.0
|
||||
for k, v in pycompat.items(res[val.id]):
|
||||
for k, v in res[val.id].items():
|
||||
setattr(val, k, v)
|
||||
return res
|
||||
|
||||
@@ -6,7 +6,6 @@ import uuid
|
||||
from odoo import api, fields, models, tools, _
|
||||
|
||||
from odoo.modules.module import get_resource_path
|
||||
from odoo.tools import pycompat
|
||||
|
||||
RATING_LIMIT_SATISFIED = 7
|
||||
RATING_LIMIT_OK = 3
|
||||
@@ -275,7 +274,7 @@ class RatingMixin(models.AbstractModel):
|
||||
values.update((d['rating'], d['rating_count']) for d in data)
|
||||
# add other stats
|
||||
if add_stats:
|
||||
rating_number = sum(pycompat.values(values))
|
||||
rating_number = sum(values.values())
|
||||
result = {
|
||||
'repartition': values,
|
||||
'avg': sum(float(key * values[key]) for key in values) / rating_number if rating_number > 0 else 0,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.tools import pycompat
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
@@ -80,13 +79,13 @@ class Project(models.Model):
|
||||
domain = [('create_date', '>=', fields.Datetime.to_string(fields.datetime.now() - timedelta(days=30)))]
|
||||
for project in self:
|
||||
activity = project.tasks.rating_get_grades(domain)
|
||||
project.percentage_satisfaction_project = activity['great'] * 100 / sum(pycompat.values(activity)) if sum(pycompat.values(activity)) else -1
|
||||
project.percentage_satisfaction_project = activity['great'] * 100 / sum(activity.values()) if sum(activity.values()) else -1
|
||||
|
||||
@api.one
|
||||
@api.depends('tasks.rating_ids.rating')
|
||||
def _compute_percentage_satisfaction_task(self):
|
||||
activity = self.tasks.rating_get_grades()
|
||||
self.percentage_satisfaction_task = activity['great'] * 100 / sum(pycompat.values(activity)) if sum(pycompat.values(activity)) else -1
|
||||
self.percentage_satisfaction_task = activity['great'] * 100 / sum(activity.values()) if sum(activity.values()) else -1
|
||||
|
||||
percentage_satisfaction_task = fields.Integer(
|
||||
compute='_compute_percentage_satisfaction_task', string="Happy % on Task", store=True, default=-1)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
|
||||
@@ -63,11 +62,11 @@ class Project(models.Model):
|
||||
if project.use_tasks:
|
||||
activity_task = project.tasks.rating_get_grades(domain)
|
||||
activity_great = activity_task['great']
|
||||
activity_sum = sum(pycompat.values(activity_task))
|
||||
activity_sum = sum(activity_task.values())
|
||||
if project.use_issues:
|
||||
activity_issue = self.env['project.issue'].search([('project_id', '=', project.id)]).rating_get_grades(domain)
|
||||
activity_great += activity_issue['great']
|
||||
activity_sum += sum(pycompat.values(activity_issue))
|
||||
activity_sum += sum(activity_issue.values())
|
||||
project.percentage_satisfaction_project = activity_great * 100 / activity_sum if activity_sum else -1
|
||||
|
||||
@api.one
|
||||
@@ -75,7 +74,7 @@ class Project(models.Model):
|
||||
def _compute_percentage_satisfaction_issue(self):
|
||||
project_issue = self.env['project.issue'].search([('project_id', '=', self.id)])
|
||||
activity = project_issue.rating_get_grades()
|
||||
self.percentage_satisfaction_issue = activity['great'] * 100 / sum(pycompat.values(activity)) if sum(pycompat.values(activity)) else -1
|
||||
self.percentage_satisfaction_issue = activity['great'] * 100 / sum(activity.values()) if sum(activity.values()) else -1
|
||||
|
||||
percentage_satisfaction_issue = fields.Integer(compute='_compute_percentage_satisfaction_issue', string="Happy % on Issue", store=True, default=-1)
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
from itertools import groupby
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
@@ -58,7 +57,7 @@ class AccountInvoice(models.Model):
|
||||
result = super(AccountInvoice, self)._refund_cleanup_lines(lines)
|
||||
if self.env.context.get('mode') == 'modify':
|
||||
for i, line in enumerate(lines):
|
||||
for name, field in pycompat.items(line._fields):
|
||||
for name, field in line._fields.items():
|
||||
if name == 'sale_line_ids':
|
||||
result[i][2][name] = [(6, 0, line[name].ids)]
|
||||
line[name] = False
|
||||
|
||||
@@ -8,7 +8,7 @@ from datetime import datetime, timedelta
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT, pycompat
|
||||
from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.tools.misc import formatLang
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
@@ -400,7 +400,7 @@ class SaleOrder(models.Model):
|
||||
if not invoices:
|
||||
raise UserError(_('There is no invoicable line.'))
|
||||
|
||||
for invoice in pycompat.values(invoices):
|
||||
for invoice in invoices.values():
|
||||
if not invoice.invoice_line_ids:
|
||||
raise UserError(_('There is no invoicable line.'))
|
||||
# If invoice is negative, do a refund invoice instead
|
||||
@@ -417,7 +417,7 @@ class SaleOrder(models.Model):
|
||||
invoice.message_post_with_view('mail.message_origin_link',
|
||||
values={'self': invoice, 'origin': references[invoice]},
|
||||
subtype_id=self.env.ref('mail.mt_note').id)
|
||||
return [inv.id for inv in pycompat.values(invoices)]
|
||||
return [inv.id for inv in invoices.values()]
|
||||
|
||||
@api.multi
|
||||
def action_draft(self):
|
||||
@@ -557,7 +557,7 @@ class SaleOrder(models.Model):
|
||||
if tax.include_base_amount:
|
||||
base_tax += tax.compute_all(price_reduce + base_tax, quantity=1, product=line.product_id,
|
||||
partner=self.partner_shipping_id)['taxes'][0]['amount']
|
||||
res = sorted(pycompat.items(res), key=lambda l: l[0].sequence)
|
||||
res = sorted(res.items(), key=lambda l: l[0].sequence)
|
||||
res = [(l[0].name, l[1]) for l in res]
|
||||
return res
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
@@ -41,7 +40,7 @@ class SaleOrderLine(models.Model):
|
||||
qty = d['unit_amount']
|
||||
lines[line] += qty
|
||||
|
||||
for line, qty in pycompat.items(lines):
|
||||
for line, qty in lines.items():
|
||||
line.qty_delivered = qty
|
||||
return True
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.exceptions import UserError, AccessError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
from .test_sale_common import TestSale
|
||||
|
||||
@@ -18,10 +17,10 @@ class TestSaleOrder(TestSale):
|
||||
'partner_id': self.partner.id,
|
||||
'partner_invoice_id': self.partner.id,
|
||||
'partner_shipping_id': self.partner.id,
|
||||
'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for (_, p) in pycompat.items(self.products)],
|
||||
'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for p in self.products.values()],
|
||||
'pricelist_id': self.env.ref('product.list0').id,
|
||||
})
|
||||
self.assertEqual(so.amount_total, sum([2 * p.list_price for (k, p) in pycompat.items(self.products)]), 'Sale: total amount is wrong')
|
||||
self.assertEqual(so.amount_total, sum([2 * p.list_price for p in self.products.values()]), 'Sale: total amount is wrong')
|
||||
|
||||
# send quotation
|
||||
so.force_quotation_send()
|
||||
@@ -36,7 +35,7 @@ class TestSaleOrder(TestSale):
|
||||
inv_id = so.action_invoice_create()
|
||||
inv = inv_obj.browse(inv_id)
|
||||
self.assertEqual(len(inv.invoice_line_ids), 2, 'Sale: invoice is missing lines')
|
||||
self.assertEqual(inv.amount_total, sum([2 * p.list_price if p.invoice_policy == 'order' else 0 for (k, p) in pycompat.items(self.products)]), 'Sale: invoice total amount is wrong')
|
||||
self.assertEqual(inv.amount_total, sum([2 * p.list_price if p.invoice_policy == 'order' else 0 for p in self.products.values()]), 'Sale: invoice total amount is wrong')
|
||||
self.assertTrue(so.invoice_status == 'no', 'Sale: SO status after invoicing should be "nothing to invoice"')
|
||||
self.assertTrue(len(so.invoice_ids) == 1, 'Sale: invoice is missing')
|
||||
|
||||
@@ -47,7 +46,7 @@ class TestSaleOrder(TestSale):
|
||||
inv_id = so.action_invoice_create()
|
||||
inv = inv_obj.browse(inv_id)
|
||||
self.assertEqual(len(inv.invoice_line_ids), 2, 'Sale: second invoice is missing lines')
|
||||
self.assertEqual(inv.amount_total, sum([2 * p.list_price if p.invoice_policy == 'delivery' else 0 for (k, p) in pycompat.items(self.products)]), 'Sale: second invoice total amount is wrong')
|
||||
self.assertEqual(inv.amount_total, sum([2 * p.list_price if p.invoice_policy == 'delivery' else 0 for p in self.products.values()]), 'Sale: second invoice total amount is wrong')
|
||||
self.assertTrue(so.invoice_status == 'invoiced', 'Sale: SO status after invoicing everything should be "invoiced"')
|
||||
self.assertTrue(len(so.invoice_ids) == 2, 'Sale: invoice is missing')
|
||||
# go over the sold quantity
|
||||
@@ -72,7 +71,7 @@ class TestSaleOrder(TestSale):
|
||||
'partner_id': self.partner.id,
|
||||
'partner_invoice_id': self.partner.id,
|
||||
'partner_shipping_id': self.partner.id,
|
||||
'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for (_, p) in pycompat.items(self.products)],
|
||||
'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for p in self.products.values()],
|
||||
'pricelist_id': self.env.ref('product.list0').id,
|
||||
})
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
from odoo.addons.sale.tests.test_sale_common import TestSale
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class TestSaleStock(TestSale):
|
||||
@@ -17,7 +16,7 @@ class TestSaleStock(TestSale):
|
||||
'partner_id': self.partner.id,
|
||||
'partner_invoice_id': self.partner.id,
|
||||
'partner_shipping_id': self.partner.id,
|
||||
'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for (_, p) in pycompat.items(self.products)],
|
||||
'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for p in self.products.values()],
|
||||
'pricelist_id': self.env.ref('product.list0').id,
|
||||
'picking_policy': 'direct',
|
||||
})
|
||||
@@ -74,7 +73,7 @@ class TestSaleStock(TestSale):
|
||||
'partner_id': self.partner.id,
|
||||
'partner_invoice_id': self.partner.id,
|
||||
'partner_shipping_id': self.partner.id,
|
||||
'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for (_, p) in pycompat.items(self.products)],
|
||||
'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for p in self.products.values()],
|
||||
'pricelist_id': self.env.ref('product.list0').id,
|
||||
'picking_policy': 'direct',
|
||||
})
|
||||
|
||||
@@ -9,8 +9,7 @@ from psycopg2 import OperationalError
|
||||
|
||||
from odoo import api, fields, models, registry, _
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, float_compare, \
|
||||
float_round, pycompat
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, float_compare, float_round
|
||||
|
||||
import logging
|
||||
|
||||
@@ -311,7 +310,7 @@ class ProcurementOrder(models.Model):
|
||||
location_data[key]['orderpoints'] += orderpoint
|
||||
location_data[key]['groups'] = self._procurement_from_orderpoint_get_groups([orderpoint.id])
|
||||
|
||||
for location_id, location_data in pycompat.items(location_data):
|
||||
for location_id, location_data in location_data.items():
|
||||
location_orderpoints = location_data['orderpoints']
|
||||
product_context = dict(self._context, location=location_orderpoints[0].location_id.id)
|
||||
substract_quantity = location_orderpoints.subtract_procurements_from_orderpoints()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import float_utils, pycompat
|
||||
from odoo.tools import float_utils
|
||||
|
||||
|
||||
class Inventory(models.Model):
|
||||
@@ -251,7 +251,7 @@ class Inventory(models.Model):
|
||||
|
||||
for product_data in self.env.cr.dictfetchall():
|
||||
# replace the None the dictionary by False, because falsy values are tested later on
|
||||
for void_field in [item[0] for item in pycompat.items(product_data) if item[1] is None]:
|
||||
for void_field in [item[0] for item in product_data.items() if item[1] is None]:
|
||||
product_data[void_field] = False
|
||||
product_data['theoretical_qty'] = product_data['product_qty']
|
||||
if product_data['product_id']:
|
||||
|
||||
@@ -10,7 +10,7 @@ from odoo import api, fields, models, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.addons.procurement.models import procurement
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, pycompat
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.tools.float_utils import float_compare, float_round, float_is_zero
|
||||
|
||||
|
||||
@@ -595,7 +595,7 @@ class StockMove(models.Model):
|
||||
(move_waiting | move_create_proc).write({'state': 'waiting'})
|
||||
|
||||
# assign picking in batch for all confirmed move that share the same details
|
||||
for key, moves in pycompat.items(to_assign):
|
||||
for moves in to_assign.values():
|
||||
moves.assign_picking()
|
||||
self._push_apply()
|
||||
return self
|
||||
|
||||
@@ -7,7 +7,7 @@ import time
|
||||
|
||||
from itertools import groupby
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, pycompat
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.tools.float_utils import float_compare, float_round
|
||||
from odoo.addons.procurement.models import procurement
|
||||
from odoo.exceptions import UserError
|
||||
@@ -665,7 +665,7 @@ class Picking(models.Model):
|
||||
self.ensure_one()
|
||||
moves = self.env['stock.move']
|
||||
for move_line in self.move_line_ids:
|
||||
for product, remaining_qty in pycompat.items(move_line._get_remaining_prod_quantities()):
|
||||
for product, remaining_qty in move_line._get_remaining_prod_quantities().items():
|
||||
if float_compare(remaining_qty, 0, precision_rounding=product.uom_id.rounding) > 0:
|
||||
vals = self._prepare_values_extra_move(move_line, product, remaining_qty)
|
||||
moves |= moves.create(vals)
|
||||
|
||||
@@ -5,7 +5,6 @@ from psycopg2 import OperationalError
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import pycompat
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
@@ -274,7 +273,7 @@ class QuantPackage(models.Model):
|
||||
|
||||
@api.multi
|
||||
def name_get(self):
|
||||
return list(pycompat.items(self._compute_complete_name()))
|
||||
return list(self._compute_complete_name().items())
|
||||
|
||||
def _compute_complete_name(self):
|
||||
""" Forms complete name of location from parent location to child location. """
|
||||
|
||||
@@ -8,7 +8,7 @@ from dateutil import relativedelta
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, pycompat
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
|
||||
|
||||
import logging
|
||||
|
||||
@@ -99,7 +99,7 @@ class Warehouse(models.Model):
|
||||
'wh_output_stock_loc_id': {'name': _('Output'), 'active': delivery_steps != 'ship_only', 'usage': 'internal'},
|
||||
'wh_pack_stock_loc_id': {'name': _('Packing Zone'), 'active': delivery_steps == 'pick_pack_ship', 'usage': 'internal'},
|
||||
}
|
||||
for field_name, values in pycompat.items(sub_locations):
|
||||
for field_name, values in sub_locations.items():
|
||||
values['location_id'] = vals['view_location_id']
|
||||
if vals.get('company_id'):
|
||||
values['company_id'] = vals.get('company_id')
|
||||
@@ -240,10 +240,10 @@ class Warehouse(models.Model):
|
||||
},
|
||||
}
|
||||
data = self._get_picking_type_values(self.reception_steps, self.delivery_steps, self.wh_pack_stock_loc_id)
|
||||
for field_name, values in pycompat.items(data):
|
||||
for field_name in data:
|
||||
data[field_name].update(create_data[field_name])
|
||||
|
||||
for picking_type, values in pycompat.items(data):
|
||||
for picking_type, values in data.items():
|
||||
sequence = IrSequenceSudo.create(sequence_data[picking_type])
|
||||
values.update(warehouse_id=self.id, color=color, sequence_id=sequence.id)
|
||||
warehouse_data[picking_type] = PickingType.create(values).id
|
||||
@@ -598,8 +598,8 @@ class Warehouse(models.Model):
|
||||
@api.one
|
||||
def _update_picking_type(self):
|
||||
picking_type_values = self._get_picking_type_values(self.reception_steps, self.delivery_steps, self.wh_pack_stock_loc_id)
|
||||
for field_name, values in pycompat.items(picking_type_values):
|
||||
getattr(self, field_name).write(values)
|
||||
for field_name, values in picking_type_values.items():
|
||||
self[field_name].write(values)
|
||||
|
||||
@api.multi
|
||||
def _update_name_and_code(self, new_name=False, new_code=False):
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class MakeProcurement(models.TransientModel):
|
||||
@@ -51,8 +50,8 @@ class MakeProcurement(models.TransientModel):
|
||||
@api.onchange('product_id')
|
||||
def onchange_product_id(self):
|
||||
if self.product_id:
|
||||
for key, value in pycompat.items(self.onchange_product_id_dict(self.product_id.id)):
|
||||
setattr(self, key, value)
|
||||
for key, value in self.onchange_product_id_dict(self.product_id.id).items():
|
||||
self[key] = value
|
||||
|
||||
@api.model
|
||||
def create(self, values):
|
||||
|
||||
@@ -7,7 +7,6 @@ from odoo import api, fields, models, tools, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.addons.stock_landed_costs.models import product
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class StockMove(models.Model):
|
||||
@@ -123,7 +122,7 @@ class LandedCost(models.Model):
|
||||
for val_line in landed_cost.valuation_adjustment_lines:
|
||||
val_to_cost_lines[val_line.cost_line_id] += val_line.additional_landed_cost
|
||||
if any(tools.float_compare(cost_line.price_unit, val_amount, precision_digits=prec_digits) != 0
|
||||
for cost_line, val_amount in pycompat.items(val_to_cost_lines)):
|
||||
for cost_line, val_amount in val_to_cost_lines.items()):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -204,9 +203,8 @@ class LandedCost(models.Model):
|
||||
towrite_dict[valuation.id] = value
|
||||
else:
|
||||
towrite_dict[valuation.id] += value
|
||||
if towrite_dict:
|
||||
for key, value in pycompat.items(towrite_dict):
|
||||
AdjustementLines.browse(key).write({'additional_landed_cost': value})
|
||||
for key, value in towrite_dict.items():
|
||||
AdjustementLines.browse(key).write({'additional_landed_cost': value})
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
from odoo.addons.website.models.website import slug
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
email_validator = re.compile(r"[^@]+@[^@]+\.[^@]+")
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,7 +24,7 @@ def dict_keys_startswith(dictionary, string):
|
||||
.. note::
|
||||
This function uses dictionary comprehensions (Python >= 2.7)
|
||||
"""
|
||||
return {k: v for k, v in pycompat.items(dictionary) if k.startswith(string)}
|
||||
return {k: v for k, v in dictionary.items() if k.startswith(string)}
|
||||
|
||||
|
||||
class SurveyStage(models.Model):
|
||||
@@ -240,7 +238,7 @@ class Survey(models.Model):
|
||||
answers[input_line.value_suggested.id]['count'] += 1
|
||||
if input_line.answer_type == 'text' and (not(current_filters) or input_line.user_input_id.id in current_filters):
|
||||
comments.append(input_line)
|
||||
result_summary = {'answers': list(pycompat.values(answers)), 'comments': comments}
|
||||
result_summary = {'answers': list(answers.values()), 'comments': comments}
|
||||
|
||||
# Calculate and return statistics for matrix
|
||||
if question.type == 'matrix':
|
||||
@@ -640,7 +638,7 @@ class SurveyQuestion(models.Model):
|
||||
if self.comments_allowed:
|
||||
comment_answer = answer_candidates.pop(("%s_%s" % (answer_tag, 'comment')), '').strip()
|
||||
# Preventing answers with blank value
|
||||
if all(not answer.strip() for answer in pycompat.values(answer_candidates)) and answer_candidates:
|
||||
if all(not answer.strip() for answer in answer_candidates.values()) and answer_candidates:
|
||||
errors.update({answer_tag: self.constr_error_msg})
|
||||
# There is no answer neither comments (if comments count as answer)
|
||||
if not answer_candidates and self.comment_count_as_answer and (not comment_flag or not comment_answer):
|
||||
|
||||
@@ -13,8 +13,6 @@ from odoo.exceptions import UserError
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.addons.website.models.website import slug
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class TestSurvey(TransactionCase):
|
||||
|
||||
@@ -179,7 +177,7 @@ class TestSurvey(TransactionCase):
|
||||
|
||||
base_url = self.env['ir.config_parameter'].get_param('web.base.url')
|
||||
urltypes = {'public': 'start', 'print': 'print', 'result': 'results'}
|
||||
for urltype, urltxt in pycompat.items(urltypes):
|
||||
for urltype, urltxt in urltypes.items():
|
||||
survey_url = getattr(self.survey1, urltype + '_url')
|
||||
survey_url_relative = getattr(self.survey1.with_context({'relative_url': True}), urltype + '_url')
|
||||
self.assertTrue(validate_url(survey_url))
|
||||
@@ -211,8 +209,8 @@ class TestSurvey(TransactionCase):
|
||||
answers = [input_portal.user_input_line_ids[0], input_public.user_input_line_ids[0]]
|
||||
expected_values = {'answer_type': 'free_text', 'value_free_text': "Test Answer"}
|
||||
for answer in answers:
|
||||
for field, value in pycompat.items(expected_values):
|
||||
self.assertEqual(getattr(answer, field), value, msg="Unable to answer the survey. Expected behaviour of %s is not proper." % (field))
|
||||
for field, value in expected_values.items():
|
||||
self.assertEqual(answer[field], value, msg="Unable to answer the survey. Expected behaviour of %s is not proper." % (field))
|
||||
|
||||
def test_10_survey_result_simple_multiple_choice(self):
|
||||
question = self.env['survey.question'].sudo(self.survey_manager).create({
|
||||
@@ -265,7 +263,7 @@ class TestSurvey(TransactionCase):
|
||||
'print': {'method': 'print', 'token': '/test', 'text': 'Print'},
|
||||
'result': {'method': 'result', 'token': '', 'text': 'Results of the'},
|
||||
'test': {'method': 'public', 'token': '/phantom', 'text': 'Results of the'}}
|
||||
for action, val in pycompat.items(actions):
|
||||
for action, val in actions.items():
|
||||
result = getattr(self.survey1.with_context({'survey_token': val['token'][1:]}), 'action_' + action + '_survey')()
|
||||
url = getattr(self.survey1.with_context({'relative_url': True}), val['method'] + '_url') + val['token']
|
||||
self.assertEqual(result['url'], url)
|
||||
|
||||
@@ -963,7 +963,7 @@ class Binary(http.Controller):
|
||||
def force_contenttype(self, headers, contenttype='image/png'):
|
||||
dictheaders = dict(headers)
|
||||
dictheaders['Content-Type'] = contenttype
|
||||
return list(pycompat.items(dictheaders))
|
||||
return list(dictheaders.items())
|
||||
|
||||
@http.route(['/web/content',
|
||||
'/web/content/<string:xmlid>',
|
||||
@@ -1216,7 +1216,7 @@ class Export(http.Controller):
|
||||
else:
|
||||
fields['.id'] = fields.pop('id', {'string': 'ID'})
|
||||
|
||||
fields_sequence = sorted(pycompat.items(fields),
|
||||
fields_sequence = sorted(fields.items(),
|
||||
key=lambda field: odoo.tools.ustr(field[1].get('string', '')))
|
||||
|
||||
records = []
|
||||
@@ -1227,7 +1227,7 @@ class Export(http.Controller):
|
||||
if field.get('readonly'):
|
||||
# If none of the field's states unsets readonly, skip the field
|
||||
if all(dict(attrs).get('readonly', True)
|
||||
for attrs in pycompat.values(field.get('states', {}))):
|
||||
for attrs in field.get('states', {}).values()):
|
||||
continue
|
||||
if not field.get('exportable', True):
|
||||
continue
|
||||
@@ -1319,7 +1319,7 @@ class Export(http.Controller):
|
||||
export_fields = [field.split('/', 1)[1] for field in fields]
|
||||
return (
|
||||
(prefix + '/' + k, prefix_string + '/' + v)
|
||||
for k, v in pycompat.items(self.fields_info(model, export_fields)))
|
||||
for k, v in self.fields_info(model, export_fields).items())
|
||||
|
||||
class ExportFormat(object):
|
||||
raw_data = False
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import odoo.http as http
|
||||
from odoo.tools import pycompat
|
||||
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
@@ -46,7 +45,7 @@ class DiagramView(http.Controller):
|
||||
isolate_nodes[blnk_node['id']] = blnk_node
|
||||
y = [
|
||||
t['y']
|
||||
for t in pycompat.values(nodes)
|
||||
for t in nodes.values()
|
||||
if t['x'] == 20
|
||||
if t['y']
|
||||
]
|
||||
@@ -99,11 +98,11 @@ class DiagramView(http.Controller):
|
||||
color='white',
|
||||
options={}
|
||||
)
|
||||
for color, expr in pycompat.items(bgcolors):
|
||||
for color, expr in bgcolors.items():
|
||||
if safe_eval(expr, act):
|
||||
n['color'] = color
|
||||
|
||||
for shape, expr in pycompat.items(shapes):
|
||||
for shape, expr in shapes.items():
|
||||
if safe_eval(expr, act):
|
||||
n['shape'] = shape
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ class IrUiView(models.Model):
|
||||
@api.model
|
||||
def to_field_ref(self, el):
|
||||
# filter out meta-information inserted in the document
|
||||
attributes = {k: v for k, v in pycompat.items(el.attrib)
|
||||
attributes = {k: v for k, v in el.attrib.items()
|
||||
if not k.startswith('data-oe-')}
|
||||
attributes['t-field'] = el.get('data-oe-expression')
|
||||
|
||||
|
||||
@@ -38,11 +38,11 @@ class QueryURL(object):
|
||||
|
||||
def __call__(self, path=None, path_args=None, **kw):
|
||||
path = path or self.path
|
||||
for key, value in pycompat.items(self.args):
|
||||
for key, value in self.args.items():
|
||||
kw.setdefault(key, value)
|
||||
path_args = OrderedSet(path_args or []) | self.path_args
|
||||
paths, fragments = {}, []
|
||||
for key, value in pycompat.items(kw):
|
||||
for key, value in kw.items():
|
||||
if value and key in path_args:
|
||||
if isinstance(value, models.BaseModel):
|
||||
paths[key] = slug(value)
|
||||
|
||||
@@ -14,7 +14,7 @@ import odoo
|
||||
from odoo import api, models
|
||||
from odoo import SUPERUSER_ID
|
||||
from odoo.http import request
|
||||
from odoo.tools import config, pycompat
|
||||
from odoo.tools import config
|
||||
from odoo.exceptions import QWebException
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
@@ -244,7 +244,7 @@ class Http(models.AbstractModel):
|
||||
def _postprocess_args(cls, arguments, rule):
|
||||
super(Http, cls)._postprocess_args(arguments, rule)
|
||||
|
||||
for key, val in pycompat.items(arguments):
|
||||
for key, val in arguments.items():
|
||||
# Replace uid placeholder by the current request.uid
|
||||
if isinstance(val, models.BaseModel) and isinstance(val._uid, RequestUID):
|
||||
arguments[key] = val.sudo(request.uid)
|
||||
|
||||
@@ -5,7 +5,6 @@ import ast
|
||||
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class QWeb(models.AbstractModel):
|
||||
@@ -82,7 +81,7 @@ class QWeb(models.AbstractModel):
|
||||
atts = super(QWeb, self)._get_dynamic_att(tagName, atts, options, values)
|
||||
if options.get('rendering_bundle'):
|
||||
return atts
|
||||
for name, value in pycompat.items(atts):
|
||||
for name, value in atts.items():
|
||||
atts[name] = self._website_build_attribute(tagName, name, value, options, values)
|
||||
return atts
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ class Website(models.Model):
|
||||
|
||||
def get_url_localized(router, lang):
|
||||
arguments = dict(request.endpoint_arguments)
|
||||
for key, val in list(pycompat.items(arguments)):
|
||||
for key, val in list(arguments.items()):
|
||||
if isinstance(val, models.BaseModel):
|
||||
arguments[key] = val.with_context(lang=lang)
|
||||
return router.build(request.endpoint, arguments)
|
||||
@@ -496,7 +496,7 @@ class Website(models.Model):
|
||||
endpoint = rule.endpoint
|
||||
methods = endpoint.routing.get('methods') or ['GET']
|
||||
|
||||
converters = list(pycompat.values(rule._converters))
|
||||
converters = list(rule._converters.values())
|
||||
if not ('GET' in methods
|
||||
and endpoint.routing['type'] == 'http'
|
||||
and endpoint.routing['auth'] in ('none', 'public')
|
||||
@@ -541,7 +541,7 @@ class Website(models.Model):
|
||||
values = [{}]
|
||||
# converters with a domain are processed after the other ones
|
||||
convitems = sorted(
|
||||
pycompat.items(converters),
|
||||
converters.items(),
|
||||
key=lambda x: hasattr(x[1], 'domain') and (x[1].domain != '[]'))
|
||||
for (i, (name, converter)) in enumerate(convitems):
|
||||
newval = []
|
||||
@@ -557,7 +557,7 @@ class Website(models.Model):
|
||||
for value in values:
|
||||
domain_part, url = rule.build(value, append_unknown=False)
|
||||
page = {'loc': url}
|
||||
for key, val in pycompat.items(value):
|
||||
for key, val in value.items():
|
||||
if key.startswith('__'):
|
||||
page[key[2:]] = val
|
||||
if url in ('/sitemap.xml',):
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
import unittest
|
||||
from odoo.addons.website.models.website import slugify, unslug
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class TestUnslug(unittest.TestCase):
|
||||
|
||||
@@ -25,7 +23,7 @@ class TestUnslug(unittest.TestCase):
|
||||
'foo1': (None, None),
|
||||
}
|
||||
|
||||
for slug, expected in pycompat.items(tests):
|
||||
for slug, expected in tests.items():
|
||||
self.assertEqual(unslug(slug), expected)
|
||||
|
||||
|
||||
|
||||
@@ -11,11 +11,10 @@ from lxml import etree as ET, html
|
||||
from lxml.html import builder as h
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
def attrs(**kwargs):
|
||||
return {'data-oe-%s' % key: str(value) for key, value in pycompat.items(kwargs)}
|
||||
return {'data-oe-%s' % key: str(value) for key, value in kwargs.items()}
|
||||
|
||||
|
||||
class TestViewSaving(common.TransactionCase):
|
||||
|
||||
@@ -13,7 +13,6 @@ from odoo.http import request
|
||||
from odoo.addons.website.models.website import slug, unslug
|
||||
from odoo.addons.website_partner.controllers.main import WebsitePartnerPage
|
||||
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.translate import _
|
||||
|
||||
from odoo.addons.website_portal.controllers.main import website_account
|
||||
@@ -151,7 +150,7 @@ class WebsiteAccount(website_account):
|
||||
'pager': pager,
|
||||
'searchbar_sortings': searchbar_sortings,
|
||||
'sortby': sortby,
|
||||
'searchbar_filters': OrderedDict(sorted(pycompat.items(searchbar_filters))),
|
||||
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
|
||||
'filterby': filterby,
|
||||
})
|
||||
return request.render("website_crm_partner_assign.portal_my_opportunities", values)
|
||||
|
||||
@@ -5,7 +5,6 @@ import random
|
||||
|
||||
from odoo.addons.base_geolocalize.models.res_partner import geo_find, geo_query_address
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class CrmLead(models.Model):
|
||||
@@ -45,7 +44,7 @@ class CrmLead(models.Model):
|
||||
if lead.partner_assigned_id and lead.partner_assigned_id.user_id != lead.user_id:
|
||||
salesmans_leads.setdefault(lead.partner_assigned_id.user_id.id, []).append(lead.id)
|
||||
|
||||
for salesman_id, leads_ids in pycompat.items(salesmans_leads):
|
||||
for salesman_id, leads_ids in salesmans_leads.items():
|
||||
leads = self.browse(leads_ids)
|
||||
leads.write({'user_id': salesman_id})
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class CrmLeadForwardToPartner(models.TransientModel):
|
||||
@@ -86,7 +85,7 @@ class CrmLeadForwardToPartner(models.TransientModel):
|
||||
else:
|
||||
partners_leads[partner.id] = {'partner': partner, 'leads': [lead_details]}
|
||||
|
||||
for partner_id, partner_leads in pycompat.items(partners_leads):
|
||||
for partner_id, partner_leads in partners_leads.items():
|
||||
in_portal = False
|
||||
if portal_group:
|
||||
for contact in (partner.child_ids or partner).filtered(lambda contact: contact.user_ids):
|
||||
|
||||
@@ -9,7 +9,6 @@ from dateutil.relativedelta import relativedelta
|
||||
from odoo import fields, http, _
|
||||
from odoo.addons.website.models.website import slug
|
||||
from odoo.http import request
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class WebsiteEventController(http.Controller):
|
||||
@@ -80,7 +79,7 @@ class WebsiteEventController(http.Controller):
|
||||
|
||||
def dom_without(without):
|
||||
domain = [('state', "in", ['draft', 'confirm', 'done'])]
|
||||
for key, search in pycompat.items(domain_search):
|
||||
for key, search in domain_search.items():
|
||||
if key != without:
|
||||
domain += search
|
||||
return domain
|
||||
@@ -234,16 +233,16 @@ class WebsiteEventController(http.Controller):
|
||||
''' Process data posted from the attendee details form. '''
|
||||
registrations = {}
|
||||
global_values = {}
|
||||
for key, value in pycompat.items(details):
|
||||
for key, value in details.items():
|
||||
counter, field_name = key.split('-', 1)
|
||||
if counter == '0':
|
||||
global_values[field_name] = value
|
||||
else:
|
||||
registrations.setdefault(counter, dict())[field_name] = value
|
||||
for key, value in pycompat.items(global_values):
|
||||
for registration in pycompat.values(registrations):
|
||||
for key, value in global_values.items():
|
||||
for registration in registrations.values():
|
||||
registration[key] = value
|
||||
return list(pycompat.values(registrations))
|
||||
return list(registrations.values())
|
||||
|
||||
@http.route(['/event/<model("event.event"):event>/registration/confirm'], type='http', auth="public", methods=['POST'], website=True)
|
||||
def registration_confirm(self, event, **post):
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
from odoo.addons.website_event.controllers.main import WebsiteEventController
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class WebsiteEvent(WebsiteEventController):
|
||||
|
||||
@@ -13,7 +11,7 @@ class WebsiteEvent(WebsiteEventController):
|
||||
registrations = super(WebsiteEvent, self)._process_registration_details(details)
|
||||
for registration in registrations:
|
||||
answer_ids = []
|
||||
for key, value in pycompat.items(registration):
|
||||
for key, value in registration.items():
|
||||
if key.startswith('answer_ids-'):
|
||||
answer_ids.append([4, int(value)])
|
||||
registration['answer_ids'] = answer_ids
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
from odoo import http, _
|
||||
from odoo.addons.website_event.controllers.main import WebsiteEventController
|
||||
from odoo.http import request
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class WebsiteEventSaleController(WebsiteEventController):
|
||||
@@ -16,7 +15,7 @@ class WebsiteEventSaleController(WebsiteEventController):
|
||||
|
||||
def _process_tickets_details(self, data):
|
||||
ticket_post = {}
|
||||
for key, value in pycompat.items(data):
|
||||
for key, value in data.items():
|
||||
if not key.startswith('nb_register') or '-' not in key:
|
||||
continue
|
||||
items = key.split('-')
|
||||
|
||||
@@ -8,7 +8,7 @@ import pytz
|
||||
|
||||
from odoo import fields, http
|
||||
from odoo.http import request
|
||||
from odoo.tools import html_escape as escape, html2plaintext, pycompat
|
||||
from odoo.tools import html_escape as escape, html2plaintext
|
||||
|
||||
|
||||
class WebsiteEventTrackController(http.Controller):
|
||||
@@ -75,7 +75,7 @@ class WebsiteEventTrackController(http.Controller):
|
||||
|
||||
days = {}
|
||||
tracks_by_days = {}
|
||||
for day, tracks in pycompat.items(days_tracks):
|
||||
for day, tracks in days_tracks.items():
|
||||
tracks_by_days[day] = tracks
|
||||
days[day] = self._prepare_calendar(event, tracks)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from psycopg2 import IntegrityError
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, pycompat
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from odoo.tools.translate import _
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.base.ir.ir_qweb.fields import nl2br
|
||||
@@ -118,7 +118,7 @@ class WebsiteForm(http.Controller):
|
||||
error_fields = []
|
||||
|
||||
|
||||
for field_name, field_value in pycompat.items(values):
|
||||
for field_name, field_value in values.items():
|
||||
# If the value of the field if a file
|
||||
if hasattr(field_value, 'filename'):
|
||||
# Undo file upload field name indexing
|
||||
@@ -164,7 +164,7 @@ class WebsiteForm(http.Controller):
|
||||
if hasattr(dest_model, "website_form_input_filter"):
|
||||
data['record'] = dest_model.website_form_input_filter(request, data['record'])
|
||||
|
||||
missing_required_fields = [label for label, field in pycompat.items(authorized_fields) if field['required'] and not label in data['record']]
|
||||
missing_required_fields = [label for label, field in authorized_fields.items() if field['required'] and not label in data['record']]
|
||||
if any(error_fields):
|
||||
raise ValidationError(error_fields + missing_required_fields)
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import itertools
|
||||
|
||||
from odoo import models, fields, api
|
||||
from odoo.http import request
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class website_form_config(models.Model):
|
||||
@@ -42,7 +41,7 @@ class website_form_model(models.Model):
|
||||
])
|
||||
}
|
||||
return {
|
||||
k: v for k, v in pycompat.items(self.get_authorized_fields(self.model))
|
||||
k: v for k, v in self.get_authorized_fields(self.model).items()
|
||||
if k in included
|
||||
}
|
||||
|
||||
@@ -52,7 +51,7 @@ class website_form_model(models.Model):
|
||||
model = self.env[model_name]
|
||||
fields_get = model.fields_get()
|
||||
|
||||
for key, val in pycompat.items(model._inherits):
|
||||
for key, val in model._inherits.items():
|
||||
fields_get.pop(val, None)
|
||||
|
||||
# Unrequire fields with default values
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class WebsiteLivechat(http.Controller):
|
||||
@@ -27,7 +26,7 @@ class WebsiteLivechat(http.Controller):
|
||||
# compute percentage
|
||||
percentage = dict.fromkeys(['great', 'okay', 'bad'], 0)
|
||||
for grade in repartition:
|
||||
percentage[grade] = repartition[grade] * 100 / sum(pycompat.values(repartition)) if sum(pycompat.values(repartition)) else 0
|
||||
percentage[grade] = repartition[grade] * 100 / sum(repartition.values()) if sum(repartition.values()) else 0
|
||||
|
||||
# the value dict to render the template
|
||||
values = {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo import tools
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.translate import _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
@@ -134,7 +133,7 @@ class website_account(http.Controller):
|
||||
error["vat"] = 'error'
|
||||
|
||||
# error message for empty required fields
|
||||
if [err for err in pycompat.values(error) if err == 'missing']:
|
||||
if [err for err in error.values() if err == 'missing']:
|
||||
error_message.append(_('Some required fields are empty.'))
|
||||
|
||||
unknown = [k for k in data if k not in self.MANDATORY_BILLING_FIELDS + self.OPTIONAL_BILLING_FIELDS]
|
||||
|
||||
@@ -6,7 +6,6 @@ from collections import OrderedDict
|
||||
from odoo import http
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.http import request
|
||||
from odoo.tools import pycompat
|
||||
from odoo.tools.translate import _
|
||||
|
||||
from odoo.addons.website_portal.controllers.main import website_account, get_records_pager
|
||||
@@ -89,7 +88,7 @@ class WebsitePortal(website_account):
|
||||
'archive_groups': archive_groups,
|
||||
'searchbar_sortings': searchbar_sortings,
|
||||
'sortby': sortby,
|
||||
'searchbar_filters': OrderedDict(sorted(pycompat.items(searchbar_filters))),
|
||||
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
|
||||
'filterby': filterby,
|
||||
'default_url': '/my/purchase',
|
||||
})
|
||||
|
||||
@@ -8,7 +8,6 @@ from odoo.http import request
|
||||
|
||||
from odoo.addons.website_portal.controllers.main import website_account, get_records_pager
|
||||
from odoo.osv.expression import OR
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class WebsiteAccount(website_account):
|
||||
@@ -156,7 +155,7 @@ class WebsiteAccount(website_account):
|
||||
'searchbar_inputs': searchbar_inputs,
|
||||
'search_in': search_in,
|
||||
'sortby': sortby,
|
||||
'searchbar_filters': OrderedDict(sorted(pycompat.items(searchbar_filters))),
|
||||
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
|
||||
'filterby': filterby,
|
||||
})
|
||||
return request.render("website_project.my_tasks", values)
|
||||
|
||||
@@ -105,7 +105,7 @@ class WebsiteAccount(website_account):
|
||||
'searchbar_sortings': searchbar_sortings,
|
||||
'searchbar_inputs': searchbar_inputs,
|
||||
'sortby': sortby,
|
||||
'searchbar_filters': OrderedDict(sorted(pycompat.items(searchbar_filters))),
|
||||
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
|
||||
'filterby': filterby,
|
||||
'search_in': search_in,
|
||||
'search': search,
|
||||
|
||||
@@ -12,8 +12,6 @@ from odoo.addons.website.controllers.main import QueryURL
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.website_form.controllers.main import WebsiteForm
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
PPG = 20 # Products Per Page
|
||||
@@ -78,10 +76,10 @@ class TableCompute(object):
|
||||
index += 1
|
||||
|
||||
# Format table according to HTML needs
|
||||
rows = sorted(pycompat.items(self.table))
|
||||
rows = sorted(self.table.items())
|
||||
rows = [r[1] for r in rows]
|
||||
for col in range(len(rows)):
|
||||
cols = sorted(pycompat.items(rows[col]))
|
||||
cols = sorted(rows[col].items())
|
||||
x += len(cols)
|
||||
rows[col] = [r[1] for r in cols if r[1]]
|
||||
|
||||
@@ -373,7 +371,7 @@ class WebsiteSale(http.Controller):
|
||||
return request.redirect("/shop/cart")
|
||||
|
||||
def _filter_attributes(self, **kw):
|
||||
return {k: v for k, v in pycompat.items(kw) if "attribute" in k}
|
||||
return {k: v for k, v in kw.items() if "attribute" in k}
|
||||
|
||||
@http.route(['/shop/cart/update_json'], type='json', auth="public", methods=['POST'], website=True, csrf=False)
|
||||
def cart_update_json(self, product_id, line_id=None, add_qty=None, set_qty=None, display=True):
|
||||
@@ -491,7 +489,7 @@ class WebsiteSale(http.Controller):
|
||||
except ValidationError:
|
||||
error["vat"] = 'error'
|
||||
|
||||
if [err for err in pycompat.items(error) if err == 'missing']:
|
||||
if [err for err in error.items() if err == 'missing']:
|
||||
error_message.append(_('Some required fields are empty.'))
|
||||
|
||||
return error, error_message
|
||||
@@ -517,7 +515,7 @@ class WebsiteSale(http.Controller):
|
||||
def values_postprocess(self, order, mode, values, errors, error_msg):
|
||||
new_values = {}
|
||||
authorized_fields = request.env['ir.model']._get('res.partner')._get_form_writable_fields()
|
||||
for k, v in pycompat.items(values):
|
||||
for k, v in values.items():
|
||||
# don't drop empty value, it could be a field to reset
|
||||
if k in authorized_fields and v is not None:
|
||||
new_values[k] = v
|
||||
@@ -680,7 +678,7 @@ class WebsiteSale(http.Controller):
|
||||
# if form posted
|
||||
if 'post_values' in post:
|
||||
values = {}
|
||||
for field_name, field_value in pycompat.items(post):
|
||||
for field_name, field_value in post.items():
|
||||
if field_name in request.env['sale.order']._fields and field_name.startswith('x_'):
|
||||
values[field_name] = field_value
|
||||
if values:
|
||||
|
||||
@@ -6,7 +6,6 @@ import random
|
||||
from odoo import api, models, fields, _
|
||||
from odoo.http import request
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import pycompat
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -93,7 +92,7 @@ class SaleOrder(models.Model):
|
||||
|
||||
# add untracked attributes in the name
|
||||
untracked_attributes = []
|
||||
for k, v in pycompat.items(attributes):
|
||||
for k, v in attributes.items():
|
||||
# attribute should be like 'attribute-48-1' where 48 is the product_id, 1 is the attribute_id and v is the attribute value
|
||||
attribute_value = self.env['product.attribute.value'].sudo().browse(int(v))
|
||||
if attribute_value and not attribute_value.attribute_id.create_variant:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from mock import patch
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class TestWebsitePriceList(TransactionCase):
|
||||
@@ -61,7 +60,7 @@ class TestWebsitePriceList(TransactionCase):
|
||||
'CA': ['Canada'],
|
||||
'US': ['USD', 'EUR', 'Benelux', 'Canada']
|
||||
}
|
||||
for country, result in pycompat.items(country_list):
|
||||
for country, result in country_list.items():
|
||||
pls = self.get_pl(show, current_pl, country)
|
||||
self.assertEquals(len(set(pls.mapped('name')) & set(result)), len(pls), 'Test failed for %s (%s %s vs %s %s)'
|
||||
% (country, len(pls), pls.mapped('name'), len(result), result))
|
||||
@@ -78,7 +77,7 @@ class TestWebsitePriceList(TransactionCase):
|
||||
'CA': ['Canada']
|
||||
}
|
||||
|
||||
for country, result in pycompat.items(country_list):
|
||||
for country, result in country_list.items():
|
||||
pls = self.get_pl(show, current_pl, country)
|
||||
self.assertEquals(len(set(pls.mapped('name')) & set(result)), len(pls), 'Test failed for %s (%s %s vs %s %s)'
|
||||
% (country, len(pls), pls.mapped('name'), len(result), result))
|
||||
@@ -99,7 +98,7 @@ class TestWebsitePriceList(TransactionCase):
|
||||
'CA': False
|
||||
}
|
||||
|
||||
for country, result in pycompat.items(country_list):
|
||||
for country, result in country_list.items():
|
||||
self.args['country'] = country
|
||||
# mock patch method could not pass env context
|
||||
available = self.website.is_pricelist_available(christmas_pl)
|
||||
@@ -120,7 +119,7 @@ class TestWebsitePriceList(TransactionCase):
|
||||
'CA': ['EUR', 'Canada'],
|
||||
'US': ['USD', 'EUR', 'Benelux', 'Canada']
|
||||
}
|
||||
for country, result in pycompat.items(country_list):
|
||||
for country, result in country_list.items():
|
||||
pls = self.get_pl(show, current_pl, country)
|
||||
self.assertEquals(len(set(pls.mapped('name')) & set(result)), len(pls), 'Test failed for %s (%s %s vs %s %s)'
|
||||
% (country, len(pls), pls.mapped('name'), len(result), result))
|
||||
|
||||
@@ -5,8 +5,6 @@ from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
||||
|
||||
from odoo.tools import pycompat
|
||||
|
||||
|
||||
class WebsiteSaleOptions(WebsiteSale):
|
||||
|
||||
@@ -26,7 +24,7 @@ class WebsiteSaleOptions(WebsiteSale):
|
||||
|
||||
option_ids = product.optional_product_ids.mapped('product_variant_ids').ids
|
||||
optional_product_ids = []
|
||||
for k, v in pycompat.items(kw):
|
||||
for k, v in kw.items():
|
||||
if "optional-product-" in k and int(kw.get(k.replace("product", "add"))) and int(v) in option_ids:
|
||||
optional_product_ids.append(int(v))
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import re
|
||||
from werkzeug import urls
|
||||
|
||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||
from odoo.tools import image, pycompat
|
||||
from odoo.tools import image
|
||||
from odoo.tools.translate import html_translate
|
||||
from odoo.exceptions import Warning
|
||||
from odoo.addons.website.models.website import slug
|
||||
@@ -323,8 +323,8 @@ class Slide(models.Model):
|
||||
values = res['values']
|
||||
if not values.get('document_id'):
|
||||
raise Warning(_('Please enter valid Youtube or Google Doc URL'))
|
||||
for key, value in pycompat.items(values):
|
||||
setattr(self, key, value)
|
||||
for key, value in values.items():
|
||||
self[key] = value
|
||||
|
||||
# website
|
||||
date_published = fields.Datetime('Publish Date')
|
||||
@@ -385,7 +385,7 @@ class Slide(models.Model):
|
||||
values['date_published'] = datetime.datetime.now()
|
||||
if values.get('url') and not values.get('document_id'):
|
||||
doc_data = self._parse_document_url(values['url']).get('values', dict())
|
||||
for key, value in pycompat.items(doc_data):
|
||||
for key, value in doc_data.items():
|
||||
values.setdefault(key, value)
|
||||
# Do not publish slide if user has not publisher rights
|
||||
if not self.user_has_groups('website.group_website_publisher'):
|
||||
@@ -399,7 +399,7 @@ class Slide(models.Model):
|
||||
def write(self, values):
|
||||
if values.get('url') and values['url'] != self.url:
|
||||
doc_data = self._parse_document_url(values['url']).get('values', dict())
|
||||
for key, value in pycompat.items(doc_data):
|
||||
for key, value in doc_data.items():
|
||||
values.setdefault(key, value)
|
||||
if values.get('channel_id'):
|
||||
custom_channels = self.env['slide.channel'].search([('custom_slide_id', '=', self.id), ('id', '!=', values.get('channel_id'))])
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user