#!/usr/bin/env python3 """ Генератор PDF: Детальная оценка найма команды для Montana Protocol + Перевозчик """ from reportlab.lib import colors from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import mm from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont import os # Путь к PDF OUTPUT_PATH = os.path.dirname(os.path.abspath(__file__)) PDF_FILE = os.path.join(OUTPUT_PATH, "ОЦЕНКА_НАЙМА_КОМАНДЫ.pdf") # Регистрация шрифта с поддержкой кириллицы try: pdfmetrics.registerFont(TTFont('DejaVu', '/System/Library/Fonts/Supplemental/Arial Unicode.ttf')) FONT_NAME = 'DejaVu' except: try: pdfmetrics.registerFont(TTFont('DejaVu', '/Library/Fonts/Arial Unicode.ttf')) FONT_NAME = 'DejaVu' except: FONT_NAME = 'Helvetica' def create_pdf(): doc = SimpleDocTemplate( PDF_FILE, pagesize=A4, rightMargin=15*mm, leftMargin=15*mm, topMargin=15*mm, bottomMargin=15*mm ) elements = [] styles = getSampleStyleSheet() # Стили title_style = ParagraphStyle( 'Title', parent=styles['Title'], fontName=FONT_NAME, fontSize=18, spaceAfter=10 ) heading_style = ParagraphStyle( 'Heading', parent=styles['Heading2'], fontName=FONT_NAME, fontSize=14, spaceBefore=15, spaceAfter=8, textColor=colors.HexColor('#1a5f7a') ) normal_style = ParagraphStyle( 'Normal', parent=styles['Normal'], fontName=FONT_NAME, fontSize=10, spaceAfter=6 ) # Заголовок elements.append(Paragraph("MONTANA PROTOCOL + ПЕРЕВОЗЧИК", title_style)) elements.append(Paragraph("Детальная оценка найма команды разработки", normal_style)) elements.append(Paragraph("Дата: Январь 2026", normal_style)) elements.append(Spacer(1, 10*mm)) # Статус проекта elements.append(Paragraph("1. ТЕКУЩИЙ СТАТУС ПРОЕКТА", heading_style)) status_data = [ ['Компонент', 'Готовность', 'Оставшаяся работа'], ['Montana Core (криптография, бот, сеть)', '95%', 'Поддержка, баги'], ['Перевозчик (iOS + backend)', '40%', 'Frontend, интеграция'], ['iOS приложения (4 app)', '50%', 'Swift код, UI, публикация'], ['Сайт Montana', '40%', 'React frontend, деплой'], ] status_table = Table(status_data, colWidths=[70*mm, 30*mm, 70*mm]) status_table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#1a5f7a')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), ('FONTNAME', (0, 0), (-1, -1), FONT_NAME), ('FONTSIZE', (0, 0), (-1, -1), 9), ('ALIGN', (1, 0), (1, -1), 'CENTER'), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#f5f5f5')]), ])) elements.append(status_table) elements.append(Spacer(1, 8*mm)) # Необходимые роли elements.append(Paragraph("2. НЕОБХОДИМЫЕ РОЛИ И ЗАРПЛАТЫ", heading_style)) roles_data = [ ['Роль', 'Уровень', 'США/EU', 'СНГ (РФ/KZ)', 'Задачи'], ['iOS Developer', 'Senior', '$6,000-12,000', '$3,000-5,000', 'Перевозчик, Wallet'], ['Python Backend', 'Senior', '$5,000-10,000', '$2,500-4,500', 'API, интеграции'], ['React Frontend', 'Middle+', '$4,000-8,000', '$2,000-3,500', 'Сайт, MiniApp'], ['DevOps', 'Middle', '$4,000-7,000', '$2,000-3,500', '5 узлов, CI/CD'], ['QA Engineer', 'Middle', '$3,000-5,000', '$1,500-2,500', 'Тестирование'], ] roles_table = Table(roles_data, colWidths=[35*mm, 25*mm, 35*mm, 35*mm, 40*mm]) roles_table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#2d6a4f')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), ('FONTNAME', (0, 0), (-1, -1), FONT_NAME), ('FONTSIZE', (0, 0), (-1, -1), 8), ('ALIGN', (2, 0), (3, -1), 'CENTER'), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#f5f5f5')]), ])) elements.append(roles_table) elements.append(Spacer(1, 10*mm)) # ВАРИАНТ A elements.append(Paragraph("3. ВАРИАНТ A: КОМАНДА В СНГ (РОССИЯ/КАЗАХСТАН)", heading_style)) elements.append(Paragraph("Полная команда для быстрого завершения проекта", normal_style)) variant_a_data = [ ['Роль', 'Кол-во', 'Ставка/мес', 'Итого'], ['iOS Senior', '1', '$4,000', '$4,000'], ['Python Senior', '1', '$3,500', '$3,500'], ['React Middle', '1', '$2,500', '$2,500'], ['DevOps (part-time)', '0.5', '$2,500', '$1,250'], ['QA (part-time)', '0.5', '$2,000', '$1,000'], ['', '', 'Подитог:', '$12,250'], ['', '', 'Накладные (+20%):', '$2,450'], ['', '', 'ИТОГО:', '$14,700/мес'], ] variant_a_table = Table(variant_a_data, colWidths=[50*mm, 25*mm, 45*mm, 45*mm]) variant_a_table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#d4a373')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.black), ('FONTNAME', (0, 0), (-1, -1), FONT_NAME), ('FONTSIZE', (0, 0), (-1, -1), 9), ('ALIGN', (1, 0), (-1, -1), 'CENTER'), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#faedcd')), ('FONTNAME', (2, -1), (-1, -1), FONT_NAME), ('TEXTCOLOR', (3, -1), (3, -1), colors.HexColor('#bc4749')), ])) elements.append(variant_a_table) elements.append(Paragraph("Срок: 1.5-2 месяца | Общая стоимость: $22,000-29,000", normal_style)) elements.append(Spacer(1, 8*mm)) # ВАРИАНТ B elements.append(Paragraph("4. ВАРИАНТ B: УДАЛЁННАЯ КОМАНДА (СМЕШАННАЯ)", heading_style)) elements.append(Paragraph("Оптимизация по соотношению цена/качество", normal_style)) variant_b_data = [ ['Роль', 'Локация', 'Ставка/мес', 'Итого'], ['iOS Senior', 'Сербия/Польша', '$5,500', '$5,500'], ['Python Senior', 'Украина/Грузия', '$4,000', '$4,000'], ['React Middle', 'Россия', '$2,500', '$2,500'], ['DevOps', 'Казахстан', '$2,500', '$2,500'], ['', '', 'ИТОГО:', '$14,500/мес'], ] variant_b_table = Table(variant_b_data, colWidths=[45*mm, 50*mm, 35*mm, 35*mm]) variant_b_table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#457b9d')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), ('FONTNAME', (0, 0), (-1, -1), FONT_NAME), ('FONTSIZE', (0, 0), (-1, -1), 9), ('ALIGN', (2, 0), (-1, -1), 'CENTER'), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#a8dadc')), ('TEXTCOLOR', (3, -1), (3, -1), colors.HexColor('#1d3557')), ])) elements.append(variant_b_table) elements.append(Paragraph("Срок: 1.5-2 месяца | Общая стоимость: $21,000-29,000", normal_style)) elements.append(Spacer(1, 8*mm)) # ВАРИАНТ C elements.append(Paragraph("5. ВАРИАНТ C: ЗАПАДНЫЙ РЫНОК (США/EU)", heading_style)) elements.append(Paragraph("Максимальное качество, максимальная цена", normal_style)) variant_c_data = [ ['Роль', 'Ставка/мес', 'Итого'], ['iOS Senior', '$12,000', '$12,000'], ['Python Senior', '$10,000', '$10,000'], ['React Middle', '$7,000', '$7,000'], ['DevOps', '$6,000', '$6,000'], ['', 'ИТОГО:', '$35,000/мес'], ] variant_c_table = Table(variant_c_data, colWidths=[60*mm, 50*mm, 50*mm]) variant_c_table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#9d4edd')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), ('FONTNAME', (0, 0), (-1, -1), FONT_NAME), ('FONTSIZE', (0, 0), (-1, -1), 9), ('ALIGN', (1, 0), (-1, -1), 'CENTER'), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#e0aaff')), ('TEXTCOLOR', (2, -1), (2, -1), colors.HexColor('#7b2cbf')), ])) elements.append(variant_c_table) elements.append(Paragraph("Срок: 1-1.5 месяца | Общая стоимость: $35,000-52,000", normal_style)) elements.append(Spacer(1, 8*mm)) # ВАРИАНТ D - Минимальный elements.append(Paragraph("6. ВАРИАНТ D: МИНИМАЛЬНАЯ КОМАНДА (MVP)", heading_style)) elements.append(Paragraph("Только Перевозчик + MontanaWallet", normal_style)) variant_d_data = [ ['Роль', 'Кол-во', 'Ставка (СНГ)', 'Срок'], ['iOS Full-stack', '1', '$4,500/мес', '2 мес'], ['Python/DevOps', '1', '$3,500/мес', '2 мес'], ['', '', 'ИТОГО:', '$8,000/мес'], ] variant_d_table = Table(variant_d_data, colWidths=[50*mm, 30*mm, 40*mm, 40*mm]) variant_d_table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#40916c')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), ('FONTNAME', (0, 0), (-1, -1), FONT_NAME), ('FONTSIZE', (0, 0), (-1, -1), 9), ('ALIGN', (1, 0), (-1, -1), 'CENTER'), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#b7e4c7')), ('TEXTCOLOR', (2, -1), (2, -1), colors.HexColor('#1b4332')), ])) elements.append(variant_d_table) elements.append(Paragraph("Срок: 2 месяца | Общая стоимость: $16,000", normal_style)) elements.append(Spacer(1, 8*mm)) # ВАРИАНТ E - Solo + AI elements.append(Paragraph("7. ВАРИАНТ E: SOLO + AI TOOLS (РЕАЛЬНЫЕ РАСХОДЫ)", heading_style)) elements.append(Paragraph("Актуальная стоимость инфраструктуры и AI-инструментов", normal_style)) variant_e_data = [ ['Ресурс', 'Стоимость/мес', 'Примечание'], ['Серверы (5 узлов)', '$250', '5 × $50 (Timeweb, AMS, etc)'], ['Claude Pro', '$200', 'Anthropic subscription'], ['ChatGPT Plus', '$20', 'OpenAI subscription'], ['Cursor Pro', '$200', 'AI-powered IDE'], ['API запросы (доп.)', '$200-400', 'Anthropic/OpenAI API'], ['Apple Developer', '$8', '$99/год'], ['Домены, SSL, misc', '$50-100', 'Прочие расходы'], ['', 'ИТОГО:', '$1,000-1,500/мес'], ] variant_e_table = Table(variant_e_data, colWidths=[55*mm, 45*mm, 60*mm]) variant_e_table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#0077b6')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), ('FONTNAME', (0, 0), (-1, -1), FONT_NAME), ('FONTSIZE', (0, 0), (-1, -1), 9), ('ALIGN', (1, 0), (1, -1), 'CENTER'), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#caf0f8')), ('TEXTCOLOR', (1, -1), (1, -1), colors.HexColor('#03045e')), ])) elements.append(variant_e_table) elements.append(Paragraph("Срок: 3-4 месяца | Общая стоимость: $3,000-6,000", normal_style)) elements.append(Spacer(1, 10*mm)) # ИТОГОВОЕ СРАВНЕНИЕ elements.append(Paragraph("8. ИТОГОВОЕ СРАВНЕНИЕ ВАРИАНТОВ", heading_style)) comparison_data = [ ['Вариант', 'Команда', 'Цена/мес', 'Срок', 'Общая стоимость'], ['A: СНГ полная', '4 чел', '$14,700', '1.5-2 мес', '$22,000-29,000'], ['B: Смешанная', '4 чел', '$14,500', '1.5-2 мес', '$21,000-29,000'], ['C: США/EU', '4 чел', '$35,000', '1-1.5 мес', '$35,000-52,000'], ['D: MVP минимум', '2 чел', '$8,000', '2 мес', '$16,000'], ['E: Solo + AI', '1 чел + AI', '$1,000-1,500', '3-4 мес', '$3,000-6,000'], ] comparison_table = Table(comparison_data, colWidths=[40*mm, 28*mm, 32*mm, 30*mm, 40*mm]) comparison_table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#212529')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), ('FONTNAME', (0, 0), (-1, -1), FONT_NAME), ('FONTSIZE', (0, 0), (-1, -1), 9), ('ALIGN', (1, 0), (-1, -1), 'CENTER'), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#f8f9fa')]), ('BACKGROUND', (0, -1), (-1, -1), colors.HexColor('#d8f3dc')), ('TEXTCOLOR', (2, -1), (2, -1), colors.HexColor('#2d6a4f')), ])) elements.append(comparison_table) elements.append(Spacer(1, 10*mm)) # Рекомендация elements.append(Paragraph("9. РЕКОМЕНДАЦИЯ", heading_style)) rec_style = ParagraphStyle( 'Recommendation', parent=normal_style, backColor=colors.HexColor('#fff3cd'), borderPadding=8, fontSize=9 ) elements.append(Paragraph( "ОПТИМАЛЬНЫЙ ВЫБОР: Вариант D (MVP) или Вариант E (Solo + AI)

" "Montana Core готов на 95%. Основная работа - iOS приложения (Перевозчик + Wallet).

" "Вариант D: 1 iOS-разработчик на контракт ($4,500/мес, 2 месяца) = $9,000-10,000
" "Backend и сайт можно доделать самостоятельно с AI tools.

" "Вариант E: Solo + AI инфраструктура: $1,000-1,500/мес (3-4 мес) = $3,000-6,000
" "Серверы $250 + Claude $200 + GPT $20 + Cursor $200 + API ~$300 + misc $100

" "Экономия vs полная команда: $16,000-46,000", rec_style )) elements.append(Spacer(1, 8*mm)) # Футер footer_style = ParagraphStyle( 'Footer', parent=normal_style, fontSize=8, textColor=colors.grey ) elements.append(Paragraph( "Montana Protocol (Ɉ) | Time is the only real currency | Автор: Alejandro Montana", footer_style )) # Генерация PDF doc.build(elements) print(f"PDF создан: {PDF_FILE}") return PDF_FILE if __name__ == "__main__": create_pdf()