Files
tgex-backend/telegram_bot/screens/purchases.go
Artem Tsyrulnikov eb54b01835 фиксы
2026-01-08 21:50:04 +03:00

154 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package screens
import (
"context"
"fmt"
"example.com/m/bot"
"github.com/NicoNex/echotron/v3"
"github.com/rs/zerolog/log"
)
type Purchases struct {
WorkspaceID string
ProjectID string
ProjectTitle string
BackState bot.State
}
func (s *Purchases) Enter(b *bot.Bot, mode bot.RenderMode) {
jwt := b.Session.JWT
if jwt == "" {
log.Error().Msg("JWT is empty in session")
b.SendNew("❌ Ошибка авторизации. Попробуйте /start", bot.Keyboard())
return
}
s.renderPurchases(b, mode, jwt)
}
func (s *Purchases) renderPurchases(b *bot.Bot, mode bot.RenderMode, jwt string) {
purchases, err := b.Backend.GetPurchases(
context.Background(),
jwt,
s.WorkspaceID,
s.ProjectID,
)
if err != nil {
log.Error().Err(err).Msg("Failed to get purchases")
b.SendNew("❌ Не удалось загрузить закупы", bot.Keyboard())
return
}
// Навигация: 2 последних уровня
navPath := "… Закупы"
if s.ProjectTitle != "" {
navPath = fmt.Sprintf("… %s Закупы", s.ProjectTitle)
}
text := fmt.Sprintf("<i>%s</i>\n\n<b>Закупы</b>\n\n", navPath)
var buttons [][]echotron.InlineKeyboardButton
if len(purchases) == 0 {
text += `Список закупов пуст.
<i>Закуп — это план размещения рекламы в каналах:</i>
‣ Выбор креатива
‣ Список каналов для размещения
‣ Планируемая стоимость
‣ Статус выполнения
Создайте первый закуп`
} else {
text += "Управление закупами для проекта.\n\n"
text += "Выберите закуп для деталей:\n\n"
for i, purchase := range purchases {
// Определяем статус
statusSymbol := "●"
switch purchase.Status {
case "active":
statusSymbol = "●"
case "archived":
statusSymbol = "■"
}
// Считаем каналы по статусам
totalChannels := len(purchase.Channels)
completedChannels := 0
for _, ch := range purchase.Channels {
if ch.Status == "completed" {
completedChannels++
}
}
buttonText := fmt.Sprintf("%s Закуп #%d (%d/%d каналов)",
statusSymbol,
i+1,
completedChannels,
totalChannels,
)
buttons = append(buttons, bot.Row(
bot.Button(buttonText, fmt.Sprintf("purchase:%s", purchase.ID)),
))
}
}
// Кнопка создания нового закупа
buttons = append(buttons, bot.Row(
bot.Button(" Создать закуп", "add_purchase"),
))
// Кнопка назад
buttons = append(buttons, bot.Row(
bot.Button("← Назад", "back"),
))
keyboard := bot.Keyboard(buttons...)
b.Render(text, keyboard, mode)
}
func (s *Purchases) HandleCallback(b *bot.Bot, u *echotron.Update) {
if u.CallbackQuery == nil || u.CallbackQuery.Data == "" {
return
}
data := u.CallbackQuery.Data
switch data {
case "back":
if s.BackState != nil {
b.SetState(s.BackState, bot.EditMessage)
}
case "add_purchase":
b.SetState(&AddPurchase{
WorkspaceID: s.WorkspaceID,
ProjectID: s.ProjectID,
ProjectTitle: s.ProjectTitle,
ActivePicker: "",
BackState: s,
}, bot.EditMessage)
default:
// Проверяем, не нажали ли на конкретный закуп
if len(data) > 9 && data[:9] == "purchase:" {
purchaseID := data[9:]
b.SetState(&PurchaseDetails{
WorkspaceID: s.WorkspaceID,
ProjectID: s.ProjectID,
ProjectTitle: s.ProjectTitle,
PurchaseID: purchaseID,
BackState: s,
}, bot.EditMessage)
} else {
s.Enter(b, bot.NewMessage)
}
}
}
func (s *Purchases) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return }
func (s *Purchases) Handle(_ *bot.Bot, _ *echotron.Update) { return }