summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-08-14 19:43:32 +0200
committerChristophe Simonis <chs@odoo.com>2018-08-14 19:43:32 +0200
commitdabe59df9c84d5dbb7109decb193606b8cc2efe0 (patch)
tree412a986b495a3c104b51c60be453dd7b663389fe /addons
parente08f947abe5dc53768eb20463133c5fef177d816 (diff)
parent27d8daf8a75845fa1e23676b91776a0e0a8b5165 (diff)
[MERGE] forward port branch saas-11.3 up to 27d8daf8a75
Diffstat (limited to 'addons')
-rw-r--r--addons/account/models/company.py8
-rw-r--r--addons/account/views/report_invoice.xml14
-rw-r--r--addons/account/wizard/setup_wizards.py11
-rw-r--r--addons/anonymization/wizard/anonymize_wizard.py3
-rw-r--r--addons/crm/models/crm_lead.py2
-rw-r--r--addons/delivery/models/sale_order.py3
-rw-r--r--addons/hr_payroll_account/models/hr_payroll_account.py3
-rw-r--r--addons/hw_escpos/escpos/escpos.py2
-rw-r--r--addons/l10n_in/views/report_invoice.xml9
-rw-r--r--addons/l10n_in_stock/views/report_stockpicking_operations.xml4
-rw-r--r--addons/mail/controllers/main.py14
-rw-r--r--addons/mail/models/mail_activity.py2
-rw-r--r--addons/mass_mailing/models/mail_thread.py2
-rw-r--r--addons/mass_mailing/models/mass_mailing_stats.py5
-rw-r--r--addons/mrp/static/src/xml/mrp.xml2
-rw-r--r--addons/payment/static/src/js/payment_form.js4
-rw-r--r--addons/purchase/models/account_invoice.py11
-rw-r--r--addons/purchase_stock/models/purchase.py7
-rw-r--r--addons/report_intrastat/report/report_intrastat_invoice_template.xml15
-rw-r--r--addons/sale/models/sale.py6
-rw-r--r--addons/sale/report/sale_report_templates.xml8
-rw-r--r--addons/sale_timesheet/views/account_invoice_views.xml10
-rw-r--r--addons/stock/models/stock_picking.py2
-rw-r--r--addons/stock/tests/test_move.py13
-rw-r--r--addons/stock_landed_costs/__manifest__.py1
-rw-r--r--addons/stock_landed_costs/models/stock_landed_cost.py2
-rw-r--r--addons/stock_landed_costs/security/stock_landed_cost_security.xml13
-rw-r--r--addons/web/static/src/js/views/basic/basic_controller.js6
-rw-r--r--addons/web_editor/static/src/js/widgets/widgets.js3
29 files changed, 95 insertions, 90 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 &amp; 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');
}