mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 12:11:35 +00:00
Add more logics bareframes
This commit is contained in:
parent
a1771ae5ea
commit
34e05465c2
@ -30,7 +30,7 @@ class OrderAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
|
||||
|
||||
@admin.register(LNPayment)
|
||||
class LNPaymentAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
|
||||
list_display = ('id','concept','status','num_satoshis','type','invoice','preimage','expires_at','sender_link','receiver_link')
|
||||
list_display = ('id','concept','status','num_satoshis','type','invoice','expires_at','sender_link','receiver_link')
|
||||
list_display_links = ('id','concept')
|
||||
change_links = ('sender','receiver')
|
||||
|
||||
|
@ -13,7 +13,7 @@ class LNNode():
|
||||
Place holder functions to interact with Lightning Node
|
||||
'''
|
||||
|
||||
def gen_hodl_invoice(num_satoshis, description):
|
||||
def gen_hodl_invoice(num_satoshis, description, expiry):
|
||||
'''Generates hodl invoice to publish an order'''
|
||||
# TODO
|
||||
invoice = ''.join(random.choices(string.ascii_uppercase + string.digits, k=80)) #FIX
|
||||
|
@ -11,6 +11,12 @@ BOND_SIZE = float(config('BOND_SIZE'))
|
||||
MARKET_PRICE_API = config('MARKET_PRICE_API')
|
||||
ESCROW_USERNAME = config('ESCROW_USERNAME')
|
||||
|
||||
EXP_MAKER_BOND_INVOICE = int(config('EXP_MAKER_BOND_INVOICE'))
|
||||
EXP_TAKER_BOND_INVOICE = int(config('EXP_TAKER_BOND_INVOICE'))
|
||||
EXP_TRADE_ESCR_INVOICE = int(config('EXP_TRADE_ESCR_INVOICE'))
|
||||
|
||||
BOND_EXPIRY = int(config('BOND_EXPIRY'))
|
||||
ESCROW_EXPIRY = int(config('ESCROW_EXPIRY'))
|
||||
|
||||
class Logics():
|
||||
|
||||
@ -46,12 +52,10 @@ class Logics():
|
||||
if order.is_explicit:
|
||||
satoshis_now = order.satoshis
|
||||
else:
|
||||
# TODO Add fallback Public APIs and error handling
|
||||
market_prices = requests.get(MARKET_PRICE_API).json()
|
||||
print(market_prices)
|
||||
exchange_rate = float(market_prices[Order.Currencies(order.currency).label]['last'])
|
||||
print(exchange_rate)
|
||||
satoshis_now = ((float(order.amount) * 1+float(order.premium)) / exchange_rate) * 100*1000*1000
|
||||
print(satoshis_now)
|
||||
|
||||
return satoshis_now
|
||||
|
||||
@ -85,25 +89,57 @@ class Logics():
|
||||
if order.status == Order.Status.FAI:
|
||||
order.status = Order.Status.UPI
|
||||
order.save()
|
||||
return True
|
||||
return True, None
|
||||
|
||||
return False, {'bad_request':'Invalid Lightning Network Invoice. It starts by LNTB...'}
|
||||
|
||||
@classmethod
|
||||
def cancel_order(cls, order, user, state):
|
||||
|
||||
# 1) When maker cancels before bond
|
||||
'''The order never shows up on the book and status
|
||||
changes to cancelled. That's it.'''
|
||||
|
||||
# 2) When maker cancels after bond
|
||||
'''The order dissapears from book and goes to cancelled.
|
||||
Maker is charged a small amount of sats, to prevent DDOS
|
||||
on the LN node and order book'''
|
||||
|
||||
# 3) When taker cancels before bond
|
||||
''' The order goes back to the book as public.
|
||||
LNPayment "order.taker_bond" is deleted() '''
|
||||
|
||||
# 4) When taker or maker cancel after bond
|
||||
'''The order goes into cancelled status if maker cancels.
|
||||
The order goes into the public book if taker cancels.
|
||||
In both cases there is a small fee.'''
|
||||
|
||||
# 5) When trade collateral has been posted
|
||||
'''Always goes to cancelled status. Collaboration is needed.
|
||||
When a user asks for cancel, 'order.is_pending_cancel' goes True.
|
||||
When the second user asks for cancel. Order is totally cancelled.
|
||||
Has a small cost for both parties to prevent node DDOS.'''
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def gen_maker_hodl_invoice(cls, order, user):
|
||||
|
||||
# Do not and delete if order is more than 5 minutes old
|
||||
# Do not gen and delete if order is more than 5 minutes old
|
||||
if order.expires_at < timezone.now():
|
||||
cls.order_expires(order)
|
||||
return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'}
|
||||
|
||||
# Return the previous invoice if there was one
|
||||
if order.maker_bond:
|
||||
return True, {'invoice':order.maker_bond.invoice,'bond_satoshis':order.maker_bond.num_satoshis}
|
||||
|
||||
order.satoshis_now = cls.satoshis_now(order)
|
||||
bond_satoshis = order.satoshis_now * BOND_SIZE
|
||||
description = f'Robosats maker bond for order ID {order.id}. Will return to you if you do not cheat!'
|
||||
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(num_satoshis = bond_satoshis, description=description)
|
||||
description = f'RoboSats - Maker bond for order ID {order.id}. These sats will return to you if you do not cheat!'
|
||||
|
||||
# Gen HODL Invoice
|
||||
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(bond_satoshis, description, BOND_EXPIRY*3600)
|
||||
|
||||
order.maker_bond = LNPayment.objects.create(
|
||||
concept = LNPayment.Concepts.MAKEBOND,
|
||||
@ -115,30 +151,32 @@ class Logics():
|
||||
num_satoshis = bond_satoshis,
|
||||
description = description,
|
||||
payment_hash = payment_hash,
|
||||
expires_at = expires_at,
|
||||
)
|
||||
expires_at = expires_at)
|
||||
|
||||
order.save()
|
||||
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}
|
||||
|
||||
@classmethod
|
||||
def gen_taker_buyer_hodl_invoice(cls, order, user):
|
||||
def gen_takerbuyer_hodl_invoice(cls, order, user):
|
||||
|
||||
# Do not and delete if order is more than 5 minutes old
|
||||
if order.expires_at < timezone.now():
|
||||
cls.order_expires(order)
|
||||
return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'}
|
||||
# Do not gen and cancel if a taker invoice is there and older than 2 minutes
|
||||
if order.taker_bond.created_at < (timezone.now()+timedelta(minutes=EXP_TAKER_BOND_INVOICE)):
|
||||
cls.cancel_order(order, user, 3) # State 3, cancel order before taker bond
|
||||
return False, {'Invoice expired':'You did not confirm taking the order in time.'}
|
||||
|
||||
if order.maker_bond:
|
||||
return True, {'invoice':order.maker_bond.invoice,'bond_satoshis':order.maker_bond.num_satoshis}
|
||||
# Return the previous invoice if there was one
|
||||
if order.taker_bond:
|
||||
return True, {'invoice':order.taker_bond.invoice,'bond_satoshis':order.taker_bond.num_satoshis}
|
||||
|
||||
order.satoshis_now = cls.satoshis_now(order)
|
||||
bond_satoshis = order.satoshis_now * BOND_SIZE
|
||||
description = f'Robosats maker bond for order ID {order.id}. Will return to you if you do not cheat!'
|
||||
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(num_satoshis = bond_satoshis, description=description)
|
||||
description = f'RoboSats - Taker bond for order ID {order.id}. These sats will return to you if you do not cheat!'
|
||||
|
||||
# Gen HODL Invoice
|
||||
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(bond_satoshis, description, BOND_EXPIRY*3600)
|
||||
|
||||
order.maker_bond = LNPayment.objects.create(
|
||||
concept = LNPayment.Concepts.MAKEBOND,
|
||||
order.taker_bond = LNPayment.objects.create(
|
||||
concept = LNPayment.Concepts.TAKEBOND,
|
||||
type = LNPayment.Types.HODL,
|
||||
sender = user,
|
||||
receiver = User.objects.get(username=ESCROW_USERNAME),
|
||||
@ -147,8 +185,7 @@ class Logics():
|
||||
num_satoshis = bond_satoshis,
|
||||
description = description,
|
||||
payment_hash = payment_hash,
|
||||
expires_at = expires_at,
|
||||
)
|
||||
expires_at = expires_at)
|
||||
|
||||
order.save()
|
||||
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}
|
@ -49,7 +49,6 @@ class LNPayment(models.Model):
|
||||
# payment info
|
||||
invoice = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True)
|
||||
payment_hash = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True)
|
||||
preimage = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True)
|
||||
description = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
expires_at = models.DateTimeField()
|
||||
@ -79,22 +78,21 @@ class Order(models.Model):
|
||||
PUB = 1, 'Public'
|
||||
DEL = 2, 'Deleted'
|
||||
TAK = 3, 'Waiting for taker bond' # only needed when taker is a buyer
|
||||
UCA = 4, 'Unilaterally cancelled'
|
||||
RET = 5, 'Returned to order book' # Probably same as 1 in most cases.
|
||||
WF2 = 6, 'Waiting for trade collateral and buyer invoice'
|
||||
WTC = 7, 'Waiting only for trade collateral'
|
||||
WBI = 8, 'Waiting only for buyer invoice'
|
||||
EXF = 9, 'Exchanging fiat / In chat'
|
||||
CCA = 10, 'Collaboratively cancelled'
|
||||
FSE = 11, 'Fiat sent'
|
||||
FCO = 12, 'Fiat confirmed'
|
||||
SUC = 13, 'Sucessfully settled'
|
||||
FAI = 14, 'Failed lightning network routing'
|
||||
UPI = 15, 'Updated invoice'
|
||||
DIS = 16, 'In dispute'
|
||||
MLD = 17, 'Maker lost dispute'
|
||||
TLD = 18, 'Taker lost dispute'
|
||||
EXP = 19, 'Expired'
|
||||
UCA = 4, 'Cancelled'
|
||||
WF2 = 5, 'Waiting for trade collateral and buyer invoice'
|
||||
WTC = 6, 'Waiting only for seller trade collateral'
|
||||
WBI = 7, 'Waiting only for buyer invoice'
|
||||
EXF = 8, 'Sending fiat - In chatroom'
|
||||
CCA = 9, 'Collaboratively cancelled'
|
||||
FSE = 10, 'Fiat sent - In chatroom'
|
||||
FCO = 11, 'Fiat confirmed'
|
||||
SUC = 12, 'Sucessfully settled'
|
||||
FAI = 13, 'Failed lightning network routing'
|
||||
UPI = 14, 'Updated invoice'
|
||||
DIS = 15, 'In dispute'
|
||||
MLD = 16, 'Maker lost dispute'
|
||||
TLD = 17, 'Taker lost dispute'
|
||||
EXP = 18, 'Expired'
|
||||
|
||||
# order info
|
||||
status = models.PositiveSmallIntegerField(choices=Status.choices, null=False, default=Status.WFB)
|
||||
@ -117,11 +115,11 @@ class Order(models.Model):
|
||||
t0_satoshis = models.PositiveBigIntegerField(null=True, validators=[MinValueValidator(MIN_TRADE), MaxValueValidator(MAX_TRADE)], blank=True) # sats at creation
|
||||
last_satoshis = models.PositiveBigIntegerField(null=True, validators=[MinValueValidator(0), MaxValueValidator(MAX_TRADE*2)], blank=True) # sats last time checked. Weird if 2* trade max...
|
||||
|
||||
|
||||
# order participants
|
||||
maker = models.ForeignKey(User, related_name='maker', on_delete=models.CASCADE, null=True, default=None) # unique = True, a maker can only make one order
|
||||
taker = models.ForeignKey(User, related_name='taker', on_delete=models.SET_NULL, null=True, default=None, blank=True) # unique = True, a taker can only take one order
|
||||
|
||||
is_pending_cancel = models.BooleanField(default=False, null=False) # When collaborative cancel is needed and one partner has cancelled.
|
||||
|
||||
# order collateral
|
||||
maker_bond = models.ForeignKey(LNPayment, related_name='maker_bond', on_delete=models.SET_NULL, null=True, default=None, blank=True)
|
||||
taker_bond = models.ForeignKey(LNPayment, related_name='taker_bond', on_delete=models.SET_NULL, null=True, default=None, blank=True)
|
||||
|
@ -11,12 +11,7 @@ class MakeOrderSerializer(serializers.ModelSerializer):
|
||||
model = Order
|
||||
fields = ('type','currency','amount','payment_method','is_explicit','premium','satoshis')
|
||||
|
||||
class UpdateOrderSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Order
|
||||
fields = ('id','buyer_invoice')
|
||||
|
||||
class UpdateInvoiceSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = LNPayment
|
||||
fields = ['invoice']
|
||||
class UpdateOrderSerializer(serializers.Serializer):
|
||||
invoice = serializers.CharField(max_length=300, allow_null=True, allow_blank=True, default=None)
|
||||
action = serializers.ChoiceField(choices=('take','dispute','cancel','confirm','rate'), allow_null=False)
|
||||
rating = serializers.ChoiceField(choices=('1','2','3','4','5'), allow_null=True, allow_blank=True, default=None)
|
@ -3,7 +3,7 @@ from .views import OrderMakerView, OrderView, UserView, BookView
|
||||
|
||||
urlpatterns = [
|
||||
path('make/', OrderMakerView.as_view()),
|
||||
path('order/', OrderView.as_view({'get':'get','post':'take_or_update'})),
|
||||
path('order/', OrderView.as_view({'get':'get','post':'take_update_confirm_dispute_cancel'})),
|
||||
path('usergen/', UserView.as_view()),
|
||||
path('book/', BookView.as_view()),
|
||||
]
|
146
api/views.py
146
api/views.py
@ -7,9 +7,9 @@ from rest_framework.response import Response
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from .serializers import ListOrderSerializer, MakeOrderSerializer, UpdateInvoiceSerializer
|
||||
from .serializers import ListOrderSerializer, MakeOrderSerializer, UpdateOrderSerializer
|
||||
from .models import Order
|
||||
from .logics import Logics
|
||||
from .logics import EXP_MAKER_BOND_INVOICE, Logics
|
||||
|
||||
from .nick_generator.nick_generator import NickGenerator
|
||||
from robohash import Robohash
|
||||
@ -23,7 +23,7 @@ from django.utils import timezone
|
||||
|
||||
from decouple import config
|
||||
|
||||
EXPIRATION_MAKE = config('EXPIRATION_MAKE')
|
||||
EXP_MAKER_BOND_INVOICE = int(config('EXP_MAKER_BOND_INVOICE'))
|
||||
|
||||
avatar_path = Path('frontend/static/assets/avatars')
|
||||
avatar_path.mkdir(parents=True, exist_ok=True)
|
||||
@ -36,44 +36,39 @@ class OrderMakerView(CreateAPIView):
|
||||
def post(self,request):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
|
||||
if serializer.is_valid():
|
||||
otype = serializer.data.get('type')
|
||||
currency = serializer.data.get('currency')
|
||||
amount = serializer.data.get('amount')
|
||||
payment_method = serializer.data.get('payment_method')
|
||||
premium = serializer.data.get('premium')
|
||||
satoshis = serializer.data.get('satoshis')
|
||||
is_explicit = serializer.data.get('is_explicit')
|
||||
if not serializer.is_valid(): return Response(status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
valid, context = Logics.validate_already_maker_or_taker(request.user)
|
||||
if not valid:
|
||||
return Response(context, status=status.HTTP_409_CONFLICT)
|
||||
type = serializer.data.get('type')
|
||||
currency = serializer.data.get('currency')
|
||||
amount = serializer.data.get('amount')
|
||||
payment_method = serializer.data.get('payment_method')
|
||||
premium = serializer.data.get('premium')
|
||||
satoshis = serializer.data.get('satoshis')
|
||||
is_explicit = serializer.data.get('is_explicit')
|
||||
|
||||
# Creates a new order in db
|
||||
order = Order(
|
||||
type=otype,
|
||||
status=Order.Status.WFB,
|
||||
currency=currency,
|
||||
amount=amount,
|
||||
payment_method=payment_method,
|
||||
premium=premium,
|
||||
satoshis=satoshis,
|
||||
is_explicit=is_explicit,
|
||||
expires_at=timezone.now()+timedelta(minutes=EXPIRATION_MAKE),
|
||||
maker=request.user)
|
||||
valid, context = Logics.validate_already_maker_or_taker(request.user)
|
||||
if not valid: return Response(context, status=status.HTTP_409_CONFLICT)
|
||||
|
||||
order.t0_satoshis=Logics.satoshis_now(order) # TODO reate Order class method when new instance is created!
|
||||
order.last_satoshis=Logics.satoshis_now(order)
|
||||
order.save()
|
||||
# Creates a new order
|
||||
order = Order(
|
||||
type=type,
|
||||
currency=currency,
|
||||
amount=amount,
|
||||
payment_method=payment_method,
|
||||
premium=premium,
|
||||
satoshis=satoshis,
|
||||
is_explicit=is_explicit,
|
||||
expires_at=timezone.now()+timedelta(minutes=EXP_MAKER_BOND_INVOICE),
|
||||
maker=request.user)
|
||||
|
||||
if not serializer.is_valid():
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
order.last_satoshis = order.t0_satoshis = Logics.satoshis_now(order) # TODO move to Order class method when new instance is created!
|
||||
|
||||
order.save()
|
||||
return Response(ListOrderSerializer(order).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
|
||||
class OrderView(viewsets.ViewSet):
|
||||
serializer_class = UpdateInvoiceSerializer
|
||||
serializer_class = UpdateOrderSerializer
|
||||
lookup_url_kwarg = 'order_id'
|
||||
|
||||
def get(self, request, format=None):
|
||||
@ -88,7 +83,7 @@ class OrderView(viewsets.ViewSet):
|
||||
if len(order) == 1 :
|
||||
order = order[0]
|
||||
|
||||
# If order expired
|
||||
# 1) If order expired
|
||||
if order.status == Order.Status.EXP:
|
||||
return Response({'bad_request':'This order has expired'},status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@ -99,11 +94,11 @@ class OrderView(viewsets.ViewSet):
|
||||
data['is_taker'] = order.taker == request.user
|
||||
data['is_participant'] = data['is_maker'] or data['is_taker']
|
||||
|
||||
# If not a participant and order is not public, forbid.
|
||||
# 2) If not a participant and order is not public, forbid.
|
||||
if not data['is_participant'] and order.status != Order.Status.PUB:
|
||||
return Response({'bad_request':'Not allowed to see this order'},status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# non participants can view some details, but only if PUB
|
||||
# 3) Non participants can view details (but only if PUB)
|
||||
elif not data['is_participant'] and order.status != Order.Status.PUB:
|
||||
return Response(data, status=status.HTTP_200_OK)
|
||||
|
||||
@ -114,45 +109,73 @@ class OrderView(viewsets.ViewSet):
|
||||
data['taker_nick'] = str(order.taker)
|
||||
data['status_message'] = Order.Status(order.status).label
|
||||
|
||||
# If status is 'waiting for maker bond', reply with a hodl invoice too.
|
||||
# 4) If status is 'waiting for maker bond', reply with a MAKER HODL invoice.
|
||||
if order.status == Order.Status.WFB and data['is_maker']:
|
||||
valid, context = Logics.gen_maker_hodl_invoice(order, request.user)
|
||||
if valid:
|
||||
data = {**data, **context}
|
||||
else:
|
||||
Response(context, status=status.HTTP_400_BAD_REQUEST)
|
||||
data = {**data, **context} if valid else Response(context, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 5) If status is 'Public' and user is taker/buyer, reply with a TAKER HODL invoice.
|
||||
elif order.status == Order.Status.PUB and data['is_taker'] and data['is_buyer']:
|
||||
valid, context = Logics.gen_takerbuyer_hodl_invoice(order, request.user)
|
||||
data = {**data, **context} if valid else Response(context, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 6) If status is 'Public' and user is taker/seller, reply with a ESCROW HODL invoice.
|
||||
elif order.status == Order.Status.PUB and data['is_taker'] and data['is_seller']:
|
||||
valid, context = Logics.gen_seller_hodl_invoice(order, request.user)
|
||||
data = {**data, **context} if valid else Response(context, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 7) If status is 'WF2/WTC' and user is maker/seller, reply with an ESCROW HODL invoice.
|
||||
elif (order.status == Order.Status.WF2 or order.status == Order.Status.WF2) and data['is_maker'] and data['is_seller']:
|
||||
valid, context = Logics.gen_seller_hodl_invoice(order, request.user)
|
||||
data = {**data, **context} if valid else Response(context, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
return Response(data, status=status.HTTP_200_OK)
|
||||
|
||||
return Response({'Order Not Found':'Invalid Order Id'},status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
|
||||
|
||||
def take_or_update(self, request, format=None):
|
||||
def take_update_confirm_dispute_cancel(self, request, format=None):
|
||||
order_id = request.GET.get(self.lookup_url_kwarg)
|
||||
|
||||
serializer = UpdateInvoiceSerializer(data=request.data)
|
||||
serializer = UpdateOrderSerializer(data=request.data)
|
||||
if not serializer.is_valid(): return Response(status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
order = Order.objects.get(id=order_id)
|
||||
|
||||
if serializer.is_valid():
|
||||
invoice = serializer.data.get('invoice')
|
||||
# action is either 1)'take', 2)'confirm', 3)'cancel', 4)'dispute' , 5)'update' (invoice) 6)'rate' (counterparty)
|
||||
action = serializer.data.get('action')
|
||||
invoice = serializer.data.get('invoice')
|
||||
rating = serializer.data.get('rating')
|
||||
|
||||
# 1) If action is take, it is be taker request!
|
||||
if action == 'take':
|
||||
if order.status == Order.Status.PUB:
|
||||
valid, context = Logics.validate_already_maker_or_taker(request.user)
|
||||
if not valid: return Response(context, status=status.HTTP_409_CONFLICT)
|
||||
|
||||
Logics.take(order, request.user)
|
||||
else: Response({'bad_request':'This order is not public anymore.'}, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# 2) If action is update (invoice)
|
||||
elif action == 'update' and invoice:
|
||||
updated, context = Logics.update_invoice(order,request.user,invoice)
|
||||
if not updated: return Response(context,status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# If this is an empty POST request (no invoice), it must be taker request!
|
||||
if not invoice and order.status == Order.Status.PUB:
|
||||
valid, context = Logics.validate_already_maker_or_taker(request.user)
|
||||
if not valid: return Response(context, status=status.HTTP_409_CONFLICT)
|
||||
# 3) If action is cancel
|
||||
elif action == 'cancel':
|
||||
pass
|
||||
|
||||
Logics.take(order, request.user)
|
||||
# 4) If action is confirm
|
||||
elif action == 'confirm':
|
||||
pass
|
||||
|
||||
# An invoice came in! update it
|
||||
elif invoice:
|
||||
print(invoice)
|
||||
updated = Logics.update_invoice(order=order,user=request.user,invoice=invoice)
|
||||
if not updated:
|
||||
return Response({'bad_request':'Invalid Lightning Network Invoice. It starts by LNTB...'})
|
||||
|
||||
# Something else is going on. Probably not allowed.
|
||||
# 5) If action is dispute
|
||||
elif action == 'dispute':
|
||||
pass
|
||||
|
||||
# 6) If action is dispute
|
||||
elif action == 'rate' and rating:
|
||||
pass
|
||||
|
||||
# If nothing... something else is going on. Probably not allowed!
|
||||
else:
|
||||
return Response({'bad_request':'Not allowed'})
|
||||
|
||||
@ -264,6 +287,7 @@ class BookView(ListAPIView):
|
||||
user = User.objects.filter(id=data['maker'])
|
||||
if len(user) == 1:
|
||||
data['maker_nick'] = user[0].username
|
||||
|
||||
# Non participants should not see the status or who is the taker
|
||||
for key in ('status','taker'):
|
||||
del data[key]
|
||||
|
@ -87,8 +87,10 @@ export default class OrderPage extends Component {
|
||||
console.log(this.state)
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')},
|
||||
body: JSON.stringify({}),
|
||||
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken'),},
|
||||
body: JSON.stringify({
|
||||
'action':'take',
|
||||
}),
|
||||
};
|
||||
fetch('/api/order/' + '?order_id=' + this.orderId, requestOptions)
|
||||
.then((response) => response.json())
|
||||
|
Loading…
Reference in New Issue
Block a user