import logging from aiogram.dispatcher import FSMContext from aiogram.types import Message, CallbackQuery, ReplyKeyboardMarkup, ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton from keyboards.inline.products_from_cart import product_markup, product_cb from aiogram.utils.callback_data import CallbackData from keyboards.default.markups import * from aiogram.types.chat import ChatActions from states import CheckoutState from loader import dp, db, bot from filters import IsUser from .menu import cart @dp.message_handler(IsUser(), text=cart) async def process_cart(message: Message, state: FSMContext): cart_data = db.fetchall( 'SELECT * FROM cart WHERE cid=?', (message.chat.id,)) if len(cart_data) == 0: await message.answer('Ваша корзина пуста.') else: await bot.send_chat_action(message.chat.id, ChatActions.TYPING) async with state.proxy() as data: data['products'] = {} order_cost = 0 for _, idx, count_in_cart in cart_data: product = db.fetchone('SELECT * FROM products WHERE idx=?', (idx,)) if product == None: db.query('DELETE FROM cart WHERE idx=?', (idx,)) else: _, title, body, image, price, _ = product order_cost += price async with state.proxy() as data: data['products'][idx] = [title, price, count_in_cart] markup = product_markup(idx, count_in_cart) text = f'{title}\n\n{body}\n\nЦена: {price}₽.' await message.answer_photo(photo=image, caption=text, reply_markup=markup) if order_cost != 0: markup = ReplyKeyboardMarkup(resize_keyboard=True, selective=True) markup.add('📦 Оформить заказ') await message.answer('Перейти к оформлению?', reply_markup=markup) @dp.callback_query_handler(IsUser(), product_cb.filter(action='count')) @dp.callback_query_handler(IsUser(), product_cb.filter(action='increase')) @dp.callback_query_handler(IsUser(), product_cb.filter(action='decrease')) async def product_callback_handler(query: CallbackQuery, callback_data: dict, state: FSMContext): idx = callback_data['id'] action = callback_data['action'] if 'count' == action: async with state.proxy() as data: if 'products' not in data.keys(): await process_cart(query.message, state) else: await query.answer('Количество - ' + data['products'][idx][2]) else: async with state.proxy() as data: if 'products' not in data.keys(): await process_cart(query.message, state) else: data['products'][idx][2] += 1 if 'increase' == action else -1 count_in_cart = data['products'][idx][2] if count_in_cart == 0: db.query('''DELETE FROM cart WHERE cid = ? AND idx = ?''', (query.message.chat.id, idx)) await query.message.delete() else: db.query('''UPDATE cart SET quantity = ? WHERE cid = ? AND idx = ?''', (count_in_cart, query.message.chat.id, idx)) await query.message.edit_reply_markup(product_markup(idx, count_in_cart)) @dp.message_handler(IsUser(), text='📦 Оформить заказ') async def process_checkout(message: Message, state: FSMContext): await CheckoutState.check_cart.set() await checkout(message, state) async def checkout(message, state): answer = '' total_price = 0 async with state.proxy() as data: for title, price, count_in_cart in data['products'].values(): tp = count_in_cart * price answer += f'{title} * {count_in_cart}шт. = {tp}₽\n' total_price += tp await message.answer(f'{answer}\nОбщая сумма заказа: {total_price}₽.', reply_markup=check_markup()) @dp.message_handler(IsUser(), lambda message: message.text not in [all_right_message, back_message], state=CheckoutState.check_cart) async def process_check_cart_invalid(message: Message): await message.reply('Такого варианта не было.') @dp.message_handler(IsUser(), text=back_message, state=CheckoutState.check_cart) async def process_check_cart_back(message: Message, state: FSMContext): await state.finish() await process_cart(message, state) @dp.message_handler(IsUser(), text=all_right_message, state=CheckoutState.check_cart) async def process_check_cart_all_right(message: Message, state: FSMContext): await CheckoutState.next() await message.answer('Укажите свое имя.', reply_markup=back_markup()) @dp.message_handler(IsUser(), text=back_message, state=CheckoutState.name) async def process_name_back(message: Message, state: FSMContext): await CheckoutState.check_cart.set() await checkout(message, state) @dp.message_handler(IsUser(), state=CheckoutState.name) async def process_name(message: Message, state: FSMContext): async with state.proxy() as data: data['name'] = message.text if 'address' in data.keys(): await confirm(message) await CheckoutState.confirm.set() else: await CheckoutState.next() await message.answer('Укажите свой адрес места жительства.', reply_markup=back_markup()) @dp.message_handler(IsUser(), text=back_message, state=CheckoutState.address) async def process_address_back(message: Message, state: FSMContext): async with state.proxy() as data: await message.answer('Изменить имя с ' + data['name'] + '?', reply_markup=back_markup()) await CheckoutState.name.set() @dp.message_handler(IsUser(), state=CheckoutState.address) async def process_address(message: Message, state: FSMContext): async with state.proxy() as data: data['address'] = message.text await confirm(message) await CheckoutState.next() async def confirm(message): await message.answer('Убедитесь, что все правильно оформлено и подтвердите заказ.', reply_markup=confirm_markup()) @dp.message_handler(IsUser(), lambda message: message.text not in [confirm_message, back_message], state=CheckoutState.confirm) async def process_confirm_invalid(message: Message): await message.reply('Такого варианта не было.') @dp.message_handler(IsUser(), text=back_message, state=CheckoutState.confirm) async def process_confirm(message: Message, state: FSMContext): await CheckoutState.address.set() async with state.proxy() as data: await message.answer('Изменить адрес с ' + data['address'] + '?', reply_markup=back_markup()) @dp.message_handler(IsUser(), text=confirm_message, state=CheckoutState.confirm) async def process_confirm(message: Message, state: FSMContext): enough_money = True # enough money on the balance sheet markup = ReplyKeyboardRemove() if enough_money: logging.info('Deal was made.') async with state.proxy() as data: cid = message.chat.id products = [idx + '=' + str(quantity) for idx, quantity in db.fetchall('''SELECT idx, quantity FROM cart WHERE cid=?''', (cid,))] # idx=quantity db.query('INSERT INTO orders VALUES (?, ?, ?, ?)', (cid, data['name'], data['address'], ' '.join(products))) db.query('DELETE FROM cart WHERE cid=?', (cid,)) await message.answer('Ок! Ваш заказ уже в пути 🚀\nИмя: ' + data['name'] + '\nАдрес: ' + data['address'] + '', reply_markup=markup) else: await message.answer('У вас недостаточно денег на счете. Пополните баланс!', reply_markup=markup) await state.finish()