This commit is contained in:
Artem Tsyrulnikov
2026-01-19 12:50:36 +03:00
parent 62e8f98429
commit 5473b26787
17 changed files with 478 additions and 599 deletions

View File

@@ -28,71 +28,60 @@ func (s *Purchases) Enter(b *bot.Bot, mode bot.RenderMode) {
}
func (s *Purchases) renderPurchases(b *bot.Bot, mode bot.RenderMode, jwt string) {
purchases, err := b.Backend.GetPurchases(
resp, err := b.Backend.GetPlacements(
context.Background(),
jwt,
s.WorkspaceID,
s.ProjectID,
)
if err != nil {
log.Error().Err(err).Msg("Failed to get purchases")
b.SendNew("❌ Не удалось загрузить закупы", Keyboard())
log.Error().Err(err).Msg("Failed to get placements")
b.SendNew("❌ Не удалось загрузить размещения", Keyboard())
return
}
text := "<b>Закупы</b>\n\n"
text := "<b>Размещения</b>\n\n"
var buttons [][]echotron.InlineKeyboardButton
if len(purchases) == 0 {
text += `Список закупов пуст.
if len(resp.Placements) == 0 {
text += `Список размещений пуст.
<i>Закуп — это план размещения рекламы в каналах:</i>
<i>Размещение — это план публикации рекламы в канале:</i>
‣ Выбор креатива
Список каналов для размещения
Планируемая стоимость
Канал размещения
Стоимость и формат
‣ Статус выполнения
Создайте первый закуп`
Создайте первое размещение`
} else {
text += "Управление закупами для проекта.\n\n"
text += "Выберите закуп для деталей:\n\n"
text += "Управление размещениями для проекта.\n\n"
text += "Выберите размещение для деталей:\n\n"
for i, purchase := range purchases {
// Определяем статус
for i, placement := range resp.Placements {
statusSymbol := "●"
switch purchase.Status {
case "active":
statusSymbol = "●"
case "archived":
if placement.Status == "archived" {
statusSymbol = "■"
}
// Считаем каналы по статусам
totalChannels := len(purchase.Channels)
completedChannels := 0
for _, ch := range purchase.Channels {
if ch.Status == "completed" {
completedChannels++
}
channelName := "Без названия"
if placement.Channel.Title != nil && *placement.Channel.Title != "" {
channelName = *placement.Channel.Title
} else if placement.Channel.Username != nil && *placement.Channel.Username != "" {
channelName = "@" + *placement.Channel.Username
}
buttonText := fmt.Sprintf("%s Закуп #%d (%d/%d каналов)",
statusSymbol,
i+1,
completedChannels,
totalChannels,
)
buttonText := fmt.Sprintf("%s Размещение #%d — %s", statusSymbol, i+1, channelName)
buttons = append(buttons, Row(
Button(buttonText, fmt.Sprintf("purchase:%s", purchase.ID)),
Button(buttonText, fmt.Sprintf("placement:%s", placement.ID)),
))
}
}
// Кнопка создания нового закупа
// Кнопка создания нового размещения
buttons = append(buttons, Row(
Button(" Создать закуп", "add_purchase"),
Button(" Создать размещение", "add_purchase"),
))
// Кнопка назад
@@ -127,13 +116,13 @@ func (s *Purchases) HandleCallback(b *bot.Bot, u *echotron.Update) {
}, bot.EditMessage)
default:
// Проверяем, не нажали ли на конкретный закуп
if len(data) > 9 && data[:9] == "purchase:" {
purchaseID := data[9:]
b.SetState(&PurchaseDetails{
// Проверяем, не нажали ли на конкретное размещение
if len(data) > 10 && data[:10] == "placement:" {
placementID := data[10:]
b.SetState(&PlacementDetails{
WorkspaceID: s.WorkspaceID,
ProjectID: s.ProjectID,
PurchaseID: purchaseID,
PlacementID: placementID,
BackState: s,
}, bot.EditMessage)
} else {