blob: 04758e3ba58a97d845e331e5c14d63454559ce9c [file] [log] [blame]
# Copyright 2014 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Logic for slot transfer requests."""
from google.appengine.ext import ndb
from melange.utils import rich_bool
from summerofcode.models import slot_transfer as slot_transfer_model
PENDING_SLOT_TRANSFER_EXISTS = 'pending_slot_transfer_exists'
NOT_ENOUGH_SLOTS_ALLOCATED = 'not_enough_slots_allocated'
NOT_ENOUGH_SLOTS_TRANSFERRED = 'not_enough_slots_transferred'
SLOT_TRANSFER_NOT_EXISTING = 'slot_transfer_not_existing'
SLOT_TRANSFER_NOT_PENDING = 'slot_transfer_not_pending'
ORG_NOT_EXISTING = 'org_not_existing'
@ndb.transactional
def createSlotTransfer(org_key, quantity, org_message=None):
"""Creates a new slot transfer entity for the specified quantity and
organization.
Args:
org_key: ndb.Key of organization entity.
quantity: An integer telling how many slots is requested to be given back.
org_message: Optional string with a message from the organization.
Returns:
rich_bool.RichBool whose value is set to True, if a new slot transfer
request has been created properly. In that case, the extra part points to
the newly created entity. Otherwise, rich_bool.RichBool whose value is set
to False and extra part is a string that represents the reason why it is
not possible to create a new slot transfer request.
"""
if hasPendingSlotTransfer(org_key):
# a pending slot transfer request exists for the organization
return rich_bool.RichBool(False, PENDING_SLOT_TRANSFER_EXISTS)
else:
organization = org_key.get()
if organization.slot_allocation < quantity:
return rich_bool.RichBool(False, NOT_ENOUGH_SLOTS_ALLOCATED)
elif quantity <= 0:
return rich_bool.RichBool(False, NOT_ENOUGH_SLOTS_TRANSFERRED)
else:
slot_transfer = slot_transfer_model.SlotTransfer(
parent=org_key, quantity=quantity, program=organization.program,
org_message=org_message)
slot_transfer.put()
return rich_bool.RichBool(True, slot_transfer)
@ndb.transactional
def acceptSlotTransfer(slot_transfer_key):
"""Accepts the specified slot transfer.
Args:
slot_trasnfer_key: ndb.Key of slot transfer entity.
Returns:
rich_bool.RichBool whose value is set to True, if the slot transfer is
properly accepted. Otherwise, rich_bool.RichBool whose value is set
to False and extra part is a string that represents the reason why the
action is not possible at this time.
"""
slot_transfer = slot_transfer_key.get()
if not slot_transfer:
return rich_bool.RichBool(False, SLOT_TRANSFER_NOT_EXISTING)
elif slot_transfer.status != slot_transfer_model.Status.PENDING:
return rich_bool.RichBool(False, SLOT_TRANSFER_NOT_PENDING)
elif slot_transfer.quantity <= 0:
return rich_bool.RichBool(False, NOT_ENOUGH_SLOTS_TRANSFERRED)
else:
org = slot_transfer.key.parent().get()
if not org:
return rich_bool.RichBool(False, ORG_NOT_EXISTING)
else:
slot_transfer.status = slot_transfer_model.Status.ACCEPTED
org.slot_allocation = max(org.slot_allocation - slot_transfer.quantity, 0)
ndb.put_multi([slot_transfer, org])
return rich_bool.TRUE
@ndb.transactional
def rejectSlotTransfer(slot_transfer_key):
"""Rejects the specified slot transfer request.
Args:
slot_trasnfer_key: ndb.Key of slot transfer entity.
Returns:
rich_bool.RichBool whose value is set to True, if the slot transfer is
properly rejected. Otherwise, rich_bool.RichBool whose value is set
to False and extra part is a string that represents the reason why the
action is not possible at this time.
"""
slot_transfer = slot_transfer_key.get()
if not slot_transfer:
return rich_bool.RichBool(False, SLOT_TRANSFER_NOT_EXISTING)
elif slot_transfer.status != slot_transfer_model.Status.PENDING:
return rich_bool.RichBool(False, SLOT_TRANSFER_NOT_PENDING)
else:
slot_transfer.status = slot_transfer_model.Status.REJECTED
slot_transfer.put()
return rich_bool.TRUE
def getSlotTransfersForOrg(org_key):
"""Returns all slot transfer requests for the specified organization.
Args:
org_key: ndb.Key of organization entity.
Returns:
A list of slot_transfer.SlotTransfer entities.
"""
return slot_transfer_model.SlotTransfer.query(
ancestor=org_key).fetch(1000)
def hasPendingSlotTransfer(org_key):
"""Tells whether the specified organization has a pending slot transfer
request at this time.
Args:
org_key: ndb.Key of organization entity.
Returns:
True, if the organization has a pending slot transfer request. Otherwise,
False is returned.
"""
query = slot_transfer_model.SlotTransfer.query(
slot_transfer_model.SlotTransfer.status
== slot_transfer_model.Status.PENDING, ancestor=org_key)
return bool(query.count())