Exemplo n.º 1
0
def __bill_slot(slot, membership=None, bill_for_member=None):
    ret = {}

    if membership is None:
        membership = LocationMembership.objects.get(
            person=slot.person, location=slot.load.location, deleted=False)

    pp = misc.get_person_profile(membership)
    billing_mode = pp['billing_mode']

    if billing_mode == 'other' and bill_for_member:
        billing_mode = 'post'

    if billing_mode == 'other':
        try:
            payer_membership = LocationMembership.objects.get(
                person=pp['bill_person'],
                location=slot.load.location,
                deleted=False)
        except:
            payer_membership = None
            billing_mode = 'post'
        if payer_membership:
            req_person = Person.objects.getOwn(req.user)
            ret['payer'] = misc.formatFullname(pp['bill_person'],
                                               req_person.name_order, True)
            ret.update(__bill_slot(slot, payer_membership, membership))
            return ret

    # bill extra items if any
    # extra items are always billed even if billing mode is 'none'
    __bill_extra_items(membership, pp, bill_for_member)

    # if item or price is not set, set billing to none
    # only 'pre' and 'post' billing modes are processed
    if not slot.item or not slot.price:
        billing_mode = 'none'

    # at this stage prepaid and postpaid mode are the same
    # because even if limits are reached, user forced the
    # load.
    if billing_mode in ('pre', 'post'):
        ret['payment_type'] = 'prepaid' if billing_mode == 'pre' else 'postpaid'
        # buyed item
        buyed_item = None
        buyed_items_rs = BuyedItem.objects.filter(membership=membership,
                                                  item=slot.item,
                                                  price=slot.price,
                                                  consumed=False,
                                                  deleted=False)
        buyed_items_count = buyed_items_rs.count()
        if buyed_items_count == 1:
            buyed_item = buyed_items_rs[0]
        elif buyed_items_count > 1:
            agg = buyed_items_rs.aggregate(Max('usage_count'))
            buyed_item = buyed_items_rs.filter(
                usage_count=agg['usage_count__max'])[0]
        # found a buyed item
        if buyed_item:
            if slot.item.reuseable:
                total_slots = __get_item_total_slots(slot.item)
                if buyed_item.usage_count + 1 == total_slots:
                    buyed_item.consumed = True
                    buyed_item.consuming = False
                else:
                    buyed_item.consuming = True
                buyed_item.usage_count = F('usage_count') + 1
            else:
                buyed_item.usage_count = 1
                buyed_item.consumed = True
            buyed_item.save(force_update=True)
            # item is already paid
            ret['has_buyed_item'] = True
        else:
            __bill_item(membership, slot.item, slot.price, bill_for_member)

    return ret
Exemplo n.º 2
0
def __bill_extra_items(membership, p, bill_for_member):
    if bill_for_member: p = misc.get_person_profile(bill_for_member)
    for i in p['extra_items']:
        if i['price']:
            __bill_item(membership, i['item'], i['price'], bill_for_member)
Exemplo n.º 3
0
def take_slot(person_uuid, load_uuid, user_data):

    req_person = Person.objects.getOwn(req.user)
    if req_person.uuid != person_uuid:
        return HttpResponseForbidden('Access denied')

    try:
        load = Load.objects.get_by_natural_key(load_uuid)
    except ObjectDoesNotExist:
        raise Http404

    if not load.location.enable_self_manifesting or load.state not in ('P',
                                                                       'B'):
        raise Http404

    slots_used = 0
    for s in load.slot_set.filter(deleted=False):
        if s.person or s.phantom or s.related_slot:
            slots_used += 1
    if slots_used >= load.aircraft.max_slots:
        return HttpResponseForbidden('This load is full')

    try:
        membership = LocationMembership.objects.get(location=load.location,
                                                    person=req_person,
                                                    deleted=False)
    except ObjectDoesNotExist:
        return HttpResponseForbidden('Access denied')

    if not misc.is_clear_member(membership):
        return HttpResponseForbidden('Access denied')

    pp = misc.get_person_profile(membership)

    if not isinstance(user_data, dict):
        user_data = {}

    slot_data = {}
    slot_data['load'] = load
    slot_data['owner'] = load.owner
    slot_data['person'] = req_person
    slot_data['membership_uuid'] = membership.uuid

    slot_data['item'] = None
    slot_data['element'] = None
    slot_data['price'] = None
    slot_data['payer'] = None

    # item and price
    user_default_item = None
    if pp['catalog_access']:
        try:
            user_default_item = LocationCatalogItem.objects.get_by_natural_key(
                user_data['item'])
        except:
            pass
    if user_default_item and pp['available_items'].has_key(
            user_default_item.uuid):
        slot_data['item'] = user_default_item
        slot_data['price'] = pp['available_items'][user_default_item.uuid]
    elif pp['default_item']:
        slot_data['item'] = pp['default_item']
        if pp['default_price']: slot_data['price'] = pp['default_price']
        else:
            slot_data['price'] = misc.get_default_price(
                membership, pp['default_item'])

    # account check
    if slot_data['item'] and slot_data['price']:
        if not misc.check_member_account(membership, pp, slot_data['item'],
                                         slot_data['price']):
            return HttpResponseForbidden('Boarding denied')
    else:
        return HttpResponseForbidden('No default catalog item')

    # element
    if slot_data['item'] and not slot_data['element']:
        try:
            slot_data['element'] = slot_data[
                'item'].locationcatalogelement_set.filter(deleted=False)[0]
        except:
            pass

    # payer
    if pp['billing_mode'] == 'other':
        slot_data['payer'] = pp['bill_person']

    # jump type
    try:
        user_jump_type = JumpType.objects.get_by_natural_key(
            user_data['jump_type'])
    except:
        user_jump_type = None
    if user_jump_type: slot_data['jump_type'] = user_jump_type
    if slot_data['item'] and slot_data['item'].jump_type and slot_data[
            'item'].jump_type_auto:
        slot_data['jump_type'] = slot_data['item'].jump_type

    # exit order
    max_exit_order = Slot.objects.filter(
        load__uuid=load_uuid,
        deleted=False).aggregate(Max('exit_order'))['exit_order__max']
    if max_exit_order is None: slot_data['exit_order'] = 1
    else: slot_data['exit_order'] = max_exit_order + 1

    # save slot
    s = Slot.objects.create(**slot_data)

    # notify
    comet.Notifier(None, s, 'create', True)
    return serializers.serialize("json", [s],
                                 use_natural_keys=True,
                                 fields=[
                                     'uuid', 'created', 'load', 'person',
                                     'membership_uuid', 'item', 'element',
                                     'jump_type', 'exit_order'
                                 ],
                                 relations={
                                     'person': {
                                         'fields':
                                         ['uuid', 'first_name', 'last_name'],
                                         'use_natural_keys':
                                         True
                                     },
                                 })
Exemplo n.º 4
0
def __bill_slot(slot, membership=None, bill_for_member=None):
    ret = {}
    
    if membership is None:
        membership = LocationMembership.objects.get(person=slot.person, location=slot.load.location, deleted=False)
            
    pp = misc.get_person_profile(membership)
    billing_mode = pp['billing_mode']
    
    if billing_mode == 'other' and bill_for_member:
        billing_mode = 'post'
    
    if billing_mode == 'other':
        try: payer_membership = LocationMembership.objects.get(person=pp['bill_person'], location=slot.load.location, deleted=False)
        except:
            payer_membership = None
            billing_mode = 'post'
        if payer_membership:
            req_person = Person.objects.getOwn(req.user)
            ret['payer'] = misc.formatFullname(pp['bill_person'], req_person.name_order, True)
            ret.update(__bill_slot(slot, payer_membership, membership))
            return ret

    # bill extra items if any
    # extra items are always billed even if billing mode is 'none'
    __bill_extra_items(membership, pp, bill_for_member)
    
    # if item or price is not set, set billing to none
    # only 'pre' and 'post' billing modes are processed
    if not slot.item or not slot.price:
        billing_mode = 'none'

    # at this stage prepaid and postpaid mode are the same
    # because even if limits are reached, user forced the
    # load. 
    if billing_mode in ('pre', 'post'):
        ret['payment_type'] = 'prepaid' if billing_mode == 'pre' else 'postpaid'
        # buyed item
        buyed_item = None
        buyed_items_rs = BuyedItem.objects.filter(membership=membership, item=slot.item, price=slot.price, consumed=False, deleted=False)
        buyed_items_count = buyed_items_rs.count()
        if buyed_items_count == 1:
            buyed_item = buyed_items_rs[0]
        elif buyed_items_count > 1:
            agg = buyed_items_rs.aggregate(Max('usage_count'))
            buyed_item = buyed_items_rs.filter(usage_count=agg['usage_count__max'])[0]
        # found a buyed item
        if buyed_item:
            if slot.item.reuseable:
                total_slots = __get_item_total_slots(slot.item)
                if buyed_item.usage_count+1 == total_slots:
                    buyed_item.consumed = True
                    buyed_item.consuming = False
                else:
                    buyed_item.consuming = True
                buyed_item.usage_count = F('usage_count') + 1
            else:
                buyed_item.usage_count = 1
                buyed_item.consumed = True
            buyed_item.save(force_update=True)
            # item is already paid
            ret['has_buyed_item'] = True
        else:
            __bill_item(membership, slot.item, slot.price, bill_for_member)
    
    return ret
Exemplo n.º 5
0
def __bill_extra_items(membership, p, bill_for_member):
    if bill_for_member: p = misc.get_person_profile(bill_for_member)
    for i in p['extra_items']:
        if i['price']:
            __bill_item(membership, i['item'], i['price'], bill_for_member)
Exemplo n.º 6
0
def take_slot(person_uuid, load_uuid, user_data):
    
    req_person = Person.objects.getOwn(req.user)
    if req_person.uuid != person_uuid:
        return HttpResponseForbidden('Access denied')
    
    try: load = Load.objects.get_by_natural_key(load_uuid)
    except ObjectDoesNotExist: raise Http404
    
    if not load.location.enable_self_manifesting or load.state not in ('P', 'B'):
        raise Http404
    
    slots_used = 0
    for s in load.slot_set.filter(deleted=False):
        if s.person or s.phantom or s.related_slot:
            slots_used += 1
    if slots_used >= load.aircraft.max_slots:
        return HttpResponseForbidden('This load is full')
    
    try: membership = LocationMembership.objects.get(location=load.location, person=req_person, deleted=False)
    except ObjectDoesNotExist: return HttpResponseForbidden('Access denied')
    
    if not misc.is_clear_member(membership):
        return HttpResponseForbidden('Access denied')
    
    pp = misc.get_person_profile(membership)
    
    if not isinstance(user_data, dict):
        user_data = {}
    
    slot_data = {}
    slot_data['load'] = load
    slot_data['owner'] = load.owner
    slot_data['person'] = req_person
    slot_data['membership_uuid'] = membership.uuid
    
    slot_data['item'] = None
    slot_data['element'] = None
    slot_data['price'] = None
    slot_data['payer'] = None
    
    # item and price
    user_default_item = None
    if pp['catalog_access']:
        try: user_default_item = LocationCatalogItem.objects.get_by_natural_key(user_data['item'])
        except: pass 
    if user_default_item and pp['available_items'].has_key(user_default_item.uuid):
        slot_data['item'] = user_default_item
        slot_data['price'] = pp['available_items'][user_default_item.uuid]
    elif pp['default_item']:
        slot_data['item'] = pp['default_item']
        if pp['default_price']: slot_data['price'] = pp['default_price']
        else: slot_data['price'] = misc.get_default_price(membership, pp['default_item'])
        
    # account check
    if slot_data['item'] and slot_data['price']:
        if not misc.check_member_account(membership, pp, slot_data['item'], slot_data['price']):
            return HttpResponseForbidden('Boarding denied')
    else:
        return HttpResponseForbidden('No default catalog item')
        
    # element
    if slot_data['item'] and not slot_data['element']:
        try: slot_data['element'] = slot_data['item'].locationcatalogelement_set.filter(deleted=False)[0]
        except: pass
        
    # payer
    if pp['billing_mode'] == 'other':
        slot_data['payer'] = pp['bill_person']
        
    # jump type
    try: user_jump_type = JumpType.objects.get_by_natural_key(user_data['jump_type'])
    except: user_jump_type = None
    if user_jump_type: slot_data['jump_type'] = user_jump_type
    if slot_data['item'] and slot_data['item'].jump_type and slot_data['item'].jump_type_auto:
        slot_data['jump_type'] = slot_data['item'].jump_type
    
    # exit order
    max_exit_order = Slot.objects.filter(load__uuid=load_uuid, deleted=False).aggregate(Max('exit_order'))['exit_order__max']
    if max_exit_order is None: slot_data['exit_order'] = 1
    else: slot_data['exit_order'] = max_exit_order+1 
    
    # save slot
    s = Slot.objects.create(**slot_data)
    
    # notify
    comet.Notifier(None, s, 'create', True)
    return serializers.serialize("json", [s],
        use_natural_keys=True, 
        fields=['uuid', 'created', 'load', 'person', 'membership_uuid', 'item', 'element', 'jump_type', 'exit_order'], 
        relations={
            'person': {'fields': ['uuid', 'first_name', 'last_name'], 'use_natural_keys': True},
        }
    )