Esempio n. 1
0
    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
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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)
Esempio n. 7
0
    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)