'This function reserves quants for the given move and optionally
given link. If the total of quantity reserved is enough, the move state
is also set to \'assigned\'
:param quants: list of tuple(quant browse record or None, qty to reserve). If None is given as first tuple element, the item will be ignored. Negative quants should not be received as argument
:param move: browse record
:param link: browse record (stock.move.operation.link)'

@api.model
def quants_reserve(self, quants, move, link=False):

    quants_to_reserve_sudo = self.env['stock.quant'].sudo()
    reserved_availability = move.reserved_availability
    for (quant, qty) in quants:
        if ((qty <= 0.0) or (quant and (quant.qty <= 0.0))):
            raise UserError(_('You    can    not    reserve    a    negative    quantity    or    a    negative    quant.'))
        if (not quant):
            continue
        quant._quant_split(qty)
        quants_to_reserve_sudo |= quant
        reserved_availability += quant.qty
    if quants_to_reserve_sudo:
        quants_to_reserve_sudo.write({'reservation_id': move.id})
    rounding = move.product_id.uom_id.rounding
    if ((float_compare(reserved_availability, move.product_qty, precision_rounding=rounding) == 0) and (move.state in ('confirmed', 'waiting'))):
        move.write({'state': 'assigned'})
    elif ((float_compare(reserved_availability, 0, precision_rounding=rounding) > 0) and (not move.partially_available)):
        move.write({'partially_available': True})
