def post(self, community_id):
        data = parser.parse_args()

        owner = UserModel.find_by_username(get_jwt_identity())
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]

        if not community:
            abort(400, message=COMMUNIY_DOESNT_EXIST)

        if owner.id not in community_member_ids:
            abort(401, message=UNAUTHORIZED)

        if not data['end'] > data['start']:
            abort(400, message=END_MUST_BE_AFTER_START)

        new_event = EventModel(owner=owner,
                               title=data['title'],
                               description=data['description'],
                               start=data['start'],
                               end=data['end'],
                               community_id=community.id)

        try:
            new_event.persist()
            return new_event, 201
        except:
            abort(500, message=INTERNAL_SERVER_ERROR)
Ejemplo n.º 2
0
    def post(self, community_id):
        data = parser.parse_args()

        owner = UserModel.find_by_username(get_jwt_identity())
        community: CommunityModel = CommunityModel.find_by_id(community_id)

        if not community:
            abort(400, message=COMMUNIY_DOESNT_EXIST)

        if owner.id not in [u.id for u in community.users]:
            abort(401, message=UNAUTHORIZED)

        new_refuel = RefuelModel(
            owner=owner,
            community=community,
            costs=round(data['costs'], 2),
            liters=data['liters'],
            gas_station_name=data['gas_station_name'],
        )

        try:
            new_refuel.persist()
            return new_refuel, 201
        except:
            abort(500, message=INTERNAL_SERVER_ERROR)
Ejemplo n.º 3
0
    def put(self, community_id, id):
        data = finish_tour_parser.parse_args()

        tour = TourModel.find_by_id(id)
        user = UserModel.find_by_username(get_jwt_identity())
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]

        if not tour:
            abort(404, message=TOUR_NOT_FOUND)

        if not user.id == tour.owner.id:
            abort(401, message=UNAUTHORIZED)

        if tour.end_km:
            abort(400, message=TOUR_HAS_ALREADY_BEEN_FINISHED)

        passengers = []
        if data['passengers']:
            for passenger_id in set(data['passengers']):
                if passenger_id not in community_member_ids:
                    abort(400, message=PASSENGERS_MUST_BE_COMMUNITY_MEMBERS)
                else:
                    passengers.append([u for u in community.users if u.id == passenger_id][0])

        tour.end_time = datetime.datetime.now(pytz.utc)
        tour.passengers = passengers
        tour.end_km = data['end_km']
        tour.comment = data['comment']
        tour.parking_position = data['parking_position']
        tour.persist()

        create_km_triggered_task_instances(community_id, tour.end_km)

        return tour, 200
Ejemplo n.º 4
0
    def post(self):
        data = invitation_parser.parse_args()

        user = UserModel.find_by_username(data['user'])
        community = CommunityModel.find_by_id(data['community'])

        if not user:
            abort(404, message=USER_DOESNT_EXIST)

        if not community:
            abort(404, message=COMMUNIY_DOESNT_EXIST)

        if user in community.users:
            abort(400, message=USER_ALREADY_INVITED)

        new_community_user_link = CommunityUserLinkModel(
            user_id=user.id,
            community_id=community.id,
            invitation_accepted=False,
            is_owner=False)

        try:
            new_community_user_link.persist()
            return SimpleMessage(COMMUNIY_INVITATION_SENT), 200
        except:
            abort(500, message=INTERNAL_SERVER_ERROR)
Ejemplo n.º 5
0
    def get(self, community_id):
        user = UserModel.find_by_username(get_jwt_identity())
        community = CommunityModel.find_by_id(community_id)

        if user not in community.users:
            abort(401, message=UNAUTHORIZED)

        return community.users, 200
Ejemplo n.º 6
0
    def get(self, community_id):
        tasks: List[TaskModel] = TaskModel.find_by_community(community_id)
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]
        user = UserModel.find_by_username(get_jwt_identity())

        if user.id not in community_member_ids:
            abort(401, message=UNAUTHORIZED)

        set_km_to_next_instance(tasks)

        return tasks, 200
Ejemplo n.º 7
0
    def get(self, community_id):

        user = UserModel.find_by_username(get_jwt_identity())
        community = CommunityModel.find_by_id(community_id)

        if not community:
            abort(400, message=COMMUNIY_DOESNT_EXIST)

        if user.id not in [u.id for u in community.users]:
            abort(401, message=UNAUTHORIZED)

        return TourModel.find_running_by_community(community_id), 200
Ejemplo n.º 8
0
    def put(self, id):
        data = put_parser.parse_args()

        community = CommunityModel.find_by_id(id)

        if not community:
            abort(404, message=COMMUNIY_DOESNT_EXIST)

        community.name = data['name']
        community.persist()

        return community, 200
Ejemplo n.º 9
0
    def get(self, id):
        community = CommunityModel.find_by_id(id)
        user = UserModel.find_by_username(get_jwt_identity())

        if not community:
            abort(404, message=COMMUNIY_DOESNT_EXIST)

        if user.id not in [u.id for u in community.users]:
            abort(401, message=UNAUTHORIZED)

        debts = DebtModel.find_unsettled_by_community(id)

        return debts, 200
    def get(self, community_id):
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]
        user = UserModel.find_by_username(get_jwt_identity())

        if user.id not in community_member_ids:
            abort(401, message=UNAUTHORIZED)

        task_instances: List[
            TaskInstanceModel] = TaskInstanceModel.find_by_community(
                community_id)
        open_task_instances = [i for i in task_instances if i.is_open]

        return open_task_instances, 200
Ejemplo n.º 11
0
    def get(self, community_id: int):

        user = UserModel.find_by_username(get_jwt_identity())
        community = CommunityModel.find_by_id(community_id)

        if not community:
            abort(404, message=COMMUNIY_DOESNT_EXIST)

        if user not in community.users:
            abort(401, message=UNAUTHORIZED)

        invitations = CommunityUserLinkModel.find_open_invitations_by_community(
            community_id)
        return [i.user for i in invitations], 200
Ejemplo n.º 12
0
    def get(self, community_id):
        user = UserModel.find_by_username(get_jwt_identity())
        community = CommunityModel.find_by_id(community_id)

        if not community:
            abort(400, message=COMMUNIY_DOESNT_EXIST)

        if user.id not in [u.id for u in community.users]:
            abort(401, message=UNAUTHORIZED)

        tour = TourModel.find_newest_tour_for_community(community_id)

        if not tour:
            abort(400, message=NO_TOUR_EXISTING)

        return tour, 200
Ejemplo n.º 13
0
    def get(self, community_id, number_of_events):

        owner = UserModel.find_by_username(get_jwt_identity())
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]

        if not community:
            abort(400, message=COMMUNIY_DOESNT_EXIST)

        if owner.id not in community_member_ids:
            abort(401, message=UNAUTHORIZED)

        events: EventModel = EventModel.find_next_n_by_community(
            community_id, number_of_events)

        return events, 200
Ejemplo n.º 14
0
    def get(self, id):

        user = UserModel.find_by_username(get_jwt_identity())

        community = CommunityModel.find_by_id(id)
        if not community:
            abort(404, message=COMMUNIY_DOESNT_EXIST)

        if user not in community.users:
            abort(401, message=UNAUTHORIZED)

        is_owner = CommunityUserLinkModel.find_by_user_and_community(
            user.id, community.id).is_owner
        community.is_deletable = is_owner
        community.is_editable = is_owner

        return community, 200
def get_community_statistic(community_id, from_datetime, to_datetime):
    community: CommunityModel = CommunityModel.find_by_id(community_id)

    if not community:
        abort(404, message=COMMUNIY_DOESNT_EXIST)

    user = UserModel.find_by_username(get_jwt_identity())

    community_member_ids = [m.id for m in community.users]
    if user.id not in community_member_ids:
        abort(401, message=UNAUTHORIZED)

    statistic = CommunityStatisticModel()
    statistic.community = community
    statistic.statistic_start = from_datetime
    statistic.statistic_end = to_datetime

    all_tours = TourModel.find_finished_by_community(community_id)
    all_costs = RefuelModel.find_by_community(community_id)
    km_per_user_dict = {}
    costs_per_user_dict = {}
    for user in community.users:
        km_per_user_dict[user.id] = KmPerUserModel()
        km_per_user_dict[user.id].user = user
        statistic.km_per_user.append(km_per_user_dict[user.id])
        costs_per_user_dict[user.id] = CostsPerUserModel()
        costs_per_user_dict[user.id].user = user
        statistic.costs_per_user.append(costs_per_user_dict[user.id])
    for tour in all_tours:
        if from_datetime <= tour.end_time.astimezone(pytz.utc) <= to_datetime:
            tour_km = tour.end_km - tour.start_km
            km_per_user_dict[tour.owner_id].km += tour_km
            # Divide km of passengers
            all_passengers_ids = [tour.owner_id] + [
                passenger.id for passenger in tour.passengers
            ]
            for passenger_id in all_passengers_ids:
                km_per_user_dict[
                    passenger_id].km_accounted_for_passengers += tour_km / len(
                        all_passengers_ids)
    for cost in all_costs:
        if from_datetime <= cost.time_created.astimezone(
                pytz.utc) <= to_datetime:
            costs_per_user_dict[cost.owner_id].costs += cost.costs

    return statistic
Ejemplo n.º 16
0
    def get(self, id):

        payoff = PayoffModel.find_by_id(id)

        if not payoff:
            abort(404, message=PAYOFF_DOESNT_EXIST)

        community = CommunityModel.find_by_id(payoff.community_id)
        user = UserModel.find_by_username(get_jwt_identity())

        if not community:
            abort(404, message=COMMUNIY_DOESNT_EXIST)

        if user.id not in [u.id for u in community.users]:
            abort(401, message=UNAUTHORIZED)

        return payoff, 200
Ejemplo n.º 17
0
    def get(self):
        data = search_parser.parse_args()
        username = get_jwt_identity()
        users = UserModel.search_by_username(data['q'], username)
        if not data['only-uninvited']:
            return users
        else:
            if not data['community']:
                abort(400, message=NO_COMMUNITY_ID_GIVEN)

            community = CommunityModel.find_by_id(data['community'])
            if not community:
                abort(404, message=COMMUNIY_DOESNT_EXIST)

            if username not in [u.username for u in community.users]:
                abort(401, message=UNAUTHORIZED)

            invitations = CommunityUserLinkModel.find_by_community(data['community'])
            return [u for u in users if u.id not in [i.user_id for i in invitations]]
Ejemplo n.º 18
0
    def get(self, community_id, from_datetime, to_datetime):

        owner = UserModel.find_by_username(get_jwt_identity())
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]

        if not community:
            abort(400, message=COMMUNIY_DOESNT_EXIST)

        if owner.id not in community_member_ids:
            abort(401, message=UNAUTHORIZED)

        from_datetime = moment(from_datetime)
        to_datetime = moment(to_datetime)

        if not to_datetime > from_datetime:
            abort(400, message=TO_MUST_BE_AFTER_FROM)

        events: EventModel = EventModel.find_by_community(
            community_id, from_datetime, to_datetime)

        return events, 200
Ejemplo n.º 19
0
    def put(self, community_id, id):
        data = edit_tour_parser.parse_args()

        tour = TourModel.find_by_id(id)
        user = UserModel.find_by_username(get_jwt_identity())
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]

        if not tour:
            abort(404, message=TOUR_NOT_FOUND)

        if not user.id == tour.owner.id:
            abort(401, message=UNAUTHORIZED)

        passengers = []
        if data['passengers']:
            for passenger_id in set(data['passengers']):
                if passenger_id not in community_member_ids:
                    abort(400, message=PASSENGERS_MUST_BE_COMMUNITY_MEMBERS)
                else:
                    passengers.append([u for u in community.users if u.id == passenger_id][0])

        tour.comment = data['comment']
        tour.parking_position = data['parking_position']

        if not tour.is_open:
            abort(400, message=CANNOT_UPDATE_SENSITIVE_TOUR_DATA_WHEN_TOUR_IS_ALREADY_PAYED_FOR)
        else:
            if data['end_km'] <= data['start_km']:
                abort(400, message=END_KM_MUST_BE_GREATER_START_KM)
            tour.end_km = data['end_km']
            tour.start_km = data['start_km']
            tour.passengers = passengers

        tour.persist()

        return tour, 200
Ejemplo n.º 20
0
    def post(self, community_id):
        data = parser.parse_args()

        owner = UserModel.find_by_username(get_jwt_identity())
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]

        if not community:
            abort(400, message=COMMUNIY_DOESNT_EXIST)

        if owner.id not in community_member_ids:
            abort(401, message=UNAUTHORIZED)

        if TourModel.find_running_by_community(community_id):
            abort(400, message=CANT_START_TOUR_WHEN_HAVING_UNFINISHED_TOURS_IN_COMMUNITY)

        passengers = []
        if data['passengers']:
            for passenger_id in set(data['passengers']):
                if passenger_id not in community_member_ids:
                    abort(400, message=PASSENGERS_MUST_BE_COMMUNITY_MEMBERS)
                else:
                    passengers.append([u for u in community.users if u.id == passenger_id][0])

        new_tour = TourModel(
            owner=owner,
            community=community,
            start_time=datetime.datetime.now(pytz.utc),
            start_km=data['start_km'],
            passengers=passengers
        )

        try:
            new_tour.persist()
            return new_tour, 201
        except:
            abort(500, message=INTERNAL_SERVER_ERROR)
Ejemplo n.º 21
0
    def post(self, community_id):
        parser = reqparse.RequestParser()
        parser.add_argument('time_next_instance', type=moment, required=False)
        parser.add_argument('time_interval', type=int, required=False)
        parser.add_argument('name', type=str)
        parser.add_argument('description', type=str)
        parser.add_argument('km_interval', type=int, required=False)
        parser.add_argument('km_next_instance', type=float, required=False)
        parser.add_argument('is_reocurrent', type=bool, required=True)
        data = parser.parse_args()

        owner = UserModel.find_by_username(get_jwt_identity())
        community: CommunityModel = CommunityModel.find_by_id(community_id)
        community_member_ids = [m.id for m in community.users]

        if not community:
            abort(400, message=COMMUNIY_DOESNT_EXIST)

        if owner.id not in community_member_ids:
            abort(401, message=UNAUTHORIZED)

        if data['is_reocurrent'] and (
                not (data['time_next_instance'] and data['time_interval'] or data['km_interval'] and data[
            'km_next_instance']) or data['km_interval'] and (data['time_interval'] or data['time_next_instance']) or \
                data['time_interval'] and (data['km_interval'] or data['km_next_instance'])):
            abort(400, message=TASK_MUST_BE_EITHER_TIME_OR_KM_TRIGGERED)

        newest_tour: TourModel = TourModel.find_newest_tour_for_community(community_id)
        if data['km_next_instance'] and data['km_next_instance'] < newest_tour.end_km:
            abort(400, message=TASK_KM_NEXT_INSTANCE_MUST_BE_HIGHER_THEN_CURRENT_KM)

        if data['time_next_instance'] and data['time_next_instance'] < datetime.now(pytz.timezone('Europe/Berlin')):
            abort(400, message=TASK_TIME_NEXT_INSTANCE_MUST_BE_HIGHER_THEN_CURRENT_TIME)

        time_interval = None
        if data['time_interval']:
            time_interval = timedelta(days=data['time_interval'])

        new_task = TaskModel(
            owner=owner,
            community=community,
            time_interval=time_interval,
            time_next_instance=data['time_next_instance'],
            km_interval=data['km_interval'],
            km_next_instance=data['km_next_instance'],
            name=data['name'],
            description=data['description'],
            is_reocurrent=data['is_reocurrent']
        )

        try:
            new_task.persist()
            set_km_to_next_instance(new_task)

            if not data['is_reocurrent']:
                new_task_instance = TaskInstanceModel(
                    task=new_task,
                    is_open=True,
                    community=new_task.community
                )
                new_task_instance.persist()

            return new_task, 201
        except:
            abort(500, message=INTERNAL_SERVER_ERROR)
Ejemplo n.º 22
0
    def post(self, id):
        community = CommunityModel.find_by_id(id)
        user = UserModel.find_by_username(get_jwt_identity())

        if not community:
            abort(404, message=COMMUNIY_DOESNT_EXIST)

        if user.id not in [u.id for u in community.users]:
            abort(401, message=UNAUTHORIZED)

        if TourModel.find_running_by_community(id):
            abort(400, message=CANT_CREATE_PAYOFF_WHEN_UNFINISHED_TOURS_EXIST)

        # tours: List[TourModel] = TourModel.find_finished_and_open_by_community(id)
        # refuels: List[RefuelModel] = RefuelModel.find_open_by_community(id)
        tours: List[TourModel] = TourModel.find_finished_by_community(id)
        refuels: List[RefuelModel] = RefuelModel.find_by_community(id)

        if not [t for t in tours if t.is_open
                ] and not [r for r in refuels if r.is_open]:
            abort(400,
                  message=CANT_CREATE_PAYOFF_WITHOUT_NEW_REFUELS_AND_TOURS)

        # Calculate some basic statistics
        total_km = sum(map(lambda t: t.end_km - t.start_km, tours))
        km_per_user = {}
        for tour in tours:
            involved_users = [tour.owner] + tour.passengers
            km_per_involved_user = (tour.end_km -
                                    tour.start_km) / len(involved_users)
            for involved_user in involved_users:
                if involved_user.id not in km_per_user:
                    km_per_user[involved_user.id] = 0
                km_per_user[involved_user.id] += km_per_involved_user
        # If there is a user from refuels missing, he has zero costs/kms
        for refuel in refuels:
            if refuel.owner.id not in km_per_user:
                km_per_user[refuel.owner.id] = 0
        km_fraction_per_user = {}
        for user_id, km in km_per_user.items():
            km_fraction_per_user[user_id] = km / total_km

        # Create reference user id to user dict
        user_dictionary = OrderedDict()
        for tour in tours:
            if tour.owner.id not in user_dictionary:
                user_dictionary[tour.owner.id] = tour.owner
            for passenger in tour.passengers:
                if passenger.id not in user_dictionary:
                    user_dictionary[passenger.id] = passenger
        for refuel in refuels:
            if refuel.owner.id not in user_dictionary:
                user_dictionary[refuel.owner.id] = refuel.owner

        # Create debt matrix (debtee on y axis, recipient on x axis)
        debt_matrix = np.zeros((len(user_dictionary), len(user_dictionary)))
        for refuel in refuels:
            recipient_position = list(user_dictionary.keys()).index(
                refuel.owner.id)
            for user_id in user_dictionary.keys():
                if user_id != refuel.owner.id:
                    debtee_position = list(
                        user_dictionary.keys()).index(user_id)
                    debt_amount = refuel.costs * km_fraction_per_user[user_id]
                    debt_matrix[debtee_position,
                                recipient_position] += float(debt_amount)

        # Include already created debts from previous payoffs
        debts = DebtModel.find_by_community(id)
        for debt in debts:
            recipient_position = list(user_dictionary.keys()).index(
                debt.recepient_id)
            debtee_position = list(user_dictionary.keys()).index(
                debt.debtee_id)
            debt_matrix[debtee_position,
                        recipient_position] -= float(debt.amount)

        # Simplify debt matrix
        debt_matrix = simplify_debt_matrix(debt_matrix)

        # Create and persist payoff
        payoff = PayoffModel()
        payoff.community_id = id
        payoff.persist()

        # Create and persist debt objects
        for i in range(debt_matrix.shape[0]):
            for j in range(debt_matrix.shape[0]):
                if debt_matrix[i, j] != 0:
                    debt = DebtModel()
                    debt.debtee = list(user_dictionary.values())[i]
                    debt.recepient = list(user_dictionary.values())[j]
                    debt.amount = round(debt_matrix[i, j], 2)
                    debt.payoff_id = payoff.id
                    debt.community_id = id
                    debt.persist()

        # If there is no resulting debt in the payoff, the payoff is settled
        if not np.any(debt_matrix != 0):
            payoff.is_settled = True

        # Set open tours to non open and add payoff id
        for tour in tours:
            if tour.is_open:
                tour.is_open = False
                tour.payoff_id = payoff.id
                tour.persist()

        # Set open refuels to non open and add payoff id
        for refuel in refuels:
            if refuel.is_open:
                refuel.is_open = False
                refuel.payoff_id = payoff.id
                refuel.persist()

        return payoff, 201