diff --git a/addons/sale/__manifest__.py b/addons/sale/__manifest__.py index ddc91098081..e7b23a61f1a 100644 --- a/addons/sale/__manifest__.py +++ b/addons/sale/__manifest__.py @@ -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', diff --git a/addons/sale/report/__init__.py b/addons/sale/report/__init__.py index 90248f477ca..4deca10a758 100644 --- a/addons/sale/report/__init__.py +++ b/addons/sale/report/__init__.py @@ -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 diff --git a/addons/sale/report/invoice_report.py b/addons/sale/report/account_invoice_report.py similarity index 61% rename from addons/sale/report/invoice_report.py rename to addons/sale/report/account_invoice_report.py index f41cc8c3f7f..cf751da997e 100644 --- a/addons/sale/report/invoice_report.py +++ b/addons/sale/report/account_invoice_report.py @@ -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" diff --git a/addons/sale/report/account_invoice_report_views.xml b/addons/sale/report/account_invoice_report_views.xml new file mode 100644 index 00000000000..90fc3f2517c --- /dev/null +++ b/addons/sale/report/account_invoice_report_views.xml @@ -0,0 +1,37 @@ + + + + + account.invoice.report.search.inherit + account.invoice.report + + + + + + + + + + + + + account.invoice.report.view.tree.inherit.sale + account.invoice.report + + + + + + + + + + Invoices Analysis + account.invoice.report + graph + [('state', 'not in', ['draft', 'cancel'])] + {'search_default_month':1, 'search_default_team_id': [active_id]} + 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. + + diff --git a/addons/sale/report/ir_actions_report.xml b/addons/sale/report/ir_actions_report.xml new file mode 100644 index 00000000000..ff5fbbe635f --- /dev/null +++ b/addons/sale/report/ir_actions_report.xml @@ -0,0 +1,27 @@ + + + + + Quotation / Order + sale.order + qweb-pdf + sale.report_saleorder + sale.report_saleorder + (object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name) + + report + + + + PRO-FORMA Invoice + sale.order + qweb-pdf + sale.report_saleorder_pro_forma + sale.report_saleorder_pro_forma + 'PRO-FORMA - %s' % (object.name) + + report + + + + diff --git a/addons/sale/report/sale_report_templates.xml b/addons/sale/report/ir_actions_report_templates.xml similarity index 85% rename from addons/sale/report/sale_report_templates.xml rename to addons/sale/report/ir_actions_report_templates.xml index f6d0ba612a0..2c98288aeb8 100644 --- a/addons/sale/report/sale_report_templates.xml +++ b/addons/sale/report/ir_actions_report_templates.xml @@ -13,10 +13,16 @@ and doc.partner_invoice_id != doc.partner_id or doc.partner_shipping_id != doc.partner_invoice_id"> - Invoicing and Shipping Address: - Invoicing Address: + + + Invoicing and Shipping Address: + + + Invoicing Address: + +
+ t-options='{"widget": "contact", "fields": ["address", "name", "phone"], "no_marker": True, "phone_icons": True}'/> Shipping Address:

- - Order # - Quotation # - - - Pro-Forma Invoice # - + Pro-Forma Invoice # + Quotation # + Order #

-
+
Your Reference:

-
- Order Date: -

-

-
- Quotation Date: +
+ Quotation Date: + Order Date:

-
+
Expiration:

@@ -111,14 +112,14 @@ - + - + @@ -170,7 +171,8 @@

-

+

Fiscal Position Remark:

diff --git a/addons/sale/report/report_all_channels_sales.py b/addons/sale/report/report_all_channels_sales.py deleted file mode 100644 index b5355b4d776..00000000000 --- a/addons/sale/report/report_all_channels_sales.py +++ /dev/null @@ -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()) diff --git a/addons/sale/report/report_all_channels_sales_views.xml b/addons/sale/report/report_all_channels_sales_views.xml deleted file mode 100644 index e6f3cc065ef..00000000000 --- a/addons/sale/report/report_all_channels_sales_views.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - Sales Analysis - sale.report - pivot - - diff --git a/addons/sale/report/sale_report.py b/addons/sale/report/sale_report.py index 1e623181231..7bb5546e9e4 100644 --- a/addons/sale/report/sale_report.py +++ b/addons/sale/report/sale_report.py @@ -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 - } diff --git a/addons/sale/report/sale_report.xml b/addons/sale/report/sale_report.xml deleted file mode 100644 index e3160d14d83..00000000000 --- a/addons/sale/report/sale_report.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - Quotation / Order - sale.order - qweb-pdf - sale.report_saleorder - sale.report_saleorder - (object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name) - - report - - - - PRO-FORMA Invoice - sale.order - qweb-pdf - sale.report_saleorder_pro_forma - sale.report_saleorder_pro_forma - 'PRO-FORMA - %s' % (object.name) - - report - - - - diff --git a/addons/sale/report/sale_report_views.xml b/addons/sale/report/sale_report_views.xml index 33bfcdfe7b4..2300f7a4619 100644 --- a/addons/sale/report/sale_report_views.xml +++ b/addons/sale/report/sale_report_views.xml @@ -49,8 +49,8 @@ - - + + @@ -73,7 +73,7 @@ - + {'search_default_Sales':1, 'group_by_no_leaf':1,'group_by':[]} 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. + + + Sales Analysis + sale.report + pivot + + + + Quotations Analysis + sale.report + graph + [('state','=','draft'),('team_id', '=', active_id)] + {'search_default_order_month':1} + 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. + + + + Sales Analysis + sale.report + graph + [('state','not in',('draft','cancel'))] + { + 'search_default_Sales': 1, + 'search_default_filter_date': 1, + 'search_default_team_id': [active_id]} + 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. + diff --git a/addons/sale/security/ir.model.access.csv b/addons/sale/security/ir.model.access.csv index e6b7d46fcb9..2648ea4aa65 100644 --- a/addons/sale/security/ir.model.access.csv +++ b/addons/sale/security/ir.model.access.csv @@ -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 diff --git a/addons/sale/views/account_views.xml b/addons/sale/views/account_views.xml new file mode 100644 index 00000000000..0147296f53b --- /dev/null +++ b/addons/sale/views/account_views.xml @@ -0,0 +1,94 @@ + + + + + account.move.groupby + account.move + + + + + + + + + + + + + account.move.tree.inherit.sale + account.move + + + + + + + + + + Account Invoice + account.move + + + + + product.group_discount_per_so_line + + + + + + + + + + + + + + + + + Invoices + account.move + tree,form,kanban + + [ + ('state', '=', 'posted'), + ('move_type', 'in', ['out_invoice', 'out_refund'])] + { + 'search_default_team_id': [active_id], + 'default_team_id': active_id, + 'default_move_type':'out_invoice', + 'move_type':'out_invoice', + 'journal_type': 'sale', + } + + + +

+ Create a customer invoice +

+ Create invoices, register payments and keep track of the discussions with your customers. +

+
+
+ + + 1 + tree + + + + + 2 + form + + + + +
diff --git a/addons/sale/views/crm_team_views.xml b/addons/sale/views/crm_team_views.xml index e702e094449..d473b62cd2e 100644 --- a/addons/sale/views/crm_team_views.xml +++ b/addons/sale/views/crm_team_views.xml @@ -1,41 +1,30 @@ - - crm.team.form - crm.team - 9 - - - -
-
-
- - -
-
- - account.invoice.report.search.inherit - account.invoice.report - - - - - - - - - - + + + Quotations + ir.actions.act_window + sale.order + + tree,form,calendar,graph,kanban,pivot + { + 'search_default_team_id': [active_id], + 'default_team_id': active_id, + 'show_address': 1, + } + + [] + + +

+ Create a new quotation, the first step of a new sale! +

+ Once the quotation is confirmed by the customer, it becomes a sales order.
You will be able to create an invoice and collect the payment. +

+
+
- New Quotation sale.order @@ -50,6 +39,64 @@ + + Sales Orders + ir.actions.act_window + sale.order + tree,form,calendar,graph,kanban,pivot + + [('state','not in',('draft','sent','cancel'))] + { + 'search_default_team_id': [active_id], + 'default_team_id': active_id, + } + + +

+ Create a new quotation, the first step of a new sale! +

+ Once the quotation is confirmed by the customer, it becomes a sales order.
You will be able to create an invoice and collect the payment. +

+
+
+ + + Sales Orders + ir.actions.act_window + sale.order + tree,form,calendar,graph,kanban,pivot + + [('invoice_status','=','to invoice')] + { + 'search_default_team_id': [active_id], + 'default_team_id': active_id, + } + + + + + + + crm.team.form + crm.team + 9 + + +
+
+
+
+ + +
+
+ crm.team.view.kanban.dashboard.inherit.sale crm.team @@ -118,7 +165,7 @@
- + diff --git a/addons/sale/views/mail_activity_views.xml b/addons/sale/views/mail_activity_views.xml index e0f453ae228..15b9f2de144 100644 --- a/addons/sale/views/mail_activity_views.xml +++ b/addons/sale/views/mail_activity_views.xml @@ -1,6 +1,6 @@ - + Activity Types mail.activity.type @@ -8,8 +8,5 @@ ['|', ('res_model', '=', False), ('res_model', '=', 'sale.order')] {'default_res_model': 'sale.order'} - - \ No newline at end of file + + diff --git a/addons/sale/views/payment_views.xml b/addons/sale/views/payment_views.xml index c04e203528e..ef3b702d874 100644 --- a/addons/sale/views/payment_views.xml +++ b/addons/sale/views/payment_views.xml @@ -1,30 +1,30 @@ - - - payment.acquirer.form.inherit.sale.payment - payment.acquirer - - - - - - - - - payment.transaction.form.inherit.sale.payment - payment.transaction - - - - - - - - + + payment.acquirer.form.inherit.sale.payment + payment.acquirer + + + + + + + + + + payment.transaction.form.inherit.sale.payment + payment.transaction + + + + + + + + diff --git a/addons/sale/views/product_packaging_views.xml b/addons/sale/views/product_packaging_views.xml index 23b395c90e7..7e5e6795759 100644 --- a/addons/sale/views/product_packaging_views.xml +++ b/addons/sale/views/product_packaging_views.xml @@ -1,13 +1,14 @@ + product.packaging.form.view.sale product.packaging - + - + @@ -16,9 +17,10 @@ product.packaging - + - + + diff --git a/addons/sale/views/product_views.xml b/addons/sale/views/product_views.xml index 82f52914589..2c3ee71f6c1 100644 --- a/addons/sale/views/product_views.xml +++ b/addons/sale/views/product_views.xml @@ -1,24 +1,121 @@ - - product.template.sales + + product.template.form.view.inherit.sale product.template - + 0 - + + + + + + + + + -