diff --git a/addons/pos_sale/report/sale_report.py b/addons/pos_sale/report/sale_report.py
index 151d0ddfa21d9e9a07172f7e8af8ebc75024b796..71b7b9eb872097f88d8a3b7600d87f7a0ac6534d 100644
--- a/addons/pos_sale/report/sale_report.py
+++ b/addons/pos_sale/report/sale_report.py
@@ -112,7 +112,8 @@ class SaleReport(models.Model):
         if not fields:
             fields = {}
         res = super()._query(with_clause, fields, groupby, from_clause)
-        for key in fields:
+        sale_fields = self._select_additional_fields(fields)
+        for key in sale_fields:
             fields[key] = ', NULL as %s' % (key)
         current = '(SELECT %s FROM %s WHERE %s GROUP BY %s)' % \
                   (self._select_pos(fields), self._from_pos(), self._where_pos(), self._group_by_pos())
diff --git a/addons/pos_sale_margin/report/sale_report.py b/addons/pos_sale_margin/report/sale_report.py
index 7411d00f078eadd15790e7b409604b4c2f1889d6..a72f4f0774c03c2c382d1e1eb41c7ed83f73d54a 100644
--- a/addons/pos_sale_margin/report/sale_report.py
+++ b/addons/pos_sale_margin/report/sale_report.py
@@ -8,5 +8,7 @@ class SaleReport(models.Model):
     _inherit = "sale.report"
 
     def _select_pos(self, fields=None):
+        if not fields:
+            fields = {}
         fields['margin'] = ', SUM(l.price_subtotal - l.total_cost / CASE COALESCE(pos.currency_rate, 0) WHEN 0 THEN 1.0 ELSE pos.currency_rate END) AS margin'
         return super()._select_pos(fields)
diff --git a/addons/sale/report/sale_report.py b/addons/sale/report/sale_report.py
index aa8fd9433c7c3eba73fcd94cefccb08eac9983f3..d2825ff26fe74cf33778f60018af44d34a99c7a9 100644
--- a/addons/sale/report/sale_report.py
+++ b/addons/sale/report/sale_report.py
@@ -146,12 +146,23 @@ class SaleReport(models.Model):
         """ % (groupby)
         return groupby_
 
+    def _select_additional_fields(self, fields):
+        """Hook to return additional fields SQL specification for select part of the table query.
+
+        :param dict fields: additional fields info provided by _query overrides (old API), prefer overriding
+            _select_additional_fields instead.
+        :returns: mapping field -> SQL computation of the field
+        :rtype: dict
+        """
+        return fields
+
     def _query(self, with_clause='', fields=None, groupby='', from_clause=''):
         if not fields:
             fields = {}
+        sale_report_fields = self._select_additional_fields(fields)
         with_ = ("WITH %s" % with_clause) if with_clause else ""
         return '%s (SELECT %s FROM %s WHERE l.display_type IS NULL GROUP BY %s)' % \
-               (with_, self._select_sale(fields), self._from_sale(from_clause), self._group_by_sale(groupby))
+               (with_, self._select_sale(sale_report_fields), self._from_sale(from_clause), self._group_by_sale(groupby))
 
     def init(self):
         # self._table = sale_report
diff --git a/addons/sale_margin/report/sale_report.py b/addons/sale_margin/report/sale_report.py
index 1ac87891e97cd35e94430b6f29b9ea5eaacde52c..5aa7b3dbc6dffda164b784a65c3b094f3c12708b 100644
--- a/addons/sale_margin/report/sale_report.py
+++ b/addons/sale_margin/report/sale_report.py
@@ -9,6 +9,6 @@ class SaleReport(models.Model):
 
     margin = fields.Float('Margin')
 
-    def _query(self, with_clause='', fields={}, groupby='', from_clause=''):
+    def _select_additional_fields(self, fields):
         fields['margin'] = ", SUM(l.margin / CASE COALESCE(s.currency_rate, 0) WHEN 0 THEN 1.0 ELSE s.currency_rate END) AS margin"
-        return super(SaleReport, self)._query(with_clause, fields, groupby, from_clause)
+        return super()._select_additional_fields(fields)
diff --git a/addons/sale_stock/report/sale_report.py b/addons/sale_stock/report/sale_report.py
index 3c62a27930d4c81fb34ed26781a163b3f29ac15c..f98660c79816c14c1a07ec6df6f5b834af2f8c12 100644
--- a/addons/sale_stock/report/sale_report.py
+++ b/addons/sale_stock/report/sale_report.py
@@ -9,7 +9,11 @@ class SaleReport(models.Model):
 
     warehouse_id = fields.Many2one('stock.warehouse', 'Warehouse', readonly=True)
 
-    def _query(self, with_clause='', fields={}, groupby='', from_clause=''):
+    def _group_by_sale(self, groupby=''):
+        res = super()._group_by_sale(groupby)
+        res += """,s.warehouse_id"""
+        return res
+
+    def _select_additional_fields(self, fields):
         fields['warehouse_id'] = ", s.warehouse_id as warehouse_id"
-        groupby += ', s.warehouse_id'
-        return super(SaleReport, self)._query(with_clause, fields, groupby, from_clause)
+        return super()._select_additional_fields(fields)
diff --git a/addons/website_sale/report/sale_report.py b/addons/website_sale/report/sale_report.py
index 6ecf7967cadf9c835a438a2880b1fe6edf7416ae..24c271416d2bf00a775250fb990d5d64e85ac94a 100644
--- a/addons/website_sale/report/sale_report.py
+++ b/addons/website_sale/report/sale_report.py
@@ -8,7 +8,11 @@ class SaleReport(models.Model):
 
     website_id = fields.Many2one('website', readonly=True)
 
-    def _query(self, with_clause='', fields={}, groupby='', from_clause=''):
+    def _group_by_sale(self, groupby=''):
+        res = super()._group_by_sale(groupby)
+        res += """,s.website_id"""
+        return res
+
+    def _select_additional_fields(self, fields):
         fields['website_id'] = ", s.website_id as website_id"
-        groupby += ', s.website_id'
-        return super(SaleReport, self)._query(with_clause, fields, groupby, from_clause)
+        return super()._select_additional_fields(fields)