Exemplo n.º 1
0
def set_offer(request,group_id, id_in_group,valUnits,valPrice,valType):
    # When this procedure is called, it means a player makes an offer and sends, except for his identity,
    # info on the number of units, the price and the type (Sell or Buy).
    # The offer is first created and then checked against the existing offers and matched and cleared if
    # possible
    # THIS IS THE ONLY POINT WHERE MATCHING IS DONE. IF HERE THE PROCEDURE MESSES UP AND AN OFFER "ESCAPES"
    # MATCHING, THE AUCTION WILL NOT BE EXECUTED CORRECTLY!


    #if not Constants.setOffer_started:
    if True:
        Constants.setOffer_started=True
        #state.save()

        print("set_offer called!")
        context2=""
        valUnits = int(valUnits)
        valPrice = int(valPrice)
        group_id = int(group_id)
        id_in_group = int(id_in_group)
        g=getGroup(group_id)
        p = Player.objects.get(id_in_group=id_in_group,group=g)
        p.save()
        #print("BEFORE if valUnits and valPrice and int(valPrice)>0 and int(valUnits)>0:")
        if valUnits and valPrice and int(valPrice)>0 and int(valUnits)>0:
            # first delete the last standing offer
            #if Offer.objects.filter(player=p).filter(cleared=False).order_by('-id').count()>0:
            #    Offer.objects.filter(player=p).filter(cleared=False).order_by('-id').first().delete()
            #!!!!!!!!!!!!!!! must be uncommented- commented for demo

            #now create the new offer
            c = Offer(player=p)
            c.unitsAvailable = int(valUnits)
            c.unitsOriginal = int(valUnits)
            c.unitsInherited = int(valUnits)
            c.group=g
            c.priceOriginal = int(valPrice)
            c.type = valType
            c.save()
            context2={'lastOffer':c}          #standing_offer=c
            print("New Offer:..................................................................................",c)
            print("price new offer:", c.priceOriginal)
            print("unitsAvailable new offer",c.unitsAvailable)
            if valType=="SELL": #then the matcher must be a buy
                offer_list2 = Offer.objects.filter(group=p.group)\
                    .exclude(player=p)\
                    .exclude(canceled=True)\
                    .filter(priceOriginal__gte=c.priceOriginal)\
                    .filter(type__iexact="BUY")\
                    .filter(cleared=False)
                offer_list = offer_list2.order_by('-priceOriginal','timeCreated')
                print("buys:",offer_list)
                print("buys:",offer_list.first())
            elif valType == "BUY":               #then the matcher must be a sell
                offer_list2 = Offer.objects.filter(group=p.group)\
                    .exclude(player=p)\
                    .exclude(canceled=True)\
                    .filter(priceOriginal__lte=c.priceOriginal)\
                    .filter(type__iexact='SELL')\
                    .filter(cleared=False)
                offer_list = offer_list2.order_by('priceOriginal','timeCreated')
                print("sells:",offer_list)
            else:
                raise ValueError('valType is neither SELL or BUY')
            #print("BEFORE first = offer_list.first()")
            first = offer_list.first()
            #print("AFTER first = offer_list.first()")
            #print("BEFORE first_player=first.player")
            if first:
                first_player=first.player
            else:
                first_player=None
            #print("AFTER first_player=first.player")
            #print("first counteroffer is:",first)

            while first is not None and c.unitsAvailable > first.unitsAvailable :
                print("greater!")
                print("first:",first)
                #1.clear the smaller, first
                clear_offer_smaller(first,c,first)
                # now we must split up the offer into two parts, the first of which is cleared, the second part is the
                # remaining units. This will be compared with other remaining offers (if any). If there are no other
                # offers, the second part becomes the standing offer with attr "updated" set to True.
                # a new offer is created, to carry the remaining units from the original offer
                #2.make copy for the larger, c into c2
                c2=copy_offer(c,p,first)
                #3.clear the larger, c (the part of the present offer that will be cleared)
                clear_offer_larger(first,c,first)
                #4. make transaction
                t = create_transaction(c, first)
                #5. set products
                setproducts(c,p,first,first_player)
                #print("before try, first",first)
                #6. set vouchers
                #set_voucher(p,first,first.unitsCleared)  # The vouchers are ticked
                set_voucher(p,first_player,first,c.unitsCleared)    # The vouchers are ticked

                offer_list3 = offer_list.exclude(cleared=True)   # update the list of remaining counter-offers
                print(offer_list3)
                c.save()
                c2.save()
                print("old c:",c)
                print("old c2:",c2)
                del c
                c=c2
                print("new c:",c)
                print("new c2:",c2)
                if offer_list3:
                    first=offer_list3.first() # get the update the list of remaining counter-offers
                else:
                    print("no more offers:",offer_list3)
                    first=None


            if first is not None and c.unitsAvailable < first.unitsAvailable:
                first_player=first.player
                print("smaller!")
                print(first)
                # now we must split up the counteroffer into two parts, the first of which is cleared, the second part is the
                # remaining units.

                #1.clear the smaller, c
                clear_offer_smaller(c,first,first)
                #2.make copy for the larger, first into f2
                f2=copy_offer(first,first_player,c)
                #print("after f2=copy_offer(first,first_player,c)")
                #3. clear the larger, first
                clear_offer_larger(c,first,first)
                #4. make transaction
                t = create_transaction(c, first)
                #5. set products
                setproducts(c,p,first,first_player)
                #calculate production costs or buyers values
                #6. set vouchers
                print("1st setvoucher call")
#                set_voucher(p,first,c.unitsCleared)    # The vouchers are ticked
                set_voucher(p,first_player,first,c.unitsCleared)    # The vouchers are ticked
                #print("After set_voucher(p,first,c.unitsCleared)")
                #print("After clear_c(c,first)  # clear c (as first.unitsA>c.unitsA)")
                first.save()
                f2.save()
                #print("f2.save()")

            elif first is not None and c.unitsAvailable == first.unitsAvailable:
                first_player=first.player
                print("now equal!")
                print(first)

                #1.clear the smaller, c
                clear_offer_smaller(c,first,first)
                #2.make copy for the larger - not necessary as equal

                #3.clear the larger, first
                clear_offer_larger(c,first,first)

                #4. make transaction
                t = create_transaction(c, first)

                #5. set products
                setproducts(c,p,first,first_player)
                #print("f2:  ",first)
                #print("1st setvoucher call")

                #6. set vouchers
                #def set_voucher(p,first_player,first,unitsCleared)
                set_voucher(p,first_player,first,c.unitsCleared)    # The vouchers are ticked

        else:
            if valUnits=='':
                messages.add_message(request, messages.INFO, 'fill out the number of units.')
            if valPrice=='':
                messages.add_message(request, messages.INFO, 'fill out the price per unit.')
            if valUnits=='0' or valPrice=='0':
                messages.add_message(request, messages.INFO, 'choose a number larger than zero.')
        #DEM:
        #print("BEFORE if id_in_group == 1:")
        Constants.setOffer_started=False
        #state.save()
        #if id_in_group == 1:
        if True:
            print("is me, thus render!")
            return render(request,'dAuction2/spot_market/my_standing_offer2.html', context = context2)
        else:
            print("is not me, no render! Is:",id_in_group)
                # For the version with robots, obsolete here
            return request # DEM: must still be calculated context
    else:
        print("presently a set_offer procedure is running, so no others can be processed:",id_in_group)
        time.sleep(1)
        Constants.setOffer_started=False
        #state.save()
        return request