[MERGE] sale: files & xml cleanup

COM PR: odoo/odoo#82070
ENT PR: odoo/enterprise#23183
UPGRADE PR: odoo/upgrade#3135

task - 2692296

--
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr

Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
Odoo's Mergebot
2022-01-11 15:26:55 +01:00
committed by GitHub
39 changed files with 1904 additions and 1892 deletions
+27 -16
View File
@@ -12,33 +12,44 @@ This module contains all the common features of Sales Management and eCommerce.
""",
'depends': ['sales_team', 'payment', 'portal', 'utm'],
'data': [
'security/sale_security.xml',
'security/ir.model.access.csv',
'report/sale_report.xml',
'security/sale_security.xml',
'report/account_invoice_report_views.xml',
'report/ir_actions_report_templates.xml',
'report/ir_actions_report.xml',
'report/sale_report_views.xml',
'report/sale_report_templates.xml',
'report/report_all_channels_sales_views.xml',
'data/ir_sequence_data.xml',
'data/mail_data_various.xml',
'data/mail_template_data.xml',
'data/mail_templates.xml',
'data/sale_data.xml',
'wizard/account_accrued_orders_wizard_views.xml',
'wizard/payment_link_wizard_views.xml',
'wizard/sale_make_invoice_advance_views.xml',
'views/sale_views.xml',
'wizard/sale_order_cancel_views.xml',
# Define sale order views before their references
'views/sale_order_views.xml',
'views/account_views.xml',
'views/crm_team_views.xml',
'views/res_partner_views.xml',
'views/mail_activity_views.xml',
'views/variant_templates.xml',
'views/sale_portal_templates.xml',
'views/sale_onboarding_views.xml',
'views/res_config_settings_views.xml',
'views/payment_templates.xml',
'views/payment_views.xml',
'views/product_views.xml',
'views/product_packaging_views.xml',
'views/product_views.xml',
'views/res_config_settings_views.xml',
'views/res_partner_views.xml',
'views/variant_templates.xml',
'views/sale_onboarding_views.xml',
'views/sale_order_line_views.xml',
'views/sale_portal_templates.xml',
'views/utm_campaign_views.xml',
'wizard/sale_order_cancel_views.xml',
'wizard/sale_payment_link_views.xml',
'views/sale_menus.xml', # Last because referencing actions defined in previous files
],
'demo': [
'data/product_product_demo.xml',
@@ -56,9 +67,6 @@ This module contains all the common features of Sales Management and eCommerce.
'sale/static/src/js/sale_order_view.js',
'sale/static/src/js/product_discount_widget.js',
],
'web.report_assets_common': [
'sale/static/src/scss/sale_report.scss',
],
'web.assets_frontend': [
'sale/static/src/scss/sale_portal.scss',
'sale/static/src/js/sale_portal_sidebar.js',
@@ -71,6 +79,9 @@ This module contains all the common features of Sales Management and eCommerce.
'sale/static/tests/product_configurator_tests.js',
'sale/static/tests/sales_team_dashboard_tests.js',
],
'web.report_assets_common': [
'sale/static/src/scss/sale_report.scss',
],
},
'post_init_hook': '_synchronize_cron',
'license': 'LGPL-3',
+1 -2
View File
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import account_invoice_report
from . import sale_report
from . import invoice_report
from . import report_all_channels_sales
@@ -7,7 +7,7 @@ from odoo import fields, models
class AccountInvoiceReport(models.Model):
_inherit = 'account.invoice.report'
team_id = fields.Many2one('crm.team', string='Sales Team')
team_id = fields.Many2one(comodel_name='crm.team', string="Sales Team")
def _select(self):
return super(AccountInvoiceReport, self)._select() + ", move.team_id as team_id"
return super()._select() + ", move.team_id as team_id"
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_invoice_report_search_inherit" model="ir.ui.view">
<field name="name">account.invoice.report.search.inherit</field>
<field name="model">account.invoice.report</field>
<field name="inherit_id" ref="account.view_account_invoice_report_search"/>
<field name="arch" type="xml">
<filter name="user" position="after">
<filter string="Sales Team" name="sales_channel" context="{'group_by':'team_id'}"/>
</filter>
<field name="invoice_user_id" position="after">
<field name="team_id"/>
</field>
</field>
</record>
<record id="account_invoice_report_view_tree" model="ir.ui.view">
<field name="name">account.invoice.report.view.tree.inherit.sale</field>
<field name="model">account.invoice.report</field>
<field name="inherit_id" ref="account.account_invoice_report_view_tree"/>
<field name="arch" type="xml">
<field name="invoice_user_id" position="after">
<field name="team_id" optional="hide"/>
</field>
</field>
</record>
<record id="action_account_invoice_report_salesteam" model="ir.actions.act_window">
<field name="name">Invoices Analysis</field>
<field name="res_model">account.invoice.report</field>
<field name="view_mode">graph</field>
<field name="domain">[('state', 'not in', ['draft', 'cancel'])]</field>
<field name="context">{'search_default_month':1, 'search_default_team_id': [active_id]}</field>
<field name="help">From this report, you can have an overview of the amount invoiced to your customer. The search tool can also be used to personalise your Invoices reports and so, match this analysis to your needs.</field>
</record>
</odoo>
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="action_report_saleorder" model="ir.actions.report">
<field name="name">Quotation / Order</field>
<field name="model">sale.order</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">sale.report_saleorder</field>
<field name="report_file">sale.report_saleorder</field>
<field name="print_report_name">(object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name)</field>
<field name="binding_model_id" ref="model_sale_order"/>
<field name="binding_type">report</field>
</record>
<record id="action_report_pro_forma_invoice" model="ir.actions.report">
<field name="name">PRO-FORMA Invoice</field>
<field name="model">sale.order</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">sale.report_saleorder_pro_forma</field>
<field name="report_file">sale.report_saleorder_pro_forma</field>
<field name="print_report_name">'PRO-FORMA - %s' % (object.name)</field>
<field name="binding_model_id" ref="model_sale_order"/>
<field name="binding_type">report</field>
<field name="groups_id" eval="[(4, ref('sale.group_proforma_sales'))]"/>
</record>
</odoo>
@@ -13,10 +13,16 @@
and doc.partner_invoice_id != doc.partner_id
or doc.partner_shipping_id != doc.partner_invoice_id">
<t t-set="information_block">
<strong t-if="doc.partner_shipping_id == doc.partner_invoice_id">Invoicing and Shipping Address:</strong>
<strong t-if="doc.partner_shipping_id != doc.partner_invoice_id">Invoicing Address:</strong>
<strong>
<t t-if="doc.partner_shipping_id == doc.partner_invoice_id">
Invoicing and Shipping Address:
</t>
<t t-else="">
Invoicing Address:
</t>
</strong>
<div t-field="doc.partner_invoice_id"
t-options='{"widget": "contact", "fields": ["address", "name", "phone"], "no_marker": True, "phone_icons": True}'/>
t-options='{"widget": "contact", "fields": ["address", "name", "phone"], "no_marker": True, "phone_icons": True}'/>
<t t-if="doc.partner_shipping_id != doc.partner_invoice_id">
<strong>Shipping Address:</strong>
<div t-field="doc.partner_shipping_id"
@@ -28,30 +34,25 @@
<div class="oe_structure"/>
<h2 class="mt16">
<t t-if="not (env.context.get('proforma', False) or is_pro_forma)">
<span t-if="doc.state not in ['draft','sent']">Order # </span>
<span t-if="doc.state in ['draft','sent']">Quotation # </span>
</t>
<t t-if="env.context.get('proforma', False) or is_pro_forma">
<span>Pro-Forma Invoice # </span>
</t>
<span t-if="env.context.get('proforma', False) or is_pro_forma">Pro-Forma Invoice # </span>
<span t-elif="doc.state in ['draft','sent']">Quotation # </span>
<span t-else="">Order # </span>
<span t-field="doc.name"/>
</h2>
<div class="row mt32 mb32" id="informations">
<div t-if="doc.client_order_ref" class="col-auto col-3 mw-100 mb-2">
<div t-if="doc.client_order_ref" class="col-auto col-3 mw-100 mb-2" name="informations_reference">
<strong>Your Reference:</strong>
<p class="m-0" t-field="doc.client_order_ref"/>
</div>
<div t-if="doc.date_order and doc.state not in ['draft','sent']" class="col-auto col-3 mw-100 mb-2">
<strong>Order Date:</strong>
<p class="m-0" t-field="doc.date_order"/>
</div>
<div t-if="doc.date_order and doc.state in ['draft','sent']" class="col-auto col-3 mw-100 mb-2">
<strong>Quotation Date:</strong>
<div t-if="doc.date_order" class="col-auto col-3 mw-100 mb-2" name="informations_date">
<strong t-if="doc.state in ['draft', 'sent']">Quotation Date:</strong>
<strong t-else="">Order Date:</strong>
<p class="m-0" t-field="doc.date_order" t-options='{"widget": "date"}'/>
</div>
<div t-if="doc.validity_date and doc.state in ['draft', 'sent']" class="col-auto col-3 mw-100 mb-2" name="expiration_date">
<div t-if="doc.validity_date and doc.state in ['draft', 'sent']"
class="col-auto col-3 mw-100 mb-2"
name="expiration_date">
<strong>Expiration:</strong>
<p class="m-0" t-field="doc.validity_date"/>
</div>
@@ -111,14 +112,14 @@
<span t-field="line.price_total" groups="account.group_show_line_subtotals_tax_included"/>
</td>
</t>
<t t-if="line.display_type == 'line_section'">
<t t-elif="line.display_type == 'line_section'">
<td name="td_section_line" colspan="99">
<span t-field="line.name"/>
</td>
<t t-set="current_section" t-value="line"/>
<t t-set="current_subtotal" t-value="0"/>
</t>
<t t-if="line.display_type == 'line_note'">
<t t-elif="line.display_type == 'line_note'">
<td name="td_note_line" colspan="99">
<span t-field="line.name"/>
</td>
@@ -170,7 +171,8 @@
<p t-if="not is_html_empty(doc.payment_term_id.note)">
<span t-field="doc.payment_term_id.note"/>
</p>
<p id="fiscal_position_remark" t-if="doc.fiscal_position_id and not is_html_empty(doc.fiscal_position_id.sudo().note)">
<p t-if="doc.fiscal_position_id and not is_html_empty(doc.fiscal_position_id.sudo().note)"
id="fiscal_position_remark">
<strong>Fiscal Position Remark:</strong>
<span t-field="doc.fiscal_position_id.sudo().note"/>
</p>
@@ -1,87 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, tools
class PosSaleReport(models.Model):
_name = "report.all.channels.sales"
_description = "Sales by Channel (All in One)"
_auto = False
name = fields.Char('Order Reference', readonly=True)
partner_id = fields.Many2one('res.partner', 'Partner', readonly=True)
product_id = fields.Many2one('product.product', string='Product', readonly=True)
product_tmpl_id = fields.Many2one('product.template', 'Product Template', readonly=True)
date_order = fields.Datetime(string='Date Order', readonly=True)
user_id = fields.Many2one('res.users', 'Salesperson', readonly=True)
categ_id = fields.Many2one('product.category', 'Product Category', readonly=True)
company_id = fields.Many2one('res.company', 'Company', readonly=True)
price_total = fields.Float('Total', readonly=True)
pricelist_id = fields.Many2one('product.pricelist', 'Pricelist', readonly=True)
country_id = fields.Many2one('res.country', 'Partner Country', readonly=True)
price_subtotal = fields.Float(string='Price Subtotal', readonly=True)
product_qty = fields.Float('Product Quantity', readonly=True)
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=True)
team_id = fields.Many2one('crm.team', 'Sales Team', readonly=True)
def _so(self):
so_str = """
SELECT sol.id AS id,
so.name AS name,
so.partner_id AS partner_id,
sol.product_id AS product_id,
pro.product_tmpl_id AS product_tmpl_id,
so.date_order AS date_order,
so.user_id AS user_id,
pt.categ_id AS categ_id,
so.company_id AS company_id,
sol.price_total / CASE COALESCE(so.currency_rate, 0) WHEN 0 THEN 1.0 ELSE so.currency_rate END AS price_total,
so.pricelist_id AS pricelist_id,
rp.country_id AS country_id,
sol.price_subtotal / CASE COALESCE(so.currency_rate, 0) WHEN 0 THEN 1.0 ELSE so.currency_rate END AS price_subtotal,
(sol.product_uom_qty / u.factor * u2.factor) as product_qty,
so.analytic_account_id AS analytic_account_id,
so.team_id AS team_id
FROM sale_order_line sol
JOIN sale_order so ON (sol.order_id = so.id)
LEFT JOIN product_product pro ON (sol.product_id = pro.id)
JOIN res_partner rp ON (so.partner_id = rp.id)
LEFT JOIN product_template pt ON (pro.product_tmpl_id = pt.id)
LEFT JOIN product_pricelist pp ON (so.pricelist_id = pp.id)
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 in ('sale','done')
"""
return so_str
def _from(self):
return """(%s)""" % (self._so())
def _get_main_request(self):
request = """
CREATE or REPLACE VIEW %s AS
SELECT id AS id,
name,
partner_id,
product_id,
product_tmpl_id,
date_order,
user_id,
categ_id,
company_id,
price_total,
pricelist_id,
analytic_account_id,
country_id,
team_id,
price_subtotal,
product_qty
FROM %s
AS foo""" % (self._table, self._from())
return request
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute(self._get_main_request())
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="report_all_channels_sales_action" model="ir.actions.act_window">
<field name="name">Sales Analysis</field>
<field name="res_model">sale.report</field>
<field name="view_mode">pivot</field>
</record>
</odoo>
+4 -19
View File
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import tools
from odoo import api, fields, models
from odoo import api, fields, models, tools
class SaleReport(models.Model):
@@ -53,9 +52,9 @@ class SaleReport(models.Model):
discount = fields.Float('Discount %', readonly=True)
discount_amount = fields.Float('Discount Amount', readonly=True)
campaign_id = fields.Many2one('utm.campaign', 'Campaign')
medium_id = fields.Many2one('utm.medium', 'Medium')
source_id = fields.Many2one('utm.source', 'Source')
campaign_id = fields.Many2one('utm.campaign', 'Campaign', readonly=True)
medium_id = fields.Many2one('utm.medium', 'Medium', readonly=True)
source_id = fields.Many2one('utm.source', 'Source', readonly=True)
order_id = fields.Many2one('sale.order', 'Order #', readonly=True)
@@ -157,17 +156,3 @@ class SaleReport(models.Model):
# self._table = sale_report
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (%s)""" % (self._table, self._query()))
class SaleOrderReportProforma(models.AbstractModel):
_name = 'report.sale.report_saleproforma'
_description = 'Proforma Report'
@api.model
def _get_report_values(self, docids, data=None):
docs = self.env['sale.order'].browse(docids)
return {
'doc_ids': docs.ids,
'doc_model': 'sale.order',
'docs': docs,
'proforma': True
}
-27
View File
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="action_report_saleorder" model="ir.actions.report">
<field name="name">Quotation / Order</field>
<field name="model">sale.order</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">sale.report_saleorder</field>
<field name="report_file">sale.report_saleorder</field>
<field name="print_report_name">(object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name)</field>
<field name="binding_model_id" ref="model_sale_order"/>
<field name="binding_type">report</field>
</record>
<record id="action_report_pro_forma_invoice" model="ir.actions.report">
<field name="name">PRO-FORMA Invoice</field>
<field name="model">sale.order</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">sale.report_saleorder_pro_forma</field>
<field name="report_file">sale.report_saleorder_pro_forma</field>
<field name="print_report_name">'PRO-FORMA - %s' % (object.name)</field>
<field name="binding_model_id" ref="model_sale_order"/>
<field name="binding_type">report</field>
<field name="groups_id" eval="[(4, ref('sale.group_proforma_sales'))]"/>
</record>
</data>
</odoo>
+30 -3
View File
@@ -49,8 +49,8 @@
<search string="Sales Analysis">
<field name="date"/>
<filter string="Date" name="year" invisible="1" date="date" default_period="this_year"/>
<filter name="Quotations" string="Quotations" domain="[('state','in', ('draft', 'sent'))]"/>
<filter name="Sales" string="Sales Orders" domain="[('state','not in',('draft', 'cancel', 'sent'))]"/>
<filter string="Quotations" name="Quotations" domain="[('state','in', ('draft', 'sent'))]"/>
<filter string="Sales Orders" name="Sales" domain="[('state','not in',('draft', 'cancel', 'sent'))]"/>
<separator/>
<filter name="filter_date" date="date" default_period="this_month"/>
<separator/>
@@ -73,7 +73,7 @@
<filter string="Customer Industry" name="industry_id" context="{'group_by':'industry_id'}"/>
<filter string="Product" name="Product" context="{'group_by':'product_id'}"/>
<filter string="Product Category" name="Category" context="{'group_by':'categ_id'}"/>
<filter name="status" string="Status" context="{'group_by':'state'}"/>
<filter string="Status" name="status" context="{'group_by':'state'}"/>
<filter string="Company" name="company" groups="base.group_multi_company" context="{'group_by':'company_id'}"/>
<separator/>
<filter string="Order Date" name="date" context="{'group_by':'date'}"
@@ -94,4 +94,31 @@
<field name="context">{'search_default_Sales':1, 'group_by_no_leaf':1,'group_by':[]}</field>
<field name="help">This report performs analysis on your quotations and sales orders. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application.</field>
</record>
<record id="report_all_channels_sales_action" model="ir.actions.act_window">
<field name="name">Sales Analysis</field>
<field name="res_model">sale.report</field>
<field name="view_mode">pivot</field>
</record>
<record id="action_order_report_quotation_salesteam" model="ir.actions.act_window">
<field name="name">Quotations Analysis</field>
<field name="res_model">sale.report</field>
<field name="view_mode">graph</field>
<field name="domain">[('state','=','draft'),('team_id', '=', active_id)]</field>
<field name="context">{'search_default_order_month':1}</field>
<field name="help">This report performs analysis on your quotations. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application.</field>
</record>
<record id="action_order_report_so_salesteam" model="ir.actions.act_window">
<field name="name">Sales Analysis</field>
<field name="res_model">sale.report</field>
<field name="view_mode">graph</field>
<field name="domain">[('state','not in',('draft','cancel'))]</field>
<field name="context">{
'search_default_Sales': 1,
'search_default_filter_date': 1,
'search_default_team_id': [active_id]}</field>
<field name="help">This report performs analysis on your sales orders. Analysis check your sales revenues and sort it by different group criteria (salesman, partner, product, etc.) Use this report to perform analysis on sales not having invoiced yet. If you want to analyse your turnover, you should use the Invoice Analysis report in the Accounting application.</field>
</record>
</odoo>
-1
View File
@@ -50,7 +50,6 @@ access_account_tax_sale_manager,account.tax sale manager,account.model_account_t
access_account_tax_group_sale_manager,account.tax.group sale manager,account.model_account_tax_group,sales_team.group_sale_salesman,1,0,0,0
access_account_account_sale_manager,account.account sale manager,account.model_account_account,sales_team.group_sale_manager,1,0,0,0
access_mail_activity_type_sale_manager,mail.activity.type.sale.manager,mail.model_mail_activity_type,sales_team.group_sale_manager,1,1,1,1
access_report_all_channels_sales,access_report_all_channels_sales,model_report_all_channels_sales,sales_team.group_sale_manager,1,0,0,0
access_sale_payment_acquirer_onboarding_wizard,access.sale.payment.acquirer.onboarding.wizard,model_sale_payment_acquirer_onboarding_wizard,base.group_system,1,1,1,0
access_sale_advance_payment_inv,access.sale.advance.payment.inv,model_sale_advance_payment_inv,sales_team.group_sale_salesman,1,1,1,0
access_sale_order_cancel,access.sale.order.cancel,model_sale_order_cancel,sales_team.group_sale_salesman,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
50 access_account_tax_group_sale_manager account.tax.group sale manager account.model_account_tax_group sales_team.group_sale_salesman 1 0 0 0
51 access_account_account_sale_manager account.account sale manager account.model_account_account sales_team.group_sale_manager 1 0 0 0
52 access_mail_activity_type_sale_manager mail.activity.type.sale.manager mail.model_mail_activity_type sales_team.group_sale_manager 1 1 1 1
access_report_all_channels_sales access_report_all_channels_sales model_report_all_channels_sales sales_team.group_sale_manager 1 0 0 0
53 access_sale_payment_acquirer_onboarding_wizard access.sale.payment.acquirer.onboarding.wizard model_sale_payment_acquirer_onboarding_wizard base.group_system 1 1 1 0
54 access_sale_advance_payment_inv access.sale.advance.payment.inv model_sale_advance_payment_inv sales_team.group_sale_salesman 1 1 1 0
55 access_sale_order_cancel access.sale.order.cancel model_sale_order_cancel sales_team.group_sale_salesman 1 1 1 0
+94
View File
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="account_invoice_groupby_inherit" model="ir.ui.view">
<field name="name">account.move.groupby</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
<field name="arch" type="xml">
<field name="invoice_user_id" position="after">
<field name="team_id"/>
</field>
<xpath expr="//group/filter[@name='status']" position="after">
<filter string="Sales Team" name="sales_channel" domain="[]" context="{'group_by':'team_id'}"/>
</xpath>
</field>
</record>
<record id="account_invoice_view_tree" model="ir.ui.view">
<field name="name">account.move.tree.inherit.sale</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_invoice_tree"/>
<field name="arch" type="xml">
<field name="invoice_user_id" position="after">
<field name="team_id" invisible="context.get('default_move_type') not in ('out_invoice', 'out_refund','out_receipt')" optional="hide"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="account_invoice_form">
<field name="name">Account Invoice</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='invoice_line_ids']//field[@name='discount']" position="attributes">
<attribute name="groups">product.group_discount_per_so_line</attribute>
</xpath>
<xpath expr="//group[@name='sale_info_group']/field[@name='invoice_user_id']" position="after">
<field name="team_id" kanban_view_ref="%(sales_team.crm_team_view_kanban)s"/>
</xpath>
<xpath expr="//group[@id='other_tab_group']" position="inside">
<group string="Marketing"
name="utm_link"
groups="base.group_no_one"
attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}">
<field name="campaign_id"/>
<field name="medium_id"/>
<field name="source_id"/>
</group>
</xpath>
</data>
</field>
</record>
<record id="action_invoice_salesteams" model="ir.actions.act_window">
<field name="name">Invoices</field>
<field name="res_model">account.move</field>
<field name="view_mode">tree,form,kanban</field>
<field name="view_id" ref="account.view_move_tree"/>
<field name="domain">[
('state', '=', 'posted'),
('move_type', 'in', ['out_invoice', 'out_refund'])]</field>
<field name="context">{
'search_default_team_id': [active_id],
'default_team_id': active_id,
'default_move_type':'out_invoice',
'move_type':'out_invoice',
'journal_type': 'sale',
}
</field>
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a customer invoice
</p><p>
Create invoices, register payments and keep track of the discussions with your customers.
</p>
</field>
</record>
<record id="action_invoice_salesteams_view_tree" model="ir.actions.act_window.view">
<field name="sequence">1</field>
<field name="view_mode">tree</field>
<field name="act_window_id" ref="sale.action_invoice_salesteams"/>
</record>
<record id="action_invoice_salesteams_view_form" model="ir.actions.act_window.view">
<field name="sequence">2</field>
<field name="view_mode">form</field>
<field name="view_id" ref="account.view_move_form"/>
<field name="act_window_id" ref="sale.action_invoice_salesteams"/>
</record>
</odoo>
+83 -36
View File
@@ -1,41 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="crm_team_salesteams_view_form" model="ir.ui.view">
<field name="name">crm.team.form</field>
<field name="model">crm.team</field>
<field name="priority">9</field>
<field name="inherit_id" ref="sales_team.crm_team_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='options_active']" position="inside">
<div class="o_row" style="display:inherit">
<field name="use_quotations"/><label for="use_quotations"/>
</div>
</xpath>
<xpath expr="//field[@name='company_id']" position="after">
<label for="invoiced_target"/>
<div class="o_row">
<field name="invoiced_target" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<span class="oe_read_only">/ Month</span>
</div>
</xpath>
</field>
</record>
<record id="view_account_invoice_report_search_inherit" model="ir.ui.view">
<field name="name">account.invoice.report.search.inherit</field>
<field name="model">account.invoice.report</field>
<field name="inherit_id" ref="account.view_account_invoice_report_search"/>
<field name="arch" type="xml">
<xpath expr="//group/filter[@name='user']" position="after">
<filter string="Sales Team" name="sales_channel" domain="[]" context="{'group_by':'team_id'}"/>
</xpath>
<xpath expr="//field[@name='invoice_user_id']" position="after">
<field name="team_id"/>
</xpath>
</field>
</record>
<!-- Dedicated actions used in views below -->
<record id="action_quotations_salesteams" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="view_mode">tree,form,calendar,graph,kanban,pivot</field>
<field name="context">{
'search_default_team_id': [active_id],
'default_team_id': active_id,
'show_address': 1,
}
</field>
<field name="domain">[]</field>
<field name="search_view_id" ref="sale.sale_order_view_search_inherit_quotation"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed by the customer, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<!-- Sales Team Dashboard Views -->
<record id="action_quotation_form" model="ir.actions.act_window">
<field name="name">New Quotation</field>
<field name="res_model">sale.order</field>
@@ -50,6 +39,64 @@
<field name="search_view_id" ref="sale_order_view_search_inherit_quotation"/>
</record>
<record id="action_orders_salesteams" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,calendar,graph,kanban,pivot</field>
<field name="search_view_id" ref="sale.sale_order_view_search_inherit_sale"/>
<field name="domain">[('state','not in',('draft','sent','cancel'))]</field>
<field name="context">{
'search_default_team_id': [active_id],
'default_team_id': active_id,
}
</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed by the customer, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<record id="action_orders_to_invoice_salesteams" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,calendar,graph,kanban,pivot</field>
<field name="search_view_id" ref="sale.sale_order_view_search_inherit_sale"/>
<field name="domain">[('invoice_status','=','to invoice')]</field>
<field name="context">{
'search_default_team_id': [active_id],
'default_team_id': active_id,
}
</field>
</record>
<!-- crm.team views (& actions) -->
<record id="crm_team_salesteams_view_form" model="ir.ui.view">
<field name="name">crm.team.form</field>
<field name="model">crm.team</field>
<field name="priority">9</field>
<field name="inherit_id" ref="sales_team.crm_team_view_form"/>
<field name="arch" type="xml">
<div name="options_active" position="inside">
<div class="o_row" style="display:inherit">
<field name="use_quotations"/><label for="use_quotations"/>
</div>
</div>
<field name="company_id" position="after">
<label for="invoiced_target"/>
<div class="o_row">
<field name="invoiced_target" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<span class="oe_read_only">/ Month</span>
</div>
</field>
</field>
</record>
<record id="crm_team_view_kanban_dashboard" model="ir.ui.view">
<field name="name">crm.team.view.kanban.dashboard.inherit.sale</field>
<field name="model">crm.team</field>
@@ -118,7 +165,7 @@
</div>
</xpath>
<xpath expr="//div[hasclass('o_kanban_manage_reports')]/div[@name='o_team_kanban_report_separator']" position="before">
<div name="o_team_kanban_report_separator" position="before">
<div t-if="record.use_quotations.raw_value">
<a name="%(action_order_report_quotation_salesteam)d" type="action">
Quotations
@@ -134,7 +181,7 @@
Invoices
</a>
</div>
</xpath>
</div>
</data>
</field>
+3 -6
View File
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<odoo>
<!-- Activity types config -->
<record id="mail_activity_type_action_config_sale" model="ir.actions.act_window">
<field name="name">Activity Types</field>
<field name="res_model">mail.activity.type</field>
@@ -8,8 +8,5 @@
<field name="domain">['|', ('res_model', '=', False), ('res_model', '=', 'sale.order')]</field>
<field name="context">{'default_res_model': 'sale.order'}</field>
</record>
<menuitem id="sale_menu_config_activity_type"
action="mail_activity_type_action_config_sale"
parent="menu_sale_config"
groups="base.group_no_one"/>
</odoo>
</odoo>
+26 -26
View File
@@ -1,30 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="acquirer_form_inherit_sale" model="ir.ui.view">
<field name="name">payment.acquirer.form.inherit.sale.payment</field>
<field name="model">payment.acquirer</field>
<field name="inherit_id" ref="payment.payment_acquirer_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='payment_form']" position="inside">
<field name="so_reference_type" attrs="{'invisible': [('provider', '!=', 'transfer')]}"/>
</xpath>
</field>
</record>
<record id="transaction_form_inherit_sale" model="ir.ui.view">
<field name="name">payment.transaction.form.inherit.sale.payment</field>
<field name="model">payment.transaction</field>
<field name="inherit_id" ref="payment.payment_transaction_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('oe_button_box')]" position="inside">
<button name="action_view_sales_orders" type="object"
class="oe_stat_button" icon="fa-money"
attrs="{'invisible': [('sale_order_ids_nbr', '=', 0)]}">
<field name="sale_order_ids_nbr" widget="statinfo" string="Sales Order(s)"/>
</button>
</xpath>
</field>
</record>
</data>
<record id="acquirer_form_inherit_sale" model="ir.ui.view">
<field name="name">payment.acquirer.form.inherit.sale.payment</field>
<field name="model">payment.acquirer</field>
<field name="inherit_id" ref="payment.payment_acquirer_form"/>
<field name="arch" type="xml">
<group name="payment_form" position="inside">
<field name="so_reference_type" attrs="{'invisible': [('provider', '!=', 'transfer')]}"/>
</group>
</field>
</record>
<record id="transaction_form_inherit_sale" model="ir.ui.view">
<field name="name">payment.transaction.form.inherit.sale.payment</field>
<field name="model">payment.transaction</field>
<field name="inherit_id" ref="payment.payment_transaction_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('oe_button_box')]" position="inside">
<button name="action_view_sales_orders" type="object"
class="oe_stat_button" icon="fa-money"
attrs="{'invisible': [('sale_order_ids_nbr', '=', 0)]}">
<field name="sale_order_ids_nbr" widget="statinfo" string="Sales Order(s)"/>
</button>
</xpath>
</field>
</record>
</odoo>
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="product_packaging_form_view_sale" model="ir.ui.view">
<field name="name">product.packaging.form.view.sale</field>
<field name="model">product.packaging</field>
<field name="inherit_id" ref="product.product_packaging_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='group_product']" position="inside">
<group name="group_product" position="inside">
<field name="sales"/>
</xpath>
</group>
</field>
</record>
@@ -16,9 +17,10 @@
<field name="model">product.packaging</field>
<field name="inherit_id" ref="product.product_packaging_tree_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='product_uom_id']" position="after">
<field name="product_uom_id" position="after">
<field name="sales" optional="show"/>
</xpath>
</field>
</field>
</record>
</odoo>
+105 -8
View File
@@ -1,24 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record model="ir.ui.view" id="product_template_sale_form_view">
<field name="name">product.template.sales</field>
<record id="product_template_form_view" model="ir.ui.view">
<field name="name">product.template.form.view.inherit.sale</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='sale']" position="attributes">
<page name="sales" position="attributes">
<attribute name="invisible">0</attribute>
</xpath>
</page>
<field name="product_variant_count" position="after">
<field name="service_type" widget="radio" invisible="True"/>
<field name="visible_expense_policy" invisible="1"/>
</field>
<field name="detailed_type" position="after">
<field name="invoice_policy" required="1"/>
<field name="expense_policy" widget="radio" attrs="{'invisible': [('visible_expense_policy', '=', False)]}"/>
</field>
<field name="product_tooltip" position="after">
<label for="product_tooltip" string="" attrs="{'invisible': ['|', ('type', 'not in', ('product', 'consu')), ('invoice_policy', '!=', 'order')]}"/>
<div attrs="{'invisible': ['|', ('type', 'not in', ('product', 'consu')), ('invoice_policy', '!=', 'order')]}" class="font-italic text-muted">
<label for="product_tooltip" string=""
attrs="{'invisible': ['|', ('type', 'not in', ('product', 'consu')), ('invoice_policy', '!=', 'order')]}"/>
<div attrs="{'invisible': ['|', ('type', 'not in', ('product', 'consu')), ('invoice_policy', '!=', 'order')]}"
class="font-italic text-muted">
You can invoice them before they are delivered.
</div>
<label for="product_tooltip" string="" attrs="{'invisible': ['|', ('type', 'not in', ('product', 'consu')), ('invoice_policy', '!=', 'delivery')]}"/>
<div attrs="{'invisible': ['|', ('type', 'not in', ('product', 'consu')), ('invoice_policy', '!=', 'delivery')]}" class="font-italic text-muted">
<label for="product_tooltip" string=""
attrs="{'invisible': ['|', ('type', 'not in', ('product', 'consu')), ('invoice_policy', '!=', 'delivery')]}"/>
<div attrs="{'invisible': ['|', ('type', 'not in', ('product', 'consu')), ('invoice_policy', '!=', 'delivery')]}"
class="font-italic text-muted">
Invoice after delivery, based on quantities delivered, not ordered.
</div>
</field>
</field>
</record>
<!-- TODO VFE inherit product_template_form_view and factorize both views -->
<record model="ir.ui.view" id="product_form_view_sale_order_button">
<field name="name">product.product.sale.order</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button class="oe_stat_button"
name="action_view_sales"
type="object"
icon="fa-signal"
help="Sold in the last 365 days"
groups="sales_team.group_sale_salesman"
attrs="{'invisible': [('sale_ok', '=', False)]}">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="sales_count" widget="statinfo" nolabel="1" class="mr4"/>
<field name="uom_name"/>
</span>
<span class="o_stat_text">Sold</span>
</div>
</button>
</div>
<group name="description" position="after">
<group string="Warning when Selling this Product" groups="sale.group_warning_sale">
<field name="sale_line_warn" nolabel="1"/>
<field name="sale_line_warn_msg" colspan="3" nolabel="1"
attrs="{'required':[('sale_line_warn','!=','no-message')],'readonly':[('sale_line_warn','=','no-message')]}"/>
</group>
</group>
</field>
</record>
<record model="ir.ui.view" id="product_template_form_view_sale_order_button">
<field name="name">product.template.sale.order.button</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button class="oe_stat_button"
name="action_view_sales"
type="object" icon="fa-signal"
help="Sold in the last 365 days"
groups="sales_team.group_sale_salesman"
attrs="{'invisible': [('sale_ok', '=', False)]}">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="sales_count" widget="statinfo" nolabel="1" class="mr4"/>
<field name="uom_name"/>
</span>
<span class="o_stat_text">Sold</span>
</div>
</button>
</div>
<group name="description" position="after">
<group string="Warning when Selling this Product" groups="sale.group_warning_sale">
<field name="sale_line_warn" nolabel="1"/>
<field name="sale_line_warn_msg" colspan="3" nolabel="1"
attrs="{'required':[('sale_line_warn','!=','no-message')],'readonly':[('sale_line_warn','=','no-message')], 'invisible':[('sale_line_warn','=','no-message')]}"/>
</group>
</group>
</field>
</record>
<record id="product_template_action" model="ir.actions.act_window">
<field name="name">Products</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.template</field>
<field name="view_mode">kanban,tree,form,activity</field>
<field name="view_id" ref="product.product_template_kanban_view"/>
<field name="search_view_id" ref="product.product_template_search_view"/>
<field name="context">{"search_default_filter_to_sell":1, "sale_multi_pricelist_product_template": 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new product
</p><p>
You must define a product for everything you sell or purchase,
whether it's a storable product, a consumable or a service.
</p>
</field>
</record>
</odoo>
@@ -8,7 +8,11 @@
<field name="inherit_id" ref="base.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block o_not_app" data-string="Sales" string="Sales" data-key="sale_management" groups="sales_team.group_sale_manager">
<div class="app_settings_block o_not_app"
string="Sales"
data-string="Sales"
data-key="sale_management"
groups="sales_team.group_sale_manager">
<h2>Product Catalog</h2>
<div class="row mt16 o_settings_container" name="catalog_setting_container">
<div class="col-12 col-lg-6 o_setting_box" id="variant_options">
@@ -446,11 +450,4 @@
<field name="context">{'module' : 'sale_management', 'bin_size': False}</field>
</record>
<menuitem id="menu_sale_general_settings"
name="Settings"
parent="menu_sale_config"
sequence="0"
action="action_sale_config_settings"
groups="base.group_system"/>
</odoo>
+81 -77
View File
@@ -1,87 +1,91 @@
<?xml version="1.0"?>
<odoo>
<record id="act_res_partner_2_sale_order" model="ir.actions.act_window">
<field name="name">Quotations and Sales</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,graph</field>
<field name="context">{'search_default_partner_id': active_id, 'default_partner_id': active_id}</field>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed by the customer, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<!-- Partner kanban view inherte -->
<record model="ir.ui.view" id="crm_lead_partner_kanban_view">
<field name="name">res.partner.kanban.saleorder.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.res_partner_kanban_view"/>
<field name="priority" eval="20"/>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
<field name="arch" type="xml">
<field name="mobile" position="after">
<field name="sale_order_count"/>
</field>
<xpath expr="//span[hasclass('oe_kanban_partner_links')]" position="inside">
<span t-if="record.sale_order_count.value>0" class="badge badge-pill"><i class="fa fa-fw fa-usd" role="img" aria-label="Sale orders" title="Sales orders"/><t t-esc="record.sale_order_count.value"/></span>
</xpath>
</field>
</record>
<record id="act_res_partner_2_sale_order" model="ir.actions.act_window">
<field name="name">Quotations and Sales</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,graph</field>
<field name="context">{'search_default_partner_id': active_id, 'default_partner_id': active_id}</field>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed by the customer, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<record id="res_partner_view_buttons" model="ir.ui.view">
<field name="name">res.partner.view.buttons</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="priority" eval="3"/>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button class="oe_stat_button" type="action" name="%(sale.act_res_partner_2_sale_order)d"
groups="sales_team.group_sale_salesman"
icon="fa-usd">
<field string="Sales" name="sale_order_count" widget="statinfo"/>
</button>
</div>
<page name="internal_notes" position="inside">
<group colspan="2" col="2" groups="sale.group_warning_sale">
<separator string="Warning on the Sales Order" colspan="4" />
<field name="sale_warn" nolabel="1" />
<field name="sale_warn_msg" colspan="3" nolabel="1"
attrs="{'required':[('sale_warn','!=', False), ('sale_warn','!=','no-message')], 'invisible':[('sale_warn','in',(False,'no-message'))]}"/>
</group>
</page>
<record model="ir.ui.view" id="crm_lead_partner_kanban_view">
<field name="name">res.partner.kanban.saleorder.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.res_partner_kanban_view"/>
<field name="priority" eval="20"/>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
<field name="arch" type="xml">
<field name="mobile" position="after">
<field name="sale_order_count"/>
</field>
</record>
<xpath expr="//span[hasclass('oe_kanban_partner_links')]" position="inside">
<span t-if="record.sale_order_count.value>0" class="badge badge-pill">
<i class="fa fa-fw fa-usd" role="img" aria-label="Sale orders" title="Sales orders"/>
<t t-esc="record.sale_order_count.value"/>
</span>
</xpath>
</field>
</record>
<record id="res_partner_view_form_payment_defaultcreditcard" model="ir.ui.view">
<field name="name">res.partner.view.form.payment.defaultcreditcard</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="payment.view_partners_form_payment_defaultcreditcard"/>
<field name="arch" type="xml">
<button name="%(payment.action_payment_token)d" position="attributes">
<attribute name="groups">sales_team.group_sale_salesman</attribute>
<record id="res_partner_view_buttons" model="ir.ui.view">
<field name="name">res.partner.view.buttons</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="priority" eval="3"/>
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button class="oe_stat_button" type="action" name="%(sale.act_res_partner_2_sale_order)d"
groups="sales_team.group_sale_salesman"
icon="fa-usd">
<field string="Sales" name="sale_order_count" widget="statinfo"/>
</button>
</field>
</record>
<record id="res_partner_view_form_property_inherit" model="ir.ui.view">
<field name="name">res.partner.view.form.property.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="account.view_partner_property_form"/>
<field name="arch" type="xml">
<group name="fiscal_information" position="attributes">
<attribute name="groups">account.group_account_invoice, sales_team.group_sale_salesman</attribute>
</div>
<page name="internal_notes" position="inside">
<group colspan="2" col="2" groups="sale.group_warning_sale">
<separator string="Warning on the Sales Order" colspan="4" />
<field name="sale_warn" nolabel="1" />
<field name="sale_warn_msg" colspan="3" nolabel="1"
attrs="{'required':[('sale_warn','!=', False), ('sale_warn','!=','no-message')], 'invisible':[('sale_warn','in',(False,'no-message'))]}"/>
</group>
<field name="property_payment_term_id" position="attributes">
<attribute name="groups">account.group_account_invoice, sales_team.group_sale_salesman</attribute>
</field>
<field name="property_supplier_payment_term_id" position="attributes">
<attribute name="groups">account.group_account_invoice, sales_team.group_sale_salesman</attribute>
</field>
</page>
</field>
</record>
<record id="res_partner_view_form_payment_defaultcreditcard" model="ir.ui.view">
<field name="name">res.partner.view.form.payment.defaultcreditcard</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="payment.view_partners_form_payment_defaultcreditcard"/>
<field name="arch" type="xml">
<button name="%(payment.action_payment_token)d" position="attributes">
<attribute name="groups">sales_team.group_sale_salesman</attribute>
</button>
</field>
</record>
<record id="res_partner_view_form_property_inherit" model="ir.ui.view">
<field name="name">res.partner.view.form.property.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="account.view_partner_property_form"/>
<field name="arch" type="xml">
<group name="fiscal_information" position="attributes">
<attribute name="groups">account.group_account_invoice, sales_team.group_sale_salesman</attribute>
</group>
<field name="property_payment_term_id" position="attributes">
<attribute name="groups">account.group_account_invoice, sales_team.group_sale_salesman</attribute>
</field>
</record>
<field name="property_supplier_payment_term_id" position="attributes">
<attribute name="groups">account.group_account_invoice, sales_team.group_sale_salesman</attribute>
</field>
</field>
</record>
</odoo>
+149
View File
@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<menuitem id="sale_menu_root"
name="Sales"
web_icon="sale_management,static/description/icon.png"
active="False"
sequence="30">
<menuitem id="sale_order_menu"
name="Orders"
sequence="2">
<menuitem id="menu_sale_quotations"
action="action_quotations_with_onboarding"
groups="sales_team.group_sale_salesman"
sequence="1"/>
<menuitem id="menu_sale_order"
name="Orders"
action="action_orders"
groups="sales_team.group_sale_salesman"
sequence="2"/>
<menuitem id="report_sales_team"
name="Sales Teams"
action="sales_team.crm_team_action_sales"
groups="sales_team.group_sale_manager"
sequence="3"/>
<menuitem id="res_partner_menu"
action="account.res_partner_action_customer"
groups="sales_team.group_sale_salesman"
sequence="4"/>
</menuitem>
<menuitem id="menu_sale_invoicing"
name="To Invoice"
groups="sales_team.group_sale_salesman"
sequence="3">
<menuitem id="menu_sale_order_invoice"
action="action_orders_to_invoice"
sequence="2"/>
<menuitem id="menu_sale_order_upselling"
action="action_orders_upselling"
sequence="5"/>
</menuitem>
<menuitem id="product_menu_catalog"
name="Products"
groups="sales_team.group_sale_salesman"
sequence="4">
<menuitem id="menu_product"
name="Product Variants"
sequence="2"
groups="base.group_no_one"/>
<menuitem id="menu_product_template_action"
action="product_template_action"
sequence="1"/>
<menuitem id="menu_products"
action="product.product_normal_action_sell"
groups="product.group_product_variant"
sequence="2"/>
<menuitem id="menu_product_pricelist_main"
name="Pricelists"
action="product.product_pricelist_action2"
groups="product.group_product_pricelist"
sequence="3"/>
</menuitem>
<menuitem id="menu_sale_report"
name="Reporting"
groups="sales_team.group_sale_manager"
sequence="5">
<menuitem id="menu_report_product_all"
name="Sales"
action="action_order_report_all"
sequence="1"/>
</menuitem>
<menuitem id="menu_sale_config"
name="Configuration"
groups="sales_team.group_sale_manager"
sequence="35">
<menuitem id="menu_sale_general_settings"
name="Settings"
sequence="0"
action="action_sale_config_settings"
groups="base.group_system"/>
<menuitem id="sales_team_config"
name="Sales Teams"
action="sales_team.crm_team_action_config"
sequence="2"/>
<menuitem id="menu_sales_config"
sequence="4"
name="Sales Orders">
<menuitem id="menu_tag_config"
name="Tags"
action="sales_team.sales_team_crm_tag_action"
sequence="2"/>
</menuitem>
<menuitem id="prod_config_main"
name="Products"
sequence="5">
<menuitem id="menu_product_attribute_action"
action="product.attribute_action"
groups="product.group_product_variant"
sequence="1"/>
</menuitem>
<menuitem id="next_id_16"
name="Units of Measure"
groups="uom.group_uom"
sequence="6">
<menuitem id="menu_product_uom_form_action"
action="uom.product_uom_form_action"
groups="base.group_no_one"
sequence="7"/>
<menuitem id="menu_product_uom_categ_form_action"
action="uom.product_uom_categ_form_action"
sequence="8"/>
</menuitem>
<menuitem id="sale_menu_config_activity_type"
action="mail_activity_type_action_config_sale"
groups="base.group_no_one"/>
</menuitem>
</menuitem>
</odoo>
+1 -1
View File
@@ -23,7 +23,7 @@
<t t-set="state" t-value="state.get('sale_onboarding_order_confirmation_state')" />
</t>
</template>
<template id="sale_onboarding_sample_quotation_step">
<template id="sale_onboarding_sample_quotation_step">
<t t-call="base.onboarding_step">
<t t-set="title">Sample Quotation</t>
<t t-set="description">Send a quotation to test the customer portal.</t>
+111
View File
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_order_line_tree" model="ir.ui.view">
<field name="name">sale.order.line.tree</field>
<field name="model">sale.order.line</field>
<field name="arch" type="xml">
<tree string="Sales Order Lines" create="false">
<field name="order_id"/>
<field name="order_partner_id"/>
<field name="name"/>
<field name="salesman_id"/>
<field name="product_uom_qty" string="Qty"/>
<field name="qty_delivered"/>
<field name="qty_invoiced"/>
<field name="qty_to_invoice"/>
<field name="product_uom" string="Unit of Measure" groups="uom.group_uom"/>
<field name="price_subtotal" sum="Total" widget="monetary"/>
<field name="currency_id" invisible="1"/>
</tree>
</field>
</record>
<record id="sale_order_line_view_form_readonly" model="ir.ui.view">
<field name="name">sale.order.line.form.readonly</field>
<field name="model">sale.order.line</field>
<field name="arch" type="xml">
<form string="Sales Order Item">
<sheet>
<div class="oe_title">
<h1>
<field name="display_name" readonly="1"/>
</h1>
</div>
<group>
<group>
<field name="order_id" readonly="1"/>
<field name="product_id" readonly="1"/>
<field name="name" readonly="1"/>
<field name="product_uom_qty" readonly="1"/>
<field name="qty_delivered" readonly="1"/>
<field name="qty_invoiced"/>
<field name="product_uom" readonly="1"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field name="order_partner_id" invisible="1"/>
<field name="display_type" invisible="1"/>
<field name="product_updatable" invisible="1"/>
</group>
<group>
<field name="price_unit" readonly="1"/>
<field name="discount" groups="product.group_discount_per_so_line" readonly="1"/>
<field name="price_subtotal" widget="monetary"/>
<field name="tax_id" widget="many2many_tags" readonly="1"/>
<field name="price_tax" widget="monetary"/>
<field name="price_total" widget="monetary"/>
<field name="currency_id" invisible="1"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_sales_order_line_filter" model="ir.ui.view">
<field name="name">sale.order.line.select</field>
<field name="model">sale.order.line</field>
<field name="arch" type="xml">
<search string="Search Sales Order">
<filter string="To Invoice"
name="to_invoice"
domain="[('qty_to_invoice', '!=', 0)]"
help="Sales Order Lines ready to be invoiced"/>
<separator/>
<filter string="My Sales Order Lines"
name="my_sales_order_lines"
domain="[('salesman_id','=',uid)]"
help="Sales Order Lines related to a Sales Order of mine"/>
<field name="order_id"/>
<field name="order_partner_id" operator="child_of"/>
<field name="product_id"/>
<field name="salesman_id"/>
<group expand="0" string="Group By">
<filter string="Product" name="product" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="Order" name="order" domain="[]" context="{'group_by':'order_id'}"/>
<filter string="Salesperson" name="salesperson" domain="[]" context="{'group_by':'salesman_id'}"/>
</group>
</search>
</field>
</record>
<record id="sale_order_line_view_kanban" model="ir.ui.view">
<field name="name">sale.order.line.kanban</field>
<field name="model">sale.order.line</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile">
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_content oe_kanban_global_click">
<div class="row">
<div class="col-12">
<field name="display_name"/>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
</odoo>
+903
View File
@@ -0,0 +1,903 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- VIEWS -->
<record id="sale_order_view_activity" model="ir.ui.view">
<field name="name">sale.order.activity</field>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<activity string="Sales Orders">
<templates>
<div t-name="activity-box">
<div>
<field name="name" display="full"/>
<field name="partner_id" muted="1" display="full"/>
</div>
</div>
</templates>
</activity>
</field>
</record>
<record id="view_sale_order_calendar" model="ir.ui.view">
<field name="name">sale.order.calendar</field>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<calendar string="Sales Orders" date_start="date_order" color="state" hide_time="true" event_limit="5">
<field name="currency_id" invisible="1"/>
<field name="partner_id" avatar_field="avatar_128"/>
<field name="amount_total" widget="monetary"/>
<field name="payment_term_id"/>
<field name="state" filters="1" invisible="1"/>
</calendar>
</field>
</record>
<record id="view_sale_order_graph" model="ir.ui.view">
<field name="name">sale.order.graph</field>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<graph string="Sales Orders" sample="1">
<field name="partner_id"/>
<field name="amount_total" type="measure"/>
</graph>
</field>
</record>
<record id="view_sale_order_pivot" model="ir.ui.view">
<field name="name">sale.order.pivot</field>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<pivot string="Sales Orders" sample="1">
<field name="date_order" type="row"/>
<field name="amount_total" type="measure"/>
</pivot>
</field>
</record>
<record id="view_sale_order_kanban" model="ir.ui.view">
<field name="name">sale.order.kanban</field>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile" sample="1">
<field name="name"/>
<field name="partner_id"/>
<field name="amount_total"/>
<field name="date_order"/>
<field name="state"/>
<field name="currency_id"/>
<field name="activity_state"/>
<progressbar field="activity_state"
colors='{"planned": "success", "today": "warning", "overdue": "danger"}'/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
<div class="o_kanban_record_top mb16">
<div class="o_kanban_record_headings mt4">
<strong class="o_kanban_record_title">
<span t-esc="record.partner_id.value"/>
</strong>
</div>
<strong>
<field name="amount_total" widget="monetary"/>
</strong>
</div>
<div class="o_kanban_record_bottom">
<div class="oe_kanban_bottom_left text-muted">
<span>
<t t-esc="record.name.value"/> <t t-esc="record.date_order.value"/>
</span>
<field name="activity_ids" widget="kanban_activity"/>
</div>
<div class="oe_kanban_bottom_right">
<field name="state"
widget="label_selection"
options="{'classes': {'draft': 'default', 'cancel': 'default', 'done': 'success'}}"/>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- TODO VFE factorize core fields between quotation & SO views -->
<record id="view_order_tree" model="ir.ui.view">
<field name="name">sale.order.tree</field>
<field name="model">sale.order</field>
<field name="priority">2</field>
<field name="arch" type="xml">
<tree string="Sales Orders" sample="1"
decoration-info="invoice_status == 'to invoice'"
decoration-muted="state == 'cancel'">
<field name="message_needaction" invisible="1"/>
<field name="name" string="Number" readonly="1" decoration-bf="1"/>
<field name="date_order" string="Order Date" widget="date" optional="show"/>
<field name="commitment_date" optional="hide"/>
<field name="expected_date" optional="hide"/>
<field name="partner_id" readonly="1"/>
<field name="user_id" optional="show" widget="many2one_avatar_user"/>
<field name="activity_ids" widget="list_activity" optional="show"/>
<field name="team_id" optional="hide"/>
<field name="company_id" groups="base.group_multi_company" optional="show" readonly="1"/>
<field name="amount_untaxed" sum="Total Tax Excluded" widget="monetary" optional="hide"/>
<field name="amount_tax" sum="Tax Total" widget="monetary" optional="hide"/>
<field name="amount_total" sum="Total Tax Included" widget="monetary" decoration-bf="1" optional="show"/>
<field name="currency_id" invisible="1"/>
<field name="invoice_status"
decoration-success="invoice_status == 'invoiced'"
decoration-info="invoice_status == 'to invoice'"
decoration-warning="invoice_status == 'upselling'"
widget="badge" optional="show"/>
<field name="tag_ids" optional="hide" widget="many2many_tags" options="{'color_field': 'color'}"/>
<field name="state" invisible="1"/>
</tree>
</field>
</record>
<record id="view_quotation_tree" model="ir.ui.view">
<field name="name">sale.order.tree</field>
<field name="model">sale.order</field>
<field name="priority">4</field>
<field name="arch" type="xml">
<tree string="Quotation" class="o_sale_order" sample="1"
decoration-info="state in ['draft', 'sent']"
decoration-muted="state == 'cancel'">
<field name="name" string="Number" readonly="1" decoration-bf="1"/>
<field name="create_date" string="Creation Date" widget="date" optional="show"/>
<field name="commitment_date" widget="date" optional="hide"/>
<field name="expected_date" widget="date" optional="hide"/>
<field name="partner_id" readonly="1"/>
<field name="user_id" widget="many2one_avatar_user" optional="show"/>
<field name="activity_ids" widget="list_activity" optional="show"/>
<field name="team_id" optional="hide"/>
<field name="tag_ids" optional="hide" widget="many2many_tags" options="{'color_field': 'color'}"/>
<field name="company_id" groups="base.group_multi_company" optional="show" readonly="1"/>
<field name="amount_untaxed" sum="Total Tax Excluded" widget="monetary" optional="hide"/>
<field name="amount_tax" sum="Tax Total" widget="monetary" optional="hide"/>
<field name="amount_total" sum="Total Tax Included" widget="monetary" decoration-bf="1" optional="show"/>
<field name="state"
decoration-success="state == 'sale' or state == 'done'"
decoration-info="state == 'draft' or state == 'sent'"
widget="badge" optional="show"/>
<field name="invoice_status" optional="hide"/>
<field name="message_needaction" invisible="1"/>
<field name="currency_id" invisible="1"/>
</tree>
</field>
</record>
<record id="view_quotation_tree_with_onboarding" model="ir.ui.view">
<field name="name">sale.order.tree</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="view_quotation_tree"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<xpath expr="//tree" position="attributes">
<attribute name="banner_route">/sales/sale_quotation_onboarding_panel</attribute>
</xpath>
</field>
</record>
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale.order.form</field>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<form string="Sales Order" class="o_sale_order" js_class="sale_discount_form">
<header>
<field name="authorized_transaction_ids" invisible="1"/>
<button name="payment_action_capture" type="object" data-hotkey="shift+g"
string="Capture Transaction" class="oe_highlight"
attrs="{'invisible': [('authorized_transaction_ids', '=', [])]}"/>
<button name="payment_action_void" type="object"
string="Void Transaction" data-hotkey="shift+v"
confirm="Are you sure you want to void the authorized transaction? This action can't be undone."
attrs="{'invisible': [('authorized_transaction_ids', '=', [])]}"/>
<button name="%(sale.action_view_sale_advance_payment_inv)d" string="Create Invoice"
type="action" class="btn-primary" data-hotkey="q"
attrs="{'invisible': [('invoice_status', '!=', 'to invoice')]}"/>
<button name="%(sale.action_view_sale_advance_payment_inv)d" string="Create Invoice"
type="action" context="{'default_advance_payment_method': 'percentage'}" data-hotkey="q"
attrs="{'invisible': ['|',('invoice_status', '!=', 'no'), ('state', '!=', 'sale')]}"/>
<button name="action_quotation_send" string="Send by Email" type="object" states="draft" class="btn-primary" data-hotkey="g"/>
<button name="action_quotation_send" type="object" string="Send PRO-FORMA Invoice"
groups="sale.group_proforma_sales" class="btn-primary"
attrs="{'invisible': ['|', ('state', '!=', 'draft'), ('invoice_count','&gt;=',1)]}" context="{'proforma': True}"/>
<button name="action_confirm" id="action_confirm" data-hotkey="v"
string="Confirm" class="btn-primary" type="object"
attrs="{'invisible': [('state', 'not in', ['sent'])]}"/>
<button name="action_confirm" data-hotkey="v"
string="Confirm" type="object"
attrs="{'invisible': [('state', 'not in', ['draft'])]}"/>
<button name="action_quotation_send" type="object" string="Send PRO-FORMA Invoice" groups="sale.group_proforma_sales" attrs="{'invisible': ['|', ('state', '=', 'draft'), ('invoice_count','&gt;=',1)]}" context="{'proforma': True}"/>
<button name="action_quotation_send" string="Send by Email" type="object" states="sent,sale" data-hotkey="g"/>
<button name="action_cancel" type="object" string="Cancel" attrs="{'invisible': ['|', ('state', 'not in', ['draft', 'sent','sale']), ('id', '=', False)]}" data-hotkey="z"/>
<button name="action_draft" states="cancel" type="object" string="Set to Quotation" data-hotkey="w"/>
<field name="state" widget="statusbar" statusbar_visible="draft,sent,sale"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_view_invoice"
type="object"
class="oe_stat_button"
icon="fa-pencil-square-o"
attrs="{'invisible': [('invoice_count', '=', 0)]}">
<field name="invoice_count" widget="statinfo" string="Invoices"/>
</button>
<button name="preview_sale_order"
type="object"
class="oe_stat_button"
icon="fa-globe icon">
<div class="o_field_widget o_stat_info">
<span class="o_stat_text">Customer</span>
<span class="o_stat_text">Preview</span>
</div>
</button>
</div>
<div class="oe_title">
<h1>
<field name="name" readonly="1"/>
</h1>
</div>
<group name="sale_header">
<group name="partner_details">
<field name="partner_id" widget="res_partner_many2one" context="{'res_partner_search_mode': 'customer', 'show_address': 1, 'show_vat': True}" options='{"always_reload": True}'/>
<field name="partner_invoice_id" groups="account.group_delivery_invoice_address" context="{'default_type':'invoice'}" options='{"always_reload": True}'/>
<field name="partner_shipping_id" groups="account.group_delivery_invoice_address" context="{'default_type':'delivery'}" options='{"always_reload": True}'/>
</group>
<group name="order_details">
<field name="validity_date" attrs="{'invisible': [('state', 'in', ['sale', 'done'])]}"/>
<div class="o_td_label" groups="base.group_no_one" attrs="{'invisible': [('state', 'in', ['sale', 'done', 'cancel'])]}">
<label for="date_order" string="Quotation Date"/>
</div>
<field name="date_order" nolabel="1" groups="base.group_no_one" attrs="{'invisible': [('state', 'in', ['sale', 'done', 'cancel'])]}"/>
<div class="o_td_label" attrs="{'invisible': [('state', 'in', ['draft', 'sent'])]}">
<label for="date_order" string="Order Date"/>
</div>
<field name="date_order" attrs="{'required': [('state', 'in', ['sale', 'done'])], 'invisible': [('state', 'in', ['draft', 'sent'])]}" nolabel="1"/>
<field name="show_update_pricelist" invisible="1"/>
<label for="pricelist_id" groups="product.group_product_pricelist"/>
<div groups="product.group_product_pricelist" class="o_row">
<field name="pricelist_id" options="{'no_open':True,'no_create': True}"/>
<button name="update_prices" type="object"
string=" Update Prices"
help="Recompute all prices based on this pricelist"
class="btn-link mb-1 px-0" icon="fa-refresh"
confirm="This will update all unit prices based on the currently set pricelist."
attrs="{'invisible': ['|', ('show_update_pricelist', '=', False), ('state', 'in', ['sale', 'done','cancel'])]}"/>
</div>
<field name="currency_id" invisible="1"/>
<field name="tax_country_id" invisible="1"/>
<field name="payment_term_id" options="{'no_open':True,'no_create': True}"/>
</group>
</group>
<notebook>
<page string="Order Lines" name="order_lines">
<field
name="order_line"
widget="section_and_note_one2many"
mode="tree,kanban"
attrs="{'readonly': [('state', 'in', ('done','cancel'))]}"
>
<form>
<field name="display_type" invisible="1"/>
<!--
We need the sequence field to be here for new lines to be added at the correct position.
TODO: at some point we want to fix this in the framework so that an invisible field is not required.
-->
<field name="sequence" invisible="1"/>
<field name="product_uom_category_id" invisible="1"/>
<group>
<group attrs="{'invisible': [('display_type', '!=', False)]}">
<field name="product_updatable" invisible="1"/>
<field name="product_id"
domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'company_id': parent.company_id}"
attrs="{
'readonly': [('product_updatable', '=', False)],
'required': [('display_type', '=', False)],
}"
force_save="1"
widget="many2one_barcode"
/>
<field name="invoice_status" invisible="1"/>
<field name="qty_to_invoice" invisible="1"/>
<field name="qty_delivered_method" invisible="1"/>
<field name="price_total" invisible="1"/>
<field name="price_tax" invisible="1"/>
<field name="price_subtotal" invisible="1"/>
<field name="product_uom_readonly" invisible="1"/>
<label for="product_uom_qty"/>
<div class="o_row" name="ordered_qty">
<field
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom, 'uom_qty_change':True, 'company_id': parent.company_id}"
name="product_uom_qty"/>
<field
name="product_uom"
force_save="1"
groups="uom.group_uom"
class="oe_no_button"
attrs="{
'readonly': [('product_uom_readonly', '=', True)],
'required': [('display_type', '=', False)],
}"
/>
</div>
<label for="qty_delivered" string="Delivered" attrs="{'invisible': [('parent.state', 'not in', ['sale', 'done'])]}"/>
<div name="delivered_qty" attrs="{'invisible': [('parent.state', 'not in', ['sale', 'done'])]}">
<field name="qty_delivered" attrs="{'readonly': [('qty_delivered_method', '!=', 'manual')]}"/>
</div>
<label for="qty_invoiced" string="Invoiced" attrs="{'invisible': [('parent.state', 'not in', ['sale', 'done'])]}"/>
<div name="invoiced_qty" attrs="{'invisible': [('parent.state', 'not in', ['sale', 'done'])]}">
<field name="qty_invoiced" attrs="{'invisible': [('parent.state', 'not in', ['sale', 'done'])]}"/>
</div>
<field name="product_packaging_id" attrs="{'invisible': [('product_id', '=', False)]}" context="{'default_product_id': product_id, 'tree_view_ref':'product.product_packaging_tree_view', 'form_view_ref':'product.product_packaging_form_view'}" groups="product.group_stock_packaging" />
<field name="price_unit"/>
<field name="tax_id" widget="many2many_tags" options="{'no_create': True}" context="{'search_view_ref': 'account.account_tax_view_search'}" domain="[('type_tax_use','=','sale'), ('company_id','=',parent.company_id), ('country_id', '=', parent.tax_country_id)]"
attrs="{'readonly': [('qty_invoiced', '&gt;', 0)]}"/>
<label for="discount" groups="product.group_discount_per_so_line"/>
<div name="discount" groups="product.group_discount_per_so_line">
<field name="discount" class="oe_inline"/> %
</div>
<!--
We need the sequence field to be here
because we want to be able to overwrite the default sequence value in the JS
in order for new lines to be added at the correct position.
NOTE: at some point we want to fix this in the framework so that an invisible field is not required.
-->
<field name="sequence" invisible="1"/>
</group>
<group attrs="{'invisible': [('display_type', '!=', False)]}">
<label for="customer_lead"/>
<div name="lead">
<field name="customer_lead" class="oe_inline"/> days
</div>
<field name="analytic_tag_ids" widget="many2many_tags" groups="analytic.group_analytic_tags" options="{'color_field': 'color'}" domain="['|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"/>
</group>
</group>
<label for="name" string="Description" attrs="{'invisible': [('display_type', '!=', False)]}"/>
<label for="name" string="Section Name (eg. Products, Services)" attrs="{'invisible': [('display_type', '!=', 'line_section')]}"/>
<label for="name" string="Note" attrs="{'invisible': [('display_type', '!=', 'line_note')]}"/>
<field name="name"/>
<div name="invoice_lines" groups="base.group_no_one" attrs="{'invisible': [('display_type', '!=', False)]}">
<label for="invoice_lines"/>
<field name="invoice_lines"/>
</div>
<field name="state" invisible="1"/>
<field name="company_id" invisible="1"/>
</form>
<tree
string="Sales Order Lines"
editable="bottom"
>
<control>
<create name="add_product_control" string="Add a product"/>
<create name="add_section_control" string="Add a section" context="{'default_display_type': 'line_section'}"/>
<create name="add_note_control" string="Add a note" context="{'default_display_type': 'line_note'}"/>
</control>
<field name="sequence" widget="handle" />
<!-- We do not display the type because we don't want the user to be bothered with that information if he has no section or note. -->
<field name="display_type" invisible="1"/>
<field name="product_uom_category_id" invisible="1"/>
<field name="product_updatable" invisible="1"/>
<field
name="product_id"
attrs="{
'readonly': [('product_updatable', '=', False)],
'required': [('display_type', '=', False)],
}"
force_save="1"
context="{
'partner_id': parent.partner_id,
'quantity': product_uom_qty,
'pricelist': parent.pricelist_id,
'uom':product_uom,
'company_id': parent.company_id,
'default_lst_price': price_unit,
'default_description_sale': name
}"
domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"
widget="product_configurator"
/>
<field name="product_template_id"
string="Product"
invisible="1"
attrs="{
'readonly': [('product_updatable', '=', False)],
'required': [('display_type', '=', False)],
}"
context="{
'partner_id': parent.partner_id,
'quantity': product_uom_qty,
'pricelist': parent.pricelist_id,
'uom':product_uom,
'company_id': parent.company_id,
'default_list_price': price_unit,
'default_description_sale': name
}"
domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"
widget="product_configurator"/>
<field name="name" widget="section_and_note_text" optional="show"/>
<field
name="analytic_tag_ids"
optional="hide"
groups="analytic.group_analytic_tags"
widget="many2many_tags"
options="{'color_field': 'color'}"
domain="['|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"
/>
<field
name="product_uom_qty"
decoration-info="(not display_type and invoice_status == 'to invoice')" decoration-bf="(not display_type and invoice_status == 'to invoice')"
context="{
'partner_id': parent.partner_id,
'quantity': product_uom_qty,
'pricelist': parent.pricelist_id,
'uom': product_uom,
'company_id': parent.company_id
}"
/>
<field
name="qty_delivered"
decoration-info="(not display_type and invoice_status == 'to invoice')" decoration-bf="(not display_type and invoice_status == 'to invoice')"
string="Delivered"
attrs="{
'column_invisible': [('parent.state', 'not in', ['sale', 'done'])],
'readonly': [('qty_delivered_method', '!=', 'manual')]
}"
optional="show"
/>
<field name="qty_delivered_method" invisible="1"/>
<field
name="qty_invoiced"
decoration-info="(not display_type and invoice_status == 'to invoice')" decoration-bf="(not display_type and invoice_status == 'to invoice')"
string="Invoiced"
attrs="{'column_invisible': [('parent.state', 'not in', ['sale', 'done'])]}"
optional="show"
/>
<field name="qty_to_invoice" invisible="1"/>
<field name="product_uom_readonly" invisible="1"/>
<field
name="product_uom"
force_save="1"
string="UoM"
attrs="{
'readonly': [('product_uom_readonly', '=', True)],
'required': [('display_type', '=', False)],
}"
context="{'company_id': parent.company_id}"
groups="uom.group_uom"
options='{"no_open": True}'
optional="show"
/>
<field
name="customer_lead"
optional="hide"
attrs="{'readonly': [('parent.state', 'not in', ['draft', 'sent', 'sale'])]}"
/>
<field name="product_packaging_qty" attrs="{'invisible': ['|', ('product_id', '=', False), ('product_packaging_id', '=', False)]}" groups="product.group_stock_packaging" optional="show"/>
<field name="product_packaging_id" attrs="{'invisible': [('product_id', '=', False)]}" context="{'default_product_id': product_id, 'tree_view_ref':'product.product_packaging_tree_view', 'form_view_ref':'product.product_packaging_form_view'}" groups="product.group_stock_packaging" optional="show"/>
<field
name="price_unit"
attrs="{'readonly': [('qty_invoiced', '&gt;', 0)]}"
/>
<field
name="tax_id"
widget="many2many_tags"
options="{'no_create': True}"
domain="[('type_tax_use','=','sale'),('company_id','=',parent.company_id), ('country_id', '=', parent.tax_country_id)]"
attrs="{'readonly': [('qty_invoiced', '&gt;', 0)]}"
optional="show"
/>
<field name="discount" string="Disc.%" groups="product.group_discount_per_so_line" optional="show" widget="product_discount"/>
<field name="price_subtotal" widget="monetary" groups="account.group_show_line_subtotals_tax_excluded"/>
<field name="price_total" widget="monetary" groups="account.group_show_line_subtotals_tax_included"/>
<field name="state" invisible="1"/>
<field name="invoice_status" invisible="1"/>
<field name="currency_id" invisible="1"/>
<field name="price_tax" invisible="1"/>
<field name="company_id" invisible="1"/>
</tree>
<kanban class="o_kanban_mobile">
<field name="name"/>
<field name="product_id"/>
<field name="product_uom_qty"/>
<field name="product_uom" groups="uom.group_uom"/>
<field name="price_subtotal"/>
<field name="price_total"/>
<field name="price_tax" invisible="1"/>
<field name="price_total" invisible="1"/>
<field name="price_unit"/>
<field name="display_type"/>
<field name="tax_id" invisible="1"/>
<field name="company_id" invisible="1"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_card oe_kanban_global_click pl-0 pr-0 {{ record.display_type.raw_value ? 'o_is_' + record.display_type.raw_value : '' }}">
<t t-if="!record.display_type.raw_value">
<div class="row no-gutters">
<div class="col-2 pr-3">
<img t-att-src="kanban_image('product.product', 'image_128', record.product_id.raw_value)" t-att-title="record.product_id.value" t-att-alt="record.product_id.value" style="max-width: 100%;"/>
</div>
<div class="col-10">
<div class="row">
<div class="col">
<strong t-esc="record.product_id.value" />
</div>
<div class="col-auto">
<t t-set="line_price" t-value="record.price_subtotal.value" groups="account.group_show_line_subtotals_tax_excluded"/>
<t t-set="line_price" t-value="record.price_total.value" groups="account.group_show_line_subtotals_tax_included"/>
<strong class="float-right text-right" t-esc="line_price" />
</div>
</div>
<div class="row">
<div class="col-12 text-muted">
Quantity:
<t t-esc="record.product_uom_qty.value"/>
<t t-esc="record.product_uom.value"/>
</div>
</div>
<div class="row">
<div class="col-12 text-muted">
Unit Price:
<t t-esc="record.price_unit.value"/>
</div>
</div>
</div>
</div>
</t>
<t t-if="record.display_type.raw_value === 'line_section' || record.display_type.raw_value === 'line_note'">
<div class="row">
<div class="col-12">
<t t-esc="record.name.value"/>
</div>
</div>
</t>
</div>
</t>
</templates>
</kanban>
</field>
<group name="note_group" col="6" class="mt-2 mt-md-0">
<group colspan="4">
<field name="note" nolabel="1" placeholder="Terms and conditions..."/>
</group>
<group class="oe_subtotal_footer oe_right" colspan="2" name="sale_total">
<field name="tax_totals_json" widget="account-tax-totals-field" nolabel="1" colspan="2"/>
</group>
<div class="oe_clear"/>
</group>
</page>
<page string="Other Info" name="other_information">
<group>
<group name="sales_person" string="Sales">
<field name="user_id" domain="[('share', '=', False)]" widget="many2one_avatar_user"/>
<field name="team_id" kanban_view_ref="%(sales_team.crm_team_view_kanban)s" options="{'no_create': True}"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field name="require_signature"/>
<field name="require_payment"/>
<field name="reference" readonly="1" attrs="{'invisible': [('reference', '=', False)]}"/>
<field name="client_order_ref"/>
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color', 'no_create_edit': True}"/>
</group>
<group name="sale_info" string="Invoicing">
<field name="fiscal_position_id" options="{'no_create': True}"/>
<field name="analytic_account_id" context="{'default_partner_id':partner_invoice_id, 'default_name':name}" attrs="{'readonly': [('invoice_count','!=',0),('state','=','sale')]}" groups="analytic.group_analytic_accounting" force_save="1"/>
<field name="invoice_status" states="sale,done" groups="base.group_no_one"/>
</group>
</group>
<group>
<group name="sale_shipping">
<label for="commitment_date" string="Delivery Date"/>
<div name="commitment_date_div" class="o_row">
<field name="commitment_date"/>
<span name="expected_date_span" class="text-muted">Expected: <field name="expected_date" widget="date"/></span>
</div>
</group>
<group string="Tracking" name="sale_reporting">
<group name="technical" colspan="2" class="mb-0">
<field name="origin"/>
</group>
<group name="utm_link" colspan="2" class="mt-0">
<field name="campaign_id"/>
<field name="medium_id"/>
<field name="source_id"/>
</group>
</group>
</group>
</page>
<page groups="base.group_no_one" string="Customer Signature" name="customer_signature" attrs="{'invisible': [('require_signature', '=', False), ('signed_by', '=', False), ('signature', '=', False), ('signed_on', '=', False)]}">
<group>
<field name="signed_by"/>
<field name="signed_on"/>
<field name="signature" widget="image"/>
</group>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="activity_ids"/>
<field name="message_ids"/>
</div>
</form>
</field>
</record>
<record id="view_sales_order_auto_done_setting" model="ir.ui.view">
<field name="name">sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="groups_id" eval="[(4, ref('sale.group_auto_done_setting'))]"/>
<field name="arch" type="xml">
<button name="action_draft" position="after">
<button name="action_done" type="object" string="Lock"
states="sale"
help="If the sale is locked, you can not modify it anymore. However, you will still be able to invoice or deliver." groups="sales_team.group_sale_manager"/>
<button name="action_unlock" type="object" string="Unlock"
states="done"
groups="sales_team.group_sale_manager"/>
</button>
</field>
</record>
<record id="view_sales_order_filter" model="ir.ui.view">
<field name="name">sale.order.list.select</field>
<field name="model">sale.order</field>
<field name="priority" eval="15"/>
<field name="arch" type="xml">
<search string="Search Sales Order">
<field name="name" string="Order"
filter_domain="['|', '|', ('name', 'ilike', self), ('client_order_ref', 'ilike', self), ('partner_id', 'child_of', self)]"/>
<field name="partner_id" operator="child_of"/>
<field name="user_id"/>
<field name="team_id" string="Sales Team"/>
<field name="order_line" string="Product" filter_domain="[('order_line.product_id', 'ilike', self)]"/>
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
<!-- We only allow to search on the following sale order line fields (product, name) because the other fields, such as price, quantity, ...
will not be searched as often, and if they need to be searched it's usually in the context of products
and then they can be searched from the page listing the sale order lines related to a product (from the product itself).
-->
<filter string="My Orders" domain="[('user_id', '=', uid)]" name="my_sale_orders_filter"/>
<filter invisible="1" string="Late Activities" name="activities_overdue"
domain="[('my_activity_date_deadline', '&lt;', context_today().strftime('%Y-%m-%d'))]"
help="Show all records which has next action date is before today"/>
<filter invisible="1" string="Today Activities" name="activities_today"
domain="[('my_activity_date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
<filter invisible="1" string="Future Activities" name="activities_upcoming_all"
domain="[('my_activity_date_deadline', '&gt;', context_today().strftime('%Y-%m-%d'))]"/>
<group expand="0" string="Group By">
<filter string="Salesperson" name="salesperson" domain="[]" context="{'group_by': 'user_id'}"/>
<filter name="customer" string="Customer" domain="[]" context="{'group_by': 'partner_id'}"/>
<filter string="Order Date" name="order_month" domain="[]" context="{'group_by': 'date_order'}"/>
</group>
</search>
</field>
</record>
<record id="sale_order_view_search_inherit_quotation" model="ir.ui.view">
<field name="name">sale.order.search.inherit.quotation</field>
<field name="model">sale.order</field>
<field name="mode">primary</field>
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
<field name="arch" type="xml">
<filter name="my_sale_orders_filter" position="replace">
<field name="campaign_id"/>
<separator/>
<filter string="My Quotations" name="my_quotation" domain="[('user_id', '=', uid)]"/>
<separator/>
<filter string="Quotations" name="draft" domain="[('state','in',('draft', 'sent'))]"/>
<filter string="Sales Orders" name="sales" domain="[('state','in',('sale','done'))]"/>
<separator/>
<filter string="Create Date" name="filter_create_date" date="create_date"/>
</filter>
</field>
</record>
<record id="sale_order_view_search_inherit_sale" model="ir.ui.view">
<field name="name">sale.order.search.inherit.sale</field>
<field name="model">sale.order</field>
<field name="mode">primary</field>
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
<field name="arch" type="xml">
<filter name="my_sale_orders_filter" position="after">
<separator/>
<filter string="To Invoice" name="to_invoice" domain="[('invoice_status','=','to invoice')]" />
<filter string="To Upsell" name="upselling" domain="[('invoice_status','=','upselling')]" />
<separator/>
<filter string="Order Date" name="order_date" date="date_order"/>
</filter>
</field>
</record>
<!-- ACTIONS (WINDOW) -->
<record id="action_orders" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
<field name="search_view_id" ref="sale_order_view_search_inherit_sale"/>
<field name="context">{}</field>
<field name="domain">[('state', 'not in', ('draft', 'sent', 'cancel'))]</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<record id="sale_order_action_view_order_tree" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="sale.view_order_tree"/>
<field name="act_window_id" ref="action_orders"/>
</record>
<record id="sale_order_action_view_order_kanban" model="ir.actions.act_window.view">
<field name="sequence" eval="2"/>
<field name="view_mode">kanban</field>
<field name="view_id" ref="sale.view_sale_order_kanban"/>
<field name="act_window_id" ref="action_orders"/>
</record>
<record id="sale_order_action_view_order_form" model="ir.actions.act_window.view">
<field name="sequence" eval="3"/>
<field name="view_mode">form</field>
<field name="view_id" ref="sale.view_order_form"/>
<field name="act_window_id" ref="action_orders"/>
</record>
<record id="sale_order_action_view_order_calendar" model="ir.actions.act_window.view">
<field name="sequence" eval="4"/>
<field name="view_mode">calendar</field>
<field name="view_id" ref="sale.view_sale_order_calendar"/>
<field name="act_window_id" ref="action_orders"/>
</record>
<record id="sale_order_action_view_order_pivot" model="ir.actions.act_window.view">
<field name="sequence" eval="5"/>
<field name="view_mode">pivot</field>
<field name="view_id" ref="sale.view_sale_order_pivot"/>
<field name="act_window_id" ref="action_orders"/>
</record>
<record id="sale_order_action_view_order_graph" model="ir.actions.act_window.view">
<field name="sequence" eval="6"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="sale.view_sale_order_graph"/>
<field name="act_window_id" ref="action_orders"/>
</record>
<record id="action_quotations_with_onboarding" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_id" ref="view_quotation_tree_with_onboarding"/>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
<field name="search_view_id" ref="sale_order_view_search_inherit_quotation"/>
<field name="context">{'search_default_my_quotation': 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed by the customer, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<record id="action_quotations" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
<field name="search_view_id" ref="sale_order_view_search_inherit_quotation"/>
<field name="context">{'search_default_my_quotation': 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed by the customer, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<record id="sale_order_action_view_quotation_tree" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="sale.view_quotation_tree"/>
<field name="act_window_id" ref="action_quotations"/>
</record>
<record id="sale_order_action_view_quotation_kanban" model="ir.actions.act_window.view">
<field name="sequence" eval="2"/>
<field name="view_mode">kanban</field>
<field name="view_id" ref="sale.view_sale_order_kanban"/>
<field name="act_window_id" ref="action_quotations"/>
</record>
<record id="sale_order_action_view_quotation_form" model="ir.actions.act_window.view">
<field name="sequence" eval="3"/>
<field name="view_mode">form</field>
<field name="view_id" ref="sale.view_order_form"/>
<field name="act_window_id" ref="action_quotations"/>
</record>
<record id="sale_order_action_view_quotation_calendar" model="ir.actions.act_window.view">
<field name="sequence" eval="4"/>
<field name="view_mode">calendar</field>
<field name="view_id" ref="sale.view_sale_order_calendar"/>
<field name="act_window_id" ref="action_quotations"/>
</record>
<record id="sale_order_action_view_quotation_pivot" model="ir.actions.act_window.view">
<field name="sequence" eval="5"/>
<field name="view_mode">pivot</field>
<field name="view_id" ref="sale.view_sale_order_pivot"/>
<field name="act_window_id" ref="action_quotations"/>
</record>
<record id="sale_order_action_view_quotation_graph" model="ir.actions.act_window.view">
<field name="sequence" eval="6"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="sale.view_sale_order_graph"/>
<field name="act_window_id" ref="action_quotations"/>
</record>
<record id="action_orders_to_invoice" model="ir.actions.act_window">
<field name="name">Orders to Invoice</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,calendar,graph,pivot,kanban,activity</field>
<field name="context">{'create': False}</field>
<field name="domain">[('invoice_status','=','to invoice')]</field>
<field name="search_view_id" ref="view_sales_order_filter"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No orders to invoice found
</p><p>
You can select all orders and invoice them in batch,<br/>
or check every order and invoice them one by one.
</p>
</field>
</record>
<record id="action_orders_upselling" model="ir.actions.act_window">
<field name="name">Orders to Upsell</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form,calendar,graph,pivot,kanban,activity</field>
<field name="domain">[('invoice_status','=','upselling')]</field>
<field name="context">{'create': False}</field>
<field name="search_view_id" ref="view_sales_order_filter"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No orders to upsell found.
</p><p>
An order is to upsell when delivered quantities are above initially
ordered quantities, and the invoicing policy is based on ordered quantities.
</p><p>
As an example, if you sell pre-paid hours of services, Odoo recommends you
to sell extra hours when all ordered hours have been consumed.
</p>
</field>
</record>
<!-- ACTIONS (SERVER) -->
<record id="model_sale_order_action_quotation_sent" model="ir.actions.server">
<field name="name">Mark Quotation as Sent</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="binding_model_id" ref="sale.model_sale_order"/>
<field name="binding_view_types">form,list</field>
<field name="state">code</field>
<field name="code">action = records.action_quotation_sent()</field>
</record>
</odoo>
+90 -49
View File
@@ -40,9 +40,6 @@
<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>
<t t-if="quotations" t-call="portal.portal_table">
<thead>
<tr class="active">
@@ -59,8 +56,10 @@
<td class="text-right"><span t-field="quotation.date_order"/></td>
<td class="text-right"><span t-field="quotation.validity_date"/></td>
<td class="text-center">
<span t-if="quotation.state == 'cancel'" class="badge badge-pill badge-secondary"><i class="fa fa-fw fa-remove"/> Cancelled</span>
<span t-if="quotation.is_expired" class="badge badge-pill badge-secondary"><i class="fa fa-fw fa-clock-o"/> Expired</span>
<span t-if="quotation.state == 'cancel'" class="badge badge-pill badge-secondary">
<i class="fa fa-fw fa-remove"/> Cancelled</span>
<span t-if="quotation.is_expired" class="badge badge-pill badge-secondary">
<i class="fa fa-fw fa-clock-o"/> Expired</span>
</td>
<td class="text-right">
<span t-field="quotation.amount_total"/>
@@ -68,6 +67,7 @@
</tr>
</t>
</t>
<p t-else="">There are currently no quotations for your account.</p>
</t>
</template>
@@ -78,9 +78,6 @@
<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>
<t t-if="orders" t-call="portal.portal_table">
<thead>
<tr class="active">
@@ -109,6 +106,7 @@
</tr>
</t>
</t>
<p t-else="">There are currently no orders for your account.</p>
</t>
</template>
@@ -177,14 +175,21 @@
</t>
<li t-if="sale_order.user_id" class="list-group-item flex-grow-1">
<div class="small mb-1"><strong class="text-muted">Salesperson</strong></div>
<div class="small mb-1">
<strong class="text-muted">Salesperson</strong>
</div>
<div class="row flex-nowrap">
<div class="col flex-grow-0 pr-2">
<img class="rounded-circle mr4 float-left o_portal_contact_img" t-att-src="image_data_uri(sale_order.user_id.avatar_1024)" alt="Contact"/>
<img class="rounded-circle mr4 float-left o_portal_contact_img"
t-att-src="image_data_uri(sale_order.user_id.avatar_1024)"
alt="Contact"/>
</div>
<div class="col pl-0" style="min-width: 150px">
<span t-field="sale_order.user_id" t-options='{"widget": "contact", "fields": ["name", "phone"], "no_marker": True}'/>
<a href="#discussion" class="small"><i class="fa fa-comment"></i> Send message</a>
<span t-field="sale_order.user_id"
t-options='{"widget": "contact", "fields": ["name", "phone"], "no_marker": True}'/>
<a href="#discussion" class="small">
<i class="fa fa-comment"></i> Send message
</a>
</div>
</div>
</li>
@@ -208,9 +213,15 @@
<p>
<span>By signing this proposal, I agree to the following terms:</span>
<ul>
<li><span>Accepted on the behalf of:</span> <b t-field="sale_order.partner_id.commercial_partner_id"/></li>
<li><span>For an amount of:</span> <b data-id="total_amount" t-field="sale_order.amount_total"/></li>
<li t-if="sale_order.payment_term_id"><span>With payment terms:</span> <b t-field="sale_order.payment_term_id.note"/></li>
<li>
<span>Accepted on the behalf of:</span> <b t-field="sale_order.partner_id.commercial_partner_id"/>
</li>
<li>
<span>For an amount of:</span> <b data-id="total_amount" t-field="sale_order.amount_total"/>
</li>
<li t-if="sale_order.payment_term_id">
<span>With payment terms:</span> <b t-field="sale_order.payment_term_id.note"/>
</li>
</ul>
</p>
<t t-call="portal.signature_form">
@@ -231,9 +242,15 @@
<p>
<span>By paying this proposal, I agree to the following terms:</span>
<ul>
<li><span>Accepted on the behalf of:</span> <b t-field="sale_order.partner_id.commercial_partner_id"/></li>
<li><span>For an amount of:</span> <b data-id="total_amount" t-field="sale_order.amount_total"/></li>
<li t-if="sale_order.payment_term_id"><span>With payment terms:</span> <b t-field="sale_order.payment_term_id.note"/></li>
<li>
<span>Accepted on the behalf of:</span> <b t-field="sale_order.partner_id.commercial_partner_id"/>
</li>
<li>
<span>For an amount of:</span> <b data-id="total_amount" t-field="sale_order.amount_total"/>
</li>
<li t-if="sale_order.payment_term_id">
<span>With payment terms:</span> <b t-field="sale_order.payment_term_id.note"/>
</li>
</ul>
</p>
<div t-if="acquirers or tokens" id="payment_method" class="text-left">
@@ -265,8 +282,12 @@
<textarea rows="4" name="decline_message" required="" placeholder="Your feedback..." class="form-control" />
</main>
<footer class="modal-footer">
<button type="submit" t-att-id="sale_order.id" class="btn btn-danger"><i class="fa fa-times"></i> Reject</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
<button type="submit" t-att-id="sale_order.id" class="btn btn-danger">
<i class="fa fa-times"></i> Reject
</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">
Cancel
</button>
</footer>
</form>
</div>
@@ -276,8 +297,12 @@
<div t-if="message == 'sign_ok'" class="alert alert-success alert-dismissable d-print-none" role="status">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">×</button>
<strong>Thank You!</strong><br/>
<t t-if="message == 'sign_ok' and sale_order.state in ['sale', 'done']">Your order has been confirmed.</t>
<t t-elif="message == 'sign_ok' and sale_order.has_to_be_paid()">Your order has been signed but still needs to be paid to be confirmed.</t>
<t t-if="message == 'sign_ok' and sale_order.state in ['sale', 'done']">
Your order has been confirmed.
</t>
<t t-elif="message == 'sign_ok' and sale_order.has_to_be_paid()">
Your order has been signed but still needs to be paid to be confirmed.
</t>
<t t-else="">Your order has been signed.</t>
</div>
@@ -380,19 +405,29 @@
</div>
<div class="row">
<div class="col-lg-6">
<strong t-if="sale_order.partner_shipping_id == sale_order.partner_invoice_id" class="d-block mb-1">Invoicing and Shipping Address:</strong>
<strong t-if="sale_order.partner_shipping_id != sale_order.partner_invoice_id" class="d-block mb-1">Invoicing Address:</strong>
<address t-field="sale_order.partner_invoice_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
<strong class="d-block mb-1">
<t t-if="sale_order.partner_shipping_id == sale_order.partner_invoice_id">
Invoicing and Shipping Address:
</t>
<t t-else="">
Invoicing Address:
</t>
</strong>
<address t-field="sale_order.partner_invoice_id"
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
</div>
<div t-if="sale_order.partner_shipping_id != sale_order.partner_invoice_id"
id="shipping_address"
class="col-lg-6">
<strong class="d-block mb-1">
Shipping Address:
</strong>
<address t-field="sale_order.partner_shipping_id"
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
</div>
<t t-if="sale_order.partner_shipping_id != sale_order.partner_invoice_id">
<div id="shipping_address" class="col-lg-6">
<strong class="d-block mb-1">Shipping Address:</strong>
<address t-field="sale_order.partner_shipping_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'/>
</div>
</t>
</div>
<t t-set="invoices" t-value="[i for i in sale_order.invoice_ids if i.state not in ['draft', 'cancel']]"/>
<t t-set="invoices" t-value="sale_order.invoice_ids.filtered(lambda i: i.state not in ['draft', 'cancel'])"/>
<div t-if="invoices" class="row">
<div class="col">
<strong class="d-block mb-1">Invoices</strong>
@@ -406,8 +441,12 @@
</a>
<div class="small d-lg-inline-block">Date: <span class="text-muted" t-field="i.invoice_date"/></div>
</div>
<span t-if="i.payment_state in ('paid', 'in_payment')" class="small badge badge-success orders_label_text_align"><i class="fa fa-fw fa-check"/> <b>Paid</b></span>
<span t-else="" class="small badge badge-info orders_label_text_align"><i class="fa fa-fw fa-clock-o"/> <b>Waiting Payment</b></span>
<span t-if="i.payment_state in ('paid', 'in_payment')" class="small badge badge-success orders_label_text_align">
<i class="fa fa-fw fa-check"/> <b>Paid</b>
</span>
<span t-else="" class="small badge badge-info orders_label_text_align">
<i class="fa fa-fw fa-clock-o"/> <b>Waiting Payment</b>
</span>
</div>
</t>
</ul>
@@ -425,7 +464,9 @@
<tr>
<th class="text-left">Products</th>
<th class="text-right">Quantity</th>
<th t-attf-class="text-right {{ 'd-none d-sm-table-cell' if report_type == 'html' else '' }}">Unit Price</th>
<th t-attf-class="text-right {{ 'd-none d-sm-table-cell' if report_type == 'html' else '' }}">
Unit Price
</th>
<th t-if="display_discount" t-attf-class="text-right {{ 'd-none d-sm-table-cell' if report_type == 'html' else '' }}">
<span>Disc.%</span>
</th>
@@ -449,7 +490,9 @@
<tr t-att-class="'bg-200 font-weight-bold o_line_section' if line.display_type == 'line_section' else 'font-italic o_line_note' if line.display_type == 'line_note' else ''">
<t t-if="not line.display_type">
<td id="product_name"><span t-field="line.name"/></td>
<td id="product_name">
<span t-field="line.name"/>
</td>
<td class="text-right">
<div id="quote_qty">
<span t-field="line.product_uom_qty"/>
@@ -494,17 +537,15 @@
</t>
</tr>
<t t-if="current_section and (line_last or sale_order.order_line[line_index+1].display_type == 'line_section')">
<tr class="is-subtotal text-right">
<td colspan="99">
<strong class="mr16">Subtotal</strong>
<span
t-esc="current_subtotal"
t-options='{"widget": "monetary", "display_currency": sale_order.pricelist_id.currency_id}'
/>
</td>
</tr>
</t>
<tr t-if="current_section and (line_last or sale_order.order_line[line_index+1].display_type == 'line_section')"
class="is-subtotal text-right">
<td colspan="99">
<strong class="mr16">Subtotal</strong>
<span t-esc="current_subtotal"
t-options='{"widget": "monetary", "display_currency": sale_order.pricelist_id.currency_id}'
/>
</td>
</tr>
</t>
</tbody>
</table>
@@ -526,7 +567,7 @@
</div>
</section>
<section id="terms" class="mt-5" t-if="not is_html_empty(sale_order.note)">
<section t-if="not is_html_empty(sale_order.note)" id="terms" class="mt-5">
<h3 class="">Terms &amp; Conditions</h3>
<hr class="mt-0 mb-1"/>
<t t-if="sale_order.terms_type == 'html'">
@@ -539,7 +580,7 @@
</t>
</section>
<section class="mt-5" t-if="sale_order.payment_term_id">
<section t-if="sale_order.payment_term_id" class="mt-5">
<h3 class="">Payment terms</h3>
<hr class="mt-0 mb-1"/>
<span t-field="sale_order.payment_term_id"/>
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -4,6 +4,6 @@
from . import account_payment_register
from . import mail_compose_message
from . import payment_acquirer_onboarding_wizard
from . import payment_link_wizard
from . import sale_make_invoice_advance
from . import sale_order_cancel
from . import sale_payment_link
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="action_accrued_revenue_entry" model="ir.actions.act_window">
<field name="name">Accrued Revenue Entry</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.accrued.orders.wizard</field>
<field name="view_mode">form</field>
<field name="binding_model_id" ref="sale.model_sale_order"/>
<field name="groups_id" eval="[(4, ref('account.group_account_user'))]"/>
<field name="target">new</field>
</record>
</odoo>
+15 -8
View File
@@ -38,17 +38,24 @@ The Dashboard for the Sales Manager will include
'website': 'https://www.odoo.com/app/sales',
'depends': ['sale', 'digest'],
'data': [
'security/sale_management_security.xml',
# TODO VFE add data validation on manifest loading
# We were loading digest_data twice...
'data/digest_data.xml',
'views/sale_portal_templates.xml',
'views/sale_order_template_views.xml',
'security/ir.model.access.csv',
'views/res_config_settings_views.xml',
'data/digest_data.xml',
'views/sale_management_views.xml',
'views/digest_views.xml',
'views/sale_order_views.xml',
'security/sale_management_security.xml',
'report/sale_report_templates.xml',
# Define SO template views & actions before their place of use
'views/sale_order_template_views.xml',
'views/digest_views.xml',
'views/res_config_settings_views.xml',
'views/sale_order_views.xml',
'views/sale_portal_templates.xml',
'views/sale_management_menus.xml',
],
'demo': [
'data/sale_order_template_demo.xml',
@@ -1,18 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="digest_digest_view_form" model="ir.ui.view">
<field name="name">digest.digest.view.form.inherit.sale.order</field>
<field name="model">digest.digest</field>
<field name="priority">10</field>
<field name="inherit_id" ref="digest.digest_digest_view_form" />
<field name="arch" type="xml">
<xpath expr="//group[@name='kpi_sales']" position="attributes">
<group name="kpi_sales" position="attributes">
<attribute name="string">Sales</attribute>
<attribute name="groups">sales_team.group_sale_salesman_all_leads</attribute>
</xpath>
<xpath expr="//group[@name='kpi_sales']" position="inside">
</group>
<group name="kpi_sales" position="inside">
<field name="kpi_all_sale_total"/>
</xpath>
</group>
</field>
</record>
</odoo>
@@ -47,4 +47,15 @@
</field>
</record>
<record id="res_config_settings_view_form_inherit_sale_management" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.sale.management</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="sale.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@data-key='sale_management']" position="attributes">
<attribute name="class">app_settings_block</attribute>
</xpath>
</field>
</record>
</odoo>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="sale.sale_menu_root" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<menuitem id="sale_order_template_menu"
name="Quotation Templates"
action="sale_order_template_action"
parent="sale.menu_sales_config"
groups="sale_management.group_sale_order_template"
sequence="1"/>
</odoo>
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="sale.sale_menu_root" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_report_product_all" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_sales_config" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.product_menu_catalog" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_product" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_product_template_action" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.prod_config_main" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_products" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.next_id_16" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_product_uom_categ_form_action" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_product_pricelist_main" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_sale_order" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_sale_invoicing" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_sale_order_invoice" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_sale_order_upselling" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="sale.menu_sale_quotations" model="ir.ui.menu">
<field name="active" eval="True"/>
</record>
<record id="res_config_settings_view_form_inherit_sale_management" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.sale.management</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="sale.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@data-key='sale_management']" position="attributes">
<attribute name="class">app_settings_block</attribute>
</xpath>
</field>
</record>
</odoo>
@@ -144,6 +144,4 @@
</field>
</record>
<menuitem id="sale_order_template_menu" action="sale_order_template_action" parent="sale.menu_sales_config" sequence="1" name="Quotation Templates" groups="sale_management.group_sale_order_template"/>
</odoo>
@@ -1,17 +1,20 @@
<?xml version="1.0"?>
<odoo>
<record id="sale_order_form_quote" model="ir.ui.view">
<field name="name">sale.order.form.payment</field>
<field name="name">sale.order.form.inherit.sale_management</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//page/field[@name='order_line']/.." position="after">
<page string="Optional Products" name="optional_products" attrs="{'invisible': [('state', 'not in', ['draft', 'sent'])]}">
<page name="order_lines" position="after">
<page string="Optional Products"
name="optional_products"
attrs="{'invisible': [('state', 'not in', ['draft', 'sent'])]}">
<field name="sale_order_option_ids" mode="tree,form,kanban">
<form string="Optional Products">
<group>
<field name="product_id" domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"/>
<field name="product_id"
domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"/>
<field name="name"/>
<field name="quantity"/>
<field name="product_uom_category_id" invisible="1"/>
@@ -39,7 +42,11 @@
</strong>
</div>
<div class="col-2">
<button name="button_add_to_order" class="btn btn-link oe_link fa fa-shopping-cart" title="Add to order lines" type="object" attrs="{'invisible': [('is_present', '=', True)]}"/>
<button name="button_add_to_order"
class="btn btn-link oe_link fa fa-shopping-cart"
title="Add to order lines"
type="object"
attrs="{'invisible': [('is_present', '=', True)]}"/>
</div>
</div>
<div class="row">
@@ -63,47 +70,43 @@
</t>
</templates>
</kanban>
<tree string="Sales Quotation Template Lines" editable="bottom" decoration-success="is_present == True">
<tree string="Sales Quotation Template Lines"
editable="bottom"
decoration-success="is_present == True">
<control>
<create name="add_product_control" string="Add a product"/>
</control>
<field name="sequence" widget="handle"/>
<field name="product_id" domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"/>
<field name="product_id"
domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', parent.company_id)]"/>
<field name="name" optional="show"/>
<field name="quantity"/>
<field name="uom_id" string="UoM" groups="uom.group_uom" optional="show"/>
<field name="product_uom_category_id" invisible="1"/>
<field name="price_unit"/>
<field name="discount" string="Disc.%" groups="product.group_discount_per_so_line" optional="show"/>
<field name="discount"
string="Disc.%"
groups="product.group_discount_per_so_line"
optional="show"/>
<field name="is_present" invisible="1" />
<button name="button_add_to_order" class="oe_link" icon="fa-shopping-cart" title="Add to order lines" type="object" attrs="{'invisible': [('is_present', '=', True)]}"/>
<button name="button_add_to_order"
type="object"
class="oe_link"
icon="fa-shopping-cart"
title="Add to order lines"
attrs="{'invisible': [('is_present', '=', True)]}"/>
</tree>
</field>
</page>
</xpath>
</page>
<xpath expr="//field[@name='partner_shipping_id']" position="after">
<field name="sale_order_template_id" context="{'company_id': company_id}"
<field name="partner_shipping_id" position="after">
<field name="sale_order_template_id"
options="{'no_create': True, 'no_open': True}"
groups="sale_management.group_sale_order_template"
/>
</xpath>
</field>
</field>
</record>
<record id="sale.action_quotations" model="ir.actions.act_window">
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p>
<p>
Once the quotation is confirmed by the customer, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<menuitem id="menu_product_attribute_action"
action="product.attribute_action"
parent="sale.prod_config_main" groups="product.group_product_variant" sequence="1"/>
</odoo>
+1 -1
View File
@@ -4,7 +4,7 @@
<record id="product_template_form_view_invoice_policy_inherit_sale_project" model="ir.ui.view">
<field name="name">product.template.inherit.sale.projectform</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="sale.product_template_form_view_invoice_policy"/>
<field name="inherit_id" ref="sale.product_template_form_view"/>
<field name="arch" type="xml">
<field name="invoice_policy" position="after">
<field name="service_tracking" required="1" attrs="{'invisible': [('type', '!=', 'service')]}"/>
@@ -3,7 +3,7 @@
<record id="view_product_timesheet_form" model="ir.ui.view">
<field name="name">product.template.timesheet.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="sale.product_template_form_view_invoice_policy"/>
<field name="inherit_id" ref="sale.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_policy']" position="attributes">
<attribute name="invisible">False</attribute>