예제 #1
0
 def get(self, beneficiary_id: str):
     try:
         if beneficiary_id:
             beneficiary = Beneficiary.objects(
                 id=beneficiary_id).get().clean_data()
             return jsonify(Beneficiary)
         else:
             beneficiaries = [
                 v.clean_data()
                 for v in Beneficiary.objects(is_active=True).all()
             ]
             return jsonify({"list": beneficiaries})
     except Exception as error:
         return jsonify({"error": str(error)}), 400
    def run(self):
        headers = [
            self.FIELD_TITLE[f] if f in self.FIELD_TITLE else f
            for f in self.FIELDS
        ]
        rows = [headers]

        for user in Beneficiary.objects().order_by('+last_name', '+first_name',
                                                   '-age'):
            row = []
            for field in self.FIELDS:
                value = getattr(user, field)
                if field in self.tag2v.keys():
                    if ObjectId.is_valid(value):
                        tg = Tags.objects(id=value)
                        if tg:
                            row.append(tg.get().clean_data()['ro'])
                        else:
                            row.append(value)
                    else:
                        row.append(value)
                elif isinstance(value, bool):
                    row.append(1 if value else 0)
                else:
                    row.append(value)
            rows.append(row)

        return rows
예제 #3
0
def save_receive(beneficiary_id, data):
    """Uploads and saves images of shopping receipts from telegram bot api
    :param beneficiary_id: str, Beneficiary ID for whom was done the request
    :param data: bytearray, raw data corresponding to the image of shopping receipt
    :return: if the response is success then will return a json as {"response": "success"},
            otherwise - {"error": "error message"}
    """
    try:
        image = Image.open(io.BytesIO(base64.b64decode(data.encode())))
        save_path = f'{AJUBOT_RECEIPT_PATH}/{beneficiary_id}_{"{:%Y%m%d_%H%M%S}".format(datetime.now())}.{image.format.lower()}'
        image.save(save_path)
        Beneficiary.objects(id=beneficiary_id).update(sent_foto=True,
                                                      path_receipt=save_path)
        return jsonify({"response": "success"})
    except Exception as error:
        return jsonify({"error": str(error)}), 400
예제 #4
0
    def put(self, beneficiary_id, delete=False):
        """update a single user by id"""
        update = {}
        if not delete:
            for key, value in request.json:
                if key == "password":
                    value = PassHash.hash(value)
                update[f"set__{key}"] = value
        else:
            update["set__is_active"] = False

        try:
            Beneficiary.objects(id=beneficiary_id).get().update(**update)
            return jsonify({"response": "success"})
        except Exception as error:
            return jsonify({"error": str(error)}), 400
예제 #5
0
 def post(self):
     """create a new user"""
     new_Beneficiary = request.json
     # TODO: get authenticated Beneficiary and assignee to new Beneficiary
     # new_Beneficiary["created_by"] = authenticated_oprator
     try:
         assert len(
             new_Beneficiary["password"]
         ) >= MIN_PASSWORD_LEN, f"Password is to short, min length is {MIN_PASSWORD_LEN}"
         new_Beneficiary["password"] = PassHash.hash(
             new_Beneficiary["password"])
         comment = Beneficiary(**new_Beneficiary)
         comment.save()
         return jsonify({"response": "success"})
     except Exception as error:
         return jsonify({"error": str(error)}), 400
def makejson(v, user):
    u = {'distance': calc_distance(v, user), '_id': str(v['_id'])}
    for k in ['first_name','last_name','phone','email','activity_types', 'telegram_chat_id', 'latitude','longitude']:
        if k in v:
            u[k] =v[k]
    u['accepted_offer'] = False
    for it in v['offer_list']:
        if it['id'] == user['_id']:
            u['availability_day'] = utc_short_to_user_short(it['offer'])
            u['accepted_offer'] = True
    u['count'] = Beneficiary.objects(volunteer=str(v['_id']),created_at__lte=dt.now() - timedelta(days=1)).count()
    return u
예제 #7
0
def get_beneficiaries_by_filters(filters, pages=0, per_page=10000):
    try:
        item_per_age = int(per_page)
        offset = (int(pages) - 1) * item_per_age
        if len(filters) > 0:
            flt = {}
            to_bool = {'true': True, 'false': False}
            cases = ['first_name', 'last_name']
            if 'phone_name' in filters.keys():
                phone_name = filters.get('phone_name')
                if phone_name.isdigit():
                    nr = len(phone_name)
                    phone_name = int(phone_name) % 10000000
                    phone_name_ = phone_name + 1
                    #return jsonify({"error": phone_name*10**(8-nr), 'd':phone_name_*10**(8-nr)}), 400
                    obj = Beneficiary.objects(
                        phone__gt=phone_name * 10**(8 - nr),
                        phone__lt=phone_name_ *
                        10**(8 - nr)).order_by('-created_at')
                else:
                    obj = Beneficiary.objects(
                        Q(first_name__istartswith=phone_name) | Q(last_name__istartswith=phone_name))\
                        .order_by('-created_at')
            else:
                for k, v in filters.items():
                    flt[k + '__iexact' if k in cases else k] = to_bool[
                        v.lower()] if v.lower() in to_bool else v
                obj = Beneficiary.objects(**flt).order_by('-created_at')
            beneficiaries = [
                v.clean_data() for v in obj.skip(offset).limit(item_per_age)
            ]
            return jsonify({"list": beneficiaries, 'count': obj.count()})
        else:
            obj = Beneficiary.objects().order_by('-created_at')
            beneficiaries = [
                v.clean_data() for v in obj.skip(offset).limit(item_per_age)
            ]
            return jsonify({"list": beneficiaries, 'count': obj.count()})
    except Exception as error:
        return jsonify({"error": str(error)}), 400
예제 #8
0
def getBeneficiary(args):
    try:
        id = args.get('id')
        if id:
            beneficiary = Beneficiary.objects(id=id).get().clean_data()
            return jsonify(beneficiary)
        else:
            try:
                is_active = bool(args.get('is_active', None, bool))
                first_name = args.get('first_name', None, str)
                phone = args.get('phone', None, int)
                created_date_start = args.get('created_date_start', None, dt)
                created_date_end = args.get('created_date_end', None, dt)
                item_start = args.get('item_start', None, int)
                item_end = args.get('item_end', None, int)
            except Exception as _:
                return jsonify({"error": "Incorrect arg(s)."})

            ben_objs = Beneficiary.objects()
            if (is_active):
                ben_objs.filter(is_active=is_active)
            if (first_name):
                ben_objs.filter(first_name=first_name)
            if (phone):
                ben_objs.filter(phone=phone)
            if (created_date_start and created_date_end):
                ben_objs.filter((Q(created_at__gte=created_date_start)
                                 & Q(created_at__lte=created_date_end)))
            count = ben_objs.all().count()
            if (item_start and item_end):
                ben_objs.skip(item_start).limit(item_end)
            beneficiaries = [v.clean_data() for v in ben_objs.all()]
            return jsonify({"list": beneficiaries},
                           {"pagination": {
                               "count_of_records": count
                           }})
    except Exception as error:
        return jsonify({"error": str(error)}), 400
def get_volunteers_by_filters(filters, pages=0, per_page=10000):
    try:
        item_per_age = int(per_page)
        offset = (int(pages) - 1) * item_per_age
        if len(filters) > 0:
            flt = {}
            toBool = {'true':True, 'false': False}
            caseS = ['first_name', 'last_name']
            for v,k in filters.items():
                flt[v+'__iexact' if v in caseS else v] = toBool[k.lower()] if k.lower() in toBool else k

            obj = Volunteer.objects(**flt)
            volunteers = [v.clean_data() for v in obj.order_by('-created_at').skip(offset).limit(item_per_age)]
            for i,volunteer in enumerate(volunteers):
                    volunteers[i]['cases_solved'] =  Beneficiary.objects(volunteer=volunteer['_id']).count()
            return jsonify({"list": volunteers, 'count':obj.count()})
        else:
            obj = Volunteer.objects().order_by('-created_at')
            volunteers = [v.clean_data() for v in obj.skip(offset).limit(item_per_age)]
            for i,volunteer in enumerate(volunteers):
                    volunteers[i]['cases_solved'] =  Beneficiary.objects(volunteer=volunteer['_id']).count()
            return jsonify({"list": volunteers, 'count':obj.count()})
    except Exception as error:
        return jsonify({"error": str(error)}), 400
예제 #10
0
def registerBeneficiary(requestjson, created_by, fixer_id):
    """create a new user"""
    new_beneficiary = requestjson
    if len(created_by) > 30:
        user = Operator.verify_auth_token(created_by)
        created_by = user.get().clean_data()['email']
    try:
        new_beneficiary['password'] = '******'
        new_beneficiary['email'] = '*****@*****.**'
        assert len(
            new_beneficiary["password"]
        ) >= MIN_PASSWORD_LEN, f"Password is to short, min length is {MIN_PASSWORD_LEN}"
        new_beneficiary["password"] = PassHash.hash(
            new_beneficiary["password"])
        new_beneficiary['created_by'] = created_by
        new_beneficiary['fixer'] = str(fixer_id)
        comment = Beneficiary(**new_beneficiary)
        comment.save()
        if 'is_active' in new_beneficiary and new_beneficiary['is_active']:
            #sent the request to the volunteer via telegram
            telegrambot.send_request(comment)
        return jsonify({"response": "success", 'user': comment.clean_data()})
    except Exception as error:
        return jsonify({"error": str(error)}), 400
예제 #11
0
def updateBeneficiary(requestjson, beneficiary_id, delete=False):
    """update a single user by id"""
    print(beneficiary_id, '---')
    update = {}
    if not delete:
        for key, value in requestjson.items():
            if key == '_id':
                continue
            if key == "password":
                value = PassHash.hash(value)
            update[f"set__{key}"] = value
    else:
        update["set__is_active"] = False

    try:
        obj = Beneficiary.objects(id=beneficiary_id).get()
        data = obj.clean_data()  #and not data['is_active']
        if ('set__is_active' in update and update['set__is_active'] and not data['is_active']) \
            or ('set__offer' in update and update['set__offer'] != data['offer']) \
                or ('set__address' in update and update['set__address'] != data['address']):
            #change to active or different volunteer category or different address
            #return jsonify(telegrambot.send_request(obj))
            telegrambot.send_request(obj)
        elif 'set__volunteer' in update and requestjson[
                'volunteer'] != '' and requestjson[
                    'volunteer'] is not None and (
                        'volunteer' not in data
                        or update['set__volunteer'] != data['volunteer']):
            telegrambot.send_assign(beneficiary_id, requestjson['volunteer'])
        elif 'set__status' in update and update['set__status'].lower(
        ) == 'cancelled':
            #if the volunteer refused the request, delete the link
            volunteer_updates = {
                "push__offer_list": {
                    "id": beneficiary_id,
                    "offer": data['offer'],
                    "cancelled": True
                }
            }
            volunteer.update_volunteer(requestjson['volunteer'],
                                       volunteer_updates)
            update['set__volunteer'] = ''
            update['set__status'] = update['set__status'].lower()
        obj.update(**update)
        return jsonify({"response": "success"})
    except Exception as error:
        return jsonify({"error": str(error)}), 400
예제 #12
0
def updateBeneficiaryTG(requestjson):
    beneficiary_id = requestjson['request_id']
    print(beneficiary_id, '---')
    update = {
        'push__questions':
        'pretul:' + str(requestjson['amount']) + ', simptome:' +
        ','.join(requestjson['symptoms']),
        'push__comments':
        requestjson['further_comments'],
        'curator':
        requestjson['would_return'] == 1
    }

    try:
        obj = Beneficiary.objects(id=beneficiary_id).get()
        data = obj.clean_data()
        obj.update(**update)
        return jsonify({"response": "success"})
    except Exception as error:
        return jsonify({"error": str(error)}), 400
def sort_closest(id, topk, category):
    topk = int(topk)
    user = Beneficiary.objects(id=id).get().clean_data()
    filters = {}
    #get active volunteer with same activity type, with availability>0 and not bussy with other requests
    if 'offer' in user and user['offer']!='':
        category = user['offer']
        volunteers = sorted([makejson(v.clean_data(), user) for v in Volunteer.objects(is_active=True, #availability__gt=0,
                                                                                                         offer=category).all()\
                               # if not Beneficiary.objects(volunteer=str(v.clean_data()['_id']),status__ne='done')
                                ], key=lambda x: x['distance'])
    else:
        volunteers = sorted([makejson(v.clean_data(), user) for v in Volunteer.objects(is_active=True, #availability__gt=0,
                                                                                                         activity_types__in=user['activity_types']).all()\
                            ], key=lambda x: x['distance'])
    volunteers = [i for i in volunteers if i['distance']<100000]
    #todo: find the best threshhold!!!

    if 'volunteer' in user and user['volunteer']!='':
        volunteers = [makejson(Volunteer.objects(id=user['volunteer']).get().clean_data(), user)] + [i for i in volunteers if i['_id'] != user['volunteer']]
    return jsonify({'list':volunteers[:topk]})
def get_active_operator(days=2):
    days_diff = dt.now() - timedelta(days=days)
    pipeline_used_fixers = [{
        '$match': {
            'status': 'done',
            'created_at': {
                '$gte': days_diff
            }
        }
    }, {
        '$sort': {
            'created_at': 1
        }
    }, {
        '$group': {
            '_id': '$fixer',
            'count': {
                '$sum': 1
            }
        }
    }]
    fixers = []
    for f in Beneficiary.objects().aggregate(pipeline_used_fixers):
        fixers.append(f)

    available_fixers = [
        v.clean_data() for v in Operator.objects(
            is_active=True, role='fixer', created_at__gte=days_diff)
    ]
    available_fixers = [{'_id': af.get('_id')} for af in available_fixers]
    if len(fixers) is not 0 and len(fixers) == len(available_fixers):
        return fixers[0].get('_id')
    else:
        fixers_ids = [val['_id'] for val in fixers]
        fixer_id = None
        for af in available_fixers:
            fixer_id = af.get('_id')
            if fixer_id not in fixers_ids:
                break
        return fixer_id
def getVolunteers(filters):
        try:
            if len(filters.getlist('id')) == 1 :
                volunteer_id = filters.get('id')
                volunteer = Volunteer.objects(id=volunteer_id).get().clean_data()

                return jsonify(volunteer)
            elif len(filters.getlist("telegram_chat_id")) == 1:
                telegram_id = filters.get("telegram_chat_id")
                if len(Volunteer.objects(telegram_chat_id=telegram_id)) == 0:
                    return jsonify({"exists": False})
                else:
                    return jsonify({"exists": True})
            elif len(filters.getlist('id')) > 1:
                volunteers = [Volunteer.objects(id=volunteer_id).get().clean_data() for volunteer_id in filters.getlist('id')]
                return jsonify({"list": volunteers})
            else:
                volunteers = [v.clean_data() for v in Volunteer.objects(is_active=True).order_by('-created_at').all()]
                for i,volunteer in enumerate(volunteers):
                    volunteers[i]['cases_solved'] =  Beneficiary.objects(volunteer=volunteer['_id']).count()
                return jsonify({"list": volunteers})
        except Exception as error:
            return jsonify({"error": str(error)}), 400
    def test_get_active_operator_none_result(self):
        # Setup
        beneficiary = Beneficiary()
        beneficiary.first_name = 'John'
        beneficiary.last_name = 'Travolta'
        beneficiary.phone = '12345678'
        beneficiary.email = '*****@*****.**'
        beneficiary.address = 'address'
        beneficiary.zone_address = 'zone'
        beneficiary.status = 'done'
        beneficiary.fixer = '123456'
        beneficiary.password = '******'
        beneficiary.secret = 'secret'
        beneficiary.save()
        # Execute
        result = operator.get_active_operator()

        # Validate
        assert result is None