def get_queryset(self): patent = self.request.query_params.get('patent',None) block = self.request.query_params.get('block',None) phone = self.request.query_params.get('phone',None) if not (patent or block or phone): queryset = Parking.objects.all() if block and patent and phone: phone = format_phone(phone) queryset = Parking.objects.filter(block__code=block, patent=patent, phone=phone) if block and patent: queryset = Parking.objects.filter(block__code=block, patent=patent) if block and phone: phone = format_phone(phone) queryset = Parking.objects.filter(block__code=block, phone=phone) if patent and phone: phone = format_phone(phone) queryset = Parking.objects.filter(patent=patent, phone=phone) if block: queryset = Parking.objects.filter(block__code=block) if patent: queryset = Parking.objects.filter(patent=patent) if phone: phone = format_phone(phone) queryset = Parking.objects.filter(phone=phone) return queryset
def pay_faults(self, request, phone=None): """POST: Pay list of unpayed faults. All the available credit can pay. :param str phone: ``POST`` url:: WS_HOST/api/endusers/{phone}/pay_faults/ { 'id_faults':[id1,id2, . . ] } :return: JSON Dictionary. ``JSON Dictionary`` returned:: { 'status' : <string>, 'data' : <dict>, 'msg' : <string>, } :rtype: :status: 'ERR' or 'OK' :msg: Descriptive text :data: Dict of dicts. Each objects is a recharge done by user. """ data = {} ret = {'msg': '', 'data': data, 'status': 'ERR'} idsl = request.data.get('id_faults') if type(idsl) is str: import ast ids = ast.literal_eval(idsl) else: ids = idsl if not ids: ret['msg'] = "No faults received, try again." return Response(ret) faults = Fault.objects.filter(pk__in=ids).order_by('date_creation') faults_np = faults.filter(payed=False).order_by('date_creation') try: phone = format_phone(phone) usr = EndUser.objects.get(phone=phone) except EndUser.DoesNotExist: ret['msg'] = "User not registered." faults_payed = [] for fault in faults_np: amount = fault.amount try: usr.credits = F('credits') - amount usr.save() faults_payed.append(fault.id) fault.payed = True fault.save() except: break try: fps = faults.filter(pk__in=faults_payed) data = FaultSerializer(fps, many=True).data if data: data = list_to_dict(data) ret = { 'msg': "Payed {} faults".format(fps.count()), 'data': data, 'status': 'OK' } except Exception as e: ret['msg'] = "Error when paying selected faults." # ----- If the parameter to send sms is on, we send sms to asociated users if get_setting_param("fault_notify_associated"): for fault in fps: d = fault.date_creation.strftime('%d/%m/%Y %H:%M') msg = "Fault done in " + d + ", was payed by " + phone + "." UsersPatents.send_msg_to_strong_asoc(fault.patent, None, msg) return Response(ret)
def credits_history(self, request, phone=None): """GET: Obtain data of recharges/transfers of a user. :param str phone: ``GET`` url:: WS_HOST/api/endusers/{phone}/credits_history/ :return: JSON Dictionary. ``JSON Dictionary`` returned:: { 'status' : <string>, 'data' : <dict>, 'msg' : <string>, } :rtype: :status: 'ERR' or 'OK' :msg: with a message we want to return to caller of WS :data: Dict of dicts. Key : id of transfer, Value: Dict with model field. """ ret = {'msg': "", 'data': {}, 'status': 'ERR'} filter = request.GET.get('filter', 'all').lower() last = request.GET.get('last', None) data = { 'recharges_card': None, 'by_reseller': None, 'payments_mp': None, 'to_friends': None, 'from_friends': None } # si el filtro que enviaron, no está en data. if filter != 'all' and filter not in data.keys(): # Marcamos por defecto el filtro como 'all' filter = 'all' try: phone = format_phone(phone) user = EndUser.objects.get(phone=phone) except EndUser.DoesNotExist: ret['msg'] = "phone " + phone + " do not have registered account." return Response(ret) except AttributeError as err: ret['msg'] = "Error accesing data in query. %s" % (err) return Response(ret) # Obtain historial. try: if filter == 'all' or filter == 'recharges_card': # Recharges con cards. recharges_set = RechargeCard.objects.filter( end_user__phone=phone).exclude(date_activated=None) recharges_card = RechargeCardSerializerHistory(recharges_set, many=True) data['recharges_card'] = list_to_dict(recharges_card.data) if filter == 'all' or filter == 'by_reseller': # Recharges from agent (transfer from un reseller). transfers_set = Transfers.objects.filter(user_to__phone=phone, is_reseller=True) by_reseller = TransfersSerializer(transfers_set, many=True) data['by_reseller'] = list_to_dict(by_reseller.data) if filter == 'all' or filter == 'payments_mp': # Recharges from MercadoPago (payment from the app). mp_recharges = PaymentMp.objects.filter(end_user__phone=phone) payments_mp = PaymentMpSerializerShort(mp_recharges, many=True) data['payments_mp'] = list_to_dict(payments_mp.data) if filter == 'all' or filter == 'to_friends': # transfer to other user. to_friend_transfers = Transfers.objects.filter( user_from__phone=phone, is_reseller=False) to_friends = TransfersSerializer(to_friend_transfers, many=True) data['to_friends'] = list_to_dict(to_friends.data) if filter == 'all' or filter == 'from_friends': from_friend_transfers = Transfers.objects.filter( user_to__phone=phone, is_reseller=False) from_friends = TransfersSerializer(from_friend_transfers, many=True) data['from_friends'] = list_to_dict(from_friends.data) # Recorremos el objeto data for item in data.keys(): # Si el objeto, fue llenado con algo y no es None: if data[item] is not None: # Lo agregamos al objeto que vamos a devolver. ret['data'][item] = data[item] except Exception as err: ret['msg'] = "Error. %s" % (err) print(err) return Response(ret, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: ret['msg'] = 'Data obtained ok.' ret['status'] = 'OK' return Response(ret)
def transfer(self, request, phone=None): """POST: Reseller, transfer money to client :param str phone: :param str phone_client: Phone of user that will receive the credits. :param int credits: amount of credits to transfer.. ``POST`` url:: WS_HOST/api/endusers/{phone}/transfer/ { 'phone_client': "+4593415667778", 'credits': 10 } :return: JSON Dictionary. ``JSON Dictionary`` returned:: { 'status' : <string>, 'data' : <dict>, 'msg' : <string>, } :rtype: :status: 'ERR' or 'OK' :msg: with a message we want to return to caller of WS :data: {} """ ret = {'msg': "", 'data': {}, 'status': 'ERR'} # ----- Get request data and check ----- # # We receive: Patent that will park, phone (must asoc to the patent), # duration (HH:MM:SS), block code user_from_phone = phone to_friend = request.data.get("to_friend", False) user_to_phone = request.data.get('user_to', None) credits = request.data.get("credits", None) credits = float(credits) if not (user_to_phone and credits): ret['msg'] = "All parameters needed." return Response(ret) if user_to_phone == user_from_phone: ret['msg'] = "Can not transfer to your number." return Response(ret) user_to_phone = format_phone(user_to_phone) # ----- User exists? ----- # try: user_from = EndUser.objects.get(phone=user_from_phone) user_to = EndUser.objects.get(phone=user_to_phone) except EndUser.DoesNotExist: ret['msg'] = "Phone " + user_to_phone + " do not have registered account." return Response(ret) except AttributeError as err: ret['msg'] = "Error. %s" % (err) return Response(ret) # ----- Reseller has enough credits ----- # user_from_credits = user_from.credits if credits > user_from_credits: ret['msg'] = "Credits not enough to make this transfer." return Response(ret) # ----- Transfer ----- # try: # Obtain value with F operator and save. If ok, then we park user_from.credits = F('credits') - credits user_from.save() if to_friend == False: amount_recharged = calc_amount_recharged(credits) else: amount_recharged = credits user_to.credits = F('credits') + amount_recharged user_to.save() # ifit is from resller if to_friend == False: res_hist = Transfers(user_from=user_from, user_to=user_to, credits=credits, credits_transfered=amount_recharged, is_reseller=True) res_hist.save() else: # if it is from end user res_hist = Transfers(user_from=user_from, user_to=user_to, credits=0, credits_transfered=amount_recharged, is_reseller=False) res_hist.save() except Exception as err: ret['msg'] = "Error. %s" % (err) return Response(ret, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: if to_friend == False: ret = { "status": "OK", "msg": "Transfer done to client.", "data": {} } else: ret = {"status": "OK", "msg": "Transfer done.", "data": {}} return Response(ret)
def login(self, request, phone=None): """POST: Get phone and pin and check if they match. :param str phone: Phone of user :param int pin: Pin (password). :param bool is_reseller: Flag that tell uf it is a reseller or not. ``POST`` url:: WS_HOST/api/endusers/{phone}/login/ { 'pin': 1234, 'is_reseller': True o False } :return: JSON Dictionary. ``JSON Dictionary`` returned:: { 'status' : <string>, 'data' : <dict>, 'msg' : <string>, } :rtype: :status: 'ERR' or 'OK' :msg: with a message we want to return to caller of WS :data: If login ok: {} . if not : {'token':<token>,'phone':<phone>} """ ret = {'msg': "", 'data': {}, 'status': 'ERR'} pin = request.data.get('pin') is_res = request.data.get('is_reseller', None) if not pin: ret['msg'] = "No pin received, try again." return Response(ret) try: phone = format_phone(phone) enduser = EndUser.objects.get(phone=phone) if is_res and not enduser.is_reseller: ret['msg'] = "Acceso Denegado." return Response(ret) if enduser.locked: ret['msg'] = "Blocked account. Please contact the people in charge of the application." elif enduser and enduser.pin: if int(enduser.pin) == int(pin): #enduser.locked = False if enduser.init_tries != 0: enduser.init_tries = 0 enduser.save() # Create token to validate request. # Maybe it is already created, we refresh it authobj, created = AuthToken.objects.update_or_create( phone=phone, defaults={'token': AuthToken.generate_key(40)}) data = {'phone': phone, 'token': authobj.token} ret = {'msg': "Login ok", 'data': data, 'status': 'OK'} else: if enduser.init_tries == INIT_TRIES - 1: ret = { 'msg': "Pin incorrecto. Se ha bloqueado su cuenta.", 'data': {}, 'status': 'ERR' } enduser.locked = True elif enduser.init_tries >= INIT_TRIES: ret = { 'msg': "Account blocked. Please contact the people in charge of the application.", 'data': {}, 'status': 'ERR' } else: ret = { 'msg': "Incorrect pin.", 'data': {}, 'status': 'ERR' } enduser.init_tries += 1 enduser.save() else: ret['msg'] = "The user has no pin assigned. Please contact the people in charge of the application." ret['status'] = "ERR" except EndUser.DoesNotExist: ret['msg'] = "User not registerd." except Exception as err: ret['msg'] = "An error occurred while trying to check the number pin. Try again." return Response(ret)
def create(self, request): """POST : Create end user :param str phone: Phone of user we will createo :param str name: Name :param str surname: Surname. :param str dni: id number :param str dni_type: Type of id. We can see posibilities in EndUser_ model :param email: :type email: [OPCIONAL] str ``POST`` url example:: WS_HOST/api/endusers/ { 'phone' : "+45341667889", 'name' : "Gonzalo", 'surname' : "Amadio", 'dni' : "33873841", 'dni_type' : "DNI", 'email' : "*****@*****.**", } :return: JSON Dictionary. ``JSON Dictionary`` returned:: { 'status' : <string>, 'data' : <dict>, 'msg' : <string>, } :rtype: :status: 'ERR' or 'OK' :msg: with a message we want to return to caller of WS :data: """ data = {} ret = {'msg': '', 'data': {}, 'status': 'ERR'} # ----- Get data of post and check them ----- # name = request.data.get("name", None) phone = request.data.get("phone", None) surname = request.data.get("surname", None) dni = request.data.get("dni", None) dni_type = request.data.get("dni_type", None) email = request.data.get("email", None) #optional if name is None or phone is None or surname is None or dni is None or dni_type is None: ret['msg'] = "Error: missing arguments." return Response(ret) try: phone = format_phone(phone) data = {'phone': phone} request.data['phone'] = phone except Exception as err: m = "%s" % err ret = {'status': 'ERR', 'data': data, 'msg': m} return Response(ret) # ----- If user exists, do not create and return ----- # # ----- If not, we create it and return OK. Also we create the token ----- # if EndUser.objects.filter(phone=phone).exists(): ret = { 'status': 'ERR', 'data': data, 'msg': 'Phone already registerd.' } return Response(ret) else: # Create user this wat, to use serializer validators as well. pin = gen_random_num_of_length(4) request.data['pin'] = pin serializer = EndUserSerializerAll(data=request.data) if serializer.is_valid(): serializer.save() authobj, created = AuthToken.objects.update_or_create( phone=phone, defaults={'token': AuthToken.generate_key(40)}) pin = str(pin) txt = "You have been registerd in SimplE. Your pin is: " + pin enviar_sms_list([(None, str(phone), txt)]) ret['status'] = 'OK' ret['msg'] = 'User created. Your pin should arrive by sms in a moment.' ret['data'] = {'token': authobj.token} else: for item in serializer.errors: ret['msg'] += serializer.errors.get(item)[0] + " " return Response(ret)
def create(self,request): """ In: patent : patent that will be Parking phone : phone of user that is parking phone_reseller : phone of reseller that will park someones car duration : duration of parking block_code : code of block where the car is going to park. Pueden pasar las situaciones, suponiendo que A es un usuario y B un reseller. There can be 3 situations (A user, B reseller): 1) A park himeslf, we receive phone and patent of A 2) B parks A, we receive only A's patent, and B's phone 3) B parks A, we receive A's patent and phone. And B's phone """ data = {} ret = {'status': 'ERR', 'data': data, 'msg': 'Error obteniendo datos'} patent = request.data.get("patent",None) phone = request.data.get("phone",None) phone_reseller = request.data.get("phone_reseller",None) duration = request.data.get("duration",None) block_code = request.data.get("block",None) # Flags to determine if it is normal parking , or a parking done by a reseller. # If it is done by resller, users's phone can be used to send sms for example. is_p = False is_pr = False if not (patent and duration and block_code and (phone or phone_reseller)): ret['msg'] = "Error en los datos recibidos." return Response(ret) if phone_reseller: phone_reseller = format_phone(phone_reseller) is_pr = True if phone: phone = format_phone(phone) if not is_pr: is_p = True # ----- check duration format ----- # try: duration_obj = duration_format_ok(duration) except Exception as err: ret['msg'] = "%s"%err return Response(ret) # ----- Users's existence -----# # Depending if it is a self park, or a resller park, we have to check # that corresponding users exist. Also, set corresponding user as None try: if is_pr: reseller_obj = self._end_user_exists(phone_reseller) if not reseller_obj.is_reseller: ret = {'msg':"Permiso denegado.",'data':{}, 'status':'ERR'} return Response(ret) enduser_obj = None userspatents_obj = None else: # User existence and asociation to patent enduser_obj = EndUser.objects.get(phone=phone) userspatents_obj = UsersPatents.objects.get(user=enduser_obj, patent=patent) reseller_obj = None block_obj = Block.objects.get(code=block_code) except UsersPatents.DoesNotExist: ret['msg'] = "Phone "+phone+" and patent "+patent+" not associated." return Response(ret) except Block.DoesNotExist: ret['msg'] = "Block "+block_code+" does not exist." return Response(ret) except AttributeError as err: ret['msg'] = "Internal Error. %s" % (err) return Response(ret) # ----- patent YA ESTACIONADA? ----- # try: last_parking = Parking.objects.filter(patent=patent).last() if last_parking and last_parking.remaining_time > 0: ret['msg'] = "The patent is already parked on block: "+last_parking.block.code+"." return Response(ret) except Parking.DoesNotExist: pass except Exception as e: ret['msg'] = "Error %s"%(e) return Response(ret) # ----- Park ----- # # zd = zonedetails_nearest_range(block_obj.zone.code) kw = { 'block_code': block_code, 'block_obj': block_obj, 'duration': duration, 'duration_obj': duration_obj, 'enduser_obj': enduser_obj, # 'is_p': is_p, # 'is_pr': is_pr, # 'last_parking_obj': last_parking, 'patent': patent, 'phone': phone, 'phone_reseller': phone_reseller, 'reseller_obj': reseller_obj, 'ret': ret, # 'userspatents_obj': userspatents_obj, # 'zone_details': zd, 'zone_code': block_obj.zone.code } #ret = _park(block_obj,patent,duration_obj,phone,phone_reseller,enduser_obj,reseller_obj) #ret = _park(**locals()) # Call it this way, not to pass the function the entire request, # self variable, that goes into locals(). Also this way, param can be modified ret = self._park(self,**kw) return Response(ret)