diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-05-14 17:31:53 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-05-14 17:31:53 +0200 |
| commit | bca769a1e8f50ca09d871bac5ec640467c5e099d (patch) | |
| tree | c8c447e16650af5bdb4fa172c0052807cc861625 | |
| parent | aa7088bf0efb0609ee03a2ed36e4f356ecd29fd1 (diff) | |
| parent | e70e5b6cf3379f803b08296e4413a527e79b6a4c (diff) | |
[MERGE] forward port branch saas-11.2 up to e70e5b6cf33
42 files changed, 456 insertions, 170 deletions
diff --git a/addons/account/views/account_portal_templates.xml b/addons/account/views/account_portal_templates.xml index a83d9e05f83..c9d25b95aa9 100644 --- a/addons/account/views/account_portal_templates.xml +++ b/addons/account/views/account_portal_templates.xml @@ -22,9 +22,9 @@ <template id="portal_my_invoices" name="My Invoices and Payments"> <t t-call="portal.portal_layout"> - <h3>Invoices - <t t-call="portal.portal_searchbar"/> - </h3> + <t t-call="portal.portal_searchbar"> + <t t-set="title">Invoices</t> + </t> <t t-if="not invoices"> <p>There are currently no invoices and payments for your account.</p> </t> @@ -57,7 +57,7 @@ <span class="label label-default"><i class="fa fa-fw fa-remove"></i><span class="hidden-xs"> Cancelled</span></span> </t> </td> - <td><span t-field="invoice.residual" t-options='{"widget": "monetary", "display_currency": invoice.currency_id}'/></td> + <td><span t-esc="-invoice.residual if invoice.type == 'out_refund' else invoice.residual" t-options='{"widget": "monetary", "display_currency": invoice.currency_id}'/></td> </tr> </t> </table></div> diff --git a/addons/account_payment/views/account_portal_templates.xml b/addons/account_payment/views/account_portal_templates.xml index 37366eba917..5fb062ff506 100644 --- a/addons/account_payment/views/account_portal_templates.xml +++ b/addons/account_payment/views/account_portal_templates.xml @@ -5,7 +5,7 @@ </xpath> <xpath expr="//t[@t-foreach='invoices']/tr/td[last()]" position="before"> <td> - <a t-if="invoice.state == 'open'" t-att-href="'/my/invoices/%s#portal_pay' % invoice.id" alt="Pay Now" class="btn btn-xs btn-primary"> + <a t-if="invoice.state == 'open' and invoice.type == 'out_invoice'" t-att-href="'/my/invoices/%s#portal_pay' % invoice.id" alt="Pay Now" class="btn btn-xs btn-primary"> <i class="fa fa-arrow-circle-right"/><span class='hidden-xs'> Pay Now</span> </a> </td> diff --git a/addons/calendar/models/calendar.py b/addons/calendar/models/calendar.py index 793e7cf2286..ddbb5a37880 100644 --- a/addons/calendar/models/calendar.py +++ b/addons/calendar/models/calendar.py @@ -1238,7 +1238,12 @@ class Meeting(models.Model): def _rrule_parse(self, rule_str, data, date_start): day_list = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'] rrule_type = ['yearly', 'monthly', 'weekly', 'daily'] - rule = rrule.rrulestr(rule_str, dtstart=fields.Datetime.from_string(date_start)) + ddate = fields.Datetime.from_string(date_start) + if 'Z' in rule_str and not ddate.tzinfo: + ddate = ddate.replace(tzinfo=pytz.timezone('UTC')) + rule = rrule.rrulestr(rule_str, dtstart=ddate) + else: + rule = rrule.rrulestr(rule_str, dtstart=ddate) if rule._freq > 0 and rule._freq < 4: data['rrule_type'] = rrule_type[rule._freq] diff --git a/addons/calendar/views/calendar_views.xml b/addons/calendar/views/calendar_views.xml index 1548ddfacba..80994d946fa 100644 --- a/addons/calendar/views/calendar_views.xml +++ b/addons/calendar/views/calendar_views.xml @@ -194,7 +194,6 @@ <group> <field name="privacy"/> <field name="show_as"/> - <field name="rrule" invisible="1" readonly="0" /> <field name="recurrent_id" invisible="1" /> </group> </group> diff --git a/addons/delivery/models/stock_picking.py b/addons/delivery/models/stock_picking.py index f13d2465d6c..86517b1d0ec 100644 --- a/addons/delivery/models/stock_picking.py +++ b/addons/delivery/models/stock_picking.py @@ -159,7 +159,7 @@ class StockPicking(models.Model): def send_to_shipper(self): self.ensure_one() res = self.carrier_id.send_shipping(self)[0] - if self.carrier_id.free_over and self.sale_id._compute_amount_total_without_delivery() >= self.carrier_id.amount: + if self.carrier_id.free_over and self.sale_id and self.sale_id._compute_amount_total_without_delivery() >= self.carrier_id.amount: res['exact_price'] = 0.0 self.carrier_price = res['exact_price'] self.carrier_tracking_ref = res['tracking_number'] diff --git a/addons/hr_expense/i18n/zh_CN.po b/addons/hr_expense/i18n/zh_CN.po index fe9fdc58cbd..2754a62c695 100644 --- a/addons/hr_expense/i18n/zh_CN.po +++ b/addons/hr_expense/i18n/zh_CN.po @@ -119,7 +119,7 @@ msgstr "<strong>验证于:</strong>" msgid "" "A payment of %s %s with the reference <a href='/mail/view?%s'>%s</a> related" " to your expense %s has been made." -msgstr "已完成含有与费用 % 相关的参考 <a href=\"/mail/view?%s\">% 的</a> %s %s 支付 。" +msgstr "金额为 %s %s 的付款单 <a href='/mail/view?%s'>%s</a> (相关费用申请单: %s ) 已支付。" #. module: hr_expense #: model:ir.model.fields,field_description:hr_expense.field_hr_expense__account_id diff --git a/addons/hr_payroll/i18n/de.po b/addons/hr_payroll/i18n/de.po index 70edf965692..675d505ca83 100644 --- a/addons/hr_payroll/i18n/de.po +++ b/addons/hr_payroll/i18n/de.po @@ -915,7 +915,7 @@ msgstr "Netto" #. module: hr_payroll #: model:hr.salary.rule,name:hr_payroll.hr_rule_net msgid "Net Salary" -msgstr "" +msgstr "Nettogehalt" #. module: hr_payroll #: code:addons/hr_payroll/models/hr_payslip.py:199 diff --git a/addons/http_routing/geoipresolver.py b/addons/http_routing/geoipresolver.py index 1f9b0e22724..e95b9318eb2 100644 --- a/addons/http_routing/geoipresolver.py +++ b/addons/http_routing/geoipresolver.py @@ -47,10 +47,14 @@ class GeoIPResolver(object): r = self._db.city(ip) except (ValueError, geoip2.errors.AddressNotFoundError): return {} + # Compatibility with Legacy database. + # Some ips cannot be located to a specific country. Legacy DB used to locate them in + # continent instead of country. Do the same to not change behavior of existing code. + country = r.country if r.country.geoname_id else r.continent return { 'city': r.city.name, - 'country_code': r.country.iso_code, - 'country_name': r.country.name, + 'country_code': country.iso_code, + 'country_name': country.name, 'region': r.subdivisions[0].iso_code if r.subdivisions else None, 'time_zone': r.location.time_zone, } diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 9af7ea554ef..023077e1859 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -1736,6 +1736,8 @@ class MailThread(models.AbstractModel): continue if isinstance(content, pycompat.text_type): content = content.encode('utf-8') + elif content is None: + continue data_attach = { 'name': name, 'datas': base64.b64encode(content), diff --git a/addons/mass_mailing/i18n/tr.po b/addons/mass_mailing/i18n/tr.po index 6df27d5b6b1..c43c4af4b0d 100644 --- a/addons/mass_mailing/i18n/tr.po +++ b/addons/mass_mailing/i18n/tr.po @@ -1210,7 +1210,7 @@ msgstr "" #. module: mass_mailing #: model:ir.ui.view,arch_db:mass_mailing.s_mail_block_comparison_table msgid "No customization" -msgstr "" +msgstr "Özelliştirme yok" #. module: mass_mailing #: model:ir.actions.act_window,help:mass_mailing.action_create_ab_mass_mailings_from_campaign diff --git a/addons/mrp/i18n/de.po b/addons/mrp/i18n/de.po index 398b6da5f27..f8096cd40ab 100644 --- a/addons/mrp/i18n/de.po +++ b/addons/mrp/i18n/de.po @@ -3698,7 +3698,7 @@ msgstr "" #: code:addons/mrp/wizard/mrp_product_produce.py:129 #, python-format msgid "You cannot produce the same serial number twice." -msgstr "" +msgstr "Es ist nicht möglich die gleiche Seriennummer zweimal zu produzieren." #. module: mrp #: code:addons/mrp/models/mrp_unbuild.py:93 diff --git a/addons/payment/i18n/de.po b/addons/payment/i18n/de.po index 483d87b6416..e65d52bf5f6 100644 --- a/addons/payment/i18n/de.po +++ b/addons/payment/i18n/de.po @@ -1074,6 +1074,8 @@ msgstr "Bitte wählen Sie eine Zahlungsmethode aus" #, python-format msgid "Please select the option to add a new payment method." msgstr "" +"Bitte selektieren Sie diese Option, um eine neue Zahlungsmethode " +"hinzuzufügen." #. module: payment #: model:payment.acquirer,post_msg:payment.payment_acquirer_custom @@ -1108,7 +1110,7 @@ msgstr "Anbieter" #. module: payment #: selection:payment.acquirer,payment_flow:0 msgid "Redirection to the acquirer website" -msgstr "" +msgstr "Weiterleitung zur Website des Anbieters" #. module: payment #: model:ir.model.fields,field_description:payment.field_payment_transaction__reference @@ -1424,7 +1426,7 @@ msgstr "" #: code:addons/payment/static/src/js/payment_form.js:190 #, python-format msgid "We're unable to process your payment." -msgstr "" +msgstr "Es war uns nicht möglich Ihre Zahlung zu verarbeiten." #. module: payment #: model:payment.acquirer,name:payment.payment_acquirer_transfer diff --git a/addons/payment_adyen/models/payment.py b/addons/payment_adyen/models/payment.py index 3b15e51d44f..c28093f826f 100644 --- a/addons/payment_adyen/models/payment.py +++ b/addons/payment_adyen/models/payment.py @@ -14,6 +14,7 @@ from werkzeug import urls 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.pycompat import to_native _logger = logging.getLogger(__name__) @@ -192,7 +193,7 @@ class TxAdyen(models.Model): shasign_check = tx.acquirer_id._adyen_generate_merchant_sig_sha256('out', data) else: shasign_check = tx.acquirer_id._adyen_generate_merchant_sig('out', data) - if shasign_check != data.get('merchantSig'): + if to_native(shasign_check) != to_native(data.get('merchantSig')): error_msg = _('Adyen: invalid merchantSig, received %s, computed %s') % (data.get('merchantSig'), shasign_check) _logger.warning(error_msg) raise ValidationError(error_msg) diff --git a/addons/payment_authorize/i18n/de.po b/addons/payment_authorize/i18n/de.po index 88f8a477e19..bdf930f69ff 100644 --- a/addons/payment_authorize/i18n/de.po +++ b/addons/payment_authorize/i18n/de.po @@ -95,13 +95,13 @@ msgstr "Zahlungstransaktion" #: code:addons/payment_authorize/controllers/main.py:63 #, python-format msgid "Please complete your profile. " -msgstr "" +msgstr "Bitte vervollständigen Sie Ihr Profil." #. module: payment_authorize #: code:addons/payment_authorize/controllers/main.py:58 #, python-format msgid "Please sign in to complete your profile." -msgstr "" +msgstr "Bitte loggen Sie sich ein, um Ihr Profil zu vervollständigen." #. module: payment_authorize #: model:ir.model.fields,field_description:payment_authorize.field_payment_token__provider diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index b4f5676b092..0ee763feafd 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -176,7 +176,7 @@ class PosOrder(models.Model): 'comment': self.note or '', # considering partner's sale pricelist's currency 'currency_id': self.pricelist_id.currency_id.id, - 'user_id': self.env.uid, + 'user_id': self.user_id.id, } @api.model diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 0b2d94dd71f..1b59aa34cba 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -1172,9 +1172,11 @@ var ClientListScreenWidget = ScreenWidget.extend({ var order = this.pos.get_order(); if( this.has_client_changed() ){ var default_fiscal_position_id = _.findWhere(this.pos.fiscal_positions, {'id': this.pos.config.default_fiscal_position_id[0]}); - if ( this.new_client && this.new_client.property_account_position_id ) { - var client_fiscal_position_id = _.findWhere(this.pos.fiscal_positions, {'id': this.new_client.property_account_position_id[0]}); - order.fiscal_position = client_fiscal_position_id || default_fiscal_position_id; + if ( this.new_client ) { + if (this.new_client.property_account_position_id ){ + var client_fiscal_position_id = _.findWhere(this.pos.fiscal_positions, {'id': this.new_client.property_account_position_id[0]}); + order.fiscal_position = client_fiscal_position_id || default_fiscal_position_id; + } order.set_pricelist(_.findWhere(this.pos.pricelists, {'id': this.new_client.property_product_pricelist[0]}) || this.pos.default_pricelist); } else { order.fiscal_position = default_fiscal_position_id; diff --git a/addons/point_of_sale/views/report_saledetails.xml b/addons/point_of_sale/views/report_saledetails.xml index dea4d1a9e62..89ebc22648c 100644 --- a/addons/point_of_sale/views/report_saledetails.xml +++ b/addons/point_of_sale/views/report_saledetails.xml @@ -22,7 +22,8 @@ </tr></thead> <tbody> <tr t-foreach='products' t-as='line'> - <td><t t-esc="line['product_name']" /></td> + <t t-set="internal_reference" t-value="line['code'] and '[%s] ' % line['code'] or ''" /> + <td><t t-esc="internal_reference" /><t t-esc="line['product_name']" /></td> <td> <t t-esc="line['quantity']" /> <t t-if='line["uom"] != "Unit(s)"'> diff --git a/addons/portal/static/src/less/portal.less b/addons/portal/static/src/less/portal.less index e6344b3d5d9..0e34d305fb5 100644 --- a/addons/portal/static/src/less/portal.less +++ b/addons/portal/static/src/less/portal.less @@ -289,11 +289,72 @@ img { } } - .o_portal_search_panel_fixed_width { - overflow: hidden; - max-width: 125px; - text-overflow: ellipsis; - white-space: nowrap; + .o_portal_navbar { + .navbar-brand { + margin: 0; + + @media (min-width: @grid-float-breakpoint) { + padding: @navbar-padding-vertical @navbar-padding-horizontal 0 0; + } + } + + // ===== Default portal navbar design ===== + &.o_portal_navbar_default { + margin-bottom: 8px; + + .navbar-brand { + padding: @navbar-padding-vertical @navbar-padding-horizontal 0 0; + } + + .navbar-header .dropdown-menu { + right: 0; + left: auto; + } + + .navbar-toggle { + margin-right: 0; + margin-bottom: 0; + background-color: @table-bg-active; + padding: 6px 10px @navbar-padding-vertical; + border: 1px solid @btn-default-border; + border-width: 1px 1px 0 1px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + z-index: 1; + + &.collapsed { + padding:6px 10px; + border-width: 1px; + border-radius: @btn-border-radius-base; + background-color: transparent; + } + } + + @media (max-width: @grid-float-breakpoint) { + .navbar-collapse { + z-index: 0; + box-shadow: inset 0 0 0 1px @btn-default-border; + background-color: @table-bg-active; + border-radius: @btn-border-radius-base; + border-top-right-radius: 0; + .o-transform(translateY(-2px)); + + &.in { + overflow: visible; + } + } + } + + @media (min-width: @grid-float-breakpoint) { + > .container-fluid { + padding: 0; + + .navbar-form { + padding-right: 0; + } + } + } + } } table.table tr { diff --git a/addons/portal/views/portal_templates.xml b/addons/portal/views/portal_templates.xml index abdfada255a..9865d97c87c 100644 --- a/addons/portal/views/portal_templates.xml +++ b/addons/portal/views/portal_templates.xml @@ -66,7 +66,7 @@ <template id="portal_layout" name="Portal Layout"> <t t-call="portal.frontend_layout"> - <div class="container mt16 o_portal"> + <div class="container mt16 mb16 o_portal"> <div class="oe_structure"> <div t-if="not no_breadcrumbs" class="row"> <div class="col-sm-12"> @@ -147,72 +147,93 @@ :param string filterby : name of the filter criteria :param default_url : the base url of the pages (like '/my/orders') :param boolean o_portal_search_panel : set to True to active the input search - :param html $0 : content of the t-call, <li>a</li><li>b</li> + :param html $0 : content of the t-call, <li class="pull-left">Link</li> + :param title : bavbar title + :param classes : navbar classes --> <template id="portal_searchbar" name="Portal Search Bar"> - <t t-if='searchbar_inputs'> - <div class='hidden-xs pull-right o_portal_search_panel'> - <div class="input-group"> - <div class="input-group-btn"> - <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> - <span id="search_label">Search</span> <span class="caret"></span> - </button> - <ul class="dropdown-menu" role="menu"> - <li t-foreach='searchbar_inputs' t-as='input' t-att-class="search_in == searchbar_inputs[input]['input'] and 'active'"> - <a t-att-href="'#' + searchbar_inputs[input]['input']"><span t-raw="searchbar_inputs[input]['label']"/></a> - </li> - </ul> + <nav t-attf-class="navbar o_portal_navbar {{classes if classes else 'o_portal_navbar_default'}}"> + <div class="container-fluid"> + <!-- Navbar title only --> + <div class="navbar-header pull-left"> + <t t-set="no_title">No title</t> + <h3 class="navbar-brand"><t t-esc="title or no_title"/></h3> + </div> + + <!-- Non-collapsing menu item(s) --> + <div class="navbar-header navbar-right pull-right"> + <ul class="nav pull-left"> + <t t-raw="0"/> + <li t-if="searchbar_sortings" class="dropdown pull-left ml16"> + <button id="portal_searchbar_sortby" data-toggle="dropdown" class="btn btn-default navbar-btn"> + <span class="fa fa-sort"/> + <span class="hidden-xs hidden-sm"><t t-esc="searchbar_sortings[sortby].get('label', 'Newest')"/></span> + <span class="caret"/> + </button> + <ul class="dropdown-menu" aria-labelledby="portal_searchbar_sortby"> + <li t-foreach="searchbar_sortings" t-as="option" t-attf-class="#{sortby == option and 'active'}"> + <a t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)"> + <span t-esc="searchbar_sortings[option].get('label')"/> + </a> + </li> + </ul> + </li> + <li t-if="searchbar_filters" class="dropdown pull-left ml4"> + <button id="portal_searchbar_filters" data-toggle="dropdown" class="btn btn-default navbar-btn"> + <span class="fa fa-filter"/> + <span class="hidden-xs hidden-sm"><t t-esc="searchbar_filters[filterby].get('label', 'All')"/></span> + <span class="caret"/> + </button> + <ul class="dropdown-menu" aria-labelledby="portal_searchbar_filters"> + <li t-foreach="searchbar_filters" t-as="option" t-att-class="filterby == option and 'active'"> + <a t-att-href="default_url + '?' + keep_query('*', filterby=option)"> + <span t-esc="searchbar_filters[option].get('label')"/> + </a> + </li> + </ul> + </li> + <li t-if="searchbar_groupby" class="dropdown pull-left ml4"> + <button id="portal_searchbar_groupby" data-toggle="dropdown" class="btn btn-default navbar-btn"> + <span class="fa fa-object-group"/> + <span class="hidden-xs hidden-sm"><t t-esc="searchbar_groupby[groupby].get('label', 'None')"/></span> + <span class="caret"/> + </button> + <ul class="dropdown-menu" aria-labelledby="portal_searchbar_groupby"> + <li t-foreach="searchbar_groupby" t-as="option" t-att-class="groupby == option and 'active'"> + <a t-att-href="default_url + '?' + keep_query('*', groupby=option)"> + <span t-esc="searchbar_groupby[option].get('label')"/> + </a> + </li> + </ul> + </li> + </ul> + <button t-if='searchbar_inputs' type="button" class="navbar-toggle collapsed btn ml16" data-toggle="collapse" data-target="#o_portal_searchbar_collapse"><span class="fa fa-search"/></button> + </div> + <div t-if='searchbar_inputs' class="visible-xs-block clearfix"/> + + <!-- Collapsing content (searchbar_inputs) --> + <div t-if='searchbar_inputs' class="collapse navbar-collapse text-right" id="o_portal_searchbar_collapse"> + <div class="navbar-form o_portal_search_panel"> + <div class="input-group"> + <div class="input-group-btn"> + <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> + <span id="search_label" class="hidden-xs">Search</span><span class="caret"></span> + </button> + <ul class="dropdown-menu" role="menu"> + <li t-foreach='searchbar_inputs' t-as='input' t-att-class="search_in == searchbar_inputs[input]['input'] and 'active'"> + <a t-att-href="'#' + searchbar_inputs[input]['input']"><span t-raw="searchbar_inputs[input]['label']"/></a> + </li> + </ul> + </div> + <input type="text" class="form-control" t-att-value='search' name="search"/> + <span class="input-group-btn"> + <button class="btn btn-default search-submit" type="button"><span class="fa fa-search hidden-xs"/><span class="fa fa-arrow-right visible-xs-inline-block"/></button> + </span> + </div> </div> - <input type="text" class="form-control o_portal_search_panel_fixed_width" t-att-value='search' name="search"/> - <span class="input-group-btn"> - <button class="btn btn-default search-submit" type="button"><span class="fa fa-search"></span></button> - </span> </div> - </div> - </t> - <div t-if="searchbar_sortings" class="dropdown pull-right mr4"> - <button id="portal_searchbar_sortby" class="o_portal_search_panel_fixed_width btn btn-default" type="button" data-toggle="dropdown"> - <span class="fa fa-sort fa-lg" /> - <span class='hidden-xs hidden-sm hidden-md' t-esc="searchbar_sortings[sortby].get('label', 'Newest')"/> - <span class="caret"></span> - </button> - <ul class="dropdown-menu" aria-labelledby="portal_searchbar_sortby"> - <li t-foreach="searchbar_sortings" t-as="option" t-attf-class="#{sortby == option and 'active'}"> - <a t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)"> - <span t-esc="searchbar_sortings[option].get('label')"/> - </a> - </li> - </ul> - </div> - <div t-if="searchbar_filters" class="dropdown pull-right mr4"> - <button id="portal_searchbar_filters" class="o_portal_search_panel_fixed_width btn btn-default" type="button" data-toggle="dropdown"> - <span class="fa fa-filter fa-lg" /> - <span class='hidden-xs hidden-sm hidden-md' t-esc="searchbar_filters[filterby].get('label', 'All')"/> - <span class="caret"></span> - </button> - <ul class="dropdown-menu" aria-labelledby="portal_searchbar_filters"> - <li t-foreach="searchbar_filters" t-as="option" t-att-class="filterby == option and 'active'"> - <a t-att-href="default_url + '?' + keep_query('*', filterby=option)"> - <span t-esc="searchbar_filters[option].get('label')"/> - </a> - </li> - </ul> - </div> - <div t-if="searchbar_groupby" class="dropdown pull-right mr4"> - <button id="portal_searchbar_groupby" class="o_portal_search_panel_fixed_width btn btn-default" type="button" data-toggle="dropdown"> - <span class="fa fa-bars fa-lg" /> - <span class='hidden-xs hidden-sm hidden-md' t-esc="searchbar_groupby[groupby].get('label', 'None')"/> - <span class="caret"></span> - </button> - <ul class="dropdown-menu" aria-labelledby="portal_searchbar_groupby"> - <li t-foreach="searchbar_groupby" t-as="option" t-att-class="groupby == option and 'active'"> - <a t-att-href="default_url + '?' + keep_query('*', groupby=option)"> - <span t-esc="searchbar_groupby[option].get('label')"/> - </a> - </li> - </ul> - </div> - + </div> <!-- /.container-fluid --> + </nav> </template> <template id="portal_contact" name="Contact"> diff --git a/addons/pos_cache/i18n/de.po b/addons/pos_cache/i18n/de.po index 9bacc83c478..6621dae9a8f 100644 --- a/addons/pos_cache/i18n/de.po +++ b/addons/pos_cache/i18n/de.po @@ -14,10 +14,10 @@ # e2f <projects@e2f.com>, 2018 msgid "" msgstr "" -"Project-Id-Version: Odoo Server saas~11.1\n" +"Project-Id-Version: Odoo Server saas~11.2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-12-13 14:37+0000\n" -"PO-Revision-Date: 2017-12-13 14:37+0000\n" +"POT-Creation-Date: 2018-03-22 14:10+0000\n" +"PO-Revision-Date: 2018-03-22 14:10+0000\n" "Last-Translator: e2f <projects@e2f.com>, 2018\n" "Language-Team: German (https://www.transifex.com/odoo/teams/41243/de/)\n" "MIME-Version: 1.0\n" @@ -27,58 +27,58 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_config_cache_ids +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__cache +#: model:ir.model.fields,field_description:pos_cache.field_pos_config__cache_ids msgid "Cache" msgstr "Cache" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_compute_user_id +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__compute_user_id msgid "Cache compute user" msgstr "Benutzer im Cache-Speicher halten" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_config_id +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__config_id msgid "Config" msgstr "" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_create_uid +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__create_uid msgid "Created by" msgstr "Erstellt von" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_create_date +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__create_date msgid "Created on" msgstr "Erstellt am" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_display_name +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__display_name msgid "Display Name" msgstr "Anzeigename" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_id +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__id msgid "ID" msgstr "ID" #. module: pos_cache #: model:ir.ui.view,arch_db:pos_cache.pos_config_view_form_inherit_pos_cache msgid "Invalidate cache" -msgstr "" +msgstr "Cache zurücksetzen" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache___last_update +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache____last_update msgid "Last Modified on" msgstr "Zuletzt geändert am" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_write_uid +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__write_uid msgid "Last Updated by" msgstr "Zuletzt aktualisiert durch" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_write_date +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__write_date msgid "Last Updated on" msgstr "Zuletzt aktualisiert am" @@ -90,7 +90,7 @@ msgid "Loading" msgstr "Ladevorgang" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_config_oldest_cache_time +#: model:ir.model.fields,field_description:pos_cache.field_pos_config__oldest_cache_time msgid "Oldest cache time" msgstr "Älteste Cachezeit" @@ -102,12 +102,12 @@ msgid "PoS: refresh cache" msgstr "" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_product_domain +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__product_domain msgid "Product Domain" msgstr "" #. module: pos_cache -#: model:ir.model.fields,field_description:pos_cache.field_pos_cache_product_fields +#: model:ir.model.fields,field_description:pos_cache.field_pos_cache__product_fields msgid "Product Fields" msgstr "" diff --git a/addons/project/views/project_portal_templates.xml b/addons/project/views/project_portal_templates.xml index 1f24df5cef8..2a75caba97f 100644 --- a/addons/project/views/project_portal_templates.xml +++ b/addons/project/views/project_portal_templates.xml @@ -34,9 +34,9 @@ <template id="portal_my_projects" name="My Projects"> <t t-call="portal.portal_layout"> - <h3>Projects - <t t-call="portal.portal_searchbar"/> - </h3> + <t t-call="portal.portal_searchbar"> + <t t-set="title">Projects</t> + </t> <t t-if="not projects"> <div class="alert alert-warning mt8" role="alert"> There are no projects. @@ -127,9 +127,9 @@ <template id="portal_my_tasks" name="My Tasks"> <t t-call="portal.portal_layout"> - <h3>Tasks - <t t-call="portal.portal_searchbar"/> - </h3> + <t t-call="portal.portal_searchbar"> + <t t-set="title">Tasks</t> + </t> <t t-if="not grouped_tasks"> <div class="alert alert-warning mt8" role="alert"> There are no tasks. diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index c520e6914b3..2c624970f91 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -1061,10 +1061,10 @@ class ProcurementRule(models.Model): 'partner_id': partner.id, 'picking_type_id': self.picking_type_id.id, 'company_id': values['company_id'].id, - 'currency_id': partner.property_purchase_currency_id.id or self.env.user.company_id.currency_id.id, + 'currency_id': partner.with_context(force_company=values['company_id'].id).property_purchase_currency_id.id or self.env.user.company_id.currency_id.id, 'dest_address_id': values.get('partner_dest_id', False) and values['partner_dest_id'].id, 'origin': origin, - 'payment_term_id': partner.property_supplier_payment_term_id.id, + 'payment_term_id': partner.with_context(force_company=values['company_id'].id).property_supplier_payment_term_id.id, 'date_order': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT), 'fiscal_position_id': fpos, 'group_id': group diff --git a/addons/purchase/views/portal_templates.xml b/addons/purchase/views/portal_templates.xml index 9bded7c7de0..ee6190304ce 100644 --- a/addons/purchase/views/portal_templates.xml +++ b/addons/purchase/views/portal_templates.xml @@ -24,9 +24,9 @@ <template id="portal_my_purchase_orders" name="Portal: My Purchase Orders"> <t t-call="portal.portal_layout"> - <h3>Purchase Orders - <t t-call="portal.portal_searchbar"/> - </h3> + <t t-call="portal.portal_searchbar"> + <t t-set="title">Purchase Orders</t> + </t> <div t-if="orders" class="panel panel-default"> <div class="table-responsive"><table class="table table-hover o_portal_my_doc_table"> <thead> diff --git a/addons/sale/i18n/nl.po b/addons/sale/i18n/nl.po index 2d8f804abc3..da926f2a037 100644 --- a/addons/sale/i18n/nl.po +++ b/addons/sale/i18n/nl.po @@ -11,13 +11,14 @@ # Erwin van der Ploeg <erwin@odooexperts.nl>, 2016 # Volluta <volluta@tutanota.com>, 2016 # Pol Van Dingenen <pol.vandingenen@vanroey.be>, 2017 +# Thomas Pot <thomas@open2bizz.nl>, 2018 msgid "" msgstr "" "Project-Id-Version: Odoo Server saas~11.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-22 14:10+0000\n" "PO-Revision-Date: 2018-03-22 14:10+0000\n" -"Last-Translator: Pol Van Dingenen <pol.vandingenen@vanroey.be>, 2017\n" +"Last-Translator: Thomas Pot <thomas@open2bizz.nl>, 2018\n" "Language-Team: Dutch (https://www.transifex.com/odoo/teams/41243/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -210,6 +211,8 @@ msgid "" "<span class=\"label label-success\"><i class=\"fa fa-fw fa-check\"/> " "Done</span>" msgstr "" +"<span class=\"label label-success\"><i class=\"fa fa-fw fa-check\"/> " +"Verwerkt</span>" #. module: sale #: model:ir.ui.view,arch_db:sale.report_saleorder_document diff --git a/addons/sale/report/report_all_channels_sales.py b/addons/sale/report/report_all_channels_sales.py index 50498c8825b..5af76ba85ec 100644 --- a/addons/sale/report/report_all_channels_sales.py +++ b/addons/sale/report/report_all_channels_sales.py @@ -57,6 +57,7 @@ class PosSaleReport(models.Model): (cr.date_end IS NULL OR cr.date_end > COALESCE(so.date_order, now()))) LEFT JOIN uom_uom u on (u.id=sol.product_uom) LEFT JOIN uom_uom u2 on (u2.id=pt.uom_id) + WHERE so.state != 'cancel' """ % self.env['res.currency']._select_companies_rates() return so_str diff --git a/addons/sale/views/sale_portal_templates.xml b/addons/sale/views/sale_portal_templates.xml index 11c82f053a6..27a3da7516f 100644 --- a/addons/sale/views/sale_portal_templates.xml +++ b/addons/sale/views/sale_portal_templates.xml @@ -32,9 +32,9 @@ <template id="portal_my_quotations" name="My Quotations"> <t t-call="portal.portal_layout"> - <h3>Quotations - <t t-call="portal.portal_searchbar"/> - </h3> + <t t-call="portal.portal_searchbar"> + <t t-set="title">Quotations</t> + </t> <t t-if="not quotations"> <p>There are currently no quotations for your account.</p> </t> @@ -78,9 +78,9 @@ <template id="portal_my_orders" name="My Sales Orders"> <t t-call="portal.portal_layout"> - <h3>Sales Orders - <t t-call="portal.portal_searchbar"/> - </h3> + <t t-call="portal.portal_searchbar"> + <t t-set="title">Sales Orders</t> + </t> <t t-if="not orders"> <p>There are currently no orders for your account.</p> </t> diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py index 879fd94edf5..69c09932b66 100644 --- a/addons/sale/wizard/sale_make_invoice_advance.py +++ b/addons/sale/wizard/sale_make_invoice_advance.py @@ -186,4 +186,5 @@ class SaleAdvancePaymentInv(models.TransientModel): 'invoice_policy': 'order', 'property_account_income_id': self.deposit_account_id.id, 'taxes_id': [(6, 0, self.deposit_taxes_id.ids)], + 'company_id': False, } diff --git a/addons/sale_payment/i18n/tr.po b/addons/sale_payment/i18n/tr.po index 115b2b54e86..e5930a93beb 100644 --- a/addons/sale_payment/i18n/tr.po +++ b/addons/sale_payment/i18n/tr.po @@ -181,7 +181,7 @@ msgstr "" #. module: sale_payment #: model:ir.ui.view,arch_db:sale_payment.crm_team_salesteams_view_kanban_inherit_website_portal_sale msgid "Payments to Capture" -msgstr "" +msgstr "Yakalanacak Ödemeler" #. module: sale_payment #: model:ir.actions.act_window,name:sale_payment.payment_transaction_action_pending diff --git a/addons/sale_timesheet/tests/test_timesheet_revenue.py b/addons/sale_timesheet/tests/test_timesheet_revenue.py index 75390477496..d707f257da5 100644 --- a/addons/sale_timesheet/tests/test_timesheet_revenue.py +++ b/addons/sale_timesheet/tests/test_timesheet_revenue.py @@ -19,6 +19,11 @@ class TestSaleTimesheet(TestSale): # after the 6 june of current year. self.env.ref('base.rateUSDbis').unlink() + # Make sure the company is in USD + self.env.cr.execute( + "UPDATE res_company SET currency_id = %s WHERE id = %s", + [self.env.ref('base.USD').id, self.env.user.company_id.id]) + # create project self.project = self.env['project.project'].create({ 'name': 'Project for my timesheets', diff --git a/addons/stock/i18n/de.po b/addons/stock/i18n/de.po index 6fbdc263afc..894ae1684b9 100644 --- a/addons/stock/i18n/de.po +++ b/addons/stock/i18n/de.po @@ -1256,7 +1256,7 @@ msgstr "Kumulierte Menge" #. module: stock #: model:ir.model.fields,field_description:stock.field_stock_quant_package__current_destination_location_id msgid "Current Destination Location" -msgstr "" +msgstr "Aktueller Zielort" #. module: stock #: selection:stock.quantity.history,compute_at_date:0 @@ -1276,7 +1276,7 @@ msgstr "Buchungszeile für aktuelle Kommissionierung" #. module: stock #: model:ir.model.fields,field_description:stock.field_stock_quant_package__current_source_location_id msgid "Current Source Location" -msgstr "" +msgstr "Aktueller Ausgangsort" #. module: stock #: model:ir.actions.act_window,name:stock.location_open_quants @@ -2647,7 +2647,7 @@ msgstr "Ist gesperrt" #. module: stock #: model:ir.model.fields,field_description:stock.field_stock_quant_package__is_processed msgid "Is Processed" -msgstr "" +msgstr "Verarbeitet" #. module: stock #: model:ir.model.fields,field_description:stock.field_stock_location__return_location @@ -3743,7 +3743,7 @@ msgstr "" #. module: stock #: model:ir.ui.view,arch_db:stock.report_package_barcode msgid "Package Content" -msgstr "" +msgstr "Packungsinhalt" #. module: stock #: model:ir.ui.view,arch_db:stock.quant_package_search_view @@ -3759,7 +3759,7 @@ msgstr "Paketreferenz" #. module: stock #: model:ir.ui.view,arch_db:stock.report_package_barcode_small msgid "Package Reference:" -msgstr "" +msgstr "Verpackungsreferenz:" #. module: stock #: model:ir.ui.view,arch_db:stock.view_quant_package_form @@ -3775,7 +3775,7 @@ msgstr "Typ der Verpackung" #: model:ir.ui.view,arch_db:stock.report_package_barcode #: model:ir.ui.view,arch_db:stock.report_package_barcode_small msgid "Package Type:" -msgstr "" +msgstr "Verpackungstyp:" #. module: stock #: model:ir.actions.act_window,name:stock.action_package_view @@ -4307,7 +4307,7 @@ msgstr "Produktentnahme Strategie" #. module: stock #: model:ir.ui.view,arch_db:stock.view_picking_form msgid "Put in Pack" -msgstr "" +msgstr "Verpacken" #. module: stock #: model:ir.ui.view,arch_db:stock.res_config_settings_view_form diff --git a/addons/test_mail/data/test_mail_data.py b/addons/test_mail/data/test_mail_data.py index 52248cb3095..ef55fb82be9 100644 --- a/addons/test_mail/data/test_mail_data.py +++ b/addons/test_mail/data/test_mail_data.py @@ -290,4 +290,145 @@ X-Attachment-Id: ii_151b51a290ed6a91 R0lGODdhAgACALMAAAAAAP///wAAAP//AP8AAP+AAAD/AAAAAAAA//8A/wAAAP+AgAAAAAAAAAAA AAAAACwAAAAAAgACAAAEA3DJFQA7 --001a11416b9e9b229a05272b7052-- -"""
\ No newline at end of file +""" + +MAIL_EML_ATTACHMENT = """Subject: Re: test attac +From: Anon <anon@odoo.com> +To: anon@gmail.com +References: <f3b9f8f8-28fa-2543-cab2-7aa68f679ebb@odoo.com> +Message-ID: <cb7eaf62-58dc-2017-148c-305d0c78892f@odoo.com> +Date: Wed, 14 Mar 2018 14:26:58 +0100 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 + Thunderbird/52.6.0 +MIME-Version: 1.0 +In-Reply-To: <f3b9f8f8-28fa-2543-cab2-7aa68f679ebb@odoo.com> +Content-Type: multipart/mixed; + boundary="------------A6B5FD5F68F4D73ECD739009" +Content-Language: en-US + +This is a multi-part message in MIME format. +--------------A6B5FD5F68F4D73ECD739009 +Content-Type: text/plain; charset=utf-8; format=flowed +Content-Transfer-Encoding: 7bit + + + +On 14/03/18 14:20, Anon wrote: +> Some nice content +> + + +--------------A6B5FD5F68F4D73ECD739009 +Content-Type: message/rfc822; + name="original_msg.eml" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; + filename="original_msg.eml" + +Delivered-To: anon2@gmail1.openerp.com +Received: by 10.46.1.170 with SMTP id f42csp2379722lji; + Mon, 5 Mar 2018 01:19:23 -0800 (PST) +X-Google-Smtp-Source: AG47ELsYTlAcblMxfnaEENQuF+MFoac5Q07wieyw0cybq/qOX4+DmayqoQILkiWT+NiTOcnr/ACO +X-Received: by 10.28.154.213 with SMTP id c204mr7237750wme.64.1520241563503; + Mon, 05 Mar 2018 01:19:23 -0800 (PST) +ARC-Seal: i=1; a=rsa-sha256; t=1520241563; cv=none; + d=google.com; s=arc-20160816; + b=BqgMSbqmbpYW1ZtfGTVjj/654MBmabw4XadNZEaI96hDaub6N6cP8Guu3PoxscI9os + 0OLYVP1s/B+Vv9rIzulCwHyHsgnX+aTxGYepTDN6x8SA9Qeb9aQoNSVvQLryTAoGpaFr + vXhw8aPWyr28edE03TDFA/s7X65Bf6dV5zJdMiUPVqGkfYfcTHMf3nDER5vk8vQj7tve + Cfyy0h9vLU9RSEtdFwmlEkLmgT9NQ3GDf0jQ97eMXPgR2q6duCPoMcz15KlWOno53xgH + EiV7aIZ5ZMN/m+/2xt3br/ubJ5euFojWhDnHUZoaqd08TCSQPd4fFCCx75MjDeCnwYMn + iKSg== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=content-language:mime-version:user-agent:date:message-id:subject + :from:to:dkim-signature:arc-authentication-results; + bh=/UIFqhjCCbwBLsI4w7YY98QH6G/wxe+2W4bbMDCskjM=; + b=Wv5jt+usnSgWI96GaZWUN8/VKl1drueDpU/4gkyX/iK4d6S4CuSDjwYAc3guz/TjeW + GoKCqT30IGZoStpXQbuLry7ezXNK+Fp8MJKN2n/x5ClJWHxIsxIGlP2QC3TO8RI0P5o0 + GXG9izW93q1ubkdPJFt3unSjjwSYf5XVQAZQtRm9xKjqA+lbtFbsnbjJ4wgYBURnD8ma + Qxb2xsxXDelaZvtdlzHRDn5SEkbqhcCclEYw6oRLpVQFZeYtPxcCleVybtj2owJxdaLp + 7wXuo/gpYe6E2cPuS2opei8AzjEhYTNzlYXTPvaoxCCTTjfGTaPv22TeRDehuIXngSEl + Nmmw== +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@odoo.com header.s=mail header.b=MCzhjB9b; + spf=pass (google.com: domain of soup@odoo.com designates 149.202.180.44 as permitted sender) smtp.mailfrom=soup@odoo.com; + dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=odoo.com +Return-Path: <soup@odoo.com> +Received: from mail2.odoo.com (mail2.odoo.com. [149.202.180.44]) + by mx.google.com with ESMTPS id y4si4279200wmy.148.2018.03.05.01.19.22 + (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); + Mon, 05 Mar 2018 01:19:23 -0800 (PST) +Received-SPF: pass (google.com: domain of soup@odoo.com designates 149.202.180.44 as permitted sender) client-ip=149.202.180.44; +Authentication-Results: mx.google.com; + dkim=pass header.i=@odoo.com header.s=mail header.b=MCzhjB9b; + spf=pass (google.com: domain of soup@odoo.com designates 149.202.180.44 as permitted sender) smtp.mailfrom=soup@odoo.com; + dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=odoo.com +Received: from [10.10.31.24] (unknown [91.183.114.50]) + (Authenticated sender: soup) + by mail2.odoo.com (Postfix) with ESMTPSA id 7B571A4085 + for <what@odoo.com>; Mon, 5 Mar 2018 10:19:21 +0100 (CET) +DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=odoo.com; s=mail; + t=1520241562; bh=L2r7Sp/vjogIdM1k8H9zDGDjnhKolsTTLLjndnFC4Jc=; + h=To:From:Subject:Date:From; + b=MCzhjB9bnsrJ3uKjq+GjujFxmtrq3fc7Vv7Vg2C72EPKnkxgqy6yPjWKtXbBlaiT3 + YjKI24aiSQlOeOPQiqFgiDzeqqemNDp+CRuhoYz1Vbz+ESRaHtkWRLb7ZjvohS2k7e + RTq7tUxY2nUL2YrNHV7DFYtJVBwiTuyLP6eAiJdE= +To: what@odoo.com +From: Soup <soup@odoo.com> +Subject: =?UTF-8?Q?Soupe_du_jour_:_Pois_cass=c3=a9s?= +Message-ID: <a05d8334-7b7c-df68-c96a-4a88ed19f31b@odoo.com> +Date: Mon, 5 Mar 2018 10:19:21 +0100 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 + Thunderbird/52.6.0 +MIME-Version: 1.0 +Content-Type: multipart/alternative; + boundary="------------1F2D18B1129FC2F0B9EECF50" +Content-Language: en-US +X-Spam-Status: No, score=-1.2 required=5.0 tests=ALL_TRUSTED,BAYES_00, + HTML_IMAGE_ONLY_08,HTML_MESSAGE,T_REMOTE_IMAGE autolearn=no + autolearn_force=no version=3.4.0 +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail2.odoo.com + +This is a multi-part message in MIME format. +--------------1F2D18B1129FC2F0B9EECF50 +Content-Type: text/plain; charset=utf-8; format=flowed +Content-Transfer-Encoding: 8bit + +Résultat de recherche d'images pour "dessin la princesse au petit pois" + +-- +Soup + +Odoo S.A. +Chaussée de Namur, 40 +B-1367 Grand Rosière +Web: http://www.odoo.com + + +--------------1F2D18B1129FC2F0B9EECF50 +Content-Type: text/html; charset=utf-8 +Content-Transfer-Encoding: 8bit + +<html> + <head> + + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + </head> + <body text="#000000" bgcolor="#FFFFFF"> + <p><img +src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQjCNAadd3NDM8g9w0P_-gAVYrrqC0wmBNYKGsTZ2Pst5SsNxTRnA" + alt="Résultat de recherche d'images pour "dessin la + princesse au petit pois""></p> + <pre class="moz-signature" cols="72">-- +Soup + +Odoo S.A. +Chaussée de Namur, 40 +B-1367 Grand Rosière +Web: <a class="moz-txt-link-freetext" href="http://www.odoo.com">http://www.odoo.com</a> </pre> + </body> +</html> + +--------------1F2D18B1129FC2F0B9EECF50-- + +--------------A6B5FD5F68F4D73ECD739009--""" diff --git a/addons/test_mail/tests/test_mail_gateway.py b/addons/test_mail/tests/test_mail_gateway.py index ccf5fb64423..f07a21bcaf6 100644 --- a/addons/test_mail/tests/test_mail_gateway.py +++ b/addons/test_mail/tests/test_mail_gateway.py @@ -7,7 +7,7 @@ from email.utils import formataddr from odoo.addons.test_mail.data.test_mail_data import \ MAIL_TEMPLATE, MAIL_TEMPLATE_PLAINTEXT, MAIL_MULTIPART_MIXED, MAIL_MULTIPART_MIXED_TWO, \ - MAIL_MULTIPART_IMAGE, MAIL_SINGLE_BINARY + MAIL_MULTIPART_IMAGE, MAIL_SINGLE_BINARY, MAIL_EML_ATTACHMENT from odoo.addons.test_mail.tests.common import BaseFunctionalTest, MockEmails from odoo.tools import mute_logger @@ -79,6 +79,12 @@ class TestMailgateway(BaseFunctionalTest, MockEmails): }) @mute_logger('odoo.addons.mail.models.mail_thread') + def test_message_parse_eml(self): + """ Test that the parsing of mail with embedded emails as eml(msg) which generates empty attachments, can be processed. + """ + self.env['mail.thread'].message_process('mail.channel', MAIL_EML_ATTACHMENT) + + @mute_logger('odoo.addons.mail.models.mail_thread') def test_message_process_cid(self): record = self.format_and_process(MAIL_MULTIPART_IMAGE, to='groups@example.com') message = record.message_ids[0] diff --git a/addons/web_editor/static/src/js/editor/rte.js b/addons/web_editor/static/src/js/editor/rte.js index 44f69fc2026..b4a42f843c8 100644 --- a/addons/web_editor/static/src/js/editor/rte.js +++ b/addons/web_editor/static/src/js/editor/rte.js @@ -270,7 +270,13 @@ var RTEWidget = Widget.extend({ $.fn.carousel = this.edit_bootstrap_carousel; $(document).on('click.rte keyup.rte', function () { - var $popover = $((range.create()||{}).sc).closest('[contenteditable]'); + var current_range = {}; + try { + current_range = range.create() || {}; + } catch (e) { + // if range is on Restricted element ignore error + } + var $popover = $(current_range.sc).closest('[contenteditable]'); var popover_history = ($popover.data()||{}).NoteHistory; if (!popover_history || popover_history === history) return; var editor = $popover.parent('.note-editor'); diff --git a/addons/web_editor/static/src/js/editor/transcoder.js b/addons/web_editor/static/src/js/editor/transcoder.js index 4fa30978f84..fb3e69eda29 100644 --- a/addons/web_editor/static/src/js/editor/transcoder.js +++ b/addons/web_editor/static/src/js/editor/transcoder.js @@ -227,6 +227,26 @@ function imgToFont($editable) { }); } +/* + * Utility function to apply function over descendants elements + * + * This is needed until the following issue of jQuery is solved: + * https://github.com./jquery/sizzle/issues/403 + * + * @param {Element} node The root Element node + * @param {Function} func The function applied over descendants + */ +function applyOverDescendants(node, func) { + node = node.firstChild; + while (node) { + if (node.nodeType === 1) { + func(node); + applyOverDescendants(node, func); + } + node = node.nextSibling; + } +} + /** * Converts css style to inline style (leave the classes on elements but forces * the style they give as inline style). @@ -237,9 +257,9 @@ function classToStyle($editable) { if (!rulesCache.length) { getMatchedCSSRules($editable[0]); } - $editable.find('*').each(function () { - var $target = $(this); - var css = getMatchedCSSRules(this); + applyOverDescendants($editable[0], function (node) { + var $target = $(node); + var css = getMatchedCSSRules(node); var style = $target.attr('style') || ''; _.each(css, function (v,k) { if (!(new RegExp('(^|;)\s*' + k).test(style))) { @@ -252,12 +272,12 @@ function classToStyle($editable) { $target.attr('style', style); } // Apple Mail - if (this.nodeName === 'TD' && !this.childNodes.length) { - this.innerHTML = ' '; + if (node.nodeName === 'TD' && !node.childNodes.length) { + node.innerHTML = ' '; } // Outlook - if (this.nodeName === 'A' && $target.hasClass('btn') && !$target.children().length) { + if (node.nodeName === 'A' && $target.hasClass('btn') && !$target.children().length) { var $hack = $('<table class="o_outlook_hack"><tr><td></td></tr></table>'); $hack.find('td') .attr('height', $target.outerHeight()) @@ -269,7 +289,7 @@ function classToStyle($editable) { $target.after($hack); $target.appendTo($hack.find('td')); // the space add a line when it's a table but it's invisible when it's a link - var node = $hack[0].previousSibling; + node = $hack[0].previousSibling; if (node && node.nodeType === Node.TEXT_NODE && !node.textContent.match(/\S/)) { $(node).remove(); } @@ -297,9 +317,9 @@ function styleToClass($editable) { var $c = $('<span/>').appendTo(document.body); - $editable.find('*').each(function () { - var $target = $(this); - var css = getMatchedCSSRules(this); + applyOverDescendants($editable[0], function (node) { + var $target = $(node); + var css = getMatchedCSSRules(node); var style = ''; _.each(css, function (v,k) { if (!(new RegExp('(^|;)\s*' + k).test(style))) { diff --git a/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml b/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml index c07c7577e45..f441eb74dcb 100644 --- a/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml +++ b/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml @@ -234,10 +234,9 @@ <template id="portal_my_leads" name="My Leads"> <t t-call="portal.portal_layout"> - <h3> - My Leads - <t t-call="portal.portal_searchbar"/> - </h3> + <t t-call="portal.portal_searchbar"> + <t t-set="title">My Leads</t> + </t> <div t-if="not leads" class="alert alert-warning mt8" role="alert"> There are no leads. </div> @@ -269,11 +268,10 @@ <template id="portal_my_opportunities" name="My Opportunities"> <t t-call="portal.portal_layout"> - <h3> - My Opportunities - <t t-call="portal.portal_searchbar"/> - <button t-if="request.env.user.partner_id.grade_id or request.env.user.commercial_partner_id.grade_id" name='new_opp' data-toggle="modal" data-target=".modal_new_opp" class="btn btn-default pull-right mr8"><i class="fa fa-plus fa-lg" /></button> - </h3> + <t t-call="portal.portal_searchbar"> + <t t-set="title">My Opportunities</t> + <li class="pull-left"><button t-if="request.env.user.partner_id.grade_id or request.env.user.commercial_partner_id.grade_id" name='new_opp' data-toggle="modal" data-target=".modal_new_opp" class="btn btn-default navbar-btn ml16"><i class="fa fa-plus"/></button></li> + </t> <div class="modal fade modal_new_opp" role="form" aria-hidden="true"> <div class="modal-dialog"> <form method="POST" class="modal-content js_website_submit_form new_opp_form"> diff --git a/addons/website_event/views/event_templates.xml b/addons/website_event/views/event_templates.xml index 9a04d4e7e57..9ae221bc2fd 100644 --- a/addons/website_event/views/event_templates.xml +++ b/addons/website_event/views/event_templates.xml @@ -684,10 +684,10 @@ <span class="label label-danger"><i class="fa fa-ban"></i></span> </t> <t t-if="event_dict['event'].address_id"> - <i class="fa fa-map-marker"></i> + <i class="fa fa-map-marker" title="It is a physical event"></i> </t> <t t-if="not event_dict['event'].address_id"> - <i class="fa fa-cloud"></i> + <i class="fa fa-cloud" title="It is an online event"></i> </t> <b><span t-esc="event_dict['date']"/>: <span><a t-att-href="event_dict['url']"><t t-esc="event_dict['event'].name"/></a></span></b> </div> diff --git a/addons/website_sale/models/res_partner.py b/addons/website_sale/models/res_partner.py index 6755a4b6a54..77fc633c9c8 100644 --- a/addons/website_sale/models/res_partner.py +++ b/addons/website_sale/models/res_partner.py @@ -7,4 +7,4 @@ from odoo import models, fields class ResPartner(models.Model): _inherit = 'res.partner' - last_website_so_id = fields.Many2one('sale.order', string='Last Online Sales Order') + last_website_so_id = fields.Many2one('sale.order', string='Last Online Sales Order', copy=False) diff --git a/odoo/addons/base/i18n/tr.po b/odoo/addons/base/i18n/tr.po index 1472fe800a2..9a626da8d9a 100644 --- a/odoo/addons/base/i18n/tr.po +++ b/odoo/addons/base/i18n/tr.po @@ -5965,7 +5965,7 @@ msgstr "Uygulamalar:" #. module: base #: model:ir.model.fields,field_description:base.field_ir_ui_view__arch_db msgid "Arch Blob" -msgstr "" +msgstr "Damlayı kavislendir" #. module: base #: model:ir.model.fields,field_description:base.field_ir_ui_view__arch_fs @@ -10954,6 +10954,8 @@ msgid "" "If this field is empty, the view applies to all users. Otherwise, the view " "applies to the users of those groups only." msgstr "" +"Bu alan boşsa, görünüm tüm kullanıcılara uygulanır. Değilse, görünüm sadece " +"grup kullanıcılarına uygulanır." #. module: base #: model:ir.model.fields,help:base.field_ir_ui_view__active @@ -10963,6 +10965,9 @@ msgid "" "* if False, the view currently does not extend its parent but can be enabled\n" " " msgstr "" +"Eğer bu görünüm kaldıysa,\n" +"* Eğer doğruysa, görünüm her zaman üst öğeyi genişletir\n" +"*Yanlış ise, görünüm şu anda üst öğeyi genişletmez ancak etkinleştirilebilir" #. module: base #: model:ir.ui.view,arch_db:base.view_rule_form @@ -15878,7 +15883,7 @@ msgstr "" #. module: base #: model:ir.model.fields,field_description:base.field_ir_actions_report__print_report_name msgid "Printed Report Name" -msgstr "" +msgstr "Basılan Rapor Adı" #. module: base #: model:ir.model.fields,field_description:base.field_ir_cron__priority @@ -19068,7 +19073,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_website_delivery_ups msgid "UPS Bill My Account" -msgstr "" +msgstr "UPS Fatura Hesabım" #. module: base #: model:ir.module.module,shortdesc:base.module_delivery_ups @@ -19779,7 +19784,7 @@ msgstr "" #. module: base #: model:ir.model.fields,field_description:base.field_ir_ui_view__inherit_children_ids msgid "Views which inherit from this one" -msgstr "" +msgstr "Birisinden kalan görünümler." #. module: base #: model:res.country,name:base.vg @@ -20704,7 +20709,7 @@ msgstr "ir.actions.client" #: model:ir.model,name:base.model_ir_actions_report #: selection:ir.ui.menu,action:0 msgid "ir.actions.report" -msgstr "" +msgstr "ir.actions.report" #. module: base #: model:ir.model,name:base.model_ir_actions_server diff --git a/odoo/addons/base/tests/test_mail.py b/odoo/addons/base/tests/test_mail.py index c0f437be385..5693906c092 100644 --- a/odoo/addons/base/tests/test_mail.py +++ b/odoo/addons/base/tests/test_mail.py @@ -116,7 +116,7 @@ class TestSanitizer(unittest.TestCase): test_data = [ ( '<span style="position: fixed; top: 0px; left: 50px; width: 40%; height: 50%; background-color: red;">Coin coin </span>', - ['background-color: red', 'Coin coin'], + ['background-color:red', 'Coin coin'], ['position', 'top', 'left'] ), ( """<div style='before: "Email Address; coincoin cheval: lapin"; @@ -124,7 +124,7 @@ class TestSanitizer(unittest.TestCase): this; means: anything ?#ùµ" ; some-property: 2px; top: 3'>youplaboum</div>""", - ['font-size: 30px', 'youplaboum'], + ['font-size:30px', 'youplaboum'], ['some-property', 'top', 'cheval'] ), ( '<span style="width">Coincoin</span>', diff --git a/odoo/addons/base/tests/test_mail_examples.py b/odoo/addons/base/tests/test_mail_examples.py index 4f3b5b48300..032d321ff06 100644 --- a/odoo/addons/base/tests/test_mail_examples.py +++ b/odoo/addons/base/tests/test_mail_examples.py @@ -510,7 +510,7 @@ REMOVE_CLASS = u""" </div> """ REMOVE_CLASS_IN = [ - u'<div style="font-size: 12pt; font-family: \'Times New Roman\'; color: #000000">', + u'<div style="font-size:12pt; font-family:\'Times New Roman\'; color:#000000">', u'An error occured in a modal and I will send you back the html to try opening one on your end'] REMOVE_CLASS_OUT = [ u'<div class="modal-backdrop in">', diff --git a/odoo/fields.py b/odoo/fields.py index 51e3456a383..7ad1ba04996 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -1827,6 +1827,8 @@ class Selection(Field): def convert_to_cache(self, value, record, validate=True): if not validate: return value or False + if value and self.column_type[0] == 'int4': + value = int(value) if value in self.get_values(record.env): return value elif not value: diff --git a/odoo/tools/mail.py b/odoo/tools/mail.py index 931c2f01215..31c42ebd8c9 100644 --- a/odoo/tools/mail.py +++ b/odoo/tools/mail.py @@ -155,7 +155,7 @@ class _Cleaner(clean.Cleaner): if style[0].lower() in self._style_whitelist: valid_styles[style[0].lower()] = style[1] if valid_styles: - el.attrib['style'] = '; '.join('%s: %s' % (key, val) for (key, val) in valid_styles.items()) + el.attrib['style'] = '; '.join('%s:%s' % (key, val) for (key, val) in valid_styles.items()) else: del el.attrib['style'] |
