OpenXE/www/pages/docscan.php
2021-05-21 08:49:41 +02:00

534 lines
20 KiB
PHP

<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
use Xentral\Modules\DocumentScanner\DataTable\DocScanFilesDataTable;
use Xentral\Widgets\DataTable\DataTableBuildConfig;
use Xentral\Widgets\DataTable\Service\DataTableRequestHandler;
class Docscan
{
/** @var erpooSystem $app */
var $app;
/** @var string MODULE_NAME */
const MODULE_NAME = 'DocumentScanner';
/** @var array $javascript */
public $javascript = [
'./classes/Modules/DocumentScanner/www/js/document-scanner.js',
];
/** @var array $stylesheet */
public $stylesheet = [
'./classes/Modules/DocumentScanner/www/css/document-scanner.css',
];
/**
* @param erpooSystem $app
* @param bool $intern
*/
public function __construct($app, $intern = false)
{
$this->app = $app;
if ($intern) {
return;
}
$this->app->ActionHandlerInit($this);
$this->app->ActionHandler("list", "DocscanList");
$this->app->ActionHandler("edit", "DocscanEdit");
$this->app->ActionHandler("preview", "DocscanFilePreview");
$this->app->DefaultActionHandler("list");
$this->app->ActionHandlerListen($app);
}
public function Install()
{
if ($this->app->DB->CheckTableExistence("scanbot")) {
$this->app->DB->Query("RENAME TABLE `scanbot` TO `docscan`");
$this->app->DB->Query("UPDATE `datei_stichwoerter` SET objekt = 'DocScan' WHERE objekt = 'scanbot'");
}
$this->app->erp->CheckTable("docscan");
$this->app->erp->CheckColumn("id", "int(11)", "docscan", "NOT NULL AUTO_INCREMENT");
$this->app->erp->CheckColumn("datei", "int", "docscan");
$this->app->erp->CheckColumn("kategorie", "text", "docscan");
$this->app->erp->CheckTable("docscan_metadata");
$this->app->erp->CheckColumn("id", "INT(10) UNSIGNED", "docscan_metadata", "NOT NULL AUTO_INCREMENT");
$this->app->erp->CheckColumn("docscan_id", "INT(10) UNSIGNED", "docscan_metadata", "NOT NULL");
$this->app->erp->CheckColumn("meta_key", "VARCHAR(32)", "docscan_metadata", "NOT NULL");
$this->app->erp->CheckColumn("meta_value", "VARCHAR(32)", "docscan_metadata", "NOT NULL");
}
protected function DocscanMenu()
{
$this->app->erp->Headlines('Dokumenten Scanner');
$this->app->erp->MenuEintrag('index.php?module=docscan&action=list', '&Uuml;bersicht');
if ($this->app->Secure->GetGET('action') === 'list') {
$this->app->erp->MenuEintrag('index.php?module=welcome&action=start', 'Zur&uuml;ck zur &Uuml;bersicht');
} else {
$this->app->erp->MenuEintrag('index.php?module=docscan&action=list', 'Zur&uuml;ck zur &Uuml;bersicht');
}
}
public function DocscanList()
{
$cmd = $this->app->Secure->GetGET('cmd');
if ($cmd === 'drop-file') {
header('Content-Type: application/json');
echo $this->DocscanAjaxHandleFileDrop();
$this->app->erp->ExitWawi();
}
$this->DocscanMenu();
/** @var DataTableRequestHandler $handler */
$handler = $this->app->Container->get('DataTableRequestHandler');
$buildConfig = new DataTableBuildConfig(
'docscan_files',
DocScanFilesDataTable::class,
'index.php?module=docscan&action=list&cmd=table'
);
if ($cmd === 'table'){
if ($handler->canHandleRequest($buildConfig)){
$response = $handler->handleRequest($buildConfig);
$response->send();
$this->app->ExitXentral();
}
}
$htmlData = $handler->generateHtml($buildConfig);
$this->app->Tpl->Set('TAB1', $htmlData);
// Datei-Zuweisen-Dialog
$table = new FileTable($this->app, 'adressen', 0);
$this->app->Tpl->Set('FILEDIALOGCONTENT', $table->GetTabsHtml());
// Datei-Upload
$this->DocscanUploadHandling();
$this->app->Tpl->Set('ID', 0);
$this->app->Tpl->Add('EXTRASTICHWOERTER', '<option value="Belege">Beleg</option>');
$this->app->Tpl->Add('EXTRASTICHWOERTER', '<option value="Quittung">Quittung</option>');
$this->app->Tpl->Add('EXTRASTICHWOERTER', '<option value="Sonstige">Sonstige Datei</option>');
$this->app->Tpl->Add('EXTRASTICHWOERTER', '<option value="Deckblatt">Deckblatt</option>');
$this->app->Tpl->Add('EXTRASTICHWOERTER', '<option value="Anhang">Anhang</option>');
$this->app->Tpl->Parse('DOCSCANUPLOAD', 'datei_neudirekt2.tpl');
$this->app->Tpl->Parse('PAGE', 'docscan_list.tpl');
}
protected function DocscanUploadHandling()
{
if (isset($_FILES['upload'])) {
// Upload über Drag-and-Drop
if (isset($_POST['dateiv'])) {
$dateinamen = $this->app->Secure->GetPOST('dateiname');
$dateititel = $this->app->Secure->GetPOST('dateititel');
$beschreibungen = $this->app->Secure->GetPOST('beschreibung');
$stichwoerter = $this->app->Secure->GetPOST('dateistichwort');
foreach ($_POST['dateiv'] as $k => $v) {
$name = $this->app->DB->real_escape_string($dateinamen[$k]);
$titel = $this->app->DB->real_escape_string($dateititel[$k]);
$beschreibung = $this->app->DB->real_escape_string($beschreibungen[$k]);
$stichwort = $this->app->DB->real_escape_string($stichwoerter[$k]);
$data = explode(',', $v);
$encodedData = str_replace(' ', '+', $data[1]);
$decodedData = base64_decode($encodedData);
$this->app->Tpl->Set('TITLE', $titel);
$this->app->Tpl->Set('BESCHREIBUNG', $beschreibung);
if (empty($v)) {
$this->app->Tpl->Set('ERROR', "<div class=\"error\">Keine Datei ausgew&auml;hlt!</div>");
$this->app->erp->EnableTab("tabs-2");
} else {
if (empty($titel)) {
$titel = $name;
}
$fileid = $this->app->erp->CreateDatei($name, $titel, $beschreibung, "", $decodedData,
$this->app->User->GetName());
$this->app->DB->Insert("INSERT INTO docscan (id, datei) VALUES (NULL, '$fileid')");
$docscanId = $this->app->DB->GetInsertID();
$this->app->erp->AddDateiStichwort($fileid, $stichwort, 'DocScan', $docscanId);
}
}
}
// Upload über HTML-Formular
if (!isset($_POST['dateiv'])) {
$fileName = $this->app->DB->real_escape_string($_FILES['upload']['name']);
$fileTmp = $this->app->DB->real_escape_string($_FILES['upload']['tmp_name']);
$titel = $this->app->DB->real_escape_string($this->app->Secure->GetPOST("titel"));
$beschreibung = $this->app->DB->real_escape_string($this->app->Secure->GetPOST("beschreibung"));
$stichwort = $this->app->DB->real_escape_string($this->app->Secure->GetPOST("stichwort"));
$this->app->Tpl->Set('TITLE', $titel);
$this->app->Tpl->Set('BESCHREIBUNG', $beschreibung);
if (empty($fileTmp)) {
$this->app->Tpl->Set('ERROR', "<div class=\"error\">Keine Datei ausgew&auml;hlt!</div>");
$this->app->erp->EnableTab("tabs-2");
} else {
if (empty($titel)) {
$titel = $fileName;
}
$fileid = $this->app->erp->CreateDatei($fileName, $titel, $beschreibung, "", $fileTmp,
$this->app->User->GetName());
$this->app->DB->Insert("INSERT INTO docscan (id, datei) VALUES (NULL, '$fileid')");
$docscanId = $this->app->DB->GetInsertID();
$this->app->erp->AddDateiStichwort($fileid, $stichwort, 'DocScan', $docscanId);
}
}
}
}
/**
* @return string
*/
protected function DocscanAjaxHandleFileDrop()
{
$result = ['success' => false];
if (isset($_POST['name']) && isset($_POST['data'])) {
$fileName = $this->app->Secure->GetPOST('name');
$value = $this->app->Secure->GetPOST('data', null);
$offset = strpos($value, ',');
if ($offset === false) {
return json_encode($result);
}
$fileEncoded = base64_decode(substr($value, $offset + 1));
$fileId = $this->app->erp->CreateDatei($fileName, $fileName, "", "", $fileEncoded,
$this->app->User->GetName());
$this->app->DB->Update("INSERT INTO `docscan` (id, datei) VALUES (NULL, '$fileId')");
$docscanId = $this->app->DB->GetInsertID();
$this->app->erp->AddDateiStichwort($fileId, 'Bild', 'DocScan', $docscanId);
$result['success'] = true;
$result['file'] = (int)$fileId;
}
return json_encode($result);
}
public function DocscanEdit()
{
$cmd = $this->app->Secure->GetGET("cmd");
if ($cmd === "table-data") {
header('Content-Type: application/json');
echo $this->DocscanAjaxGetDataTableResultJson();
$this->app->erp->ExitWawi();
}
if ($cmd === "table-html") {
header('Content-Type: text/html');
echo $this->DocscanAjaxGetDataTableHtml();
$this->app->erp->ExitWawi();
}
if ($cmd === "table-settings") {
header('Content-Type: application/json');
echo $this->DocscanAjaxGetDataTableSettingsJson();
$this->app->erp->ExitWawi();
}
if ($cmd === "assign-file") {
header('Content-Type: application/json');
echo $this->DocscanAjaxAssignFileKeyword();
$this->app->erp->ExitWawi();
}
if ($cmd === "delete-file") {
header('Content-Type: application/json');
echo $this->DocscanAjaxDeleteFile();
$this->app->erp->ExitWawi();
}
if ($cmd === "create-liability") {
header('Content-Type: application/json');
echo $this->DocscanAjaxCreateLiability();
$this->app->erp->ExitWawi();
}
}
/**
* Datei-Stichwort zuweisen
*
* @return string
*/
protected function DocscanAjaxAssignFileKeyword()
{
try {
$keyword = strtolower($this->app->Secure->GetPOST('keyword'));
$fileId = (int)$this->app->Secure->GetPOST('file');
$objectId = (int)$this->app->Secure->GetPOST('object');
if ($fileId === 0) {
throw new RuntimeException('Ungültige File-ID.');
}
if ($objectId === 0) {
throw new RuntimeException('Ungültige Objekt-ID.');
}
if (!in_array($keyword, ['adressen', 'bestellung', 'kasse', 'reisekosten', 'verbindlichkeit'], true)) {
throw new RuntimeException(sprintf('Stichwort "%s" ist nicht zulässig.', $keyword));
}
$this->app->erp->AddDateiStichwort($fileId, 'Belege', ucfirst($keyword), $objectId);
$result = ['success' => true];
} catch (Exception $e) {
$result = [
'success' => false,
'message' => $e->getMessage(),
];
}
return json_encode($result);
}
/**
* Datei löschen
*
* @return string
*/
protected function DocscanAjaxDeleteFile()
{
$fileId = (int)$this->app->Secure->GetPOST('file');
// Prüfen ob Datei wirklich über DocScan hochgeladen wurde
$docscanId = (int)$this->app->DB->Select("SELECT d.id FROM docscan AS d WHERE d.datei = '$fileId'");
if ($docscanId === 0) {
return json_encode([
'success' => false,
'error' => 'Datei konnte nicht gelöscht werden. Datei wurde nicht über den Dokumenten Scanner hochgeladen.',
]);
}
// Prüfen ob noch andere Verknüpfungen/Stichwörter auf diese Datei existieren
$usageCount = (int)$this->app->DB->Select(
"SELECT COUNT(ds.id) AS usage_count
FROM datei_stichwoerter AS ds
WHERE ds.datei = '$fileId' AND ds.objekt != 'DocScan'"
);
if ($usageCount > 0) {
return json_encode([
'success' => false,
'error' => 'Datei konnte nicht gelöscht werden. Es existieren Verknüpfungen auf diese Datei.',
]);
}
$success = $this->app->erp->DeleteDatei($fileId);
if ($success === false) {
return json_encode([
'success' => false,
'error' => 'Datei konnte aus unbekannten Gründen nicht gelöscht werden. Fehlercode #DOCSCAN01',
]);
}
$this->app->DB->Delete("DELETE FROM docscan WHERE id = '$docscanId' AND datei = '$fileId' LIMIT 1");
return json_encode(['success' => $success]);
}
/**
* @return string
*/
/*protected function DocscanAjaxGetDialogHtml()
{
return
'<div id="filetabs">
<ul>
<li data-type="adressen"><a href="#adressen-tab">Adressen</a></li>
<li data-type="bestellung"><a href="#bestellung-tab">Bestellungen</a></li>
<li data-type="kasse"><a href="#kasse-tab">Kassenbuch</a></li>
<li data-type="reisekosten"><a href="#reisekosten-tab">Reisekosten</a></li>
<li data-type="verbindlichkeit"><a href="#verbindlichkeit-tab">Verbindlichkeiten</a></li>
</ul>
<div id="adressen-tab"></div>
<div id="bestellung-tab"></div>
<div id="kasse-tab"></div>
<div id="reisekosten-tab"></div>
<div id="verbindlichkeit-tab"></div>
</div>';
}*/
/**
* @return false|string
*/
protected function DocscanAjaxGetDataTableSettingsJson()
{
$fileId = (int)$this->app->Secure->GetGET('id');
$docType = $this->app->Secure->GetGET('type');
$table = new FileTable($this->app, $docType, $fileId);
return json_encode($table->GetSettings(
sprintf('./index.php?module=docscan&action=edit&cmd=table-data&type=%s&id=%s', $docType, $fileId)
));
}
/**
* @return string HTML-Tabelle
*/
protected function DocscanAjaxGetDataTableHtml()
{
$fileId = (int)$this->app->Secure->GetGET('id');
$docType = $this->app->Secure->GetGET('type');
$table = new FileTable($this->app, $docType, $fileId);
return $table->GetTabContentHtml();
}
/**
* @return string
*/
protected function DocscanAjaxGetDataTableResultJson()
{
$fileId = (int)$this->app->Secure->GetGET('id');
$docType = (string)$this->app->Secure->GetGET('type');
$columns = (array)$this->app->Secure->GetGET('columns');
$search = (array)$this->app->Secure->GetGET('search');
$order = (array)$this->app->Secure->GetGET('order');
$offset = (int)$this->app->Secure->GetGET('start');
$limit = (int)$this->app->Secure->GetGET('length');
$draw = (int)$this->app->Secure->GetGET('draw');
if ($fileId === 0) {
return json_encode(['error' => 'Datei-ID darf nicht leer sein']);
}
foreach ($columns as $column) {
if ($column['data'] === 'dateianzahl') {
if (!empty($column['search']['value'])) {
$filter['dateianzahl'] = true;
} else {
$filter['dateianzahl'] = false;
}
if ($draw === 1) {
$filter['dateianzahl'] = true;
}
}
}
$table = new FileTable($this->app, $docType, $fileId);
$searchQuery = !empty($search['value']) ? $search['value'] : null;
$orderCol = (int)$order[0]['column'];
$orderDir = strtolower($order[0]['dir']) === 'desc' ? 'DESC' : 'ASC';
return json_encode($table->GetData($filter, $searchQuery, $orderCol, $orderDir, $offset, $limit, $draw));
}
/**
* @return string
*/
public function DocscanAjaxCreateLiability()
{
$fileId = (int)$this->app->Secure->GetGET('id');
$liabilityId = (int)$this->app->erp->CreateVerbindlichkeit();
// Datei-Stichwort zuweisen
if ($liabilityId > 0) {
$this->app->erp->AddDateiStichwort($fileId, 'Belege', 'Verbindlichkeit', $liabilityId);
$result = [
'success' => true,
'liability' => $liabilityId,
];
} else {
$result = ['success' => false];
}
return json_encode($result);
}
public function DocscanFilePreview()
{
$id = (int)$this->app->Secure->GetGET("id");
$endung = $this->app->erp->GetDateiEndung($id);
$sendFile = !empty($this->app->Secure->GetGET("sendfile"));
if ($sendFile === false) {
$data = [
'endung' => $endung,
];
if ($endung === 'pdf') {
$data['iframe_src'] = './js/production/generic/web/viewer.html?file=';
$data['iframe_src'] .= urlencode('../../../../index.php?module=docscan&action=preview&sendfile=true&id=' . $id);
} else {
$data['iframe_src'] = './index.php?module=docscan&action=preview&sendfile=true&id=' . $id;
}
header('content-type: application/json');
echo json_encode($data);
$this->app->erp->ExitWawi();
}
if ($sendFile === true) {
$this->DisplayFilePreview($id);
}
}
/**
* @param int $dateiId
*
* @return void
*/
protected function DisplayFilePreview($dateiId)
{
$endung = $this->app->erp->GetDateiEndung($dateiId);
$dateiname = $this->app->erp->GetDateiName($dateiId);
// Bilder
if ($endung === 'jpg' || $endung === 'jpeg' || $endung === 'png') {
switch ($endung) {
case 'jpg':
case 'jpeg':
$contentType = 'image/jpeg';
break;
case 'png':
$contentType = 'image/png';
break;
}
header('Content-Type: ' . $contentType);
header('Content-Disposition: inline; filename="' . $dateiname . '"');
echo $this->app->erp->GetDatei($dateiId);
$this->app->erp->ExitWawi();
}
// PDFs
if ($endung === 'pdf') {
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . $dateiname . '"');
echo $this->app->erp->GetDatei($dateiId);
$this->app->erp->ExitWawi();
}
// Fallback bei nicht unterstützter Dateiendung
$Brief = new SuperFPDF('P', 'mm', 'A4');
$Brief->filename = "Docscan_{$dateiId}.pdf";
$Brief->AddPage();
$Brief->SetTextColor(200);
$Brief->SetFont('Arial', 'B', 80);
$Brief->Rotate(45, 45, 180);
$Brief->Text(45, 180, "DATEI FEHLT");
$Brief->Rotate(0);
$Brief->SetTextColor(0);
$Brief->displayAnhaenge();
$this->app->erp->ExitWawi();
}
}