[MERGE][IMP] sale,base,account : improve sales onboarding

Purpose : Ease navigation in default screens of Sales app to better onboard new
users and fix various issues in the views.

- onboarding tour : fix "quotations" filter and tooltip appearance
- config bar :
  -remove "Default incoterm" field in "company info" form and move it in
  "invoicing" settings.
  - improve "document layout" form design, set "paper format" as required
  field and add a "preview" button
  - rename FieldReportLayout "Preview" link and put standard report layout (the default one in odoo) as first image
  - fix small design issue in widget
  - "done" button design

- customer form :
  - improve address type tooltip
  - various changes in "accounting" and "sales & purchases" tabs (stat button, fields reorganizing)

- product form : fix "re-invoice policy" field hazardous hiding behavior and improve field appearance
- customer portal :
  - reorganize fields in "customer details" view
  - minor changes in "quotation" view

- Correct "sales order" model description

This merge is related to task ID 1892500 .

closes odoo/odoo#28254
This commit is contained in:
Robot Odoo
2018-11-19 11:55:01 +01:00
committed by GitHub
31 changed files with 77 additions and 80 deletions
-1
View File
@@ -59,7 +59,6 @@ You could use this simplified accounting in case you work with an (external) acc
'views/account_fiscal_year_view.xml',
'views/account_incoterms_view.xml',
'data/account_incoterms_data.xml',
'views/res_company_view.xml',
'views/digest_views.xml',
'wizard/account_invoice_send_views.xml',
],
@@ -89,6 +89,7 @@ class ResConfigSettings(models.TransientModel):
qr_code = fields.Boolean(string='Display SEPA QR code', related='company_id.qr_code', readonly=False)
invoice_is_print = fields.Boolean(string='Print', related='company_id.invoice_is_print', readonly=False)
invoice_is_email = fields.Boolean(string='Send Email', related='company_id.invoice_is_email', readonly=False)
incoterm_id = fields.Many2one('account.incoterms', string='Default incoterm', related='company_id.incoterm_id', help='International Commercial Terms are a series of predefined commercial terms used in international transactions.', readonly=False)
@api.multi
def set_values(self):
+4 -10
View File
@@ -156,7 +156,7 @@
<button name="toggle_active" position="before">
<button class="oe_stat_button" type="action" name="%(account.action_open_partner_analytic_accounts)d"
groups="account.group_account_invoice"
icon="fa-book" title="Analytic Accounts">
icon="fa-book" title="Analytic Accounts" attrs="{'invisible': [('contracts_count', '=', 0)]}">
<field string="Analytic Accounts" name="contracts_count" widget="statinfo"/>
</button>
</button>
@@ -204,12 +204,6 @@
<field name="acc_holder_name" invisible="1"/>
</tree>
</field>
<button type="action" class="btn-link"
name="%(base.action_res_partner_bank_account_form)d"
context="{'search_default_partner_id': active_id, 'default_partner_id': active_id, 'form_view_ref': 'account.view_company_partner_bank_form'}"
string="View accounts detail"
colspan="2"
/>
</group>
<group string="Accounting Entries" name="accounting_entries" groups="account.group_account_user">
<field name="currency_id" invisible="1"/>
@@ -224,16 +218,16 @@
</div>
</page>
</page>
<xpath expr="//page[@name='sales_purchases']/group" position="inside">
<xpath expr="//group[@name='misc']" position="before">
<group string="Fiscal Information" name="fiscal_information" priority="5" groups="account.group_account_invoice">
<field name="property_account_position_id" options="{'no_create': True, 'no_open': True}"/>
</group>
</xpath>
<group name="sale" position="inside">
<field string="Payment Terms" name="property_payment_term_id" widget="selection" groups="account.group_account_invoice"/>
<field string="Payment Terms" name="property_payment_term_id" widget="selection" groups="account.group_account_invoice" attrs="{'invisible': [('customer','=', False)]}"/>
</group>
<group name="purchase" position="inside">
<field string="Payment Terms" name="property_supplier_payment_term_id" widget="selection" groups="account.group_account_invoice"/>
<field string="Payment Terms" name="property_supplier_payment_term_id" widget="selection" groups="account.group_account_invoice" attrs="{'invisible': [('supplier','=', False)]}"/>
</group>
</field>
</record>
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="res_company_form_view_inherit_account_intrastat" model="ir.ui.view">
<field name="name">res.company.form.inherit.account.intrastat</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='company_registry']" position="after">
<field name="incoterm_id"/>
</xpath>
</field>
</record>
</data>
</odoo>
@@ -524,6 +524,18 @@
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">Default Incoterm</span>
<div class="text-muted">
Default Incoterm of your company
</div>
<div class="text-muted">
<field name="incoterm_id"/>
</div>
</div>
</div>
</div>
<h2 groups="account.group_account_user">Automated Entries</h2>
<div class="row mt16 o_settings_container" id="recommended_apps" groups="account.group_account_user">
+1 -1
View File
@@ -7,4 +7,4 @@ from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
property_delivery_carrier_id = fields.Many2one('delivery.carrier', company_dependent=True, string="Delivery Method", help="This delivery method will be used when invoicing from picking.")
property_delivery_carrier_id = fields.Many2one('delivery.carrier', company_dependent=True, string="Delivery Method", help="Default delivery method used in sales orders.")
+4 -4
View File
@@ -4,11 +4,11 @@
<record id="view_partner_property_form" model="ir.ui.view">
<field name="name">res.partner.carrier.property.form.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="mail.res_partner_view_form_inherit_mail" />
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<field name="message_bounce" position="before">
<field name="property_delivery_carrier_id"/>
</field>
<xpath expr="//page[@name='sales_purchases']//field[@name='user_id']" position="after">
<field name="property_delivery_carrier_id" attrs="{'invisible': [('customer','=', False)]}"/>
</xpath>
</field>
</record>
+9 -2
View File
@@ -16,8 +16,15 @@
<field name="email" widget="email"/>
</div>
</xpath>
<xpath expr="//page[@name='sales_purchases']//field[@name='user_id']" position="after">
<field name="message_bounce" groups="base.group_no_one"/>
<xpath expr="//button[@name='toggle_active']" position="before">
<button class="oe_stat_button" icon="fa-envelope" groups="base.group_no_one" attrs="{'invisible':[('message_bounce', '=', 0)]}">
<div class="o_form_field o_stat_info">
<span class="o_stat_value">
<field name="message_bounce" widget="statinfo" nolabel="1"/>
</span>
<span class="o_stat_text">Bounce(s)</span>
</div>
</button>
</xpath>
<xpath expr="//sheet" position="after">
<div class="oe_chatter">
@@ -33,7 +33,7 @@
<field name="payment_method" widget="radio" nolabel="1"/>
</group>
</div>
<div class="col offset-md-1" name="right-column">
<div class="col" name="right-column">
<div attrs="{'invisible': [('payment_method', '!=', 'paypal')]}">
<group>
<field name="paypal_email_account" attrs="{'required': [('payment_method', '=', 'paypal')]}" />
@@ -30,7 +30,7 @@ class PaymentWizard(models.TransientModel):
@api.onchange('journal_name', 'acc_number')
def _set_manual_post_msg_value(self):
self.manual_post_msg = _('Please make a payment to <ul><li>Bank: %s</li><li>Account Number: %s</li><li>Account Holder: %s</li></ul>') %\
self.manual_post_msg = _('<h3>Please make a payment to: </h3><ul><li>Bank: %s</li><li>Account Number: %s</li><li>Account Holder: %s</li></ul>') %\
(self.journal_name or _("Bank") , self.acc_number or _("Account"), self.env.user.company_id.name)
_payment_acquirer_onboarding_cache = {}
+1 -1
View File
@@ -54,7 +54,7 @@
<field name="arch" type="xml">
<xpath expr="//group[@name='pricelists']" position="before">
<group name="pos" string="Point Of Sale">
<group>
<group colspan="2">
<field name="available_in_pos"/>
<field name="pos_categ_id" attrs="{'invisible': [('available_in_pos', '=', False)]}" string="Category"/>
<field name="to_weight" attrs="{'invisible': [('available_in_pos', '=', False)]}"/>
@@ -363,7 +363,6 @@ img.o_we_custom_image {
address {
span[itemprop="name"] {
font-weight: bold;
margin-bottom: 0.3em;
}
+4 -4
View File
@@ -370,10 +370,6 @@
<label class="col-form-label" for="email">Email</label>
<input type="email" name="email" t-attf-class="form-control #{error.get('email') and 'is-invalid' or ''}" t-att-value="email or partner.email" />
</div>
<div t-attf-class="form-group #{error.get('phone') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label" for="phone">Phone</label>
<input type="tel" name="phone" t-attf-class="form-control #{error.get('phone') and 'is-invalid' or ''}" t-att-value="phone or partner.phone" />
</div>
<div class="clearfix" />
<div t-attf-class="form-group #{error.get('company_name') and 'o_has_error' or ''} col-xl-6">
@@ -385,6 +381,10 @@
<label class="col-form-label label-optional" for="vat">VAT Number</label>
<input type="text" name="vat" t-attf-class="form-control #{error.get('vat') and 'is-invalid' or ''}" t-att-value="vat or partner.vat" t-att-readonly="None if partner.can_edit_vat() else '1'" t-att-title="None if partner.can_edit_vat() else 'Changing VAT number is not allowed once document(s) have been issued for your account. Please contact us directly for this operation.'" />
</div>
<div t-attf-class="form-group #{error.get('phone') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label" for="phone">Phone</label>
<input type="tel" name="phone" t-attf-class="form-control #{error.get('phone') and 'is-invalid' or ''}" t-att-value="phone or partner.phone" />
</div>
<div class="clearfix" />
<div t-attf-class="form-group #{error.get('street') and 'o_has_error' or ''} col-xl-6">
+1 -1
View File
@@ -198,7 +198,7 @@ class CustomerPortal(CustomerPortal):
return {'error': _('Invalid order')}
if not order_sudo.has_to_be_signed():
return {'error': _('Order is not in a state requiring customer signature.')}
return {'error': _('The order is not in a state requiring customer signature.')}
if not signature:
return {'error': _('Signature is missing.')}
+1
View File
@@ -84,6 +84,7 @@
% if object.partner_id.parent_id:
(${object.partner_id.parent_id.name})
% endif
,
<br /><br />
Here is
% if ctx.get('proforma')
+2 -1
View File
@@ -19,7 +19,7 @@ class ProductTemplate(models.Model):
sale_line_warn_msg = fields.Text('Message for Sales Order Line')
expense_policy = fields.Selection(
[('no', 'No'), ('cost', 'At cost'), ('sales_price', 'Sales price')],
string='Re-Invoice Policy',
string='Re-Invoice Expenses',
default='no',
help="Expenses and vendor bills can be re-invoiced to a customer."
"With this option, a validated expense can be re-invoice to a customer at its cost or sales price.")
@@ -33,6 +33,7 @@ class ProductTemplate(models.Model):
default='order')
@api.multi
@api.depends('name')
def _compute_hide_expense_policy(self):
hide_expense_policy = self.user_has_groups('!analytic.group_analytic_accounting,!project.group_project_user,!hr_expense.group_hr_expense_user')
for template in self:
+1 -1
View File
@@ -20,7 +20,7 @@ from werkzeug.urls import url_encode
class SaleOrder(models.Model):
_name = "sale.order"
_inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin']
_description = "Sale Order"
_description = "Sales Order"
_order = 'date_order desc, id desc'
def _default_validity_date(self):
+1 -1
View File
@@ -67,7 +67,7 @@ tour.register('sale_tour', {
}, {
trigger: ".o_sale_print",
extra_trigger: ".o_sale_order.o_form_readonly",
content: _t("<b>Print this quotation to preview it.</b>"),
content: _t("Print this quotation to preview it."),
position: "bottom"
}, {
trigger: ".breadcrumb-item:not(.active):last",
+5 -2
View File
@@ -61,7 +61,7 @@
</field>
</record>
<record id="action_open_sale_onboarding_payment_acquirer_wizard" model="ir.actions.act_window">
<field name="name">How your customers can confirm an order</field>
<field name="name">Choose how to confirm quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.payment.acquirer.onboarding.wizard</field>
<field name="view_type">form</field>
@@ -77,6 +77,9 @@
<field name="mode">primary</field>
<field name="priority">1000</field>
<field name="arch" type="xml">
<xpath expr="//button[@special='save']" position="after">
<button string="Preview" type="action" class="btn btn-secondary" name="web.action_report_externalpreview"/>
</xpath>
<xpath expr="//button[@special='save']" position="replace">
<button string="Apply" class="btn btn-primary" type="object" name="action_save_onboarding_quotation_layout" />
</xpath>
@@ -112,7 +115,7 @@
</record>
<record id="action_open_sale_onboarding_sample_quotation" model="ir.actions.act_window">
<field name="name">Send a sample quotation.</field>
<field name="name">Send a sample quotation</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mail.compose.message</field>
<field name="view_mode">form</field>
+3 -8
View File
@@ -305,11 +305,6 @@
<strong>This quotation has been canceled.</strong> <a role="button" href="#discussion"><i class="fa fa-comment"/> Contact us to get a new quotation.</a>
</div>
<div t-if="sale_order.state == 'draft'" class="alert alert-warning alert-dismissable d-print-none" role="status">
<button type="button" class="close" data-dismiss="alert" aria-label="close">&amp;times;</button>
<strong>This is a draft quotation.</strong> <a role="button" href="#discussion"><i class="fa fa-comment"/> Contact us to get the final version.</a>
</div>
<div t-if="sale_order.is_expired" class="alert alert-warning alert-dismissable d-print-none" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="close">&amp;times;</button>
<strong>This offer expired!</strong> <a role="button" href="#discussion"><i class="fa fa-comment"/> Contact us to get a new quotation.</a>
@@ -343,7 +338,7 @@
<!-- chatter -->
<div id="sale_order_communication" class="mt-4">
<h2>Communication</h2>
<h2>History</h2>
<t t-call="portal.message_thread">
<t t-set="object" t-value="sale_order"/>
</t>
@@ -361,8 +356,8 @@
<template id="sale_order_portal_content" name="Sales Order Portal Content">
<!-- Intro -->
<div id="introduction" t-attf-class="pb-2 pt-3 #{'card-header bg-white' if report_type == 'html' else ''}">
<h2 class="my-0">
<span t-field="sale_order.type_name"></span>
<h2 class="my-0">
<t t-esc="sale_order.type_name"/>
<em t-esc="sale_order.name"/>
</h2>
</div>
@@ -15,7 +15,7 @@ class PaymentWizard(models.TransientModel):
return self.env.user.company_id.sale_onboarding_payment_method or 'digital_signature'
payment_method = fields.Selection([
('digital_signature', 'Sign online'),
('digital_signature', 'Online signature'),
('paypal', "Pay with PayPal"),
('stripe', "Pay with credit card (via Stripe)"),
('other', "Pay with another payment acquirer"),
+1 -1
View File
@@ -12,7 +12,7 @@
<field name="arch" type="xml">
<xpath expr="//page[@name='sales_purchases']/group" position="inside">
<group name="container_row_stock" groups="base.group_no_one" priority="6">
<group string="Warehouse" name="warehouse">
<group string="Inventory" name="inventory" colspan="2">
<field name="property_stock_customer" domain="[('usage','=','customer')]"/>
<field name="property_stock_supplier" domain="[('usage','=','supplier')]"/>
</group>
+5 -5
View File
@@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="report_layout_standard" model="report.layout">
<field name="view_id" ref="web.external_layout_standard"/>
<field name="image">/web/static/img/preview_standard.png</field>
<field name="pdf">/web/static/pdf/preview_standard.pdf</field>
</record>
<record id="report_layout_background" model="report.layout">
<field name="view_id" ref="web.external_layout_background"/>
<field name="image">/web/static/img/preview_background.png</field>
@@ -16,10 +21,5 @@
<field name="image">/web/static/img/preview_clean.png</field>
<field name="pdf">/web/static/pdf/preview_clean.pdf</field>
</record>
<record id="report_layout_standard" model="report.layout">
<field name="view_id" ref="web.external_layout_standard"/>
<field name="image">/web/static/img/preview_standard.png</field>
<field name="pdf">/web/static/pdf/preview_standard.pdf</field>
</record>
</data>
</odoo>
@@ -163,7 +163,7 @@ var FieldReportLayout = relational_fields.FieldMany2One.extend({
$container.append($img);
if (val.pdf) {
var $previewLink = $('<a>')
.text('Preview')
.text('Example')
.attr('href', val.pdf)
.attr('target', '_blank');
$container.append($previewLink);
+1 -1
View File
@@ -1049,7 +1049,7 @@
<div t-foreach="widget.value.data" t-as="file" class="oe_attachment">
<t t-if="!file.data.upload">
<div>
<a href="#" class="fa fa-times float-right oe_delete" title="Delete this file" aria-label="Delete this file" t-att-data-id="file.data.id"/>
<a href="#" class="fa fa-times float-right oe_delete pl-1" title="Delete this file" aria-label="Delete this file" t-att-data-id="file.data.id"/>
<t t-raw="file.data.name || file.data.filename"/>
</div>
<a class="o_image" target="_blank" t-att-href="widget.metadata[file.id] ? widget.metadata[file.id].url : false"
@@ -138,7 +138,7 @@
</group>
</xpath>
<xpath expr="//group[@name='sale']" position="inside">
<field name="assigned_partner_id" groups="base.group_no_one"/>
<field name="assigned_partner_id" groups="base.group_no_one" attrs="{'invisible': [('customer','=', False)]}"/>
</xpath>
</data>
</field>
+5 -5
View File
@@ -151,7 +151,7 @@ class Partner(models.Model):
parent_id = fields.Many2one('res.partner', string='Related Company', index=True)
parent_name = fields.Char(related='parent_id.name', readonly=True, string='Parent name')
child_ids = fields.One2many('res.partner', 'parent_id', string='Contacts', domain=[('active', '=', True)]) # force "active_test" domain to bypass _search() override
ref = fields.Char(string='Internal Reference', index=True)
ref = fields.Char(string='Reference', index=True)
lang = fields.Selection(_lang_get, string='Language', default=lambda self: self.env.lang,
help="All the emails and documents sent to this contact will be translated in this language.")
tz = fields.Selection(_tz_get, string='Timezone', default=lambda self: self._context.get('tz'),
@@ -180,13 +180,13 @@ class Partner(models.Model):
function = fields.Char(string='Job Position')
type = fields.Selection(
[('contact', 'Contact'),
('invoice', 'Invoice address'),
('delivery', 'Shipping address'),
('other', 'Other address'),
('invoice', 'Invoice Address'),
('delivery', 'Shipping Address'),
('other', 'Other Address'),
("private", "Private Address"),
], string='Address Type',
default='contact',
help="Used by Sales and Purchase Apps to select the relevant address depending on the context.")
help="Invoice & Shipping addresses are used in sales orders. Private addresses are only visible by authorized users.")
street = fields.Char()
street2 = fields.Char()
zip = fields.Char(change_default=True)
@@ -41,12 +41,10 @@
<t t-if="text_completed" t-esc="text_completed" />
<t t-else="">Nice work! Your configuration is done.</t>
</span>
<div class="btn btn-primary btn-sm">
<a type="action" class="btn btn-primary" data-toggle="collapse" href=".o_onboarding_container"
t-att-data-model="close_model" t-att-data-method="close_method">
Close
</a>
</div>
</div>
</div>
</div>
+3 -3
View File
@@ -183,12 +183,12 @@
}"/>
</group>
<group>
<field name="logo" widget="image" />
<field name="logo" widget="image" style="width: 50%"/>
<field name="report_header" widget="char"
placeholder="e.g. Global Business Solutions" />
<field name="report_footer" string="Footer"
placeholder="e.g. Opening hours, bank accounts (one per line)" />
<field name="paperformat_id" widget="selection" />
placeholder="e.g. Bank accounts (one per line)" />
<field name="paperformat_id" widget="selection" required="1"/>
</group>
<footer>
<button special="save" string="Save"
+6 -4
View File
@@ -374,18 +374,20 @@
<page name='internal_notes' string="Internal Notes">
<field name="comment" placeholder="Internal note..."/>
</page>
<page name='sales_purchases' string="Sales &amp; Purchases">
<page name='sales_purchases' string="Sales &amp; Purchase">
<group name="container_row_2">
<group string="Sales" name="sale" priority="1">
<field name="customer"/>
<field name="user_id"/>
<field name="user_id" attrs="{'invisible': [('customer','=', False)]}"/>
</group>
<group string="Purchase" name="purchase" priority="2">
<field name="supplier"/>
</group>
<group string="Misc">
<field name="ref"/>
<group string="Point Of Sale">
<field name="barcode"/>
</group>
<group name="misc" string="Misc">
<field name="ref" string="Reference"/>
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
<field name="industry_id" attrs="{'invisible': [('is_company', '=', False)]}" options="{'no_create': True}"/>
</group>
+1 -1
View File
@@ -1 +1 @@
[["Wood y Wood Pecker", "", "Snow Street, 25", "Kainuu", "Finland", "Vendor", "1", "0", "1", ""], ["Roger Pecker", "Contact", "Snow Street, 27", "Kainuu", "Finland", "Vendor", "1", "0", "0", "Wood y Wood Pecker"], ["Sharon Pecker", "Shipping address", "Snow Street, 28", "Kainuu", "Finland", "Vendor", "1", "0", "0", "Wood y Wood Pecker"], ["Thomas Pecker", "Contact", "Snow Street, 27", "Kainuu", "Finland", "Vendor", "1", "0", "0", "Wood y Wood Pecker"], ["Norseman Roundabout", "", "Atonium Street, 45a", "Brussels", "Belgium", "Vendor", "1", "0", "1", ""], ["Yvan Holiday", "Invoice address", "Atonium Street, 45b", "Brussels", "Belgium", "Vendor", "1", "0", "0", "Norseman Roundabout"], ["Jack Unsworth", "Contact", "Atonium Street, 45a", "Brussels", "Belgium", "Vendor", "1", "0", "0", "Norseman Roundabout"]]
[["Wood y Wood Pecker", "", "Snow Street, 25", "Kainuu", "Finland", "Vendor", "1", "0", "1", ""], ["Roger Pecker", "Contact", "Snow Street, 27", "Kainuu", "Finland", "Vendor", "1", "0", "0", "Wood y Wood Pecker"], ["Sharon Pecker", "Shipping Address", "Snow Street, 28", "Kainuu", "Finland", "Vendor", "1", "0", "0", "Wood y Wood Pecker"], ["Thomas Pecker", "Contact", "Snow Street, 27", "Kainuu", "Finland", "Vendor", "1", "0", "0", "Wood y Wood Pecker"], ["Norseman Roundabout", "", "Atonium Street, 45a", "Brussels", "Belgium", "Vendor", "1", "0", "1", ""], ["Yvan Holiday", "Invoice Address", "Atonium Street, 45b", "Brussels", "Belgium", "Vendor", "1", "0", "0", "Norseman Roundabout"], ["Jack Unsworth", "Contact", "Atonium Street, 45a", "Brussels", "Belgium", "Vendor", "1", "0", "0", "Norseman Roundabout"]]