diff options
36 files changed, 118 insertions, 97 deletions
diff --git a/addons/account/models/company.py b/addons/account/models/company.py index 63aa0230a1a..10c95922ca4 100644 --- a/addons/account/models/company.py +++ b/addons/account/models/company.py @@ -124,12 +124,8 @@ Best Regards,''')) @api.model def _verify_fiscalyear_last_day(self, company_id, last_day, last_month): - company = self.browse(company_id) - last_day = last_day or (company and company.fiscalyear_last_day) or 31 - last_month = last_month or (company and company.fiscalyear_last_month) or 12 - current_year = datetime.now().year - last_day_of_month = calendar.monthrange(current_year, last_month)[1] - return last_day > last_day_of_month and last_day_of_month or last_day + # FIXME: Remove this method in master + return last_day @api.multi def compute_fiscalyear_dates(self, current_date): diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml index f220b6d9059..5acb2ffcb9f 100644 --- a/addons/account/views/report_invoice.xml +++ b/addons/account/views/report_invoice.xml @@ -52,11 +52,6 @@ <!-- Is there a discount on at least one line? --> <t t-set="display_discount" t-value="any([l.discount for l in o.invoice_line_ids])"/> - <!-- show only in sale invoice --> - <t t-set="type_is_out" t-value="o.type == 'out_invoice'"/> - <!-- if Rounding Method is computed per line --> - <t t-set="display_taxamount" - t-value="o.company_id.tax_calculation_rounding_method == 'round_per_line'"/> <table class="table table-condensed" name="invoice_line_table"> <thead> @@ -67,7 +62,6 @@ <th class="text-right">Unit Price</th> <th t-if="display_discount" class="text-right">Disc.(%)</th> <th class="text-right">Taxes</th> - <th t-if="display_taxamount and type_is_out" class="text-right">Tax Amount</th> <th class="text-right">Amount</th> </tr> </thead> @@ -88,13 +82,6 @@ <td class="text-right"> <span t-esc="', '.join(map(lambda x: (x.description or x.name), l.invoice_line_tax_ids))"/> </td> - <td t-if="display_taxamount and type_is_out" class="text-right"> - <t t-set="taxes" - t-value="l.invoice_line_tax_ids.compute_all(l.price_unit, l.currency_id, l.quantity)"/> - <t t-set="tax_amount" - t-value="taxes and (taxes['total_included'] - taxes['base']) or 0.0"/> - <span t-esc="tax_amount" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> - </td> <td class="text-right" id="subtotal"> <span t-field="l.price_subtotal" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> @@ -106,7 +93,6 @@ <td></td> <td></td> <td t-if="display_discount"></td> - <td t-if="display_taxamount and type_is_out"></td> <td></td> <td></td> </tr> diff --git a/addons/account/wizard/setup_wizards.py b/addons/account/wizard/setup_wizards.py index 5128d50e2e4..69a10649a9e 100644 --- a/addons/account/wizard/setup_wizards.py +++ b/addons/account/wizard/setup_wizards.py @@ -36,17 +36,6 @@ class FinancialYearOpeningWizard(models.TransientModel): """ Forces fiscal year setup state to 'undone'.""" self.company_id.account_setup_fy_data_done = False - @api.multi - def write(self, vals): - if 'fiscalyear_last_day' in vals or 'fiscalyear_last_month' in vals: - for wizard in self: - company = wizard.company_id - vals['fiscalyear_last_day'] = company._verify_fiscalyear_last_day( - company.id, - vals.get('fiscalyear_last_day'), - vals.get('fiscalyear_last_month')) - return super(FinancialYearOpeningWizard, self).write(vals) - class SetupBarBankConfigWizard(models.TransientModel): _inherits = {'res.partner.bank': 'res_partner_bank_id'} diff --git a/addons/anonymization/wizard/anonymize_wizard.py b/addons/anonymization/wizard/anonymize_wizard.py index 4ba71b03455..7bf914ba742 100644 --- a/addons/anonymization/wizard/anonymize_wizard.py +++ b/addons/anonymization/wizard/anonymize_wizard.py @@ -127,6 +127,9 @@ class IrModelFieldsAnonymizeWizard(models.TransientModel): @api.multi def anonymize_database(self): """Sets the 'anonymized' state to defined fields""" + # pylint: disable=W0101 + raise UserError("""The Odoo Migration Platform no longer accepts anonymized databases.\n + If you wish for your data to remain private during migration, please contact us at upgrade@odoo.com""") self.ensure_one() # create a new history record: diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 9e6c4a83416..b3ffeaf2538 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -707,6 +707,8 @@ class Lead(models.Model): @api.model def _get_duplicated_leads_by_emails(self, partner_id, email, include_lost=False): """ Search for opportunities that have the same partner and that arent done or cancelled """ + if not email: + return [] partner_match_domain = [] for email in set(email_split(email) + [email]): partner_match_domain.append(('email_from', '=ilike', email)) diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py index e08f37b135e..d0ca0a7c424 100644 --- a/addons/delivery/models/sale_order.py +++ b/addons/delivery/models/sale_order.py @@ -88,6 +88,9 @@ class SaleOrder(models.Model): def _create_delivery_line(self, carrier, price_unit): SaleOrderLine = self.env['sale.order.line'] + if self.partner_id: + # set delivery detail in the customer language + carrier = carrier.with_context(lang=self.partner_id.lang) # Apply fiscal position taxes = carrier.product_id.taxes_id.filtered(lambda t: t.company_id.id == self.company_id.id) diff --git a/addons/hr_payroll_account/models/hr_payroll_account.py b/addons/hr_payroll_account/models/hr_payroll_account.py index da168912095..989d5f260f4 100644 --- a/addons/hr_payroll_account/models/hr_payroll_account.py +++ b/addons/hr_payroll_account/models/hr_payroll_account.py @@ -53,6 +53,7 @@ class HrPayslip(models.Model): @api.multi def action_payslip_done(self): + res = super(HrPayslip, self).action_payslip_done() precision = self.env['decimal.precision'].precision_get('Payroll') for slip in self: @@ -138,7 +139,7 @@ class HrPayslip(models.Model): move = self.env['account.move'].create(move_dict) slip.write({'move_id': move.id, 'date': date}) move.post() - return super(HrPayslip, self).action_payslip_done() + return res class HrSalaryRule(models.Model): diff --git a/addons/hw_escpos/escpos/escpos.py b/addons/hw_escpos/escpos/escpos.py index 7fc0e196b39..3573efb1d98 100644 --- a/addons/hw_escpos/escpos/escpos.py +++ b/addons/hw_escpos/escpos/escpos.py @@ -358,7 +358,7 @@ class Escpos: else: self._raw(string) - raw += S_RASTER_N + raw += S_RASTER_N.encode('utf-8') buffer = "%02X%02X%02X%02X" % (int((size[0]/size[1])/8), 0, size[1], 0) raw += codecs.decode(buffer, 'hex') buffer = "" diff --git a/addons/l10n_in/views/report_invoice.xml b/addons/l10n_in/views/report_invoice.xml index 7fb7337becf..f20fee72efd 100644 --- a/addons/l10n_in/views/report_invoice.xml +++ b/addons/l10n_in/views/report_invoice.xml @@ -108,7 +108,14 @@ <td></td> <td></td> <td t-if="display_discount" groups="sale.group_discount_per_so_line"></td> - <td t-att-colspan="o.company_id.country_id.code == 'IN' and 5 or 1"></td> + <td t-if="len(o.tax_line_ids) > 0"></td> + <td></td> + <t t-if="o.company_id.country_id.code == 'IN'"> + <td t-if="is_cgst"></td> + <td t-if="is_cgst"></td> + <td t-if="is_igst"></td> + <td t-if="is_cess"></td> + </t> </tr> </tbody> </table> diff --git a/addons/l10n_in_stock/views/report_stockpicking_operations.xml b/addons/l10n_in_stock/views/report_stockpicking_operations.xml index 70d9fdbc1f4..cb6fb012d2c 100644 --- a/addons/l10n_in_stock/views/report_stockpicking_operations.xml +++ b/addons/l10n_in_stock/views/report_stockpicking_operations.xml @@ -2,8 +2,8 @@ <odoo> <template id="gst_report_picking_inherit" inherit_id="stock.report_picking"> - <xpath expr="//span[@t-field='move.product_id.description_picking']" position="after"> - <t t-if="move.product_id and move.product_id.l10n_in_hsn_code and o.company_id.country_id.code == 'IN'"><h6><strong class="ml16">HSN/SAC Code:</strong> <span t-field="move.product_id.l10n_in_hsn_code"/></h6></t> + <xpath expr="//span[@t-field='ml.product_id.description_picking']" position="after"> + <t t-if="ml.product_id and ml.product_id.l10n_in_hsn_code and o.company_id.country_id.code == 'IN'"><h6><strong class="ml16">HSN/SAC Code:</strong> <span t-field="ml.product_id.l10n_in_hsn_code"/></h6></t> </xpath> </template> diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py index 949a715cddb..6386273070c 100644 --- a/addons/mail/controllers/main.py +++ b/addons/mail/controllers/main.py @@ -176,6 +176,20 @@ class MailController(http.Controller): models that have an access_token may apply variations on this. """ + # ============================================================================================== + # This block of code disappeared on saas-11.3 to be reintroduced by TBE. + # This is needed because after a migration from an older version to saas-11.3, the link + # received by mail with a message_id no longer work. + # So this block of code is needed to guarantee the backward compatibility of those links. + if kwargs.get('message_id'): + try: + message = request.env['mail.message'].sudo().browse(int(kwargs['message_id'])).exists() + except: + message = request.env['mail.message'] + if message: + model, res_id = message.model, message.res_id + # ============================================================================================== + if res_id and isinstance(res_id, pycompat.string_types): res_id = int(res_id) return self._redirect_to_record(model, res_id, access_token) diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py index 47b724aac98..b556a6ac66a 100644 --- a/addons/mail/models/mail_activity.py +++ b/addons/mail/models/mail_activity.py @@ -387,6 +387,8 @@ class MailActivityMixin(models.AbstractModel): record.activity_date_deadline = record.activity_ids[:1].date_deadline def _search_activity_date_deadline(self, operator, operand): + if operator == '=' and not operand: + return [('activity_ids', '=', False)] return [('activity_ids.date_deadline', operator, operand)] @api.model diff --git a/addons/mass_mailing/models/mail_thread.py b/addons/mass_mailing/models/mail_thread.py index 8e4ee298c67..f26aee7ff4a 100644 --- a/addons/mass_mailing/models/mail_thread.py +++ b/addons/mass_mailing/models/mail_thread.py @@ -35,7 +35,7 @@ class MailThread(models.AbstractModel): """ Override to update the parent mail statistics. The parent is found by using the References header of the incoming message and looking for matching message_id in mail.mail.statistics. """ - if message.get('References'): + if message.get('References') and routes: message_ids = [x.strip() for x in decode_smtp_header(message['References']).split()] self.env['mail.mail.statistics'].set_opened(mail_message_ids=message_ids) self.env['mail.mail.statistics'].set_replied(mail_message_ids=message_ids) diff --git a/addons/mass_mailing/models/mass_mailing_stats.py b/addons/mass_mailing/models/mass_mailing_stats.py index 0a095943f99..8e48a4cb465 100644 --- a/addons/mass_mailing/models/mass_mailing_stats.py +++ b/addons/mass_mailing/models/mass_mailing_stats.py @@ -106,7 +106,7 @@ class MailMailStats(models.Model): def set_opened(self, mail_mail_ids=None, mail_message_ids=None): statistics = self._get_records(mail_mail_ids, mail_message_ids, [('opened', '=', False)]) - statistics.write({'opened': fields.Datetime.now()}) + statistics.write({'opened': fields.Datetime.now(), 'bounced': False}) return statistics def set_clicked(self, mail_mail_ids=None, mail_message_ids=None): @@ -120,6 +120,7 @@ class MailMailStats(models.Model): return statistics def set_bounced(self, mail_mail_ids=None, mail_message_ids=None): - statistics = self._get_records(mail_mail_ids, mail_message_ids, [('bounced', '=', False)]) + statistics = self._get_records( + mail_mail_ids, mail_message_ids, [('bounced', '=', False), ('opened', '=', False)]) statistics.write({'bounced': fields.Datetime.now()}) return statistics diff --git a/addons/mrp/static/src/xml/mrp.xml b/addons/mrp/static/src/xml/mrp.xml index 75c2ce15422..9c250bcfbdd 100644 --- a/addons/mrp/static/src/xml/mrp.xml +++ b/addons/mrp/static/src/xml/mrp.xml @@ -25,7 +25,7 @@ </option> </select> </div> - <div class="form-group col-md-4"> + <div t-attf-class="form-group #{is_variant_applied ? 'col-md-4' : 'col-md-8'}"> <label>Report:</label> <select class="o_input o_mrp_bom_report_type"> <option t-att-data-type="'all'">BoM Structure & Cost</option> diff --git a/addons/payment/static/src/js/payment_form.js b/addons/payment/static/src/js/payment_form.js index 10ddb19ee37..c97da26cd39 100644 --- a/addons/payment/static/src/js/payment_form.js +++ b/addons/payment/static/src/js/payment_form.js @@ -134,7 +134,7 @@ odoo.define('payment.payment_form', function (require) { self.displayError( _t('Server Error'), _t("We are not able to add your payment method at the moment.") + - data.data.message + message.data.message ); }); } @@ -180,7 +180,7 @@ odoo.define('payment.payment_form', function (require) { self.displayError( _t('Server Error'), _t("We are not able to redirect you to the payment form. ") + - data.data.message + message.data.message ); }); } diff --git a/addons/purchase/models/account_invoice.py b/addons/purchase/models/account_invoice.py index 401bcdfa8b3..a042ce1975b 100644 --- a/addons/purchase/models/account_invoice.py +++ b/addons/purchase/models/account_invoice.py @@ -40,11 +40,12 @@ class AccountInvoice(models.Model): purchase_line_ids = self.invoice_line_ids.mapped('purchase_line_id') purchase_ids = self.invoice_line_ids.mapped('purchase_id').filtered(lambda r: r.order_line <= purchase_line_ids) - result['domain'] = {'purchase_id': [ - ('invoice_status', 'in', ['to invoice', 'no']), - ('partner_id', 'child_of', self.partner_id.id), - ('id', 'not in', purchase_ids.ids), - ]} + domain = [('invoice_status', 'in', ['to invoice', 'no'])] + if self.partner_id: + domain += [('partner_id', 'child_of', self.partner_id.id)] + if purchase_ids: + domain += [('id', 'not in', purchase_ids.ids)] + result['domain'] = {'purchase_id': domain} return result def _prepare_invoice_line_from_po_line(self, line): diff --git a/addons/purchase_stock/models/purchase.py b/addons/purchase_stock/models/purchase.py index 19a6a321d6a..950644c7675 100644 --- a/addons/purchase_stock/models/purchase.py +++ b/addons/purchase_stock/models/purchase.py @@ -98,10 +98,11 @@ class PurchaseOrder(models.Model): if order.state in ('draft', 'sent', 'to approve'): for order_line in order.order_line: if order_line.move_dest_ids: - siblings_states = (order_line.move_dest_ids.mapped('move_orig_ids')).mapped('state') + move_dest_ids = order_line.move_dest_ids.filtered(lambda m: m.state not in ('done', 'cancel')) + siblings_states = (move_dest_ids.mapped('move_orig_ids')).mapped('state') if all(state in ('done', 'cancel') for state in siblings_states): - order_line.move_dest_ids.write({'procure_method': 'make_to_stock'}) - order_line.move_dest_ids._recompute_state() + move_dest_ids.write({'procure_method': 'make_to_stock'}) + move_dest_ids._recompute_state() for pick in order.picking_ids.filtered(lambda r: r.state != 'cancel'): pick.action_cancel() diff --git a/addons/report_intrastat/report/report_intrastat_invoice_template.xml b/addons/report_intrastat/report/report_intrastat_invoice_template.xml index 2c9752ae483..47edc821e69 100644 --- a/addons/report_intrastat/report/report_intrastat_invoice_template.xml +++ b/addons/report_intrastat/report/report_intrastat_invoice_template.xml @@ -39,18 +39,12 @@ <!-- Is there a discount on at least one line? --> <t t-set="display_discount" t-value="any([l.discount for l in o.invoice_line_ids])"/> - <!-- show only in sale invoice --> - <t t-set="type_is_out" t-value="o.type == 'out_invoice'"/> - <!-- if Rounding Method is computed per line --> - <t t-set="display_taxamount" - t-value="o.company_id.tax_calculation_rounding_method == 'round_per_line'"/> <table class="table table-condensed"> <thead> <tr> <th>Description</th> <th class="text-right">Taxes</th> - <th t-if="display_taxamount and type_is_out" class="text-right">Tax Amount</th> <th class="text-right">Intrastat</th> <th class="text-right">Weight</th> <th class="text-right">Quantity</th> @@ -64,13 +58,6 @@ <tr t-foreach="o.invoice_line_ids" t-as="l"> <td><span t-field="l.name"/></td> <td class="text-right"><span t-esc="', '.join(map(lambda x: x.name, l.invoice_line_tax_ids))"/></td> - <td t-if="display_taxamount and type_is_out" class="text-right"> - <t t-set="taxes" - t-value="l.invoice_line_tax_ids.compute_all(l.price_unit, l.currency_id, l.quantity)"/> - <t t-set="tax_amount" - t-value="taxes and (taxes['total_included'] - taxes['base']) or 0.0"/> - <span t-esc="tax_amount" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> - </td> <td class="text-right"><span t-esc="l.product_id.intrastat_id.name"/></td> <td class="text-right"><span t-esc="l.product_id.weight"/></td> <td class="text-right"><span t-field="l.quantity"/></td> @@ -99,7 +86,7 @@ </td> </tr> <tr> - <td>Taxes Amount</td> + <td>Taxes</td> <td class="text-right"> <span t-field="o.amount_tax" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> </td> diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index 56a6d5c22da..a818d997549 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -667,6 +667,12 @@ class SaleOrder(models.Model): 'target': 'self', 'res_id': self.id, } + else: + action = self.env.ref('sale.action_quotations', False) + if action: + result = action.read()[0] + result['res_id'] = self.id + return result return super(SaleOrder, self).get_access_action(access_uid) def get_mail_url(self): diff --git a/addons/sale/report/sale_report_templates.xml b/addons/sale/report/sale_report_templates.xml index 3b948aef951..1911a45c3d5 100644 --- a/addons/sale/report/sale_report_templates.xml +++ b/addons/sale/report/sale_report_templates.xml @@ -68,9 +68,6 @@ <!-- Is there a discount on at least one line? --> <t t-set="display_discount" t-value="any([l.discount for l in doc.order_line])"/> - <!-- if Rounding Method is computed per line --> - <t t-set="display_taxamount" - t-value="doc.company_id.tax_calculation_rounding_method == 'round_per_line'"/> <t t-foreach="doc.order_lines_layouted()" t-as="page"> <table class="table table-condensed"> @@ -81,7 +78,6 @@ <th class="text-right">Unit Price</th> <th t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">Disc.(%)</th> <th class="text-right">Taxes</th> - <th t-if="display_taxamount" class="text-right">Tax Amount</th> <th class="text-right" groups="sale.group_show_price_subtotal">Amount</th> <th class="text-right price_tax_included" groups="sale.group_show_price_total">Total Price</th> </tr> @@ -114,10 +110,6 @@ <td class="text-right"> <span t-esc="', '.join(map(lambda x: (x.description or x.name), l.tax_id))"/> </td> - <td t-if="display_taxamount" class="text-right"> - <span t-field="l.price_tax" - t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/> - </td> <td class="text-right" groups="sale.group_show_price_subtotal"> <span t-field="l.price_subtotal" t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/> diff --git a/addons/sale_timesheet/views/account_invoice_views.xml b/addons/sale_timesheet/views/account_invoice_views.xml index 20e25720343..cb8b2ef54db 100644 --- a/addons/sale_timesheet/views/account_invoice_views.xml +++ b/addons/sale_timesheet/views/account_invoice_views.xml @@ -15,12 +15,10 @@ <field name="model">account.invoice</field> <field name="inherit_id" ref="account.invoice_form"/> <field name="arch" type="xml"> - <xpath expr="//label" position="before"> - <div class="oe_button_box" name="button_box" groups="base.group_user"> - <button name="%(sale_timesheet.action_timesheet_from_invoice)d" type="action" class="oe_stat_button" icon="fa-calendar" attrs="{'invisible':[('timesheet_count','=', 0)]}"> - <field name="timesheet_count" widget="statinfo" string="Timesheets"/> - </button> - </div> + <xpath expr="//div[@name='button_box']" position="inside"> + <button name="%(sale_timesheet.action_timesheet_from_invoice)d" type="action" class="oe_stat_button" icon="fa-calendar" attrs="{'invisible':[('timesheet_count','=', 0)]}"> + <field name="timesheet_count" widget="statinfo" string="Timesheets"/> + </button> </xpath> </field> </record> diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index a4a73229c8a..8da096cb4bd 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -711,8 +711,6 @@ class Picking(models.Model): if product and product.tracking != 'none': if not line.lot_name and not line.lot_id: raise UserError(_('You need to supply a Lot/Serial number for product %s.') % product.display_name) - elif line.qty_done == 0: - raise UserError(_('You cannot validate a transfer if you have not processed any quantity for %s.') % product.display_name) if no_quantities_done: view = self.env.ref('stock.view_immediate_transfer') diff --git a/addons/stock/tests/test_move.py b/addons/stock/tests/test_move.py index afa5560a298..bdacc2e3a3e 100644 --- a/addons/stock/tests/test_move.py +++ b/addons/stock/tests/test_move.py @@ -3150,7 +3150,7 @@ class StockMove(TransactionCase): def test_immediate_validate_4(self): """ In a picking with a single available tracked by lot move, clicking on validate without - filling any quantities should open an UserError. + filling any quantities should pop up the immediate transfer wizard. """ partner = self.env['res.partner'].create({'name': 'Jean'}) lot1 = self.env['stock.production.lot'].create({ @@ -3176,12 +3176,11 @@ class StockMove(TransactionCase): }) picking.action_confirm() picking.action_assign() - # No quantites/lot filled, it should raise. - with self.assertRaises(UserError): - picking.button_validate() - picking.move_lines.move_line_ids[0].qty_done = 5.0 - # All the information are present (lots and quantities), the wizard won't be opened. - picking.button_validate() + # No quantites filled, immediate transfer wizard should pop up. + immediate_trans_wiz_dict = picking.button_validate() + self.assertEqual(immediate_trans_wiz_dict.get('res_model'), 'stock.immediate.transfer') + immediate_trans_wiz = self.env[immediate_trans_wiz_dict['res_model']].browse(immediate_trans_wiz_dict['res_id']) + immediate_trans_wiz.process() self.assertEqual(picking.move_lines.quantity_done, 5.0) # Check move_lines data diff --git a/addons/stock_landed_costs/__manifest__.py b/addons/stock_landed_costs/__manifest__.py index aeee0e7ae24..1c6d226dc0b 100644 --- a/addons/stock_landed_costs/__manifest__.py +++ b/addons/stock_landed_costs/__manifest__.py @@ -18,6 +18,7 @@ This module allows you to easily add extra costs on pickings and decide the spli ], 'data': [ 'security/ir.model.access.csv', + 'security/stock_landed_cost_security.xml', 'data/stock_landed_cost_data.xml', 'views/product_views.xml', 'views/stock_landed_cost_views.xml', diff --git a/addons/stock_landed_costs/models/stock_landed_cost.py b/addons/stock_landed_costs/models/stock_landed_cost.py index 533d3b15e04..2137b111a9e 100644 --- a/addons/stock_landed_costs/models/stock_landed_cost.py +++ b/addons/stock_landed_costs/models/stock_landed_cost.py @@ -51,6 +51,8 @@ class LandedCost(models.Model): account_journal_id = fields.Many2one( 'account.journal', 'Account Journal', required=True, states={'done': [('readonly', True)]}) + company_id = fields.Many2one('res.company', string="Company", + related='account_journal_id.company_id') @api.one @api.depends('cost_lines.price_unit') diff --git a/addons/stock_landed_costs/security/stock_landed_cost_security.xml b/addons/stock_landed_costs/security/stock_landed_cost_security.xml new file mode 100644 index 00000000000..1182f9c687a --- /dev/null +++ b/addons/stock_landed_costs/security/stock_landed_cost_security.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> +<data noupdate="0"> + + <record model="ir.rule" id="stock_landed_cost_rule"> + <field name="name">stock_landed_cost multi-company</field> + <field name="model_id" search="[('model','=','stock.landed.cost')]" model="ir.model"/> + <field name="global" eval="True"/> + <field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field> + </record> + +</data> +</odoo>
\ No newline at end of file diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js index b4d00b6bb76..5767969d15c 100644 --- a/addons/web/static/src/js/views/basic/basic_controller.js +++ b/addons/web/static/src/js/views/basic/basic_controller.js @@ -612,12 +612,12 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { }).then(function (result) { self.do_action(result, { on_reverse_breadcrumb: function () { - if (self.renderer.alertFields.length) { + if (!_.isEmpty(self.renderer.alertFields)) { self.renderer.displayTranslationAlert(); } - return false + return false; }, - }) + }); }); }, }); diff --git a/addons/web_editor/static/src/js/widgets/widgets.js b/addons/web_editor/static/src/js/widgets/widgets.js index c4575a73105..16dfa27b34c 100644 --- a/addons/web_editor/static/src/js/widgets/widgets.js +++ b/addons/web_editor/static/src/js/widgets/widgets.js @@ -958,6 +958,9 @@ var VideoWidget = MediaWidget.extend({ return {errorCode: 1}; } + if (ytMatch) { + $video.attr('src', $video.attr('src') + '&rel=0'); + } if (options.loop && (ytMatch || vimMatch)) { $video.attr('src', $video.attr('src') + '&loop=1'); } diff --git a/doc/cla/corporate/brain-tec.md b/doc/cla/corporate/brain-tec.md index f598f64eb1b..46e4e2d3646 100644 --- a/doc/cla/corporate/brain-tec.md +++ b/doc/cla/corporate/brain-tec.md @@ -38,3 +38,4 @@ Raúl Martín raul.martin@braintec-group.com https://github.com/BT-rmartin Silvan Wyden silvan.wyden@braintec-group.com https://github.com/BT-swyden Timka Piric Muratovic timka.piric@braintec-group.com https://github.com/BT-tpiric Pascal Zenklusen pascal.zenklusen@braintec-group.com https://github.com/BT-pzenklusen +Nadal Francisco Garcia nadal.francisco@braintec-group.com https://github.com/BT-nfrancisco
\ No newline at end of file diff --git a/doc/cla/individual/as400it.md b/doc/cla/individual/as400it.md new file mode 100644 index 00000000000..d42536df0d6 --- /dev/null +++ b/doc/cla/individual/as400it.md @@ -0,0 +1,11 @@ +Italy, 2018-08-08 + +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, + +Marco Calcagni mcalcagni@dinamicheaziendali.it https://github.com/As400it diff --git a/odoo/addons/base/data/res.lang.csv b/odoo/addons/base/data/res.lang.csv index bea539d9325..cf11d7bb4c9 100644 --- a/odoo/addons/base/data/res.lang.csv +++ b/odoo/addons/base/data/res.lang.csv @@ -6,9 +6,9 @@ "base.lang_bs_BA","Bosnian / bosanski jezik","bs_BA","bs","Left-to-Right","[]",",",,"%d.%m.%Y","%H:%M:%S","True","7" "base.lang_bg","Bulgarian / български език","bg_BG","bg","Left-to-Right","[3,0]",",",,"%d.%m.%Y","%H,%M,%S","True","1" "base.lang_ca_ES","Catalan / Català","ca_ES","ca_ES","Left-to-Right","[3,0]",",",".","%d/%m/%Y","%H:%M:%S","True","1" -"base.lang_zh_CN","Chinese (CN) / 简体中文","zh_CN","zh_CN","Left-to-Right","[3,0]",".",",","%Y年%m月%d日","%H时%M分%S秒","True","7" +"base.lang_zh_CN","Chinese (Simplified) / 简体中文","zh_CN","zh_CN","Left-to-Right","[3,0]",".",",","%Y年%m月%d日","%H时%M分%S秒","True","7" "base.lang_zh_HK","Chinese (HK)","zh_HK","zh_HK","Left-to-Right","[3,0]",".",",","%Y年%m月%d日 %A","%I時%M分%S秒","True","7" -"base.lang_zh_TW","Chinese (TW) / 正體字","zh_TW","zh_TW","Left-to-Right","[3,0]",".",",","%Y年%m月%d日","%H時%M分%S秒","True","7" +"base.lang_zh_TW","Chinese (Traditional) / 正體字","zh_TW","zh_TW","Left-to-Right","[3,0]",".",",","%Y年%m月%d日","%H時%M分%S秒","True","7" "base.lang_hr","Croatian / hrvatski jezik","hr_HR","hr","Left-to-Right","[]",",",,"%d.%m.%Y","%H:%M:%S","True","1" "base.lang_cs_CZ","Czech / Čeština","cs_CZ","cs_CZ","Left-to-Right","[3,0]",","," ","%d.%m.%Y","%H:%M:%S","True","1" "base.lang_da_DK","Danish / Dansk","da_DK","da_DK","Left-to-Right","[3,0]",",",".","%d-%m-%Y","%H:%M:%S","True","1" diff --git a/odoo/addons/base/models/res_config.py b/odoo/addons/base/models/res_config.py index b693ca6be06..ab593780f61 100644 --- a/odoo/addons/base/models/res_config.py +++ b/odoo/addons/base/models/res_config.py @@ -575,8 +575,11 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin) IrDefault.set(model, field, value) # group fields: modify group / implied groups + current_settings = self.new(self.default_get(list(self.fields_get()))) with self.env.norecompute(): for name, groups, implied_group in classified['group']: + if self[name] == current_settings[name]: + continue if self[name]: groups.write({'implied_ids': [(4, implied_group.id)]}) else: diff --git a/odoo/exceptions.py b/odoo/exceptions.py index c318f9ecdac..6807485e80a 100644 --- a/odoo/exceptions.py +++ b/odoo/exceptions.py @@ -46,6 +46,10 @@ class RedirectWarning(Exception): :param string button_text: text to put on the button that will trigger the redirection. """ + # using this RedirectWarning won't crash if used as an except_orm + @property + def name(self): + return self.args[0] class AccessDenied(Exception): diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py index 639d9c7626e..8a33558c790 100644 --- a/odoo/tools/misc.py +++ b/odoo/tools/misc.py @@ -1148,10 +1148,7 @@ def formatLang(env, value, digits=None, grouping=True, monetary=False, dp=False, return '' lang = env.context.get('lang') or env.user.company_id.partner_id.lang or 'en_US' - lang_objs = env['res.lang'].search([('code', '=', lang)]) - if not lang_objs: - lang_objs = env['res.lang'].search([], limit=1) - lang_obj = lang_objs[0] + lang_obj = env['res.lang']._lang_get(lang) res = lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary) diff --git a/requirements.txt b/requirements.txt index 74db0c9fc38..ddb37dd34fa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ gevent==1.3.4 ; sys_platform != 'win32' and python_version >= '3.7' greenlet==0.4.10 ; python_version < '3.7' greenlet==0.4.13 ; python_version >= '3.7' html2text==2016.9.19 -Jinja2==2.8 +Jinja2==2.8.1 libsass==0.12.3 lxml==3.7.1 ; sys_platform != 'win32' and python_version < '3.7' lxml==4.2.3 ; sys_platform != 'win32' and python_version >= '3.7' |
