Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
bf81e38
[FIX] stock: same package in different location
amoyaux Oct 11, 2019
aab4eba
[FIX] mrp: decrease produced quantity
nim-odoo Dec 16, 2019
be6492d
[FIX] account: compute reference for all invoices in invoice_validate
grindtildeath Nov 27, 2019
4d6416d
[FIX] calendar: wrong user updated when setting last notif ack
alt-odoo Dec 16, 2019
8584537
[FIX] tools, mail: improve styling recognition in html fields
std-odoo Nov 18, 2019
3fed7ff
[FIX] stock_account: float comparison
nim-odoo Dec 17, 2019
bc8e21a
[IMP] doc: restore canonical URL
mart-e Dec 12, 2019
026224c
[CLA] signature for FedericoLaTorre
FedericoLaTorre Dec 16, 2019
294d4c7
[FIX] base: new Mauritanian currency
nim-odoo Dec 17, 2019
ed7c569
[FIX] account: Wrong unit price with included tax and fiscal position
simongoffin Dec 17, 2019
79c1e37
[FIX] stock: prevent crash on availability
nim-odoo Dec 17, 2019
66b4263
[FIX] l10n_es: Give a tax group to IVA 10,5% REAGYP
pedrobaeza Nov 4, 2019
ba1f484
[FIX]website_partner:partner description is now translatable
jhk-odoo Dec 17, 2019
a47f5a8
[FIX] website_sale_stock: allow override of context
lilee115 Dec 17, 2019
e7984c4
[FIX] project: access to portal task give access to attachment
nle-odoo Dec 13, 2019
897ded1
[FIX] core: ask OS to pick CDT port
xmo-odoo Dec 17, 2019
babc95c
[CLA] Signature for Derek Lee
lilee115 Dec 17, 2019
dd7552b
[FIX] payment_paypal: Less confusing transaction logs
jev-odoo Oct 25, 2019
8d65d5e
[FIX] google_account: no access error when token refresh fails
jev-odoo Dec 10, 2019
bbf1240
Merge remote-tracking branch 'odoo/12.0' into 12.0-update-upstream-e7…
MiquelRForgeFlow Dec 18, 2019
863d5b0
[UPD] Currency of Mauritania
MiquelRForgeFlow Dec 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions addons/account/models/account_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -1363,8 +1363,9 @@ def _check_duplicate_supplier_reference(self):

@api.multi
def invoice_validate(self):
for invoice in self.filtered(lambda invoice: invoice.partner_id not in invoice.message_partner_ids):
invoice.message_subscribe([invoice.partner_id.id])
for invoice in self:
if invoice.partner_id not in invoice.message_partner_ids:
invoice.message_subscribe([invoice.partner_id.id])

# Auto-compute reference, if not already existing and if configured on company
if not invoice.reference and invoice.type == 'out_invoice':
Expand Down Expand Up @@ -1887,12 +1888,8 @@ def _onchange_uom_id(self):
self.price_unit = 0.0

if self.product_id and self.uom_id:
if self.invoice_id.type in ('in_invoice', 'in_refund'):
price_unit = self.product_id.standard_price
else:
price_unit = self.product_id.lst_price
self.price_unit = self.product_id.uom_id._compute_price(price_unit, self.uom_id)
self._set_currency()
self._set_taxes()
self.price_unit = self.product_id.uom_id._compute_price(self.price_unit, self.uom_id)

if self.product_id.uom_id.category_id.id != self.uom_id.category_id.id:
warning = {
Expand Down
1 change: 1 addition & 0 deletions addons/account/tests/test_product_id_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def test_product_id_change(self):
'account_id': self.account_revenue.id,
})
out_line._onchange_product_id()
out_line._onchange_uom_id()
self.assertEquals(100, out_line.price_unit, "The included tax must be subtracted to the price")
in_line._onchange_product_id()
self.assertEquals(200, in_line.price_unit, "The included tax must be subtracted to the price")
2 changes: 1 addition & 1 deletion addons/calendar/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ def get_attendee_detail(self, meeting_id):

@api.model
def _set_calendar_last_notif_ack(self):
partner = self.env['res.users'].browse(self.env.uid).partner_id
partner = self.env['res.users'].browse(self.env.context.get('uid',self.env.uid)).partner_id
partner.write({'calendar_last_notif_ack': datetime.now()})
return
2 changes: 1 addition & 1 deletion addons/google_account/models/google_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def _refresh_google_token_json(self, refresh_token, service): # exchange_AUTHOR
except requests.HTTPError as error:
if error.response.status_code == 400: # invalid grant
with registry(request.session.db).cursor() as cur:
self.env(cur)['res.users'].browse(self.env.uid).write({'google_%s_rtoken' % service: False})
self.env(cur)['res.users'].browse(self.env.uid).sudo().write({'google_%s_rtoken' % service: False})
error_key = error.response.json().get("error", "nc")
_logger.exception("Bad google request : %s !", error_key)
error_msg = _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired [%s]") % error_key
Expand Down
3 changes: 3 additions & 0 deletions addons/l10n_es/data/account_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,8 @@
<record id="tax_group_retenciones_21" model="account.tax.group">
<field name="name">Retenciones 21%</field>
</record>
<record id="tax_group_iva_10-5" model="account.tax.group">
<field name="name">IVA 10,5% REAGYP</field>
</record>
</data>
</odoo>
1 change: 1 addition & 0 deletions addons/l10n_es/data/account_tax_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,7 @@
<field name="amount" eval="10.5"/>
<field name="amount_type">percent</field>
<field name="include_base_amount" eval="1"/>
<field name="tax_group_id" ref="tax_group_iva_10-5"/>
<field name="tag_ids" eval="[(6, False, [ref('mod_303_42')])]"/>
</record>
<record id="account_tax_template_s_iva0_e" model="account.tax.template">
Expand Down
5 changes: 4 additions & 1 deletion addons/mrp/wizard/change_production_qty.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ def default_get(self, fields):
def _update_product_to_produce(self, production, qty, old_qty):
production_move = production.move_finished_ids.filtered(lambda x: x.product_id.id == production.product_id.id and x.state not in ('done', 'cancel'))
if production_move:
production_move.write({'product_uom_qty': qty})
production_move._decrease_reserved_quanity(qty)
production_move.with_context(do_not_unreserve=True).write({'product_uom_qty': qty})
production_move._recompute_state()
production_move._action_assign()
else:
production_move = production._generate_finished_moves()
production_move = production.move_finished_ids.filtered(lambda x: x.state not in ('done', 'cancel') and production.product_id.id == x.product_id.id)
Expand Down
19 changes: 13 additions & 6 deletions addons/payment_paypal/models/payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,12 @@ def _paypal_form_get_invalid_parameters(self, data):
@api.multi
def _paypal_form_validate(self, data):
status = data.get('payment_status')
former_tx_state = self.state
res = {
'acquirer_reference': data.get('txn_id'),
'paypal_txn_type': data.get('payment_type'),
}
if status in ['Completed', 'Processed']:
_logger.info('Validated Paypal payment for tx %s: set as done' % (self.reference))
try:
# dateutil and pytz don't recognize abbreviations PDT/PST
tzinfos = {
Expand All @@ -208,15 +208,22 @@ def _paypal_form_validate(self, data):
date = fields.Datetime.now()
res.update(date=date)
self._set_transaction_done()
return self.write(res)
if self.state == 'done' and self.state != former_tx_state:
_logger.info('Validated Paypal payment for tx %s: set as done' % (self.reference))
return self.write(res)
return True
elif status in ['Pending', 'Expired']:
_logger.info('Received notification for Paypal payment %s: set as pending' % (self.reference))
res.update(state_message=data.get('pending_reason', ''))
self._set_transaction_pending()
return self.write(res)
if self.state == 'pending' and self.state != former_tx_state:
_logger.info('Received notification for Paypal payment %s: set as pending' % (self.reference))
return self.write(res)
return True
else:
error = 'Received unrecognized status for Paypal payment %s: %s, set as error' % (self.reference, status)
_logger.info(error)
res.update(state_message=error)
self._set_transaction_cancel()
return self.write(res)
if self.state == 'cancel' and self.state != former_tx_state:
_logger.info(error)
return self.write(res)
return True
3 changes: 3 additions & 0 deletions addons/project/controllers/portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,5 +213,8 @@ def portal_my_task(self, task_id, access_token=None, **kw):
except (AccessError, MissingError):
return request.redirect('/my')

# ensure attachment are accessible with access token inside template
for attachment in task_sudo.attachment_ids:
attachment.generate_access_token()
values = self._task_get_page_view_values(task_sudo, access_token, **kw)
return request.render("project.portal_my_task", values)
4 changes: 2 additions & 2 deletions addons/project/views/project_portal_templates.xml
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@
<div class="row">
<div t-attf-class="col {{'col-lg-6' if not task.description else 'col-lg-12'}}">
<ul class="list-group">
<a class="list-group-item list-group-item-action d-flex align-items-center oe_attachments py-1 px-2" t-foreach='task.attachment_ids' t-as='attachment' t-attf-href="/web/content/#{attachment.id}?download=true" target="_blank" data-no-post-process="">
<div class='oe_attachment_embedded o_image o_image_small mr-2 mr-lg-3' t-att-title="attachment.name" t-att-data-mimetype="attachment.mimetype" t-attf-data-src="/web/image/#{attachment.id}/50x40"/>
<a class="list-group-item list-group-item-action d-flex align-items-center oe_attachments py-1 px-2" t-foreach='task.attachment_ids' t-as='attachment' t-attf-href="/web/content/#{attachment.id}?download=true&amp;access_token=#{attachment.access_token}" target="_blank" data-no-post-process="">
<div class='oe_attachment_embedded o_image o_image_small mr-2 mr-lg-3' t-att-title="attachment.name" t-att-data-mimetype="attachment.mimetype" t-attf-data-src="/web/image/#{attachment.id}/50x40?access_token=#{attachment.access_token}"/>
<div class='oe_attachment_name text-truncate'><t t-esc='attachment.name'/></div>
</a>
</ul>
Expand Down
4 changes: 2 additions & 2 deletions addons/stock/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def _compute_product_availability(self):
if self.state == 'done':
self.availability = self.product_qty
else:
total_availability = self.env['stock.quant']._get_available_quantity(self.product_id, self.location_id)
total_availability = self.env['stock.quant']._get_available_quantity(self.product_id, self.location_id) if self.product_id else 0.0
self.availability = min(self.product_qty, total_availability)

def _compute_string_qty_information(self):
Expand Down Expand Up @@ -1148,7 +1148,7 @@ def _action_done(self):
for result_package in moves_todo\
.mapped('move_line_ids.result_package_id')\
.filtered(lambda p: p.quant_ids and len(p.quant_ids) > 1):
if len(result_package.quant_ids.filtered(lambda q: float_is_zero(abs(q.quantity) + abs(q.reserved_quantity), precision_rounding=q.product_uom_id.rounding)).mapped('location_id')) > 1:
if len(result_package.quant_ids.filtered(lambda q: not float_is_zero(abs(q.quantity) + abs(q.reserved_quantity), precision_rounding=q.product_uom_id.rounding)).mapped('location_id')) > 1:
raise UserError(_('You cannot move the same package content more than once in the same transfer or split the same package into two location.'))
picking = moves_todo.mapped('picking_id')
moves_todo.write({'state': 'done', 'date': fields.Datetime.now()})
Expand Down
43 changes: 43 additions & 0 deletions addons/stock/tests/test_packing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo.tests.common import TransactionCase
from odoo.exceptions import UserError
from odoo.tools import float_round


Expand Down Expand Up @@ -299,3 +300,45 @@ def test_move_picking_with_package(self):
picking.action_done()
# if we managed to get there, there was not any exception
# complaining that 355.4 is not 355.40000000000003. Good job!

def test_move_picking_with_package_2(self):
""" Generate two move lines going to different location in the same
package.
"""
shelf1 = self.env['stock.location'].create({
'location_id': self.stock_location.id,
'name': 'Shelf 1',
})
shelf2 = self.env['stock.location'].create({
'location_id': self.stock_location.id,
'name': 'Shelf 2',
})
package = self.env['stock.quant.package'].create({})

picking = self.env['stock.picking'].create({
'picking_type_id': self.warehouse.in_type_id.id,
'location_id': self.stock_location.id,
'location_dest_id': self.stock_location.id,
'state': 'draft',
})
self.env['stock.move.line'].create({
'location_id': self.stock_location.id,
'location_dest_id': shelf1.id,
'product_id': self.productA.id,
'product_uom_id': self.productA.uom_id.id,
'qty_done': 5.0,
'picking_id': picking.id,
'result_package_id': package.id,
})
self.env['stock.move.line'].create({
'location_id': self.stock_location.id,
'location_dest_id': shelf2.id,
'product_id': self.productA.id,
'product_uom_id': self.productA.uom_id.id,
'qty_done': 5.0,
'picking_id': picking.id,
'result_package_id': package.id,
})
picking.action_confirm()
with self.assertRaises(UserError):
picking.action_done()
3 changes: 2 additions & 1 deletion addons/stock_account/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ def do_change_standard_price(self, new_price, account_id):

product_accounts = {product.id: product.product_tmpl_id.get_product_accounts() for product in self}

prec = self.env['decimal.precision'].precision_get('Product Price')
for location in locations:
for product in self.with_context(location=location.id, compute_child=False).filtered(lambda r: r.valuation == 'real_time'):
diff = product.standard_price - new_price
if float_is_zero(diff, precision_rounding=product.currency_id.rounding):
if float_is_zero(diff, precision_digits=prec):
raise UserError(_("No difference between the standard price and the new price."))
if not product_accounts[product.id].get('stock_valuation', False):
raise UserError(_('You don\'t have any stock valuation account defined on your product category. You must define one before processing this operation.'))
Expand Down
3 changes: 2 additions & 1 deletion addons/website_partner/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

from odoo import api, fields, models
from odoo.addons.http_routing.models.ir_http import slug
from odoo.tools.translate import html_translate


class WebsiteResPartner(models.Model):
_name = 'res.partner'
_inherit = ['res.partner', 'website.seo.metadata', 'website.published.mixin']

website_description = fields.Html('Website Partner Full Description', strip_style=True)
website_description = fields.Html('Website Partner Full Description', strip_style=True, translate=html_translate)
website_short_description = fields.Text('Website Partner Short Description')

@api.multi
Expand Down
3 changes: 2 additions & 1 deletion addons/website_sale_stock/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ def _get_combination_info(self, product_template_id, product_id, combination, ad

@http.route()
def get_combination_info_website(self, product_template_id, product_id, combination, add_qty, **kw):
kw['context'] = {'website_sale_stock_get_quantity': True}
kw['context'] = kw.get('context', {})
kw['context'].update(website_sale_stock_get_quantity=True)
return super(WebsiteSale, self).get_combination_info_website(product_template_id, product_id, combination, add_qty, **kw)
5 changes: 5 additions & 0 deletions doc/_extensions/odoo_ext/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
{{ super() }}
{%- endblock -%}

{%- block linktags -%}
<link rel="canonical" href="{{ canonical }}" />
{{ super() }}
{%- endblock -%}

{%- block sidebar1 -%}{%- endblock -%}
{%- block sidebar2 -%}{%- endblock -%}
{%- block relbar1 -%}{%- endblock -%}
Expand Down
11 changes: 11 additions & 0 deletions doc/cla/individual/federicolatorre.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Argentina, 2019-12-16

I hereby agree to the terms of the Odoo Individual Contributor License
Agreement v1.0.

I declare that I am authorized and able to make this agreement and sign this
declaration.

Signed,

Federico La Torre [email protected] https://github.com/federicolatorre
9 changes: 9 additions & 0 deletions doc/cla/individual/lilee115.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Germany, 28.11.2019

I hereby agree to the terms of the Odoo Individual Contributor License Agreement v1.0.

I declare that I am authorized and able to make this agreement and sign this declaration.

Signed,

Derek Lee [email protected] https://github.com/lilee115
2 changes: 1 addition & 1 deletion odoo/addons/base/data/res_country_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,7 @@
<field name="name">Mauritania</field>
<field name="code">mr</field>
<field file="base/static/img/country_flags/mr.png" name="image" type="base64" />
<field name="currency_id" ref="MRO" />
<field name="currency_id" ref="MRU" />
<field eval="222" name="phone_code" />
</record>
<record id="ms" model="res.country">
Expand Down
9 changes: 9 additions & 0 deletions odoo/addons/base/data/res_currency_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,15 @@
<field name="currency_subunit_label">Khoums</field>
</record>

<record id="MRU" model="res.currency">
<field name="name">MRU</field>
<field name="symbol">UM</field>
<field name="rounding">0.01</field>
<field name="active" eval="False"/>
<field name="currency_unit_label">Ouguiya</field>
<field name="currency_subunit_label">Khoums</field>
</record>

<record id="MDL" model="res.currency">
<field name="name">MDL</field>
<field name="symbol">L</field>
Expand Down
3 changes: 3 additions & 0 deletions odoo/addons/base/migrations/12.0.1.3/noupdate_changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,7 @@ System</span>]]></field>
<record id="dm" model="res.country">
<field eval="1767" name="phone_code"/>
</record>
<record id="mr" model="res.country">
<field name="currency_id" ref="MRU"/>
</record>
</odoo>
9 changes: 8 additions & 1 deletion odoo/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import requests
import shutil
import signal
import socket
import subprocess
import tempfile
import threading
Expand Down Expand Up @@ -470,7 +471,7 @@ def __init__(self, logger):
if websocket is None:
self._logger.warning("websocket-client module is not installed")
raise unittest.SkipTest("websocket-client module is not installed")
self.devtools_port = PORT + 2
self.devtools_port = None
self.ws_url = '' # WebSocketUrl
self.ws = None # websocket
self.request_id = 0
Expand Down Expand Up @@ -539,6 +540,12 @@ def executable(self):
def _chrome_start(self):
if self.chrome_process is not None:
return
with socket.socket() as s:
s.bind(('localhost', 0))
if hasattr(socket, 'SO_REUSEADDR'):
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
_, self.devtools_port = s.getsockname()

switches = {
'--headless': '',
'--enable-logging': 'stderr',
Expand Down
2 changes: 1 addition & 1 deletion odoo/tools/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

class _Cleaner(clean.Cleaner):

_style_re = re.compile('''([\w-]+)\s*:\s*((?:[^;"']|"[^"]*"|'[^']*')+)''')
_style_re = re.compile(r'''([\w-]+)\s*:\s*((?:[^;"']|"[^";]*"|'[^';]*')+)''')

_style_whitelist = [
'font-size', 'font-family', 'font-weight', 'background-color', 'color', 'text-align',
Expand Down