diff --git a/addons/sale/models/account_move_line.py b/addons/sale/models/account_move_line.py
index 7acbe50b6a0b4be2023d445f58be9b5fe2c92fe6..6d52d2df7695597273b3235d738ec94856619dec 100644
--- a/addons/sale/models/account_move_line.py
+++ b/addons/sale/models/account_move_line.py
@@ -47,16 +47,13 @@ class AccountMoveLine(models.Model):
 
     def _sale_can_be_reinvoice(self):
         """ determine if the generated analytic line should be reinvoiced or not.
-            For Vendor Bill flow, if the product has a 'reinvoice policy' and is a cost, then we will find the SO on which reinvoice the AAL
-                if it is refund, we will update the quantity of the SO line
+            For Vendor Bill flow, if the product has a 'erinvoice policy' and is a cost, then we will find the SO on which reinvoice the AAL
         """
         self.ensure_one()
         if self.sale_line_ids:
             return False
-        is_refund = self.move_id.move_type in ('out_refund', 'in_refund')
-        return self.product_id.expense_policy not in [False, 'no'] and (
-                (self.currency_id.compare_amounts(self.balance, 0.0) == -1 and is_refund)
-                or (self.currency_id.compare_amounts(self.balance, 0.0) == 1 and not is_refund))
+        uom_precision_digits = self.env['decimal.precision'].precision_get('Product Unit of Measure')
+        return float_compare(self.credit or 0.0, self.debit or 0.0, precision_digits=uom_precision_digits) != 1 and self.product_id.expense_policy not in [False, 'no']
 
     def _sale_create_reinvoice_sale_line(self):
 
@@ -92,8 +89,7 @@ class AccountMoveLine(models.Model):
 
             # find the existing sale.line or keep its creation values to process this in batch
             sale_line = None
-            if (move_line.product_id.expense_policy == 'sales_price' and move_line.product_id.invoice_policy == 'delivery') \
-                    or move_line.move_id.move_type in ('out_refund', 'in_refund'):  # for those case only, we can try to reuse one
+            if move_line.product_id.expense_policy == 'sales_price' and move_line.product_id.invoice_policy == 'delivery':  # for those case only, we can try to reuse one
                 map_entry_key = (sale_order.id, move_line.product_id.id, price)  # cache entry to limit the call to search
                 sale_line = existing_sale_line_cache.get(map_entry_key)
                 if sale_line:  # already search, so reuse it. sale_line can be sale.order.line record or index of a "to create values" in `sale_line_values_to_create`
diff --git a/addons/sale/models/sale_order_line.py b/addons/sale/models/sale_order_line.py
index 811e6a37b84a408cb491b87d235e888ac9c430d2..8f44d5a47df9948fa5ad9f7c72961967956cab0e 100644
--- a/addons/sale/models/sale_order_line.py
+++ b/addons/sale/models/sale_order_line.py
@@ -344,7 +344,7 @@ class SaleOrderLine(models.Model):
         """
         # compute for analytic lines
         lines_by_analytic = self.filtered(lambda sol: sol.qty_delivered_method == 'analytic')
-        mapping = lines_by_analytic._get_delivered_quantity_by_analytic([])
+        mapping = lines_by_analytic._get_delivered_quantity_by_analytic([('amount', '<=', 0.0)])
         for so_line in lines_by_analytic:
             so_line.qty_delivered = mapping.get(so_line.id or so_line._origin.id, 0.0)
         # compute for manual lines
@@ -365,20 +365,29 @@ class SaleOrderLine(models.Model):
 
         # group analytic lines by product uom and so line
         domain = expression.AND([[('so_line', 'in', self.ids)], additional_domain])
-        analytic_lines = self.env['account.analytic.line'].search(domain)
-        for line in analytic_lines:
-            if not line.product_uom_id:
+        data = self.env['account.analytic.line'].read_group(
+            domain,
+            ['so_line', 'unit_amount', 'product_uom_id'], ['product_uom_id', 'so_line'], lazy=False
+        )
+
+        # convert uom and sum all unit_amount of analytic lines to get the delivered qty of SO lines
+        # browse so lines and product uoms here to make them share the same prefetch
+        lines = self.browse([item['so_line'][0] for item in data])
+        lines_map = {line.id: line for line in lines}
+        product_uom_ids = [item['product_uom_id'][0] for item in data if item['product_uom_id']]
+        product_uom_map = {uom.id: uom for uom in self.env['uom.uom'].browse(product_uom_ids)}
+        for item in data:
+            if not item['product_uom_id']:
                 continue
-            result.setdefault(line.so_line.id, 0.0)
-            if line.so_line.product_uom.category_id == line.product_uom_id.category_id:
-                qty = line.product_uom_id._compute_quantity(line.unit_amount, line.so_line.product_uom, rounding_method='HALF-UP')
+            so_line_id = item['so_line'][0]
+            so_line = lines_map[so_line_id]
+            result.setdefault(so_line_id, 0.0)
+            uom = product_uom_map.get(item['product_uom_id'][0])
+            if so_line.product_uom.category_id == uom.category_id:
+                qty = uom._compute_quantity(item['unit_amount'], so_line.product_uom, rounding_method='HALF-UP')
             else:
-                qty = line.unit_amount
-
-            # if greater than 0 -> refund
-            sign = line.amount and -line.amount / abs(line.amount) or 1
-
-            result[line.so_line.id] += sign * qty
+                qty = item['unit_amount']
+            result[so_line_id] += qty
 
         return result
 
diff --git a/addons/sale/tests/test_reinvoice.py b/addons/sale/tests/test_reinvoice.py
index 53841f9abcc055614bb5a01e4626f599e00d6f4e..be414b81e8c4d74bb004708246e22572c7344cb6 100644
--- a/addons/sale/tests/test_reinvoice.py
+++ b/addons/sale/tests/test_reinvoice.py
@@ -34,17 +34,6 @@ class TestReInvoice(TestSaleCommon):
             mail_create_nolog=True,
         )
 
-    def _create_sol(self, sale_order, product):
-        return self.env['sale.order.line'].create({
-            'name': product.name,
-            'product_id': product.id,
-            'product_uom_qty': 1,
-            'qty_delivered': 0,
-            'product_uom': product.uom_id.id,
-            'price_unit': product.list_price,
-            'order_id': sale_order.id,
-        })
-
     def test_at_cost(self):
         """ Test vendor bill at cost for product based on ordered and delivered quantities. """
         # create SO line and confirm SO (with only one line)
@@ -312,54 +301,3 @@ class TestReInvoice(TestSaleCommon):
         self.assertFalse(so_line4, "No re-invoicing should have created a new sale line with product #2")
         self.assertEqual(so_line1.qty_delivered, 1, "No re-invoicing should have impacted exising SO line 1")
         self.assertEqual(so_line2.qty_delivered, 1, "No re-invoicing should have impacted exising SO line 2")
-
-    def test_refund_delivered_reinvoiced(self):
-        """
-        Tests that when we refund a re-invoiced expense, the Quantity Delivered on the Sale Order Line is updated
-        - (1) We create a Sale Order
-        - (2) We create a bill to be re-invoiced
-        - (3) We create a partial credit note
-        -> The sale order lines created in (2) should be updated during (3) with the correct delivered quantity.
-        """
-        # create the setup
-        product_1 = self.company_data['product_order_cost']
-        product_2 = self.env['product.product'].create({
-            'name': 'Great Product',
-            'standard_price': 50.0,
-            'list_price': 100.0,
-            'type': 'consu',
-            'uom_id': self.env.ref('uom.product_uom_unit').id,
-            'uom_po_id': self.env.ref('uom.product_uom_unit').id,
-            'invoice_policy': 'order',
-            'expense_policy': 'cost',
-        })
-        self._create_sol(self.sale_order, product_1)
-        self._create_sol(self.sale_order, product_2)
-        self.sale_order.action_confirm()
-
-        # create the bill to be re-invoiced
-        bill_form = Form(self.AccountMove.with_context(default_move_type='in_invoice'))
-        bill_form.partner_id = self.partner_b
-        with bill_form.line_ids.new() as line_form:
-            line_form.product_id = product_1
-            line_form.quantity = 20.0
-            line_form.analytic_account_id = self.analytic_account
-        with bill_form.line_ids.new() as line_form:
-            line_form.product_id = product_2
-            line_form.quantity = 20.0
-            line_form.analytic_account_id = self.analytic_account
-        bill = bill_form.save()
-        bill.action_post()
-
-        self.assertRecordValues(self.sale_order.order_line[-2:], [{'qty_delivered': 20}, {'qty_delivered': 20}])
-
-        # create partial credit note
-        rbill_form = Form(bill._reverse_moves([{'invoice_date': '2023-03-31'}]))
-        with rbill_form.invoice_line_ids.edit(0) as line_form:
-            line_form.quantity = 10
-        with rbill_form.invoice_line_ids.edit(1) as line_form:
-            line_form.quantity = 5
-        rbill = rbill_form.save()
-        rbill.action_post()
-
-        self.assertRecordValues(self.sale_order.order_line[-2:], [{'qty_delivered': 10}, {'qty_delivered': 15}])