NEW upload a file by drag and drop on social contribution and salary

This commit is contained in:
Laurent Destailleur
2023-05-04 17:28:42 +02:00
parent 095052b3cc
commit f61f425231
8 changed files with 211 additions and 182 deletions

View File

@@ -492,8 +492,9 @@ if ($id > 0) {
}
if ($action == 'edit') {
print "<form name=\"charge\" action=\"".$_SERVER["PHP_SELF"]."?id=$object->id&amp;action=update\" method=\"post\">";
print '<form name="charge" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update">';
}
// Call Hook formConfirm
$parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);

View File

@@ -39,12 +39,6 @@ require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/fileupload.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php';
error_reporting(E_ALL | E_STRICT);
//print_r($_POST);
//print_r($_GET);
//print 'upload_dir='.GETPOST('upload_dir');
$id = GETPOST('fk_element', 'int');
$element = GETPOST('element', 'alpha'); // 'myobject' (myobject=mymodule) or 'myobject@mymodule' or 'myobject_mysubobject' (myobject=mymodule)
$elementupload = $element;
@@ -59,7 +53,7 @@ if ($usesublevelpermission && !isset($user->rights->$module->$element)) { // The
$usesublevelpermission = '';
}
//print $object->id.' - '.$object->module.' - '.$object->element.' - '.$object->table_element.' - '.$usesublevelpermission."\n";
//print 'fileupload.php: '.$object->id.' - '.$object->module.' - '.$object->element.' - '.$object->table_element.' - '.$usesublevelpermission."\n";
// Security check
if (!empty($user->socid)) {
@@ -71,7 +65,7 @@ if (!empty($user->socid)) {
$result = restrictedArea($user, $object->module, $object, $object->table_element, $usesublevelpermission, 'fk_soc', 'rowid', 0, 1); // Call with mode return
if (!$result) {
httponly_accessforbidden('Not allowed by restrictArea');
httponly_accessforbidden('Not allowed by restrictArea (module='.$object->module.' table_element='.$object->table_element.')');
}
@@ -81,6 +75,7 @@ if (!$result) {
$upload_handler = new FileUpload(null, $id, $elementupload);
top_httphead();
header('Pragma: no-cache');
@@ -103,6 +98,7 @@ switch ($_SERVER['REQUEST_METHOD']) {
$upload_handler->delete();
} else {
$upload_handler->post();
// Note: even if this return an error on 1 file in post(), we will return http code 200 because error must be managed by the caller (some files may be ok and some in error)
}
break;
case 'DELETE':

View File

@@ -30,99 +30,58 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
*/
class FileUpload
{
protected $options;
public $options;
protected $fk_element;
protected $element;
/**
* Constructor
* Constructor.
* This set ->$options
*
* @param array $options Options array
* @param int $fk_element fk_element
* @param string $element element
* @param int $fk_element ID of element
* @param string $element Code of element
*/
public function __construct($options = null, $fk_element = null, $element = null)
{
global $db, $conf;
global $object;
global $hookmanager;
$hookmanager->initHooks(array('fileupload'));
$element_prop = getElementProperties($element);
//var_dump($element_prop);
$this->fk_element = $fk_element;
$this->element = $element;
$pathname = $filename = $element;
$regs = array();
if (preg_match('/^([^_]+)_([^_]+)/i', $element, $regs)) {
$pathname = $regs[1];
$filename = $regs[2];
$pathname = str_replace('/class', '', $element_prop['classpath']);
$filename = $element_prop['classfile'];
$dir_output = $element_prop['dir_output'];
//print 'fileupload.class.php: element='.$element.' pathname='.$pathname.' filename='.$filename.' dir_output='.$dir_output;
if (empty($dir_output)) {
setEventMessage('The element '.$element.' is not supported for uploading file. dir_output is unknow.', 'errors');
throw new Exception('The element '.$element.' is not supported for uploading file. dir_output is unknow.');
}
$parentForeignKey = '';
// If pathname and filename are null then we can still upload files if we have specified upload_dir on $options
if ($pathname !== null && $filename !== null) {
// Get object from its id and type
$object = fetchObjectByElement($fk_element, $element);
// For compatibility
if ($element == 'propal') {
$pathname = 'comm/propal';
$dir_output = $conf->$element->dir_output;
} elseif ($element == 'facture') {
$pathname = 'compta/facture';
$dir_output = $conf->$element->dir_output;
} elseif ($element == 'project') {
$element = $pathname = 'projet';
$dir_output = $conf->$element->dir_output;
$object_ref = dol_sanitizeFileName($object->ref);
// Special cases to forge $object_ref used to forge $upload_dir
if ($element == 'invoice_supplier') {
$object_ref = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$object_ref;
} elseif ($element == 'project_task') {
$pathname = 'projet';
$filename = 'task';
$dir_output = $conf->project->dir_output;
$parentForeignKey = 'fk_project';
$parentClass = 'Project';
$parentElement = 'projet';
$parentObject = 'project';
} elseif ($element == 'fichinter') {
$element = 'ficheinter';
$dir_output = $conf->$element->dir_output;
} elseif ($element == 'order_supplier') {
$pathname = 'fourn';
$filename = 'fournisseur.commande';
$dir_output = $conf->fournisseur->commande->dir_output;
} elseif ($element == 'invoice_supplier') {
$pathname = 'fourn';
$filename = 'fournisseur.facture';
$dir_output = $conf->fournisseur->facture->dir_output;
} elseif ($element == 'product') {
$dir_output = $conf->product->multidir_output[$conf->entity];
} elseif ($element == 'productbatch') {
$dir_output = $conf->productbatch->multidir_output[$conf->entity];
} elseif ($element == 'action') {
$pathname = 'comm/action';
$filename = 'actioncomm';
$dir_output = $conf->agenda->dir_output;
} elseif ($element == 'chargesociales') {
$pathname = 'compta/sociales';
$filename = 'chargesociales';
$dir_output = $conf->tax->dir_output;
} else {
$dir_output = $conf->$element->dir_output;
}
// If pathname and filename are null then we can still upload files
// IF we have specified upload_dir on $this->options
if ($pathname !== null && $filename !== null) {
dol_include_once('/'.$pathname.'/class/'.$filename.'.class.php');
$classname = ucfirst($filename);
if ($element == 'order_supplier') {
$classname = 'CommandeFournisseur';
} elseif ($element == 'invoice_supplier') {
$classname = 'FactureFournisseur';
}
$object = new $classname($db);
$object->fetch($fk_element);
if (!empty($parentForeignKey)) {
dol_include_once('/'.$parentElement.'/class/'.$parentObject.'.class.php');
$parent = new $parentClass($db);
$parent->fetch($object->$parentForeignKey);
@@ -130,15 +89,8 @@ class FileUpload
$parent->fetch_thirdparty();
}
$object->$parentObject = clone $parent;
} else {
$object->fetch_thirdparty();
}
$object_ref = dol_sanitizeFileName($object->ref);
if ($element == 'invoice_supplier') {
$object_ref = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$object_ref;
} elseif ($element == 'project_task') {
$object_ref = $object->project->ref.'/'.$object_ref;
$object_ref = dol_sanitizeFileName($object->project->ref).'/'.$object_ref;
}
}
@@ -179,7 +131,7 @@ class FileUpload
*/
'thumbnail' => array(
'upload_dir' => $dir_output.'/'.$object_ref.'/thumbs/',
'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.$element.'&attachment=1&file=/'.$object_ref.'/thumbs/',
'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.urlencode($element).'&attachment=1&file=/'.$object_ref.'/thumbs/',
'max_width' => 80,
'max_height' => 80
)
@@ -451,16 +403,22 @@ class FileUpload
$file->mime = dol_mimetype($file->name, '', 2);
$file->size = intval($size);
$file->type = $type;
if ($this->validate($uploaded_file, $file, $error, $index) && dol_mkdir($this->options['upload_dir']) >= 0) {
$validate = $this->validate($uploaded_file, $file, $error, $index);
if ($validate) {
if (dol_mkdir($this->options['upload_dir']) >= 0) {
$file_path = $this->options['upload_dir'].$file->name;
$append_file = !$this->options['discard_aborted_uploads'] && is_file($file_path) && $file->size > filesize($file_path);
clearstatcache();
if ($uploaded_file && is_uploaded_file($uploaded_file)) {
// multipart/formdata uploads (POST method uploads)
if ($append_file) {
file_put_contents($file_path, fopen($uploaded_file, 'r'), FILE_APPEND);
} else {
dol_move_uploaded_file($uploaded_file, $file_path, 1, 0, 0, 0, 'userfile');
$result = dol_move_uploaded_file($uploaded_file, $file_path, 1, 0, 0, 0, 'userfile');
}
} else {
// Non-multipart uploads (PUT method support)
@@ -481,7 +439,13 @@ class FileUpload
}
$file->size = $file_size;
$this->setFileDeleteUrl($file);
} else {
$file->error = 'failedtocreatedestdir';
}
} else {
// should not happen
}
return $file;
}
@@ -506,13 +470,17 @@ class FileUpload
/**
* Output data
*
* @return string|void
* @return int 0 if OK, nb of error if errors
*/
public function post()
{
$error = 0;
if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') {
return $this->delete();
}
//var_dump($_FILES);
$upload = isset($_FILES[$this->options['param_name']]) ?
$_FILES[$this->options['param_name']] : null;
$info = array();
@@ -520,7 +488,7 @@ class FileUpload
// param_name is an array identifier like "files[]",
// $_FILES is a multi-dimensional array:
foreach ($upload['tmp_name'] as $index => $value) {
$info[] = $this->handleFileUpload(
$tmpres = $this->handleFileUpload(
$upload['tmp_name'][$index],
isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index],
isset($_SERVER['HTTP_X_FILE_SIZE']) ? $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'][$index],
@@ -528,11 +496,15 @@ class FileUpload
$upload['error'][$index],
$index
);
if (!empty($tmpres->error)) {
$error++;
}
$info[] = $tmpres;
}
} elseif ($upload || isset($_SERVER['HTTP_X_FILE_NAME'])) {
// param_name is a single object identifier like "file",
// $_FILES is a one-dimensional array:
$info[] = $this->handleFileUpload(
$tmpres = $this->handleFileUpload(
isset($upload['tmp_name']) ? $upload['tmp_name'] : null,
isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : (isset($upload['name']) ? $upload['name'] : null),
isset($_SERVER['HTTP_X_FILE_SIZE']) ? $_SERVER['HTTP_X_FILE_SIZE'] : (isset($upload['size']) ? $upload['size'] : null),
@@ -540,28 +512,37 @@ class FileUpload
isset($upload['error']) ? $upload['error'] : null,
0
);
if (!empty($tmpres->error)) {
$error++;
}
$info[] = $tmpres;
}
header('Vary: Accept');
$json = json_encode($info);
$redirect = isset($_REQUEST['redirect']) ?
stripslashes($_REQUEST['redirect']) : null;
/* disabled. Param redirect seems not used
$redirect = isset($_REQUEST['redirect']) ? stripslashes($_REQUEST['redirect']) : null;
if ($redirect) {
header('Location: '.sprintf($redirect, rawurlencode($json)));
return;
}
if (isset($_SERVER['HTTP_ACCEPT']) &&
(strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
*/
if (isset($_SERVER['HTTP_ACCEPT']) && (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
header('Content-type: application/json');
} else {
header('Content-type: text/plain');
}
echo $json;
return $error;
}
/**
* Delete uploaded file
*
* @return string|null
* @return int
*/
public function delete()
{
@@ -581,6 +562,6 @@ class FileUpload
header('Content-type: application/json');
echo json_encode($success);
return null;
return 0;
}
}

View File

@@ -3469,7 +3469,23 @@ function dragAndDropFileUpload($htmlname)
data: fd,
success:function() {
console.log("Uploaded.", arguments);
/* arguments[0] is the json string of files */
/* arguments[1] is the value for variable "success", can be 0 or 1 */
let listoffiles = JSON.parse(arguments[0]);
console.log(listoffiles);
let nboferror = 0;
for (let i = 0; i < listoffiles.length; i++) {
console.log(listoffiles[i].error);
if (listoffiles[i].error) {
nboferror++;
}
}
console.log(nboferror);
if (nboferror > 0) {
window.location.href = "'.$_SERVER["PHP_SELF"].'?id='.dol_escape_js($object->id).'&seteventmessages=ErrorOnAtLeastOneFileUpload:warnings";
} else {
window.location.href = "'.$_SERVER["PHP_SELF"].'?id='.dol_escape_js($object->id).'&seteventmessages=UploadFileDragDropSuccess:mesgs";
}
},
error:function() {
console.log("Error Uploading.", arguments)

View File

@@ -11256,17 +11256,19 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u
* Get an array with properties of an element.
*
* @param string $element_type Element type (Value of $object->element). Example:
* 'action', 'facture', 'project_task',
* 'action', 'facture', 'project', 'project_task' or
* 'myobject@mymodule' or
* 'myobject_mysubobject' (where mymodule = myobject, like 'project_task')
* @return array (module, classpath, element, subelement, classfile, classname)
* @return array array('module'=>, 'classpath'=>, 'element'=>, 'subelement'=>, 'classfile'=>, 'classname'=>, 'dir_output'=>)
* @see fetchObjectByElement()
*/
function getElementProperties($element_type)
{
global $conf;
$regs = array();
$classfile = $classname = $classpath = '';
$classfile = $classname = $classpath = $dir_output = '';
// Parse element/subelement
$module = $element_type;
@@ -11401,14 +11403,14 @@ function getElementProperties($element_type)
$classpath = 'fourn/class';
$module = 'fournisseur';
$classfile = 'fournisseur.commande';
$element = 'commande';
$element = 'order_supplier';
$subelement = '';
$classname = 'CommandeFournisseur';
} elseif ($element_type == 'invoice_supplier') {
$classpath = 'fourn/class';
$module = 'fournisseur';
$classfile = 'fournisseur.facture';
$element = 'facture';
$element = 'invoice_supplier';
$subelement = '';
$classname = 'FactureFournisseur';
} elseif ($element_type == "service") {
@@ -11434,6 +11436,9 @@ function getElementProperties($element_type)
$classpath = 'core/class';
$module = 'accounting';
$subelement = 'fiscalyear';
} elseif ($element_type == 'chargesociales') {
$classpath = 'compta/sociales/class';
$module = 'tax';
}
if (empty($classfile)) {
@@ -11446,13 +11451,32 @@ function getElementProperties($element_type)
$classpath = $module.'/class';
}
// Set dir_output
if ($module && isset($conf->$module)) { // The generic case
if (!empty($conf->$module->multidir_output[$conf->entity])) {
$dir_output = $conf->$module->multidir_output[$conf->entity];
} elseif (!empty($conf->$module->output[$conf->entity])) {
$dir_output = $conf->$module->output[$conf->entity];
} elseif (!empty($conf->$module->dir_output)) {
$dir_output = $conf->$module->dir_output;
}
}
// Overwrite value for special cases
if ($element == 'order_supplier') {
$dir_output = $conf->fournisseur->commande->dir_output;
} elseif ($element == 'invoice_supplier') {
$dir_output = $conf->fournisseur->facture->dir_output;
}
$element_properties = array(
'module' => $module,
'classpath' => $classpath,
'element' => $element,
'subelement' => $subelement,
'classpath' => $classpath,
'classfile' => $classfile,
'classname' => $classname
'classname' => $classname,
'dir_output' => $dir_output
);
return $element_properties;
}

View File

@@ -401,6 +401,9 @@ function restrictedArea(User $user, $features, $object = 0, $tableandshare = '',
if ($features == 'productbatch') {
$features = 'produit';
}
if ($features == 'tax') {
$feature2 = 'charges';
}
if ($features == 'fournisseur') { // When vendor invoice and purchase order are into module 'fournisseur'
$features = 'fournisseur';
if (is_object($object) && $object->element == 'invoice_supplier') {

View File

@@ -87,7 +87,7 @@ class modTax extends DolibarrModules
$r++;
$this->rights[$r][0] = 91;
$this->rights[$r][1] = 'Lire les charges';
$this->rights[$r][1] = 'Read social contibutions';
$this->rights[$r][2] = 'r';
$this->rights[$r][3] = 0;
$this->rights[$r][4] = 'charges';
@@ -95,7 +95,7 @@ class modTax extends DolibarrModules
$r++;
$this->rights[$r][0] = 92;
$this->rights[$r][1] = 'Creer/modifier les charges';
$this->rights[$r][1] = 'Create/modify social contributions';
$this->rights[$r][2] = 'w';
$this->rights[$r][3] = 0;
$this->rights[$r][4] = 'charges';
@@ -103,7 +103,7 @@ class modTax extends DolibarrModules
$r++;
$this->rights[$r][0] = 93;
$this->rights[$r][1] = 'Supprimer les charges';
$this->rights[$r][1] = 'Delete social contributions';
$this->rights[$r][2] = 'd';
$this->rights[$r][3] = 0;
$this->rights[$r][4] = 'charges';
@@ -111,7 +111,7 @@ class modTax extends DolibarrModules
$r++;
$this->rights[$r][0] = 94;
$this->rights[$r][1] = 'Exporter les charges';
$this->rights[$r][1] = 'Export social contributions';
$this->rights[$r][2] = 'r';
$this->rights[$r][3] = 0;
$this->rights[$r][4] = 'charges';

View File

@@ -31,6 +31,7 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
require_once DOL_DOCUMENT_ROOT.'/salaries/class/paymentsalary.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
@@ -111,6 +112,8 @@ $permissiontoread = $user->rights->salaries->read;
$permissiontoadd = $user->rights->salaries->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
$permissiontodelete = $user->rights->salaries->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
$upload_dir = $conf->salaries->multidir_output[$conf->entity];
/*
* Actions
@@ -150,12 +153,17 @@ if (empty($reshook)) {
}
$action = '';
}
// Actions to send emails
$triggersendname = 'COMPANY_SENTBYMAIL';
$paramname = 'id';
$mode = 'emailfromthirdparty';
$trackid = 'thi'.$object->id;
$trackid = 'sal'.$object->id;
include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
//var_dump($upload_dir);var_dump($permissiontoadd);var_dump($action);exit;
// Actions to build doc
include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
}
// Link to a project
@@ -758,7 +766,7 @@ if ($id > 0) {
print $formconfirm;
print dol_get_fiche_head($head, 'card', $langs->trans("SalaryPayment"), -1, 'salary');
print dol_get_fiche_head($head, 'card', $langs->trans("SalaryPayment"), -1, 'salary', 0, '', '', 0, '', 1);
$linkback = '<a href="'.DOL_URL_ROOT.'/salaries/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';