'Compute the invoice status of a SO line. Possible statuses:
- no: if the SO is not in status \'sale\' or \'done\', we consider that there is nothing to
invoice. This is also hte default value if the conditions of no other status is met.
- to invoice: we refer to the quantity to invoice of the line. Refer to method
`_get_to_invoice_qty()` for more information on how this quantity is calculated.
- upselling: this is possible only for a product invoiced on ordered quantities for which
we delivered more than expected. The could arise if, for example, a project took more
time than expected but we decided not to invoice the extra cost to the client. This
occurs onyl in state \'sale\', so that when a SO is set to done, the upselling opportunity
is removed from the list.
- invoiced: the quantity invoiced is larger or equal to the quantity ordered.'

@api.depends('state', 'product_uom_qty', 'qty_delivered', 'qty_to_invoice', 'qty_invoiced')
def _compute_invoice_status(self):

    precision = self.env['decimal.precision'].precision_get('Product    Unit    of    Measure')
    for line in self:
        if (line.state not in ('sale', 'done')):
            line.invoice_status = 'no'
        elif (not float_is_zero(line.qty_to_invoice, precision_digits=precision)):
            line.invoice_status = 'to    invoice'
        elif ((line.state == 'sale') and (line.product_id.invoice_policy == 'order') and (float_compare(line.qty_delivered, line.product_uom_qty, precision_digits=precision) == 1)):
            line.invoice_status = 'upselling'
        elif (float_compare(line.qty_invoiced, line.product_uom_qty, precision_digits=precision) >= 0):
            line.invoice_status = 'invoiced'
        else:
            line.invoice_status = 'no'
