<?php
/* Copyright (C) 2004-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
 * Copyright (C) 2024       Frédéric France         <frederic.france@free.fr>
 * Copyright (C) 2025		SuperAdmin					<daoud.mouhamed@gmail.com>
 *
 * 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    einvoicing/admin/setup_devtools.php
 * \ingroup einvoicing
 * \brief   EInvoicing setup page to provide some tools for dev or test.
 * 			This page is visible in the setup menu only if the constant EINVOICING_ALLOW_DEVTOOLS is set to 1.
 */

// Load Dolibarr environment
$res = 0;
// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
	$res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
}
// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME'];
$tmp2 = realpath(__FILE__);
$i = strlen($tmp) - 1;
$j = strlen($tmp2) - 1;
while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
	$i--;
	$j--;
}
if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
	$res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
}
if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
	$res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
}
// Try main.inc.php using relative path
if (!$res && file_exists("../../main.inc.php")) {
	$res = @include "../../main.inc.php";
}
if (!$res && file_exists("../../../main.inc.php")) {
	$res = @include "../../../main.inc.php";
}
if (!$res && file_exists("../../../../main.inc.php")) {
	$res = @include "../../../../main.inc.php";
}
if (!$res && file_exists("../../../../../main.inc.php")) {
	$res = @include "../../../../../main.inc.php";
}
if (!$res) {
	die("Include of main fails");
}
/**
 * @var Conf $conf
 * @var DoliDB $db
 * @var HookManager $hookmanager
 * @var Societe $mysoc
 * @var Translate $langs
 * @var User $user
 */
// Libraries
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
require_once '../lib/einvoicing.lib.php';
require_once "../class/providers/PDPProviderManager.class.php";
require_once "../class/protocols/ProtocolManager.class.php";
require_once "../class/einvoicing.class.php";


// Translations
$langs->loadLangs(array("admin", "bills", "einvoicing@einvoicing", "other"));

// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
/** @var HookManager $hookmanager */
$hookmanager->initHooks(array('einvoicingsetup', 'globalsetup'));

// Parameters
$action = GETPOST('action', 'aZ09');
$backtopage = GETPOST('backtopage', 'alpha');
$modulepart = GETPOST('modulepart', 'aZ09');	// Used by actions_setmoduleoptions.inc.php

$value = GETPOST('value', 'alpha');
$label = GETPOST('label', 'alpha');
$scandir = GETPOST('scan_dir', 'alpha');
$type = 'myobject';

$error = 0;
$setupnotempty = 0;

// Access control
if (!$user->admin) {
	accessforbidden();
}

$einvoicing = new EInvoicing($db);
$PDPManager = new PDPProviderManager($db);

// If Access Point is selected, show parameters for it
if (getDolGlobalString('EINVOICING_PDP')) {
	// Generate a $provider (this call the constructor that load the token with fetchOAuthTokenDB() and save it in the memory var $provider->tokenData)
	// Note: Token may have been expired
	$provider = $PDPManager->getProvider(getDolGlobalString('EINVOICING_PDP'));
	// Now we load the conf
	$providerconfig  = $provider->getConf();

	$prefix = $providerconfig['dol_prefix'].'_';
}

$invoice_path = '';

$sellerId = GETPOSTINT('seller_id');
$buyerId = GETPOSTINT('buyer_id');


/*
 * Actions
 */

if ($action == 'setMAIN_FORCE_SYSTEM_MESSAGE') {	// Test on permissions already done
	dolibarr_set_const($db, 'MAIN_FORCE_SYSTEM_MESSAGE', GETPOST('MAIN_FORCE_SYSTEM_MESSAGE', 'restricthtml'));
}

if ($action == 'buildsamplesupplierinvoice') {	// Test on permissions already done
	if ($sellerId > 0) {
		$thirdpartySeller = new Societe($db);
		$thirdpartySeller->fetch($sellerId);
	} else {
		$thirdpartySeller = $mysoc;
	}
	if ($buyerId > 0) {
		$thirdpartyBuyer = new Societe($db);
		$thirdpartyBuyer->fetch($buyerId);
	} else {
		$thirdpartyBuyer = $mysoc;
	}

	$options = array(
		'invoiceformat' => GETPOST('invoiceformat'),
		'invoicetype' => GETPOSTINT('invoicetype'),
		'referencedinvoice' => GETPOST('referencedinvoice')
	);

	// Init a dedicated provider with the selected format that is forced to the one selected.
	$providerSample = $PDPManager->getProvider(getDolGlobalString('EINVOICING_PDP'));

	$exchangeProtocolConf = (GETPOST('invoiceformat') ? GETPOST('invoiceformat') : 'EINVOICING_PROTOCOL');
	$tmpProtocolManager = new ProtocolManager($db);
	$providerSample->exchangeProtocol = $tmpProtocolManager->getProtocol($exchangeProtocolConf);

	if ((float) DOL_VERSION < 24.0) {
		$resarray = $providerSample->exchangeProtocol->generateSampleInvoiceOld($einvoicing, $thirdpartySeller, $thirdpartyBuyer, $options);
	} else {
		$resarray = $providerSample->exchangeProtocol->generateSampleInvoice($einvoicing, $thirdpartySeller, $thirdpartyBuyer, $options);
	}

	if (is_numeric($resarray) && $resarray < 0) {
		setEventMessages($providerSample->exchangeProtocol->error, $providerSample->exchangeProtocol->errors, 'errors');

		$resarray = array();
	} else {
		$invoice_path = $resarray['path'];
		$ref = $resarray['ref'];

		setEventMessages('Sample invoice generated with ref '.$ref, null, 'mesgs');
	}
}


/*
 * View
 */

$form = new Form($db);

$action = 'edit';

$help_url = 'EN:Module_EInvoicing';
$title = "EInvoicingSetup";

llxHeader('', $langs->trans($title), $help_url, '', 0, 0, '', '', '', 'mod-einvoicing page-admin-devtools');

// Subheader
$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.img_picto($langs->trans("BackToModuleList"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("BackToModuleList").'</span></a>';

print load_fiche_titre($langs->trans($title), $linkback, 'title_setup');


// Configuration header
$head = einvoicingAdminPrepareHead();
print dol_get_fiche_head($head, 'devtools', $langs->trans($title), -1, "einvoicing.png@einvoicing");

// Setup page goes here
//print info_admin($langs->trans("EInvoicingInfo"));
//print '<span class="opacitymedium">'.$langs->trans("EInvoicingSetupPage").'</span><br>';

// Alert mysoc configuration is not complete
$einvoicing = new EInvoicing($db);

$stringwarning = pdpShowWarning($einvoicing);
print $stringwarning;


print '<div class="neutral">';
print 'Link to test an E-invoice from SuperPDP (Factur-X, CII, ...): ';
print img_picto('', 'url', 'class="pictofixedwidth"');
print '<a href="https://www.superpdp.tech/outils/validateur-facture-electronique" target="_blank">here</a>';
print '<br>';
print 'Check annuary: ';
print img_picto('', 'url', 'class="pictofixedwidth"');
print '<a href="https://www.superpdp.tech/outils/info-annuaire" target="_blank">here</a>';
print '<br>';
print 'API documentation/test: ';
print img_picto('', 'url', 'class="pictofixedwidth"');
print '<a href="https://www.superpdp.tech/openapi/#afnor-flow" target="_blank">here</a>';
print '</div>';


print '<br>';


// Tool to generate sample invoice
if (getDolGlobalString('EINVOICING_PDP')) {
	$provider = $PDPManager->getProvider(getDolGlobalString('EINVOICING_PDP'));

	print '<div class="neutral">';
	print 'Generate an Einvoice sample<br><br>';

	print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
	print '<input type="hidden" name="action" value="buildsamplesupplierinvoice">';
	print '<input type="hidden" name="token" value="'.newToken().'">';

	if (GETPOST("buyer_einvoiceid") && GETPOST("buyer_einvoiceid") != 'me' && $buyerId <= 0) {
		$tmpthirdparty = new Societe($db);
		$result = $tmpthirdparty->fetch(0, '', '', '', GETPOST("buyer_einvoiceid"));
		if ($result == -2) {
			setEventMessages('Error - More than one thirdparty found with these SIREN', null, 'warnings');
		} else {
			$buyerId = $tmpthirdparty->id;
			if (!$buyerId) {
				$langs->load("errors");
				setEventMessages($langs->trans("ErrorThirdPartyNotFound"), null, 'warnings');
			}
		}
	}
	if (GETPOST("seller_einvoiceid") && GETPOST("seller_einvoiceid") != 'me' && $sellerId <= 0) {
		$tmpthirdparty = new Societe($db);
		$result = $tmpthirdparty->fetch(0, '', '', '', GETPOST("seller_einvoiceid"));
		if ($result == -2) {
			setEventMessages('Error - More than one thirdparty found with these SIREN', null, 'warnings');
		} else {
			$sellerId = $tmpthirdparty->id;
			if (!$sellerId) {
				$langs->load("errors");
				setEventMessages($langs->trans("ErrorThirdPartyNotFound"), null, 'warnings');
			}
		}
	}

	print '<span class="width150 inline-block">'.$langs->trans("Seller").'</span> ';
	//print '<input type="text" name="seller_einvoiceid" value="000000002" placeholder="Seller e-invoice ID (Usually SIREN)" class="minwidth150"><br>';
	print $form->select_company($sellerId ?: '', 'seller_id', '', $langs->trans("MyCompany").' ('.$mysoc->idprof1.')', 1, 0, array(), 0, 'width300');
	print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?seller_einvoiceid=me'.($buyerId > 0 ? '&buyer_id='.$buyerId : '').'" class="reposition">Select me</a>';
	print ' - <a href="'.$_SERVER["PHP_SELF"].'?seller_einvoiceid=000000001" class="reposition">Select thirdparty SIREN 000000001</a>';
	print ' - <a href="'.$_SERVER["PHP_SELF"].'?seller_einvoiceid=000000002'.($buyerId > 0 ? '&buyer_id='.$buyerId : '').'" class="reposition">Select thirdparty SIREN 000000002</a>';
	print '<br>';

	print '<span class="width150 inline-block">'.$langs->trans("Buyer").'</span> ';
	//print '<input type="text" name="buyer_id" value="000000001" placeholder="Supplier e-invoice ID (Usually SIREN)" class="minwidth150"><br>';
	print $form->select_company($buyerId ?: '', 'buyer_id', '', $langs->trans("MyCompany").' ('.$mysoc->idprof1.')', 1, 0, array(), 0, 'width300');
	print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?buyer_einvoiceid=000000001" class="reposition">Select thirdparty with SIREN 000000001</a>';
	print ' - <a href="'.$_SERVER["PHP_SELF"].'?buyer_einvoiceid=000000002'.($sellerId > 0 ? '&seller_id='.$sellerId : '').'" class="reposition">Select thirdparty with SIREN 000000002</a>';
	print ' - <a href="'.$_SERVER["PHP_SELF"].'?buyer_einvoiceid=me'.($sellerId > 0 ? '&seller_id='.$sellerId : '').'" class="reposition">Select me</a>';
	print '<br>';

	$ProtocolManager = new ProtocolManager($db);
	$protocolsList = $ProtocolManager->getProtocolsList();

	// Protocols list
	$TFieldProtocols = array();
	foreach ($protocolsList as $key => $protocolconfig) {
		if ($protocolconfig['is_enabled'] == 0) {
			continue;
		}
		$TFieldProtocols[$key] = $protocolconfig['protocol_name'];
	}

	// Format
	print '<span class="width150 inline-block">'.$langs->trans("InvoiceFormat").'</span> ';
	if ((float) DOL_VERSION >= 24.0) {
		print $form->selectarray('invoiceformat', $TFieldProtocols, GETPOSTISSET('invoiceformat') ? GETPOST('invoiceformat') : getDolGlobalString('EINVOICING_PROTOCOL'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth300 ');
	} else {
		print $langs->trans("Factur-X");
	}
	print '<br>';

	// Invoice type
	print '<span class="width150 inline-block">'.$langs->trans("InvoiceType").'</span> ';
	if ((float) DOL_VERSION >= 24.0) {
		$typeofinvoice = array(
			Facture::TYPE_STANDARD => array('label' => $langs->trans('Standard')),
			Facture::TYPE_DEPOSIT => array('label' => $langs->trans('Deposit')),
			Facture::TYPE_CREDIT_NOTE => array('label' => $langs->trans('CreditNote')),
		);
		print $form->selectarray('invoicetype', $typeofinvoice, GETPOSTISSET('invoicetype') ? GETPOSTINT('invoicetype') : Facture::TYPE_STANDARD, 0, 0, 0, '', 0, 0, 0, '', 'minwidth300');
	} else {
		print $langs->trans("Standard");
	}

	// Referenced invoice
	print '<span class="referencedinvoiceblock">';
	print '<span class="inline-block"> Sur la facture : </span> ';
	print '<input type="text" name="referencedinvoice" value="'.GETPOST('referencedinvoice').'" placeholder="FA0000-SPECIMEN" class="width150">';
	print '</span>';

	// JS to show/hide referenced invoice and credit note type options only if credit note type is selected
	print '<script>
	$(function() {
		function toggleCreditNoteOptions() {
			var invoicetype = $("select[name=\'invoicetype\']").val();
			if (invoicetype == "'.Facture::TYPE_CREDIT_NOTE.'") {
				$(".referencedinvoiceblock").show();
			} else {
				$(".referencedinvoiceblock").hide();
			}
		}
		$("select[name=\'invoicetype\']")
			.on("change select2:select", toggleCreditNoteOptions);
		toggleCreditNoteOptions();
	});
	</script>';

	print '<br>';

	print '<input type="submit" class="button smallpaddingimp reposition" name="Generate" value="Generate">';
	print '</form>';

	if ($invoice_path) {
		print '<br>';
		print 'Sample invoice generated into document directory into path:<br><b>'.preg_replace('/^'.preg_quote(DOL_DATA_ROOT.'/', '/').'/', '', $invoice_path).'</b>';
	}
	print '</div>';
	print '<br>';


	if (strpos(getDolGlobalString('EINVOICING_PDP'), 'SUPERPDP') !== false) {
		// Generate a $provider (this call the constructor that load the token with fetchOAuthTokenDB() and save it in the memory var $provider->tokenData)
		// Note: Token may have been expired
		print '<div class="neutral">';
		print 'Current token (can be used for '.getDolGlobalString('EINVOICING_PDP').' API as HTTP "Bearer: token")<br>';
		$tokendata = $provider->getTokenData();
		$token = $tokendata['token'] ?? '';
		//print '<input id="bearertoken" type="text" class="width500 text-security" value="'.$token.'" spellcheck="false" readonly>';
		if ($token)	{
			print showValueWithClipboardCPButton($token, 0, dol_trunc($token, 10));
		} else {
			print 'Not yet generated or error when generating token.';
		}
		print '</div>';

		print '<br>';


		$urlforproxy = dol_buildpath('einvoicing/public/proxy_oauthcallback.php', 3);


		if (getDolGlobalString('EINVOICING_SUPERPDP_VIAPARTNER') == 'proxy') {
			$providerproxy = $PDPManager->getProvider('SUPERPDPViaPartner');

			$providerproxyconfig  = $providerproxy->getConf();

			$urlproxyadmin = $providerproxyconfig['provider_url'];

			//if ($providerconfig['client_id'] && $providerconfig['client_secret']
			print '<div class="neutral">';
			print 'You are a Proxy for <b>SuperPDP Access Point registration</b> (EINVOICING_SUPERPDP_VIAPARTNER = "proxy").<br>';
			print '<div class="marginbottomonly inline-block">To have customer instances using this server as a proxy for SuperPDP registration:</div><br>';
			print '- on this instance, you must have set the Client ID and Client Secret of reseller account on the "Access Point setup" tab for proxy mode: ';
			if (getDolGlobalString('EINVOICING_LIVE')) {
				print ((getDolGlobalString('EINVOICING_SUPERPDPVIAPARTNER_CLIENT_ID_PROD') && getDolGlobalString('EINVOICING_SUPERPDPVIAPARTNER_CLIENT_SECRET_PROD')) ? '<span class="ok">'.img_picto('', 'tick').' OK</span>' : '<span class="error">KO</span>').'.<br>';
			} else {
				print ((getDolGlobalString('EINVOICING_SUPERPDPVIAPARTNER_CLIENT_ID') && getDolGlobalString('EINVOICING_SUPERPDPVIAPARTNER_CLIENT_SECRET')) ? '<span class="ok">'.img_picto('', 'tick').' OK</span>' : '<span class="error">KO</span>').'.<br>';
			}

			print '- on the <a href="'.$urlproxyadmin.'" target=_blank">SuperPDP Access Point admin dashboard '.img_picto('', 'url').'</a>, for the account of your company, the callback url must be set to <input type="text" id="idproxyurl" class="width300" value="'.$urlforproxy.'" spellcheck="false">';
			print ajax_autoselect("idproxyurl");
			print '<br>';
			print '- on the instance of your customers, the variable EINVOICING_SUPERPDP_VIAPARTNER to the name of your company, for example <input type="text" id="idproxyname" value="'.$mysoc->name.'" spellcheck="false"><br>';
			print ajax_autoselect("idproxyname");
			print '- on the instance of your customers, the variable EINVOICING_SUPERPDP_VIAPARTNER_OAUTH_URL to <input type="text" class="width300" id="idproxyurl2" value="'.$urlforproxy.'" spellcheck="false"><br>';
			print ajax_autoselect("idproxyurl2");
			print '</div>';
			print '<br>';
		}

		if (getDolGlobalString('EINVOICING_PDP') == 'SUPERPDPViaPartner') {
			print '<div class="neutral">';
			print 'You are using the <b>Proxy for SuperPDP Access Point registration</b> with property:<br>';
			print '- EINVOICING_SUPERPDP_VIAPARTNER = '.getDolGlobalString('EINVOICING_SUPERPDP_VIAPARTNER').'<br>';
			print '- EINVOICING_SUPERPDP_VIAPARTNER_OAUTH_URL = '.getDolGlobalString('EINVOICING_SUPERPDP_VIAPARTNER_OAUTH_URL');
			print '</div>';
		} elseif (getDolGlobalString('EINVOICING_SUPERPDP_VIAPARTNER') != 'proxy') {
			print '<div class="neutral">';
			print 'This instance can be a Proxy for the SuperPDP Access Point registration for your customer if you set:<br>';
			print '- on this instance, the variable EINVOICING_SUPERPDP_VIAPARTNER to the value "proxy"<br>';
			print '- on the instance of your customers, the variable EINVOICING_SUPERPDP_VIAPARTNER to the name of your company, for example "'.$mysoc->name.'"<br>';
			print '- on the instance of your customers, the variable EINVOICING_SUPERPDP_VIAPARTNER_OAUTH_URL to "'.$urlforproxy.'"<br>';
			print '- on the instance of your customers, choose the Access Point provider working through your Proxy.<br>';
			print '- on the SuperPDP Access Point, for the account of your company, the callback url must also be set to "'.$urlforproxy.'"<br>';
			print '<br>';
			print 'This instance can be a customer instance registering to SuperPDP through the OAUth proxy of a partner if you set:<br>';
			print '- on this instance, the variable EINVOICING_SUPERPDP_VIAPARTNER to the name of the company offering the proxy, for example DoliCloud.<br>';
			print '- on this instance, the variable EINVOICING_SUPERPDP_VIAPARTNER_OAUTH_URL to the url of the proxy (provided by the proxy)<br>';
			print '- on this instance, choose the Access Point provider working through the Proxy.<br>';
			print '- on the proxy instance, the variable EINVOICING_SUPERPDP_VIAPARTNER to the value "proxy"<br>';
			print '</div>';
		} else {
			print '<div class="neutral">';
			print 'This instance can also connect to SuperPDP Access Point directly but can\'t connect through a proxy as it is itself a proxy..<br>';
			print '</div>';
		}
	}
}

print '<br>';

print '<div class="neutral">';
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="action" value="setMAIN_FORCE_SYSTEM_MESSAGE">';
print '<input type="hidden" name="token" value="'.newToken().'">';

print 'You can force a legal message on instances >= 24.0 to warn users about the need to enable the E-invoicing, by setting the constant MAIN_FORCE_SYSTEM_MESSAGE.<br>';
print '<textarea name="MAIN_FORCE_SYSTEM_MESSAGE" class="quatrevingtpercent" rows="2">'.getDolGlobalString('MAIN_FORCE_SYSTEM_MESSAGE').'</textarea><br>';
print '<input type="submit" class="button smallpaddingimp reposition" name="save" value="'.$langs->trans("Save").'">';

print '</form>';
print '</div>';


// Page end
print dol_get_fiche_end();

llxFooter();
$db->close();
