def get_chart_by_state_keys(user_id, key_list, start_date, end_date): cursor = connection.cursor() response = dict() result = [] for stat_key in key_list: if not start_date: return Helper.get_json_response(False, dict(), ['Please select a start date']) if start_date and not end_date: result = cursor.execute(f"SELECT * FROM states WHERE user_id = {user_id} " f"AND type = '{stat_key}'and date >= '{start_date}'") if start_date and end_date: result = cursor.execute(f"SELECT * FROM states WHERE user_id = {user_id} " f"AND type = '{stat_key}'and date >= '{start_date}' " f"and date <= '{end_date}'") item = dict() item['date'] = json.dumps([]) item['value'] = json.dumps([]) response[stat_key] = item if result: df = pd.DataFrame(result) item['date'] = df['date'].astype(str).to_json(orient='records') item['value'] = df['value'].astype(float).to_json(orient='records') response[stat_key] = item return Helper.get_json_response(True, response, [])
def join(request): transaction_id = request.POST['trans'] selected_level = request.POST['selected_level'] ac = Authentication(request) user_id = ac.get_user_session() error_messages = [] error_messages.extend(validate_level_selection(selected_level)) error_messages.extend( validate_level_already_taken(transaction_id, selected_level)) error_messages.extend(validate_user_count_exceeded(transaction_id)) error_messages.extend( validate_level_users(transaction_id, user_id, selected_level)) parent_trade = get_parent_trade(transaction_id) error_messages.extend( validate_changes_allowed_time_exceeded( parent_trade["changes_allowed_time"])) if error_messages: return JsonResponse(Helper.get_json_response(False, {}, error_messages)) current_user = Helper.get_user_by_id(user_id) persist_join(user_id, transaction_id, parent_trade, selected_level, current_user) return JsonResponse( Helper.get_json_response(True, {}, ["Trade joined successfully"]))
def close_order(request): ac = Authentication(request) # if user is not logged in response user not exist if not ac.is_user_logged_in(): return JsonResponse( Helper.get_json_response(False, [], ['Please login'])) user_id = ac.get_user_session() post = request.POST transaction_id = post['transaction_id'] transaction = Trading.get_transaction_by_id(transaction_id, user_id) if not transaction: return JsonResponse( Helper.get_json_response(False, {}, ["Trade data is not available"])) if Trading.validate_changes_allowed_time_exceeded( transaction['changes_allowed_time']): return JsonResponse( Helper.get_json_response( False, {}, ["Trade closing time is expired and cannot be closed"])) update_transactions_by_state_outcome(transaction, Status.FINISHED.value, Outcome.NONE.value) Trading.pay_back(user_id, transaction['amount']) return JsonResponse( Helper.get_json_response(True, {}, ['Trade has been closed successfully']))
def jobs_times(self, permutation): jt = [] total_idle_time = 0 _ = self.evaluator(permutation) # Evaluate best permutation to set machines cols = ['Job', 'Start Time', 'Finish Time', 'Idle Time'] jt.append(cols) format_spec = "{:>15}" * 4 lg.msg(logging.INFO, format_spec.format(*cols)) for pi, p in enumerate(permutation): start_time = 0 end_time = 0 idle_time = 0 for ji, j in enumerate(self.machines['assigned_jobs']): if ji == 0: start_time = j[pi][1] end_time = j[pi][2] continue idle_time += j[pi][1] - end_time end_time = j[pi][2] lg.msg(logging.INFO, format_spec.format(str(p), str(start_time), str(end_time), str(idle_time))) jt.append([str(p), str(start_time), str(end_time), str(idle_time)]) total_idle_time += idle_time lg.msg(logging.INFO, 'Jobs total idle time is {}'.format(total_idle_time)) filename = self.hj.results_path + '/' + self.hj.pid + ' ' + self.hj.bid + ' ' + self.hj.oid + \ ' jobs times run ' + str(self.hj.run) + '.csv' Helper.write_to_csv(jt, filename, header=True)
def chart(request): ac = Authentication(request) # if user is not logged in redirect to login page if not ac.is_user_logged_in(): return JsonResponse(Helper.get_json_response(False, [], ["Unauthorized Access"])) post = request.POST start_date = post['start_date'] end_date = post['end_date'] user_id = ac.get_user_session() data = [] if not start_date and not end_date: return JsonResponse(Helper.get_json_response(True, get_initial_chart_data(user_id), [])) stat_key = post['type'] if stat_key == "buy_sell": return JsonResponse( get_chart_by_state_keys(user_id, [StatKeys.BUY.value, StatKeys.SELL.value], start_date, end_date)) if stat_key == "win_loss_count": return JsonResponse( get_chart_by_state_keys(user_id, [StatKeys.WON.value, StatKeys.LOSS.value], start_date, end_date)) if stat_key == "win_loss_amount": return JsonResponse( get_chart_by_state_keys(user_id, [StatKeys.D_WON.value, StatKeys.D_LOSS.value], start_date, end_date)) return JsonResponse(get_filtered_chart_data(user_id, start_date, end_date, stat_key))
def get_pending_order(request): post = request.POST transaction_id = post['transaction_id'] user_id = post['user_id'] result = Trading.get_transaction_by_id(transaction_id, user_id) if not result: return JsonResponse( Helper.get_json_response(False, {}, ["Trade data is not available"])) user_data = Helper.get_user_by_id(user_id) data = dict() data["transaction_id"] = result["transaction_id"] data["created_date"] = result["created_date"] data["trade_type"] = result["trade_type"].capitalize() data["purchase_type"] = result["purchase_type"].capitalize() data["currency"] = result["currency"] data["amount"] = result["amount"] data["start_time"] = str(result["start_time"]) data["end_time"] = str(result["end_time"]) data["changes_allowed_time"] = str(result["changes_allowed_time"]) data["outcome"] = result["outcome"].capitalize() data["status"] = result["status"].capitalize() data["amount_currency"] = user_data["currency"] return JsonResponse(Helper.get_json_response(True, data, []))
def get_filtered_chart_data(user_id, start_date, end_date, stat_key): cursor = connection.cursor() result = [] if not start_date: return Helper.get_json_response(False, dict(), ['Please select a start date']) if start_date and not end_date: result = cursor.execute(f"SELECT * FROM states WHERE user_id = {user_id} " f"AND type = '{stat_key}'and date >= '{start_date}'") if start_date and end_date: result = cursor.execute(f"SELECT * FROM states WHERE user_id = {user_id} " f"AND type = '{stat_key}'and date >= '{start_date}' " f"and date <= '{end_date}'") if result: response = dict() df = pd.DataFrame(result) item = dict() item['date'] = df['date'].astype(str).to_json(orient='records') item['value'] = df['value'].astype(float).to_json(orient='records') response[stat_key] = item return Helper.get_json_response(True, response, ['']) return Helper.get_json_response(False, dict(), ['Data not available for this range'])
def create_user(request): email = request.POST['email'] password = request.POST['password'] repassword = request.POST['repassword'] first_name = request.POST['first_name'] last_name = request.POST['last_name'] mobile = request.POST['mobile'] address = request.POST['address'] country = request.POST['country'] currency = request.POST['currency'] virtual_currency = request.POST['virtual_currency'] error_messages = [] error_messages.extend(UserHelper.validate_email(email)) error_messages.extend(UserHelper.validate_password(password, repassword)) error_messages.extend(UserHelper.validate_first_name(first_name)) error_messages.extend(UserHelper.validate_last_name(last_name)) error_messages.extend(UserHelper.validate_mobile(mobile)) error_messages.extend(UserHelper.validate_address(address)) error_messages.extend(UserHelper.validate_country(country)) error_messages.extend(UserHelper.validate_currency(currency)) error_messages.extend(UserHelper.validate_amount(virtual_currency)) if error_messages: return error_messages cursor = connection.cursor() user = cursor.execute("SELECT id FROM user_credential where email =" + "'" + email + "'") # check whether email exists if not user: # create user credentials insert = UserCredential(email=email, password=Helper.password_encrypt(password)) insert.save() # get newly created user id user_id = UserCredential.objects.filter(email=email) user_id = user_id.get().id # save user general details new_user = UserById(id=user_id, email=email, address=address, country=country, currency=currency, fname=first_name, lname=last_name, mobile=mobile, vcurrency=virtual_currency, created_date=datetime.now()) new_user.save() Helper.store_state_value(user_id, StatKeys.BALANCE.value, virtual_currency, 'subtract')
def view(request): ac = Authentication(request) # if user is not logged in redirect to login page data = dict() if not ac.is_user_logged_in(): return redirect('/login') user_id = ac.get_user_session() data['auth'] = ac.is_user_logged_in() data["pending_trades"] = Helper.get_latest_pending_trades(user_id) data["latest_outcomes"] = Helper.get_latest_outcome_trades(user_id) data["user_currency"] = Helper.get_user_by_id(user_id)['currency'] return render(request, 'dashboard.html', data)
def persist_transactions_by_state(transaction_id, user_id, parent_trade): current_user = Helper.get_user_by_id(user_id) converted_amount = Helper.convert_currency(parent_trade['amount'], parent_trade['amount_currency'], current_user['currency']) fields = "(transaction_id,user_id,currency,purchase_type,outcome,status, created_date, amount, trade_type)" values = f"({transaction_id}, {user_id},'{parent_trade['currency']}','{parent_trade['purchase_type']}'," \ f"'{parent_trade['outcome']}','{parent_trade['status']}','{created_date}',{converted_amount}," \ f"'{parent_trade['trade_type']}')" transactions_by_state = f"INSERT INTO transactions_by_state {fields} VALUES {values}" cursor = connection.cursor() cursor.execute(transactions_by_state)
def update_other_trades(transaction_id, user_id, selected_level, parent_trade): cursor = connection.cursor() level_based_by_user_id = f"SELECT * FROM level_based_by_user_id WHERE transaction_id = {transaction_id}" existing_trades = cursor.execute(level_based_by_user_id) current_user_trade = f"SELECT * FROM user_transactions WHERE transaction_id = {transaction_id} AND user_id = {user_id}" current_user_trade = cursor.execute(current_user_trade) current_user_trade = current_user_trade[0] for trade in existing_trades: if trade['user_id'] != user_id: update = f"UPDATE user_transactions SET available_levels = {current_user_trade['available_levels']}" \ f",level_owners = '{current_user_trade['level_owners']}' " \ f"WHERE transaction_id = {transaction_id} and user_id = {trade['user_id']}" cursor.execute(update) # update transactions_levels_status available_levels end_time = Helper.get_time_formatted(current_user_trade['end_time']) update_transactions_levels_status = f"UPDATE transactions_levels_status SET available_levels = " \ f"{current_user_trade['available_levels']} " \ f"WHERE status = '{parent_trade['status']}' " \ f"AND currency = '{parent_trade['currency']}'" \ f"AND end_time = '{end_time}' " \ f"AND purchase_type = '{parent_trade['purchase_type']}' " \ f"AND amount = {parent_trade['amount']} " \ f"AND transaction_id = {parent_trade['transaction_id']} " \ f"AND user_id = {parent_trade['user_id']}" cursor.execute(update_transactions_levels_status)
def update_password(request, user_id): crrpassword = request.POST['crrpassword'] password = request.POST['password'] repassword = request.POST['repassword'] error_message = [] user_data = Helper.get_user_by_id(user_id) error_message.extend( validate_current_password(crrpassword, user_data['email'])) error_message.extend(validate_new_password(password, repassword)) if error_message: return error_message new_pass = Helper.password_encrypt(password) q = UserCredential(email=user_data['email'], password=new_pass) q.update()
def join_trade(request): ac = Authentication(request) # if user is not logged in response user not exist if not ac.is_user_logged_in(): return JsonResponse( Helper.get_json_response(False, [], ['Please login'])) return join(request)
def get_forecast(request): post = request.POST currency_pair = post["currency_pair"] data = dict() cursor = connection.cursor() today_date = Helper.get_today_date() result = cursor.execute( f"SELECT * FROM forecast WHERE currency_pair = '{currency_pair}' AND " f"date > '{today_date}'") result = result.all() if result: df = pd.DataFrame(result) data["date"] = df['date'].astype(str).to_json(orient='records') data["value"] = df['value'].astype(float).to_json(orient='records') return JsonResponse(Helper.get_json_response(True, data, [])) return JsonResponse(Helper.get_json_response(False, {}, []))
class User(AbstractBaseUser, PermissionsMixin): profile_image = models.ImageField(upload_to=Helper().user_upload_file_name, default='uploads/default_img/team-{}.png'.format(randint(2,9))) username = models.CharField(_("Username"), unique=True, max_length=100, null=True, error_messages={'blank': "Please enter username."}) email = models.EmailField(max_length=40, unique=True, null=True, error_messages={'required': 'Please provide email address.', 'unique': 'A user with this email address already exist.'}) phone = models.CharField(max_length=20, unique=True, error_messages={'required': 'Please provide your phone number.', 'unique': 'A user with this phone number already exist.'}) calling_code = models.IntegerField(default=234) referral_code = models.CharField(max_length=30, blank=True, null=True) referred = models.BooleanField(default=False) is_active = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) is_moderator = models.BooleanField(default=False) is_deleted = models.BooleanField(default=False) date_joined = models.DateTimeField(default=timezone.now) birthday = models.DateField(null=True, blank=True) birthday_msg_sent = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = 'phone' REQUIRED_FIELDS = ['username', 'email', 'calling_code'] def save(self, *args, **kwargs): super(User, self).save(*args, **kwargs) return self def __str__(self): return '{} - {}'.format(self.username, self.pk)
def persist_transactions_by_end_time(transaction_id, user_id, parent_trade): end_time = Helper.get_time_formatted(parent_trade['end_time']) fields = "(transaction_id, user_id,status,trade_type,end_time)" values = f"({transaction_id},{user_id},'{parent_trade['status']}','{parent_trade['trade_type']}','{end_time}')" transactions_by_end_time = f"INSERT INTO transactions_by_end_time {fields} VALUES {values}" cursor = connection.cursor() cursor.execute(transactions_by_end_time)
def settings(request): ac = Authentication(request) # if user is not logged in redirect to login page if not ac.is_user_logged_in(): return redirect('/login') ac = Authentication(request) user_id = ac.get_user_session() data = dict() if request.method == "POST": action = request.POST['action'] if action == "Update": errors = update_settings(request, user_id) if errors: data['errors'] = errors else: data['success'] = "General has been updated successfully" if action == "Change password": errors = update_password(request, user_id) if errors: data['errors'] = errors else: data['success'] = "Password has been updated successfully" if action == "Deposit": errors = deposit(request, user_id) if errors: data['errors'] = errors else: data['success'] = "Money has been deposited successfully" if action == "Withdraw": errors = withdraw(request, user_id) if errors: data['errors'] = errors else: data['success'] = "Money withdraw is successful" user_data = Helper.get_user_by_id(user_id) data['user_data'] = user_data data['countries'] = Helper.get_countries() data['auth'] = ac.is_user_logged_in() return render(request, 'settings.html', data)
def register(request): ac = Authentication(request) if ac.is_user_logged_in(): return redirect('/account') error_messages = [] data = dict() if request.method == "POST": error_messages = create_user(request) if error_messages: data["post_data"] = request.POST else: data["success"] = True data['countries'] = Helper.get_countries() data['currency'] = Helper.get_currency() data['error_messages'] = error_messages return render(request, 'register.html', data)
def update_user_account_fields(user_id, current_user, parent_trade): cursor = connection.cursor() converted_amount = Helper.convert_currency(parent_trade['amount'], parent_trade['amount_currency'], current_user['currency']) updated_amount = float(current_user['vcurrency']) - float(converted_amount) # update account balance update_user = f"UPDATE user_by_id SET vcurrency = {updated_amount} WHERE id = {user_id}" cursor.execute(update_user)
def persist_transactions_changes_allowed_time(transaction_id, user_id, parent_trade): changes_allowed_time = Helper.get_time_formatted( parent_trade['changes_allowed_time']) fields = "(transaction_id,user_id,status,changes_allowed_time)" values = f"({transaction_id},{user_id},'{parent_trade['status']}','{changes_allowed_time}')" transactions_changes_allowed_time = f"INSERT INTO transactions_changes_allowed_time {fields} VALUES {values}" cursor = connection.cursor() cursor.execute(transactions_changes_allowed_time)
def validate_current_password(password, email): if not password: return ["Current password cannot be empty"] password = Helper.password_encrypt(password) q = f"SELECT * FROM user_credential WHERE email = '{email}'" cursor = connection.cursor() result = cursor.execute(q) if result[0]['password'] != password: return ["Current password is invalid please reenter"] return []
def machines_times(self, permutation): mt = [] total_idle_time = 0 _ = self.evaluator(permutation) cols = ['Machine', 'Start Time', 'Finish Time', 'Idle Time'] mt.append(cols) format_spec = "{:>15}" * 4 lg.msg(logging.INFO, format_spec.format(*cols)) # Calculate idle time from list tuples as start time(m+1) - finish time(m). Include last machine start time for mi, m in enumerate(self.machines['assigned_jobs']): finish_time = m[-1][2] idle_time = sum([x[1]-x[0] for x in zip([x[2] for x in m], [x[1] for x in m[1:] + [(0, m[-1][2], 0)]])]) total_idle_time += idle_time lg.msg(logging.INFO, format_spec.format(str(mi), str(m[0][1]), str(finish_time), str(idle_time))) mt.append([str(mi), str(m[0][1]), str(finish_time), str(idle_time)]) lg.msg(logging.INFO, 'Machines total idle time is {}'.format(total_idle_time)) filename = self.hj.results_path + '/' + self.hj.pid + ' ' + self.hj.bid + ' ' + self.hj.oid + \ ' machines times run ' + str(self.hj.run) + '.csv' Helper.write_to_csv(mt, filename, header=True)
def persist_user_transactions(user_id, transaction_id, parent_trade, selected_level): current_user = Helper.get_user_by_id(user_id) converted_amount = Helper.convert_currency(parent_trade['amount'], parent_trade['amount_currency'], current_user['currency']) price_range = get_selected_level_price(parent_trade['levels_price'], selected_level) available_levels = get_available_levels(parent_trade['available_levels'], selected_level) level_owners = add_level_owners(parent_trade['level_owners'], user_id, selected_level) start_time = Helper.get_time_formatted(parent_trade['start_time']) end_time = Helper.get_time_formatted(parent_trade['end_time']) changes_allowed_time = Helper.get_time_formatted( parent_trade['changes_allowed_time']) fields = "(transaction_id,user_id,created_date,trade_type,purchase_type,currency,staring_price," \ "amount,amount_currency,start_time,end_time,changes_allowed_time,outcome,status,level_pips,levels_price,level_owners," \ "join_date,level_start_price,level_end_price,level_selected,created_by,parent_id,child,available_levels)" values = f"({transaction_id},{user_id},'{created_date}','{parent_trade['trade_type']}'," \ f"'{parent_trade['purchase_type']}','{parent_trade['currency']}',{parent_trade['staring_price']}," \ f"{converted_amount},'{current_user['currency']}','{start_time}','{end_time}'," \ f"'{changes_allowed_time}','{parent_trade['outcome']}','{parent_trade['status']}'," \ f"{parent_trade['level_pips']},'{parent_trade['levels_price']}'," \ f"'{level_owners}'," \ f"'{Helper.get_current_time_formatted()}',{price_range['range'][0]},{price_range['range'][1]}," \ f"{selected_level},{parent_trade['created_by']},{parent_trade['user_id']},{True}, {available_levels})" user_transactions = f"INSERT INTO user_transactions {fields} VALUES {values}" cursor = connection.cursor() cursor.execute(user_transactions) Trading.save_levels_general_stats(user_id, selected_level, converted_amount, parent_trade['purchase_type'])
def withdraw(request, user_id): amount = request.POST['withdraw_amount'] error_messages = [] error_messages.extend(validate_withdrawal_amount(user_id, amount)) if error_messages: return error_messages current_user = Helper.get_user_by_id(user_id) new_amount = current_user["vcurrency"] - float(amount) cursor = connection.cursor() q = f"UPDATE user_by_id SET vcurrency = {new_amount} WHERE id = {user_id}" cursor.execute(q) return []
def validate_withdrawal_amount(user_id, amount): if not amount: return ["Please enter amount to withdraw"] if not amount.isnumeric(): return ['Please enter a valid amount'] amount = float(amount) if amount < 1: return ['Amount should be greater than 0'] current_user = Helper.get_user_by_id(user_id) if current_user["vcurrency"] <= float(amount): return ['Withdrawal amount cannot be greater than the account balance'] return []
def post_processing(self, j): j.end_time = time.time() j.total_comp_time_s += time.time() - self.exec_start_time if isinstance(j.rbest.candidate[0], float) and j.pid_type == 'combinatorial': j.rbest.candidate = j.pid_cls.candidate_spv_continuous_to_discrete(j.rbest.candidate) lg.msg(logging.INFO, 'Run {} best fitness is {} with candidate {}'.format(j.run, "{:.10f}".format( j.rbest.fitness), j.rbest.candidate)) lg.msg(logging.INFO, 'Completed benchmark {} optimizer {} run {}'.format(j.bid, j.oid, str(j.run))) self.log_optimizer_fitness(j) filename = self.results_path + '/' + j.pid + ' ' + j.bid + ' ' + j.oid + ' rbest fitness trend run ' + str(j.run) self.vis.fitness_trend(j.rft, filename) # Plot run-specific trend Helper.write_to_csv(j.rft, filename + '.csv', header=False) if j.run == j.runs_per_optimizer - 1: return # Reinstate full computational budget for next job run except last run, as budget used in summary reporting j.budget = j.budget_total
def deposit(request, user_id): amount = request.POST['vcurrency'] error_messages = [] error_messages.extend(UserHelper.validate_amount(amount)) if error_messages: return error_messages user_data = Helper.get_user_by_id(user_id) amount = float(amount) balance = user_data['vcurrency'] + amount user_settings = UserById(id=user_id, vcurrency=balance) user_settings.update() pass
def login(request): data = {} ac = Authentication(request) # if user is logged in redirect to account page if ac.is_user_logged_in(): return redirect('/account') if request.method == "POST": email = request.POST['email'] password = request.POST['password'] error_messages = validate_login_inputs(email, password) if not error_messages: # encrypt user enter password in the login page to check with db password password_encrypted = Helper.password_encrypt(password) cursor = connection.cursor() # check whether user exists in the DB user = cursor.execute( "SELECT * FROM user_credential where email =" + "'" + email + "' ") if user and user[0]['password'] == Helper.password_encrypt( password): # get loged user details q = f"SELECT * FROM user_by_id where id = {user[0]['id']}" user = cursor.execute(q) # create user session and store user id ac.save_user_session(str(user[0]['id'])) return redirect('/account') error_messages.append("Invalid email or password") data["error_messages"] = error_messages return render(request, 'login.html', data)
def get_transaction(request): ac = Authentication(request) # if user is not logged in response user not exist if not ac.is_user_logged_in(): return JsonResponse( Helper.get_json_response(False, [], ['Please login'])) post = request.POST trade = Trading.get_transaction_by_id(post['transaction_ref'], post['trade_owner']) if not trade: return JsonResponse( Helper.get_json_response(False, [], ["Trade not available"])) user_id = ac.get_user_session() current_user = Helper.get_user_by_id(user_id) trade_data = dict() trade_data['contract_type'] = trade['trade_type'] trade_data['transaction_ref'] = trade['transaction_id'] trade_data['purchase_type'] = trade['purchase_type'] trade_data['start_time'] = trade['start_time'] trade_data['end_time'] = trade['end_time'] if trade['trade_type'] == Types.LEVELS.value: trade_data['amount'] = Helper.convert_currency( trade['amount'], trade['amount_currency'], current_user['currency']) trade_data['selected_level'] = trade['level_selected'] trade_data['user_count'] = 4 - len(trade['available_levels']) trade_data['available_levels'] = trade['available_levels'] else: trade_data['amount'] = trade['amount'] trade_data['user_currency'] = current_user['currency'] trade_data['staring_price'] = trade['staring_price'] trade_data['closing_price'] = trade['closing_price'] trade_data['outcome'] = trade['outcome'] trade_data['status'] = trade['status'] return JsonResponse(Helper.get_json_response(True, [trade_data], []))
def save_stats(current_user, parent_trade, selected_level): converted_amount = Helper.convert_currency(parent_trade['amount'], parent_trade['amount_currency'], current_user['currency']) Helper.store_state_value(current_user['id'], StatKeys.BALANCE.value, converted_amount, 'subtract') Helper.store_state_value(current_user['id'], StatKeys.NUM_TRADES.value, 1, 'add') Helper.store_state_value(current_user['id'], StatKeys.LEVELS.value, 1, 'add') Trading.save_purchase_stats(current_user['id'], parent_trade['purchase_type']) Trading.save_levels_stats(current_user['id'], selected_level)