示例#1
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
示例#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)
        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)
示例#3
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