dolibarr/htdocs/ai/tools/reports.class.php

758 lines
26 KiB
PHP
Raw Permalink Normal View History

NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
<?php
/* Copyright (C) 2026 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2026 Nick Fragoulis
Fix: MCP server propagates authenticated service user to tools (#38294) The MCP server (htdocs/ai/server/mcp_server.php) loads a service user from AI_MCP_USER_ID but does not expose it as the PHP global $user. Several tool classes call 'global $user' to identify the caller -- they therefore see no authenticated user in HTTP MCP context (no PHP web session exists) and return 'User not authenticated' even though authentication via X-API-Key/Bearer has already succeeded. This breaks roughly 40% of the MCP tools shipped by the module when called from external clients (Claude Desktop Custom Connectors, Claude Code CLI, MCP Inspector, custom scripts). Two complementary fixes applied: 1. mcp_server.php: after successfully loading the service user, assign it to $GLOBALS['user'] and the local $user variable. This acts as a safety net for any tool (current or third-party) that relies on the legacy 'global $user' pattern. 2. Three tool classes harmonize their constructor signatures with the McpHandler contract -- new $className($db, $user, $conf): - ToolCrudObjects (htdocs/ai/tools/crud_objects.class.php) - ToolInvoices (htdocs/ai/tools/invoices.class.php) - ToolReports (htdocs/ai/tools/reports.class.php) These now accept $user via constructor (matching the pattern already used in ToolThirdParty, ToolCategories, ToolProducts) and store it as $this->user. Methods that previously called 'global $user' (execute, validateInvoice, payInvoice) now use the injected $this->user, with a fallback to the global for web-session contexts. Tested with: - create_other_document (proposal, supplier_invoice): works - search_invoice, validate_invoice, pay_invoice: works - get_sales_report, get_purchase_report: works - AI Assistant web UI: unchanged, no regression
2026-07-13 04:57:42 +00:00
* Copyright (C) 2026 Jose Martinez <jose.martinez@pichinov.com>
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/ai/tools/reports.php
* \ingroup ai
* \brief MCP Server tool for reports.
*
* This tool provides functionalities to generate various reports related to
* thirdparty transactions, sales, purchases, inventory, and other essential
* ERP/CRM reports.
*/
require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
/**
* Class ToolReports
*
* Provides various tools related to Dolibarr reports.
*/
class ToolReports extends McpTool
{
/**
* Constructor
*
Fix: MCP server propagates authenticated service user to tools (#38294) The MCP server (htdocs/ai/server/mcp_server.php) loads a service user from AI_MCP_USER_ID but does not expose it as the PHP global $user. Several tool classes call 'global $user' to identify the caller -- they therefore see no authenticated user in HTTP MCP context (no PHP web session exists) and return 'User not authenticated' even though authentication via X-API-Key/Bearer has already succeeded. This breaks roughly 40% of the MCP tools shipped by the module when called from external clients (Claude Desktop Custom Connectors, Claude Code CLI, MCP Inspector, custom scripts). Two complementary fixes applied: 1. mcp_server.php: after successfully loading the service user, assign it to $GLOBALS['user'] and the local $user variable. This acts as a safety net for any tool (current or third-party) that relies on the legacy 'global $user' pattern. 2. Three tool classes harmonize their constructor signatures with the McpHandler contract -- new $className($db, $user, $conf): - ToolCrudObjects (htdocs/ai/tools/crud_objects.class.php) - ToolInvoices (htdocs/ai/tools/invoices.class.php) - ToolReports (htdocs/ai/tools/reports.class.php) These now accept $user via constructor (matching the pattern already used in ToolThirdParty, ToolCategories, ToolProducts) and store it as $this->user. Methods that previously called 'global $user' (execute, validateInvoice, payInvoice) now use the injected $this->user, with a fallback to the global for web-session contexts. Tested with: - create_other_document (proposal, supplier_invoice): works - search_invoice, validate_invoice, pay_invoice: works - get_sales_report, get_purchase_report: works - AI Assistant web UI: unchanged, no regression
2026-07-13 04:57:42 +00:00
* Aligned with McpHandler's instantiation contract: new $className($db, $user, $conf).
*
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
* @param DoliDB $db Database handler
Fix: MCP server propagates authenticated service user to tools (#38294) The MCP server (htdocs/ai/server/mcp_server.php) loads a service user from AI_MCP_USER_ID but does not expose it as the PHP global $user. Several tool classes call 'global $user' to identify the caller -- they therefore see no authenticated user in HTTP MCP context (no PHP web session exists) and return 'User not authenticated' even though authentication via X-API-Key/Bearer has already succeeded. This breaks roughly 40% of the MCP tools shipped by the module when called from external clients (Claude Desktop Custom Connectors, Claude Code CLI, MCP Inspector, custom scripts). Two complementary fixes applied: 1. mcp_server.php: after successfully loading the service user, assign it to $GLOBALS['user'] and the local $user variable. This acts as a safety net for any tool (current or third-party) that relies on the legacy 'global $user' pattern. 2. Three tool classes harmonize their constructor signatures with the McpHandler contract -- new $className($db, $user, $conf): - ToolCrudObjects (htdocs/ai/tools/crud_objects.class.php) - ToolInvoices (htdocs/ai/tools/invoices.class.php) - ToolReports (htdocs/ai/tools/reports.class.php) These now accept $user via constructor (matching the pattern already used in ToolThirdParty, ToolCategories, ToolProducts) and store it as $this->user. Methods that previously called 'global $user' (execute, validateInvoice, payInvoice) now use the injected $this->user, with a fallback to the global for web-session contexts. Tested with: - create_other_document (proposal, supplier_invoice): works - search_invoice, validate_invoice, pay_invoice: works - get_sales_report, get_purchase_report: works - AI Assistant web UI: unchanged, no regression
2026-07-13 04:57:42 +00:00
* @param User|null $user Service user provided by McpHandler (from AI_MCP_USER_ID)
* @param Conf|null $conf Dolibarr config (optional)
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
*/
Fix: MCP server propagates authenticated service user to tools (#38294) The MCP server (htdocs/ai/server/mcp_server.php) loads a service user from AI_MCP_USER_ID but does not expose it as the PHP global $user. Several tool classes call 'global $user' to identify the caller -- they therefore see no authenticated user in HTTP MCP context (no PHP web session exists) and return 'User not authenticated' even though authentication via X-API-Key/Bearer has already succeeded. This breaks roughly 40% of the MCP tools shipped by the module when called from external clients (Claude Desktop Custom Connectors, Claude Code CLI, MCP Inspector, custom scripts). Two complementary fixes applied: 1. mcp_server.php: after successfully loading the service user, assign it to $GLOBALS['user'] and the local $user variable. This acts as a safety net for any tool (current or third-party) that relies on the legacy 'global $user' pattern. 2. Three tool classes harmonize their constructor signatures with the McpHandler contract -- new $className($db, $user, $conf): - ToolCrudObjects (htdocs/ai/tools/crud_objects.class.php) - ToolInvoices (htdocs/ai/tools/invoices.class.php) - ToolReports (htdocs/ai/tools/reports.class.php) These now accept $user via constructor (matching the pattern already used in ToolThirdParty, ToolCategories, ToolProducts) and store it as $this->user. Methods that previously called 'global $user' (execute, validateInvoice, payInvoice) now use the injected $this->user, with a fallback to the global for web-session contexts. Tested with: - create_other_document (proposal, supplier_invoice): works - search_invoice, validate_invoice, pay_invoice: works - get_sales_report, get_purchase_report: works - AI Assistant web UI: unchanged, no regression
2026-07-13 04:57:42 +00:00
public function __construct(DoliDB $db, $user = null, $conf = null)
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
{
$this->db = $db;
Fix: MCP server propagates authenticated service user to tools (#38294) The MCP server (htdocs/ai/server/mcp_server.php) loads a service user from AI_MCP_USER_ID but does not expose it as the PHP global $user. Several tool classes call 'global $user' to identify the caller -- they therefore see no authenticated user in HTTP MCP context (no PHP web session exists) and return 'User not authenticated' even though authentication via X-API-Key/Bearer has already succeeded. This breaks roughly 40% of the MCP tools shipped by the module when called from external clients (Claude Desktop Custom Connectors, Claude Code CLI, MCP Inspector, custom scripts). Two complementary fixes applied: 1. mcp_server.php: after successfully loading the service user, assign it to $GLOBALS['user'] and the local $user variable. This acts as a safety net for any tool (current or third-party) that relies on the legacy 'global $user' pattern. 2. Three tool classes harmonize their constructor signatures with the McpHandler contract -- new $className($db, $user, $conf): - ToolCrudObjects (htdocs/ai/tools/crud_objects.class.php) - ToolInvoices (htdocs/ai/tools/invoices.class.php) - ToolReports (htdocs/ai/tools/reports.class.php) These now accept $user via constructor (matching the pattern already used in ToolThirdParty, ToolCategories, ToolProducts) and store it as $this->user. Methods that previously called 'global $user' (execute, validateInvoice, payInvoice) now use the injected $this->user, with a fallback to the global for web-session contexts. Tested with: - create_other_document (proposal, supplier_invoice): works - search_invoice, validate_invoice, pay_invoice: works - get_sales_report, get_purchase_report: works - AI Assistant web UI: unchanged, no regression
2026-07-13 04:57:42 +00:00
$this->user = $user;
if ($conf !== null) {
$this->conf = $conf;
}
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
}
/**
* Returns an array of tool definitions.
*
* @return list<array<string, mixed>> Array of tool definitions.
*/
public function getDefinitions(): array
{
return [
[
"name" => "get_thirdparty_transactions",
"description" => "Generate a list of raw transactions (Invoices, Orders) for a specific thirdparty.",
"inputSchema" => [
"type" => "object",
"properties" => [
"thirdparty_id" => ["type" => "integer", "description" => "The unique ID of the thirdparty."],
"thirdparty_name" => ["type" => "string", "description" => "The name of the thirdparty."],
"date_start" => ["type" => "string", "description" => "Start date (YYYY-MM-DD)."],
"date_end" => ["type" => "string", "description" => "End date (YYYY-MM-DD)."],
"transaction_type" => [
"type" => "string",
"enum" => ["all", "invoices", "orders", "proposals"],
"description" => "Filter by type.",
"default" => "all"
]
],
"oneOf" => [
["required" => ["thirdparty_id"]],
["required" => ["thirdparty_name"]]
]
]
],
[
"name" => "get_sales_report",
"description" => "Generate a sales/revenue report. If a Thirdparty is provided, it returns a detailed breakdown for that customer. Otherwise, it returns a global summary.",
"inputSchema" => [
"type" => "object",
"properties" => [
"thirdparty_id" => [
"type" => "integer",
"description" => "Optional: The ID of the customer."
],
"date_start" => ["type" => "string", "description" => "Start date (YYYY-MM-DD)."],
"date_end" => ["type" => "string", "description" => "End date (YYYY-MM-DD)."],
"group_by" => [
"type" => "string",
"enum" => ["thirdparty", "product", "month"],
"description" => "Only used if no Thirdparty is specified. Groups global results.",
"default" => "thirdparty"
]
],
"required" => ["date_start", "date_end"]
]
],
[
"name" => "get_purchase_report",
"description" => "Generate a purchase/expense report. If a Supplier is provided, it returns a detailed breakdown. Otherwise, it returns a global summary.",
"inputSchema" => [
"type" => "object",
"properties" => [
"thirdparty_id" => [
"type" => "integer",
"description" => "Optional: The ID of the supplier."
],
"date_start" => ["type" => "string", "description" => "Start date (YYYY-MM-DD)."],
"date_end" => ["type" => "string", "description" => "End date (YYYY-MM-DD)."],
"group_by" => [
"type" => "string",
"enum" => ["supplier", "product", "month"],
"description" => "Only used if no Supplier is specified. Groups global results.",
"default" => "supplier"
]
],
"required" => ["date_start", "date_end"]
]
],
[
"name" => "get_inventory_report",
"description" => "Generate an inventory report showing current stock levels and valuation.",
"inputSchema" => [
"type" => "object",
"properties" => [
"category_id" => ["type" => "integer", "description" => "Filter by category ID."],
"warehouse_id" => ["type" => "integer", "description" => "Filter by warehouse ID."],
"include_zero_stock" => ["type" => "boolean", "default" => false]
]
]
],
[
"name" => "get_financial_report",
"description" => "Generate a summary financial report (Income vs Expense) for a period.",
"inputSchema" => [
"type" => "object",
"properties" => [
"date_start" => ["type" => "string", "description" => "Start date (YYYY-MM-DD)."],
"date_end" => ["type" => "string", "description" => "End date (YYYY-MM-DD)."]
],
"required" => ["date_start", "date_end"]
]
],
];
}
/**
* Return categories this tool belongs to.
* Used by the intent parser to filter available tools.
*
* @return array<string> List of categories (e.g., ['billing', 'commercial'])
*/
public function getCategories(): array
{
return ['reporting', 'commercial', 'billing', 'stock'];
}
/**
* Executes the requested tool function based on its name.
*
* @param string $name The name of the tool to execute.
* @param array<string, mixed> $args The arguments for the tool (key-value pairs).
* @return mixed The result of the tool execution (usually an array) or an error array.
*/
public function execute(string $name, array $args)
{
switch ($name) {
case 'get_thirdparty_transactions':
return $this->getThirdpartyTransactions($args);
case 'get_sales_report':
return $this->getSalesReport($args);
case 'get_purchase_report':
return $this->getPurchaseReport($args);
case 'get_inventory_report':
return $this->getInventoryReport($args);
case 'get_financial_report':
return $this->getFinancialReport($args);
default:
return ["error" => "Tool function '$name' not found."];
}
}
/**
* Resolves a Thirdparty ID from either an ID or a name.
*
* If `thirdparty_id` is provided, it is returned directly.
* Otherwise, if `thirdparty_name` is provided, the function searches
* the Dolibarr societe table using a LIKE match and returns the first match.
*
* @param array<string, mixed> $args Input parameters (thirdparty_id, thirdparty_name)
*
* @return int|null Thirdparty ID if found, otherwise null.
*/
private function resolveThirdparty($args)
{
if (!empty($args['thirdparty_id'])) {
return (int) $args['thirdparty_id'];
}
if (!empty($args['thirdparty_name'])) {
$sqlName = $this->db->escape($args['thirdparty_name']);
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
$sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "societe
WHERE nom LIKE '%" . $sqlName . "%'
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
AND entity IN (" . getEntity('societe') . ")
LIMIT 1";
$resql = $this->db->query($sql);
if ($resql && $obj = $this->db->fetch_object($resql)) {
return $obj->rowid;
}
}
return null;
}
/**
* Generate a sales/revenue report.
*
* @param array<string, mixed> $args Input arguments (date_start, date_end, limit, etc.)
* @return array<int, array<string, string>> List of sales with localized keys and values.
*/
private function getSalesReport(array $args): array
{
global $langs;
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$langs->loadLangs(array("main", "bills", "companies", "products"));
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$limit = isset($args['limit']) ? (int) $args['limit'] : 50;
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
$dateStart = dol_stringtotime($args['date_start']);
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$dateEnd = dol_stringtotime($args['date_end']);
$socid = $this->resolveThirdparty($args);
$groupBy = isset($args['group_by']) ? (string) $args['group_by'] : 'thirdparty';
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$list = [];
$totalSum = 0.0;
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
// Status Filter: Valid (1) and Paid (2). Exclude Draft (0) and Abandoned (3).
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$dateRange = " AND f.datef >= '" . $this->db->idate($dateStart)
. "' AND f.datef <= '" . $this->db->idate($dateEnd)
. "' AND f.fk_statut IN (1, 2)";
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
// CASE 1 -- Detailed list for a specific thirdparty.
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
if ($socid) {
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$sql = "SELECT f.rowid, f.ref, f.total_ttc, f.fk_statut, f.paye, f.datef, s.nom FROM "
. MAIN_DB_PREFIX . "facture as f LEFT JOIN "
. MAIN_DB_PREFIX . "societe as s ON f.fk_soc = s.rowid WHERE f.entity IN ("
. getEntity('facture') . ")"
. $dateRange
. " AND f.fk_soc = " . (int) $socid
. " ORDER BY f.datef DESC LIMIT " . ((int) $limit);
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$resql = $this->db->query($sql);
if ($resql) {
while ($r = $this->db->fetch_object($resql)) {
$totalSum += (float) $r->total_ttc;
$statusLabel = $langs->transnoentitiesnoconv("Unknown");
if ($r->fk_statut == 1 && $r->paye == 0) {
$statusLabel = $langs->transnoentitiesnoconv("BillStatusNotPaid");
} elseif ($r->fk_statut == 1 && $r->paye == 1) {
$statusLabel = $langs->transnoentitiesnoconv("BillStatusStarted");
} elseif ($r->fk_statut == 2) {
$statusLabel = $langs->transnoentitiesnoconv("BillStatusPaid");
}
$url = DOL_URL_ROOT . "/compta/facture/card.php?id=" . $r->rowid;
$refHtml = '<a href="' . $url . '">' . $r->ref . '</a>';
$list[] = [
$langs->transnoentitiesnoconv("Ref") => $refHtml,
$langs->transnoentitiesnoconv("Date") => dol_print_date($this->db->jdate($r->datef), 'day'),
$langs->transnoentitiesnoconv("Customer") => $r->nom,
$langs->transnoentitiesnoconv("Amount") => price($r->total_ttc),
$langs->transnoentitiesnoconv("Status") => $statusLabel
];
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
}
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$this->db->free($resql);
}
} else {
// CASE 2 -- Global grouped report.
// Mirrors the pattern already used by getPurchaseReport(); previous implementation
// of getSalesReport() ignored $groupBy entirely and always returned a flat list.
$sanitizedSqlGroup = '';
$colName = '';
$sqlJoin = " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON f.fk_soc = s.rowid";
if ($groupBy === 'month') {
$sanitizedSqlGroup = "DATE_FORMAT(f.datef, '%Y-%m')";
$colName = $langs->transnoentitiesnoconv("Month");
} elseif ($groupBy === 'product') {
// Aggregate on product line items. Lines without product_id fall back to their description.
$sanitizedSqlGroup = "COALESCE(p.ref, fd.description, '?')";
$colName = $langs->transnoentitiesnoconv("Product");
$sqlJoin .= " INNER JOIN " . MAIN_DB_PREFIX . "facturedet as fd ON fd.fk_facture = f.rowid LEFT JOIN "
. MAIN_DB_PREFIX . "product as p ON fd.fk_product = p.rowid";
} else {
// Default: group by customer
$sanitizedSqlGroup = "s.nom";
$colName = $langs->transnoentitiesnoconv("Customer");
}
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
// For product grouping we sum line totals (more accurate per-product);
// otherwise we sum the invoice total_ttc.
$amountExpr = ($groupBy === 'product') ? "SUM(fd.total_ttc)" : "SUM(f.total_ttc)";
$countExpr = ($groupBy === 'product') ? "COUNT(DISTINCT f.rowid)" : "COUNT(f.rowid)";
$sql = "SELECT " . $sanitizedSqlGroup . " as group_key, "
. $amountExpr . " as total_amount, "
. $countExpr . " as count_inv FROM "
. MAIN_DB_PREFIX . "facture as f"
. $sqlJoin
. " WHERE f.entity IN (" . getEntity('facture') . ")"
. $dateRange
. " GROUP BY group_key ORDER BY total_amount DESC LIMIT "
. ((int) max(1, $limit));
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
$resql = $this->db->query($sql);
if ($resql) {
while ($r = $this->db->fetch_object($resql)) {
$totalSum += (float) $r->total_amount;
$list[] = [
$colName => $r->group_key ? $r->group_key : $langs->transnoentitiesnoconv('Unknown'),
$langs->transnoentitiesnoconv("Number") => (int) $r->count_inv,
$langs->transnoentitiesnoconv("Amount") => price($r->total_amount)
];
}
$this->db->free($resql);
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
}
}
if (empty($list)) {
return [[$langs->transnoentitiesnoconv("Info") => $langs->transnoentitiesnoconv("NoRecordFound")]];
}
Fix: get_sales_report respects the group_by parameter (#38303) The get_sales_report tool declares a group_by parameter with enum values [thirdparty, product, month] in its inputSchema, but the implementation ignored $args['group_by'] entirely and always returned a flat list of invoices. Meanwhile getPurchaseReport() in the same class already implemented the correct grouped pattern (s.nom or DATE_FORMAT date) -- this patch ports that pattern to getSalesReport(), with three modes: - With a socid: detailed invoice list for that customer (unchanged behavior, kept for backward compatibility). - Without socid, group_by=thirdparty (default): aggregate by customer with COUNT and SUM(total_ttc) -> Top-customers report. - Without socid, group_by=month: aggregate by DATE_FORMAT(datef, '%Y-%m') -> monthly revenue report. - Without socid, group_by=product: aggregate by product reference via INNER JOIN on facturedet, with COALESCE(p.ref, fd.description) so free-text lines without a product link still appear under their description. SUM(fd.total_ttc) gives per-product revenue, COUNT(DISTINCT f.rowid) gives the number of invoices that contained the product. Tested: - group_by=thirdparty: top customers correctly ranked by total. - group_by=month: 2026-04 and 2026-05 buckets correctly populated. - group_by=product: top product (SAM-BIK3-CAS-1430-24-N) correctly ranked at 1 276 EUR over 5 invoices. - With socid: unchanged detailed listing. Note: the 'product' grouping is also missing from getPurchaseReport() in the current code. That can be addressed in a follow-up patch on the same pattern.
2026-05-17 22:04:14 +00:00
// Append Total Row (shape depends on detailed-vs-grouped path)
if ($socid) {
$list[] = [
$langs->transnoentitiesnoconv("Ref") => $langs->transnoentitiesnoconv("Total"),
$langs->transnoentitiesnoconv("Date") => "",
$langs->transnoentitiesnoconv("Customer") => "",
$langs->transnoentitiesnoconv("Amount") => price($totalSum),
$langs->transnoentitiesnoconv("Status") => ""
];
} else {
$list[] = [
$langs->transnoentitiesnoconv("Total") => $langs->transnoentitiesnoconv("Total"),
$langs->transnoentitiesnoconv("Amount") => price($totalSum)
];
}
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
return $list;
}
/**
* Generate a list of raw transactions (Invoices, Orders, Proposals).
*
* @param array<string, mixed> $args Input arguments.
* @return array<int, array<string, string>> Combined list of transactions.
*/
private function getThirdpartyTransactions(array $args): array
{
global $langs;
$langs->loadLangs(array("main", "bills", "orders", "propal"));
$dateStart = dol_stringtotime($args['date_start']);
$dateEnd = dol_stringtotime($args['date_end']);
$type = isset($args['transaction_type']) ? (string) $args['transaction_type'] : 'all';
$socid = $this->resolveThirdparty($args);
if (!$socid) {
2026-05-19 12:08:05 +00:00
$langs->load("errors");
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
return [[$langs->transnoentitiesnoconv("Error") => $langs->transnoentitiesnoconv("ErrorThirdPartyNotFound")]];
}
$sqlQueries = [];
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
// Invoices
if ($type == 'all' || $type == 'invoices') {
$sqlQueries[] = "SELECT 'Invoice' as source_type, rowid, ref, total_ttc as amount, datef as date_entry, fk_statut
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
FROM " . MAIN_DB_PREFIX . "facture
WHERE fk_soc = " . (int) $socid . " AND entity IN (" . getEntity('facture') . ")
AND fk_statut IN (1, 2)";
}
// Orders
if ($type == 'all' || $type == 'orders') {
$sqlQueries[] = "SELECT 'Order' as source_type, rowid, ref, total_ttc as amount, date_commande as date_entry, fk_statut
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
FROM " . MAIN_DB_PREFIX . "commande
WHERE fk_soc = " . (int) $socid . " AND entity IN (" . getEntity('commande') . ")
AND fk_statut > 0";
}
// Proposals
if ($type == 'all' || $type == 'proposals') {
$sqlQueries[] = "SELECT 'Proposal' as source_type, rowid, ref, total_ttc as amount, datep as date_entry, fk_statut
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
FROM " . MAIN_DB_PREFIX . "propal
WHERE fk_soc = " . (int) $socid . " AND entity IN (" . getEntity('propal') . ")
AND fk_statut > 0";
}
if (empty($sqlQueries)) {
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
return [[$langs->transnoentitiesnoconv("Error") => "Invalid transaction type"]];
}
$sql = "SELECT * FROM (";
$sql .= implode(" UNION ", $sqlQueries);
NEW: MCP server and AI Assistant (#37888) * fix list query * Update other.lang * remove duplicate * initial commit * AI Assistant initial commit * Rename htdocs/ai/index.php to htdocs/ai/assistant/index.php * AI Assistant initial commit * Initial commit * Rename htdocs/ai/ai_assistant.css to htdocs/ai/css/ai_assistant.css * Initial commit * Rename htdocs/ai/ai_assistant.js to htdocs/ai/js/ai_assistant.js * Initial commit * Rename htdocs/ai/mcp_server.php to htdocs/ai/server/mcp_server.php * Initial commit * category tools * Rename htdocs/ai/categories.php to htdocs/ai/tools/categories.php * Global tools to restrict AI * Tools for crud actions on Dolibarr objects * Tools for products and services. * Tools to generate reports * Missing PHPDoc * Tools for thirdparties and contacts * Tool for generating navigation URLs in Dolibarr * Tools related to invoices and payments * Update ai_assistant.js * Initial commit * Rename htdocs/ai/purge_logs.php to htdocs/ai/scripts/purge_logs.php * fix pre commit * re fix pre-commit * fix pre-commit * Rename categories.php to categories.class.php * Rename conversation.php to conversation.class.php * Rename crud_objects.php to crud_objects.class.php * Rename invoices.php to invoices.class.php * Rename navigation.php to navigation.class.php * Rename products.php to products.class.php * Rename reports.php to reports.class.php * Rename thirdparty.php to thirdparty.class.php * fix pre-commit * Update parse_intent.php * fix pre commit * fix phpdoc * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * fix pre-commit * add missing phpdoc * fix pre-commit * fix phpdoc * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix pre-commit * fix pre-commit * fix phpdoc * fix phpdoc * fix phpdoc * fix phpdoc * fix php-stan * fix php-stan * fix phan * fix phan * fix phan * security check * security check * security check * security check * enhance security check * enhance security check * fix pre-commit * Update log_viewer.php * Improve access control logic in log_viewer.php Refactor access control checks for admin and module activation. * fix phan * fix phan * fix phan * fix phan * fix phan * try fix phan * fix pre-commit * fix phan * try fix phan * fix phan * fix php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix pre-commit * fix phan php-stan * fix phan php-stan * fix phn php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix phan php-stan * fix pre-commit * fix phan php-stan * fix php-stan * Fix MCP tool registration for .class.php file naming * fix typo * fix ci * fix pre-commit * fix ci * fix pre-commit * Update categories.class.php * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * fix ci * add missing user in constructor * add missing user in constructor * improve invoice validation error handling * add missing user in constructor * Rename mcp_protocol.php to mcp_protocol.class.php * Update mcp_server.php --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-10 23:59:55 +00:00
$sql .= ") as combined_transactions ";
$whereParts = [];
if ($dateStart > 0) {
$whereParts[] = "date_entry >= '" . $this->db->idate($dateStart) . "'";
}
if ($dateEnd > 0) {
$whereParts[] = "date_entry <= '" . $this->db->idate($dateEnd) . "'";
}
if (!empty($whereParts)) {
$sql .= " WHERE " . implode(" AND ", $whereParts);
}
$sql .= " ORDER BY date_entry DESC";
$resql = $this->db->query($sql);
$list = [];
$totalAmt = 0.0;
if ($resql) {
while ($r = $this->db->fetch_object($resql)) {
$totalAmt += (float) $r->amount;
$statusTxt = "";
$urlPath = "";
if ($r->source_type === 'Invoice') {
$urlPath = "/compta/facture/card.php?id=" . $r->rowid;
if ($r->fk_statut == 2) {
$statusTxt = $langs->transnoentitiesnoconv("BillStatusPaid");
} elseif ($r->fk_statut == 1) {
$statusTxt = $langs->transnoentitiesnoconv("BillStatusNotPaid");
}
} elseif ($r->source_type === 'Order') {
$urlPath = "/commande/card.php?id=" . $r->rowid;
if ($r->fk_statut == 1) {
$statusTxt = $langs->transnoentitiesnoconv("StatusOrderValidated");
} elseif ($r->fk_statut == 2) {
$statusTxt = $langs->transnoentitiesnoconv("StatusOrderOnProcess");
} elseif ($r->fk_statut == 3) {
$statusTxt = $langs->transnoentitiesnoconv("StatusOrderDelivered");
}
} elseif ($r->source_type === 'Proposal') {
$urlPath = "/comm/propal/card.php?id=" . $r->rowid;
if ($r->fk_statut == 1) {
$statusTxt = $langs->transnoentitiesnoconv("PropalStatusValidated");
} elseif ($r->fk_statut == 2) {
$statusTxt = $langs->transnoentitiesnoconv("PropalStatusSigned");
} elseif ($r->fk_statut == 3) {
$statusTxt = $langs->transnoentitiesnoconv("PropalStatusNotSigned");
} elseif ($r->fk_statut == 4) {
$statusTxt = $langs->transnoentitiesnoconv("PropalStatusBilled");
}
}
$fullUrl = $urlPath ? DOL_URL_ROOT . $urlPath : "";
$refHtml = $fullUrl ? '<a href="' . $fullUrl . '">' . $r->ref . '</a>' : $r->ref;
$list[] = [
$langs->transnoentitiesnoconv("Type") => $langs->transnoentitiesnoconv($r->source_type),
$langs->transnoentitiesnoconv("Ref") => $refHtml,
$langs->transnoentitiesnoconv("Date") => dol_print_date($this->db->jdate($r->date_entry), 'day'),
$langs->transnoentitiesnoconv("Amount") => price($r->amount),
$langs->transnoentitiesnoconv("Status") => $statusTxt
];
}
$this->db->free($resql);
}
if (empty($list)) {
return [[$langs->transnoentitiesnoconv("Info") => $langs->transnoentitiesnoconv("NoRecordFound")]];
}
// Summary
$list[] = [
$langs->transnoentitiesnoconv("Type") => $langs->transnoentitiesnoconv("Total"),
$langs->transnoentitiesnoconv("Ref") => "",
$langs->transnoentitiesnoconv("Date") => "",
$langs->transnoentitiesnoconv("Amount") => price($totalAmt),
$langs->transnoentitiesnoconv("Status") => ""
];
return $list;
}
/**
* Generate a purchase/expense report.
*
* @param array<string, mixed> $args Input arguments.
* @return array<int, array<string, string>> List of purchases or groups.
*/
private function getPurchaseReport(array $args): array
{
global $langs;
$langs->loadLangs(array("main", "bills", "companies"));
$socid = $this->resolveThirdparty($args);
$groupBy = isset($args['group_by']) ? (string) $args['group_by'] : 'supplier';
$dateStart = dol_stringtotime($args['date_start']);
$dateEnd = dol_stringtotime($args['date_end']);
$list = [];
$totalSum = 0.0;
// Detailed report for a specific Supplier
if ($socid) {
$sql = "SELECT f.rowid, f.ref, f.total_ttc, f.datef, s.nom
FROM " . MAIN_DB_PREFIX . "facture_fourn as f
LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON f.fk_soc = s.rowid
WHERE f.entity IN (" . getEntity('facture_fourn') . ")
AND f.fk_soc = " . (int) $socid . "
AND f.datef >= '" . $this->db->idate($dateStart) . "'
AND f.datef <= '" . $this->db->idate($dateEnd) . "'
AND f.fk_statut > 0
ORDER BY f.datef DESC";
$resql = $this->db->query($sql);
if ($resql) {
while ($r = $this->db->fetch_object($resql)) {
$totalSum += (float) $r->total_ttc;
$url = DOL_URL_ROOT . "/fourn/facture/card.php?id=" . $r->rowid;
$refHtml = '<a href="' . $url . '">' . $r->ref . '</a>';
$list[] = [
$langs->transnoentitiesnoconv("Ref") => $refHtml,
$langs->transnoentitiesnoconv("Date") => dol_print_date($this->db->jdate($r->datef), 'day'),
$langs->transnoentitiesnoconv("Supplier") => $r->nom,
$langs->transnoentitiesnoconv("Amount") => price($r->total_ttc)
];
}
$this->db->free($resql);
}
} else { // Global Grouped Report
$sanitizedSqlGroup = "";
$colName = "";
if ($groupBy === 'month') {
$sanitizedSqlGroup = "DATE_FORMAT(f.datef, '%Y-%m')";
$colName = $langs->transnoentitiesnoconv("Month");
} else {
$sanitizedSqlGroup = "s.nom";
$colName = $langs->transnoentitiesnoconv("Supplier");
}
$sql = "SELECT " . $sanitizedSqlGroup . " as group_key, SUM(f.total_ttc) as total_amount, COUNT(f.rowid) as count_inv
FROM " . MAIN_DB_PREFIX . "facture_fourn as f
LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON f.fk_soc = s.rowid
WHERE f.entity IN (" . getEntity('facture_fourn') . ")
AND f.datef >= '" . $this->db->idate($dateStart) . "'
AND f.datef <= '" . $this->db->idate($dateEnd) . "'
AND f.fk_statut > 0
GROUP BY group_key
ORDER BY total_amount DESC";
$resql = $this->db->query($sql);
if ($resql) {
while ($r = $this->db->fetch_object($resql)) {
$totalSum += (float) $r->total_amount;
$list[] = [
$colName => $r->group_key ? $r->group_key : $langs->transnoentitiesnoconv('Unknown'),
$langs->transnoentitiesnoconv("Number") => $r->count_inv,
$langs->transnoentitiesnoconv("Amount") => price($r->total_amount)
];
}
$this->db->free($resql);
}
}
if (empty($list)) {
return [[$langs->transnoentitiesnoconv("Info") => $langs->transnoentitiesnoconv("NoRecordFound")]];
}
// Summary Row
$summary = [
$langs->transnoentitiesnoconv("Amount") => price($totalSum)
];
if ($socid) {
$summary[$langs->transnoentitiesnoconv("Ref")] = $langs->transnoentitiesnoconv("Total");
$summary[$langs->transnoentitiesnoconv("Date")] = "";
$summary[$langs->transnoentitiesnoconv("Supplier")] = "";
} else {
$summary[($groupBy === 'month' ? $langs->transnoentitiesnoconv("Month") : $langs->transnoentitiesnoconv("Supplier"))] = $langs->transnoentitiesnoconv("Total");
$summary[$langs->transnoentitiesnoconv("Number")] = "";
}
$list[] = $summary;
return $list;
}
/**
* Generate an inventory report.
*
* @param array<string, mixed> $args Input arguments.
* @return array<int, array<string, string>> Stock list.
*/
private function getInventoryReport(array $args): array
{
global $langs;
$langs->loadLangs(array("products", "stocks"));
$catId = isset($args['category_id']) ? (int) $args['category_id'] : 0;
$warehouseId = isset($args['warehouse_id']) ? (int) $args['warehouse_id'] : 0;
$includeZero = isset($args['include_zero_stock']) ? (bool) $args['include_zero_stock'] : false;
$sql = "SELECT p.rowid, p.ref, p.label, p.pmp, ";
if ($warehouseId > 0) {
$sql .= " ps.reel as stock_level ";
$sql .= " FROM " . MAIN_DB_PREFIX . "product as p ";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_stock as ps ON p.rowid = ps.fk_product ";
$sql .= " WHERE ps.fk_entrepot = " . (int) $warehouseId;
} else {
$sql .= " p.stock as stock_level ";
$sql .= " FROM " . MAIN_DB_PREFIX . "product as p ";
$sql .= " WHERE 1=1 ";
}
$sql .= " AND p.entity IN (" . getEntity('product') . ")";
if ($catId > 0) {
$sql .= " AND p.rowid IN (SELECT fk_product FROM " . MAIN_DB_PREFIX . "categorie_product WHERE fk_categorie = " . (int) $catId . ")";
}
if (!$includeZero) {
if ($warehouseId > 0) {
$sql .= " AND ps.reel > 0";
} else {
$sql .= " AND p.stock > 0";
}
}
$sql .= " ORDER BY p.ref ASC LIMIT 200";
$resql = $this->db->query($sql);
$list = [];
$totalValuation = 0.0;
$totalItems = 0;
if ($resql) {
while ($r = $this->db->fetch_object($resql)) {
$stockVal = $r->stock_level * $r->pmp;
$totalValuation += $stockVal;
$totalItems += (int) $r->stock_level;
$url = DOL_URL_ROOT . "/product/card.php?id=" . $r->rowid;
$refHtml = '<a href="' . $url . '">' . $r->ref . '</a>';
$list[] = [
$langs->transnoentitiesnoconv("Ref") => $refHtml,
$langs->transnoentitiesnoconv("Label") => $r->label,
$langs->transnoentitiesnoconv("Stock") => $r->stock_level,
$langs->transnoentitiesnoconv("PMPValue") => price($r->pmp),
$langs->transnoentitiesnoconv("TotalValue") => price($stockVal)
];
}
$this->db->free($resql);
}
if (empty($list)) {
return [[$langs->transnoentitiesnoconv("Info") => $langs->transnoentitiesnoconv("NoRecordFound")]];
}
$list[] = [
$langs->transnoentitiesnoconv("Ref") => $langs->transnoentitiesnoconv("Total"),
$langs->transnoentitiesnoconv("Label") => "",
$langs->transnoentitiesnoconv("Stock") => $totalItems,
$langs->transnoentitiesnoconv("PMPValue") => "",
$langs->transnoentitiesnoconv("TotalValue") => price($totalValuation)
];
return $list;
}
/**
* Generate a summary financial report (Income vs Expense).
*
* @param array<string, mixed> $args Input arguments.
* @return array<int, array<string, string>> Financial summary.
*/
private function getFinancialReport(array $args): array
{
global $langs;
$langs->loadLangs(array("compta", "bills"));
$dateStart = dol_stringtotime($args['date_start']);
$dateEnd = dol_stringtotime($args['date_end']);
// Income (Customer Invoices - Validated/Paid, no Drafts)
$sqlIncome = "SELECT SUM(total_ttc) as total FROM " . MAIN_DB_PREFIX . "facture
WHERE entity IN (" . getEntity('facture') . ")
AND datef >= '" . $this->db->idate($dateStart) . "'
AND datef <= '" . $this->db->idate($dateEnd) . "'
AND fk_statut IN (1, 2)";
$resIncome = $this->db->query($sqlIncome);
$objIncome = $this->db->fetch_object($resIncome);
$income = $objIncome && $objIncome->total ? (float) $objIncome->total : 0.0;
// Expenses (Supplier Invoices - Validated, no Drafts)
$sqlExpense = "SELECT SUM(total_ttc) as total FROM " . MAIN_DB_PREFIX . "facture_fourn
WHERE entity IN (" . getEntity('facture_fourn') . ")
AND datef >= '" . $this->db->idate($dateStart) . "'
AND datef <= '" . $this->db->idate($dateEnd) . "'
AND fk_statut > 0";
$resExpense = $this->db->query($sqlExpense);
$objExpense = $this->db->fetch_object($resExpense);
$expense = $objExpense && $objExpense->total ? (float) $objExpense->total : 0.0;
$net = $income - $expense;
$list = [
[
$langs->transnoentitiesnoconv("Category") => $langs->transnoentitiesnoconv("Income"),
$langs->transnoentitiesnoconv("Description") => $langs->transnoentitiesnoconv("BillsCustomers"),
$langs->transnoentitiesnoconv("Amount") => price($income)
],
[
$langs->transnoentitiesnoconv("Category") => $langs->transnoentitiesnoconv("Expenses"),
$langs->transnoentitiesnoconv("Description") => $langs->transnoentitiesnoconv("BillsSuppliers"),
$langs->transnoentitiesnoconv("Amount") => price($expense)
],
[
$langs->transnoentitiesnoconv("Category") => $langs->transnoentitiesnoconv("Total"),
$langs->transnoentitiesnoconv("Description") => $langs->transnoentitiesnoconv("Profit"),
$langs->transnoentitiesnoconv("Amount") => price($net)
]
];
return $list;
}
}