diff --git a/taxes_az/taxes_az/report/gaming_revenue_report/__init__.py b/taxes_az/taxes_az/report/gaming_revenue_report/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.js b/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.js
new file mode 100644
index 0000000..3c5427b
--- /dev/null
+++ b/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.js
@@ -0,0 +1,319 @@
+// Copyright (c) 2024, Your Company and contributors
+// For license information, please see license.txt
+
+frappe.query_reports["Gaming Revenue Report"] = {
+ "filters": [
+ {
+ "fieldname": "company",
+ "label": __("Company"),
+ "fieldtype": "Link",
+ "options": "Company",
+ "default": frappe.defaults.get_user_default("Company"),
+ "reqd": 1,
+ },
+ {
+ "fieldname": "from_date",
+ "label": __("From Date"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
+ "reqd": 1,
+ },
+ {
+ "fieldname": "to_date",
+ "label": __("To Date"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.get_today(),
+ "reqd": 1,
+ }
+ ],
+
+ "formatter": function (value, row, column, data, default_formatter) {
+ value = default_formatter(value, row, column, data);
+
+ // Подсветка колонок с суммами
+ if (column.fieldname && (column.fieldname.includes("sports_") || column.fieldname.includes("lottery_"))) {
+ if (value && parseFloat(value) > 0) {
+ let color = "#28a745"; // зеленый по умолчанию
+ let icon = "";
+
+ if (column.fieldname.includes("sports_organizer")) {
+ color = "#0d6efd"; // синий для спортивных игр организатор
+ icon = "🏆";
+ } else if (column.fieldname.includes("sports_seller")) {
+ color = "#17a2b8"; // голубой для спортивных игр продавец
+ icon = "⚽";
+ } else if (column.fieldname.includes("lottery_organizer")) {
+ color = "#dc3545"; // красный для лотереи организатор
+ icon = "🎰";
+ } else if (column.fieldname.includes("lottery_seller")) {
+ color = "#fd7e14"; // оранжевый для лотереи продавец
+ icon = "🎲";
+ }
+
+ value = `${icon} ${value}`;
+ } else if (value == 0 || !value) {
+ value = `0.00`;
+ }
+ }
+
+ // Подсветка Sales Invoice колонки
+ if (column.fieldname == "sales_invoice" && value) {
+ value = `📄 ${value}`;
+ }
+
+ // Подсветка Date колонки
+ if (column.fieldname == "posting_date" && value) {
+ value = `📅 ${value}`;
+ }
+
+ return value;
+ },
+
+ "onload": function(report) {
+ // Добавляем кастомные кнопки
+ report.page.add_inner_button(__("Export Gaming Summary"), function() {
+ export_gaming_summary(report);
+ });
+
+ report.page.add_inner_button(__("Show Game Types"), function() {
+ show_game_types_info();
+ });
+
+ // Добавляем информационное сообщение
+ report.page.add_inner_button(__("About Gaming Activities"), function() {
+ show_gaming_activities_info();
+ });
+ },
+
+ "after_datatable_render": function(datatable_obj) {
+ // Добавляем итоговую статистику
+ setTimeout(() => {
+ add_gaming_statistics(datatable_obj);
+ }, 500);
+ }
+};
+
+// Функция показа информации о игровых активностях
+function show_gaming_activities_info() {
+ let info_html = '
';
+ info_html += '
🎮 Oyun Fəaliyyətləri
';
+
+ info_html += '
';
+ info_html += '
';
+ info_html += '
🏆 İdman Oyunları:
';
+ info_html += '
';
+ info_html += '- 92000 - Həvəsləndirici oyunlar
';
+ info_html += '- 9200003 - Oyun avtomatları
';
+ info_html += '- 9200004 - Virtual oyunlar
';
+ info_html += '- 9200002 - Totalizator
';
+ info_html += '- 9200005 - İdman mərc oyunları
';
+ info_html += '
';
+ info_html += '
';
+
+ info_html += '
';
+ info_html += '
🎰 Lotereya Oyunları:
';
+ info_html += '
';
+ info_html += '- 9200001 Lotereya oyunları
';
+ info_html += '
';
+ info_html += '
';
+ info_html += '
👥 Rollər:
';
+ info_html += '
';
+ info_html += '- Təşkilatçı: Oyunu təşkil edən
';
+ info_html += '- Satıcı: Oyunu satan
';
+ info_html += '
';
+ info_html += '
';
+ info_html += '
';
+
+ info_html += '
';
+
+ frappe.msgprint({
+ title: __("Gaming Activities Information"),
+ message: info_html,
+ wide: true
+ });
+}
+
+// Функция показа типов игр
+function show_game_types_info() {
+ let info_html = '';
+ info_html += '
🎯 Hesabatda İstifadə Olunan Oyun Tipləri:
';
+ info_html += '
';
+
+ info_html += '
';
+ info_html += '
';
+ info_html += '
🏆 İdman Oyunları
';
+ info_html += '
Təşkilatçı və Satıcı rollarında gəlir
';
+ info_html += '
';
+ info_html += '
';
+
+ info_html += '
';
+ info_html += '
';
+ info_html += '
🎰 Lotereya Oyunları
';
+ info_html += '
Təşkilatçı və Satıcı rollarında gəlir
';
+ info_html += '
';
+ info_html += '
';
+
+ info_html += '
';
+ info_html += '
';
+
+ frappe.msgprint({
+ title: __("Game Types Information"),
+ message: info_html,
+ wide: true
+ });
+}
+
+// Функция экспорта сводки по игорному бизнесу
+function export_gaming_summary(report) {
+ let data = report.data;
+ let summary = calculate_gaming_totals(data);
+
+ // Создаем CSV с итогами
+ let csv_content = "Category,Role,Revenue,Documents Count\n";
+
+ csv_content += `"İdman Oyunları","Təşkilatçı",${summary.sports_organizer_total},${summary.sports_organizer_count}\n`;
+ csv_content += `"İdman Oyunları","Satıcı",${summary.sports_seller_total},${summary.sports_seller_count}\n`;
+ csv_content += `"Lotereya Oyunları","Təşkilatçı",${summary.lottery_organizer_total},${summary.lottery_organizer_count}\n`;
+ csv_content += `"Lotereya Oyunları","Satıcı",${summary.lottery_seller_total},${summary.lottery_seller_count}\n`;
+
+ // Добавляем общие итоги
+ csv_content += `\n"CƏMİ","",${summary.grand_total},${summary.total_documents}\n`;
+
+ // Скачиваем файл
+ let blob = new Blob([csv_content], { type: 'text/csv;charset=utf-8' });
+ let url = window.URL.createObjectURL(blob);
+ let a = document.createElement('a');
+ a.href = url;
+ a.download = 'gaming_revenue_summary_' + frappe.datetime.get_today() + '.csv';
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ window.URL.revokeObjectURL(url);
+
+ frappe.show_alert({message: __("Gaming summary exported successfully"), indicator: "green"});
+}
+
+// Функция расчета итогов по игорному бизнесу
+function calculate_gaming_totals(data) {
+ let summary = {
+ sports_organizer_total: 0,
+ sports_organizer_count: 0,
+ sports_seller_total: 0,
+ sports_seller_count: 0,
+ lottery_organizer_total: 0,
+ lottery_organizer_count: 0,
+ lottery_seller_total: 0,
+ lottery_seller_count: 0,
+ grand_total: 0,
+ total_documents: data.length
+ };
+
+ data.forEach(row => {
+ // Спортивные игры
+ if (row.sports_organizer && row.sports_organizer > 0) {
+ summary.sports_organizer_total += row.sports_organizer;
+ summary.sports_organizer_count++;
+ summary.grand_total += row.sports_organizer;
+ }
+ if (row.sports_seller && row.sports_seller > 0) {
+ summary.sports_seller_total += row.sports_seller;
+ summary.sports_seller_count++;
+ summary.grand_total += row.sports_seller;
+ }
+
+ // Лотерейные игры
+ if (row.lottery_organizer && row.lottery_organizer > 0) {
+ summary.lottery_organizer_total += row.lottery_organizer;
+ summary.lottery_organizer_count++;
+ summary.grand_total += row.lottery_organizer;
+ }
+ if (row.lottery_seller && row.lottery_seller > 0) {
+ summary.lottery_seller_total += row.lottery_seller;
+ summary.lottery_seller_count++;
+ summary.grand_total += row.lottery_seller;
+ }
+ });
+
+ return summary;
+}
+
+// Функция добавления статистики под таблицу
+function add_gaming_statistics(datatable_obj) {
+ if (datatable_obj && datatable_obj.data) {
+ let summary = calculate_gaming_totals(datatable_obj.data);
+
+ let stats_html = '';
+ stats_html += '
🎮 Oyun Gəlirləri Statistikası:
';
+
+ // Статистика по спортивным играм
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += '
🏆 İdman Oyunları
';
+
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += 'Təşkilatçı
';
+ stats_html += `${summary.sports_organizer_total.toFixed(2)}
`;
+ stats_html += `${summary.sports_organizer_count} sənəd`;
+ stats_html += '
';
+ stats_html += '
';
+
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += 'Satıcı
';
+ stats_html += `${summary.sports_seller_total.toFixed(2)}
`;
+ stats_html += `${summary.sports_seller_count} sənəd`;
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += '
';
+
+ stats_html += '
';
+
+ // Статистика по лотерейным играм
+ stats_html += '
';
+ stats_html += '
🎰 Lotereya Oyunları
';
+
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += 'Təşkilatçı
';
+ stats_html += `${summary.lottery_organizer_total.toFixed(2)}
`;
+ stats_html += `${summary.lottery_organizer_count} sənəd`;
+ stats_html += '
';
+ stats_html += '
';
+
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += 'Satıcı
';
+ stats_html += `${summary.lottery_seller_total.toFixed(2)}
`;
+ stats_html += `${summary.lottery_seller_count} sənəd`;
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += '
';
+
+ stats_html += '
';
+ stats_html += '
';
+
+ // Общие итоги
+ let sports_total = summary.sports_organizer_total + summary.sports_seller_total;
+ let lottery_total = summary.lottery_organizer_total + summary.lottery_seller_total;
+
+ stats_html += '
';
+ stats_html += '
';
+ stats_html += `
🏆 İdman Cəmi
${sports_total.toFixed(2)}
`;
+ stats_html += `
🎰 Lotereya Cəmi
${lottery_total.toFixed(2)}
`;
+ stats_html += `
💰 Ümumi Gəlir
${summary.grand_total.toFixed(2)}
`;
+ stats_html += `
📄 Cəmi Sənədlər
${summary.total_documents}
`;
+ stats_html += '
';
+ stats_html += '
';
+
+ stats_html += '
';
+
+ // Удаляем предыдущую статистику если есть
+ $('.gaming-statistics').remove();
+
+ // Добавляем новую статистику
+ $(stats_html).insertAfter('.datatable');
+ }
+}
\ No newline at end of file
diff --git a/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.json b/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.json
new file mode 100644
index 0000000..899b32a
--- /dev/null
+++ b/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.json
@@ -0,0 +1,33 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2025-09-18 19:33:16.290750",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "letterhead": null,
+ "modified": "2025-09-18 19:33:16.290750",
+ "modified_by": "Administrator",
+ "module": "Taxes Az",
+ "name": "Gaming Revenue Report",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Sales Invoice",
+ "report_name": "Gaming Revenue Report",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Accounts User"
+ },
+ {
+ "role": "Accounts Manager"
+ },
+ {
+ "role": "Employee Self Service"
+ }
+ ],
+ "timeout": 0
+}
\ No newline at end of file
diff --git a/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.py b/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.py
new file mode 100644
index 0000000..de50060
--- /dev/null
+++ b/taxes_az/taxes_az/report/gaming_revenue_report/gaming_revenue_report.py
@@ -0,0 +1,197 @@
+# Copyright (c) 2024, Your Company and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe import _
+from frappe.utils import flt, formatdate
+
+
+def execute(filters=None):
+ columns, data = get_columns(), get_data(filters)
+ return columns, data
+
+
+def get_data(filters):
+ """Получаем данные по Sales Invoice для игорного бизнеса"""
+
+ # Получаем Sales Invoice с учетом фильтров
+ sales_invoices = get_sales_invoices(filters)
+
+ if not sales_invoices:
+ return []
+
+ # Получаем информацию о компаниях для определения типа игры
+ companies_activity = get_companies_main_activity()
+
+ # Формируем итоговые данные
+ data = []
+
+ for invoice in sales_invoices:
+ row = frappe._dict()
+
+ # Основные данные
+ row.sales_invoice = invoice['name']
+ row.posting_date = invoice['posting_date']
+ row.company = invoice['company']
+ row.grand_total = flt(invoice['grand_total'])
+
+ # Определяем тип игры по main_activity компании
+ company_activity = companies_activity.get(invoice['company'], '')
+ game_type = determine_game_type(company_activity)
+
+ # Инициализируем все колонки нулями
+ row.sports_organizer = 0
+ row.sports_seller = 0
+ row.lottery_organizer = 0
+ row.lottery_seller = 0
+
+ # Распределяем сумму в зависимости от типа игры и роли
+ if game_type == 'sports':
+ if invoice.get('organizer'):
+ row.sports_organizer = row.grand_total
+ elif invoice.get('seller'):
+ row.sports_seller = row.grand_total
+ elif game_type == 'lottery':
+ if invoice.get('organizer'):
+ row.lottery_organizer = row.grand_total
+ elif invoice.get('seller'):
+ row.lottery_seller = row.grand_total
+
+ data.append(row)
+
+ return data
+
+
+def get_sales_invoices(filters):
+ """Получает Sales Invoice с учетом фильтров"""
+
+ conditions = []
+ values = []
+
+ # Фильтр по компании
+ if filters.get("company"):
+ conditions.append("si.company = %s")
+ values.append(filters.get("company"))
+
+ # Фильтр по датам
+ if filters.get("from_date"):
+ conditions.append("si.posting_date >= %s")
+ values.append(filters.get("from_date"))
+
+ if filters.get("to_date"):
+ conditions.append("si.posting_date <= %s")
+ values.append(filters.get("to_date"))
+
+ # Только подтвержденные документы
+ conditions.append("si.docstatus = 1")
+
+ # Только документы с отмеченными галочками organizer или seller
+ conditions.append("(si.organizer = 1 OR si.seller = 1)")
+
+ where_clause = ""
+ if conditions:
+ where_clause = "WHERE " + " AND ".join(conditions)
+
+ query = f"""
+ SELECT
+ si.name,
+ si.posting_date,
+ si.company,
+ si.grand_total,
+ si.organizer,
+ si.seller
+ FROM
+ `tabSales Invoice` si
+ {where_clause}
+ ORDER BY
+ si.posting_date DESC, si.name
+ """
+
+ return frappe.db.sql(query, values, as_dict=True)
+
+
+def get_companies_main_activity():
+ """Получает main_activity для всех компаний"""
+
+ companies = frappe.db.sql("""
+ SELECT name, main_activity
+ FROM `tabCompany`
+ WHERE main_activity IS NOT NULL
+ """, as_dict=True)
+
+ return {company['name']: company['main_activity'] for company in companies}
+
+
+def determine_game_type(main_activity):
+ """Определяет тип игры на основе main_activity"""
+
+ if not main_activity:
+ return 'unknown'
+
+ # Коды для спортивных игр
+ sports_codes = [
+ '92000',
+ '9200003',
+ '9200004',
+ '9200002',
+ '9200005'
+ ]
+
+ # Код для лотерейных игр
+ lottery_codes = [
+ '9200001'
+ ]
+
+ # Проверяем на соответствие кодам
+ for code in sports_codes:
+ if code in main_activity:
+ return 'sports'
+
+ for code in lottery_codes:
+ if code in main_activity:
+ return 'lottery'
+
+ return 'unknown'
+
+
+def get_columns():
+ """Создает колонки отчета"""
+ return [
+ {
+ "label": "Sales Invoice",
+ "fieldname": "sales_invoice",
+ "fieldtype": "Link",
+ "options": "Sales Invoice",
+ "width": 150
+ },
+ {
+ "label": "Tarix",
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "width": 100
+ },
+ {
+ "label": "İdman oyunları - Təşkilatçı",
+ "fieldname": "sports_organizer",
+ "fieldtype": "Currency",
+ "width": 160
+ },
+ {
+ "label": "İdman oyunları - Satıcı",
+ "fieldname": "sports_seller",
+ "fieldtype": "Currency",
+ "width": 160
+ },
+ {
+ "label": "Lotereya oyunları - Təşkilatçı",
+ "fieldname": "lottery_organizer",
+ "fieldtype": "Currency",
+ "width": 170
+ },
+ {
+ "label": "Lotereya oyunları - Satıcı",
+ "fieldname": "lottery_seller",
+ "fieldtype": "Currency",
+ "width": 170
+ }
+ ]
\ No newline at end of file