def get_day_details(user: User, year: int, month: int, day: int) -> str: bills = user.bills.filter( db.and_( extract('year', Bill.create_time) == year, extract('month', Bill.create_time) == month, extract('day', Bill.create_time) == day), Bill.type == 'out').order_by(text('bill.create_time')).all() bills_part = '' sum_out = Decimal('0') title = f'{month}月{day}日支出详情\n\n' for bill in bills: sum_out += bill.amount bills_part += f'{repr(bill)}\n' sum_part = f'合计消费:{str(sum_out)}元\n\n' return (title + sum_part + bills_part).rstrip()
def view_user_forecasts(user_id): user = User.query.get(user_id) items = db.session.query(Game, Forecast).\ outerjoin(Forecast, db.and_(Game.id == Forecast.game_id, Forecast.user_id == user_id)).\ all() has_prediction = lambda x: x[1] is not None games_predictions = [] games = [] for i in items: (games_predictions if has_prediction(i) else games).append(i) return render_template('admin/user_forecast.html', games_predictions=games_predictions, games=games, user=user)
def view_turn(game_id, round_id, turn_id): game = Game.query.get(game_id) game_round = Round.query.get(round_id) turn = Turn.query.options(db.joinedload(Turn.player)).get(turn_id) if turn.completed_at: return redirect( url_for('salad_bowl.view_round', game_id=game_id, round_id=round_id)) seconds_remaining = int( (turn.expected_complete_at - datetime.utcnow()).total_seconds()) word = None if turn.player_id == g.current_player.id: if request.args.get('currentWord'): word = SaladBowlWord.query.get(int(request.args['currentWord'])) else: unguessed_words_q = SaladBowlWord.query unguessed_words_q = unguessed_words_q.join( GuessedWord, db.and_(GuessedWord.round_id == round_id, GuessedWord.word_id == SaladBowlWord.id), isouter=True) unguessed_words_q = unguessed_words_q.filter( SaladBowlWord.game_id == game_id) unguessed_words_q = unguessed_words_q.filter( GuessedWord.round_id.is_(None)) word = random.choice(unguessed_words_q.all()) from app.actions.salad_bowl.turn import EndTurnForm, WordGuessedForm return render_template( 'salad_bowl/view_turn.html', game=game, game_round=game_round, turn=turn, seconds_remaining=seconds_remaining, word=word, end_turn_form=EndTurnForm() if word else None, word_guessed_form=WordGuessedForm(word_id=word.id) if word else None)
def get_month_statistic(user: User, year: int, month: int) -> str: bills = user.bills.filter( db.and_( extract('year', Bill.create_time) == year, extract('month', Bill.create_time) == month)).all() bills_in = defaultdict(lambda: Decimal('0')) bills_out = defaultdict(lambda: Decimal('0')) sum_out = sum_in = Decimal('0') for bill in bills: if bill.type == 'in': bills_in[bill.category] += bill.amount sum_in += bill.amount elif bill.type == 'out': sum_out += bill.amount bills_out[bill.category] += bill.amount bills_out = sorted(bills_out.items(), key=lambda item: item[1], reverse=True) begin_part = f'{year}年{month}月收支统计\n\n' tabs = '\t\t\t\t\t\t\t' in_part = f'收入:{str(sum_in)}元\n' out_part = f'支出:{str(sum_out)}元\n\n' if not bills_out: out_part += f'{tabs}- 无\n\n' else: for category, amount in bills_out: out_part += f'{tabs}- {category}: {str(amount)}元\n' out_part += '\n' result = begin_part + out_part + in_part if user.planned_month_deposit is not None: delta = sum_in - sum_out if delta > 0: left_budget = delta - user.planned_month_deposit result += f'\n净增:{str(delta)}元\n' result += f'剩余额度:{str(left_budget)}元\n' return result.rstrip()
def home(): sort = request.args.get('sort', 'total') total_value_calc = db.func.coalesce( db.func.sum(BankerCurrency.amount * Currency.value), 0) sorted_standings_q = db.session.query( Banker, total_value_calc.label('total_value')).outerjoin( BankerCurrency, BankerCurrency.banker_id == Banker.id).outerjoin( Currency, Currency.id == BankerCurrency.currency_id).options( db.joinedload(Banker.currencies)).group_by(Banker.id) if sort == 'total': sorted_standings_q = sorted_standings_q.order_by( db.desc(total_value_calc), Banker.id) else: sort_by_currency_id = int(sort) sorting_subq = db.session.query( Banker.id.label('banker_id'), db.func.coalesce(BankerCurrency.amount, 0).label('sorted_column_amount')).outerjoin( BankerCurrency, db.and_( BankerCurrency.banker_id == Banker.id, BankerCurrency.currency_id == sort_by_currency_id)).subquery() sorted_standings_q = sorted_standings_q.join( sorting_subq, sorting_subq.c.banker_id == Banker.id).order_by( db.desc(db.func.max(sorting_subq.c.sorted_column_amount)), Banker.id) sorted_standings = sorted_standings_q.limit(20).all() return render_template('ct_conomy/home.html', sorted_standings=sorted_standings)
def word_guessed(game_id, round_id, turn_id): form = WordGuessedForm() if form.validate_on_submit(): current_players_team_id_q = db.session.query(PlayerTeam.team_id) current_players_team_id_q = current_players_team_id_q.join(Team) current_players_team_id = current_players_team_id_q.filter(Team.game_id == game_id, PlayerTeam.player_id == g.current_player.id).scalar() guessed_word = GuessedWord( word_id=form.word_id.data, round_id=round_id, team_id=current_players_team_id, player_id=g.current_player.id) db.session.add(guessed_word) db.session.flush() unguessed_words_q = SaladBowlWord.query unguessed_words_q = unguessed_words_q.join(GuessedWord, db.and_( GuessedWord.round_id == round_id, GuessedWord.word_id == SaladBowlWord.id), isouter=True) unguessed_words_q = unguessed_words_q.filter(SaladBowlWord.game_id == game_id) unguessed_words_q = unguessed_words_q.filter(GuessedWord.round_id.is_(None)) if unguessed_words_q.count() == 0: turn = Turn.query.get(turn_id) turn.completed_at = datetime.utcnow() game_round = Round.query.get(round_id) game_round.completed_at = datetime.utcnow() db.session.flush() game = Game.query.options(db.joinedload(Game.rounds)).get(game_id) if all(round.completed_at for round in game.rounds): game.completed_at = datetime.utcnow() db.session.commit() return False, redirect(url_for('salad_bowl.view_turn', game_id=game_id, round_id=round_id, turn_id=turn_id))
def view_round(game_id, round_id): game = Game.query.options(db.joinedload(Game.teams)).get(game_id) game_round = Round.query.options(db.joinedload(Round.turns)).get(round_id) if game_round.completed_at: return redirect(url_for('salad_bowl.view_game', game_id=game_id)) for turn in game_round.turns: if turn.started_at and not turn.completed_at: return redirect( url_for('salad_bowl.view_turn', game_id=game_id, round_id=round_id, turn_id=turn.id)) turn_length = game_round.seconds_per_turn seconds_remaining = turn_length if not game_round.turns: # we are starting a new round if game_round.round_number == 1: # start of game, pick first team next_team = next( (team for team in game.teams if team.turn_order == 0)) else: # see who was going at the end of the previous round previous_turn_q = Turn.query previous_turn_q = previous_turn_q.join(Round) previous_turn_q = previous_turn_q.filter( Round.game_id == game_id, Round.round_number == game_round.round_number - 1) previous_turn_q = previous_turn_q.order_by(db.desc( Turn.started_at)) previous_turn = previous_turn_q.first() next_team = next((team for team in game.teams if team.id == previous_turn.team_id)) seconds_remaining = turn_length - int( (previous_turn.expected_complete_at - previous_turn.completed_at).total_seconds()) else: # weve already had teams go this round previous_turn = None turn_order_index = None for turn in sorted(game_round.turns, key=lambda x: x.started_at): previous_turn = turn for team in game.teams: if team.id == previous_turn.team_id: turn_order_index = (team.turn_order + 1) % len(game.teams) next_team = next((team for team in game.teams if team.turn_order == turn_order_index)) current_players_team_id_q = db.session.query(PlayerTeam.team_id) current_players_team_id_q = current_players_team_id_q.join(Team) current_players_team_id = current_players_team_id_q.filter( Team.game_id == game_id, PlayerTeam.player_id == g.current_player.id).scalar() can_start_next_turn = next_team.id == current_players_team_id unguessed_words_q = SaladBowlWord.query unguessed_words_q = unguessed_words_q.join( GuessedWord, db.and_(GuessedWord.round_id == round_id, GuessedWord.word_id == SaladBowlWord.id), isouter=True) unguessed_words_q = unguessed_words_q.filter( SaladBowlWord.game_id == game_id) unguessed_words_q = unguessed_words_q.filter( GuessedWord.round_id.is_(None)) unguessed_word_count = unguessed_words_q.count() return render_template('salad_bowl/view_round.html', game=game, game_round=game_round, next_team=next_team, seconds_remaining=seconds_remaining, unguessed_word_count=unguessed_word_count, can_start_next_turn=can_start_next_turn)