Debug feature to import stock movements from a file.

This commit is contained in:
Laurent Destailleur 2021-03-31 15:07:18 +02:00
parent 66385d4ed5
commit fafff6d9a4
2 changed files with 205 additions and 239 deletions

View File

@ -247,7 +247,8 @@ UpdateByScaningLot=Update by scan (lot|serial barcode)
DisableStockChangeOfSubProduct=Deactivate the stock change for all the subproducts of this Kit during this movement.
ImportFromCSV=Import CSV list of movement
ChooseFileToImport=Upload file then click on the %s icon to select file as source import file...
InfoTemplateImport=Uploaded file needs to have this format (* are mandatory fields) : Product_id* | Source_Warehouse_id* | Target_Warehouse_id* | Quantity* | Batch_id
OrSelectAStockMovementFileToImport=Or select a stock movement file to import
InfoTemplateImport=Uploaded file needs to have this format (* are mandatory fields):<br>Source_Warehouse_id* | Target_Warehouse_id* | Product_id* | Quantity* | Lot/serial number<br>CSV character separator must be <b>%s</b>
LabelOfInventoryMovemement=Inventory %s
ReOpen=Reopen
ConfirmFinish=Confirm closing

View File

@ -86,21 +86,7 @@ if (!empty($_SESSION['massstockmove'])) {
* Actions
*/
if (GETPOST('sendit') && !empty($conf->global->MAIN_UPLOAD_DOC)) {
dol_mkdir($conf->stock->dir_temp);
$nowyearmonth = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
$fullpath = $conf->stock->dir_temp."/".$nowyearmonth.'-'.$_FILES['userfile']['name'];
if (dol_move_uploaded_file($_FILES['userfile']['tmp_name'], $fullpath, 1) > 0) {
dol_syslog("File ".$fullpath." was added for import");
} else {
$langs->load("errors");
setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
}
}
if ($action == 'addline') {
if ($action == 'addline' && !empty($user->rights->stock->mouvement->creer)) {
if (!($id_product > 0)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors');
@ -162,7 +148,7 @@ if ($action == 'addline') {
}
}
if ($action == 'delline' && $idline != '') {
if ($action == 'delline' && $idline != '' && !empty($user->rights->stock->mouvement->creer)) {
if (!empty($listofdata[$idline])) {
unset($listofdata[$idline]);
}
@ -173,7 +159,7 @@ if ($action == 'delline' && $idline != '') {
}
}
if ($action == 'createmovements') {
if ($action == 'createmovements' && !empty($user->rights->stock->mouvement->creer)) {
$error = 0;
if (!GETPOST("label")) {
@ -308,75 +294,107 @@ if ($action == 'createmovements') {
}
}
if ($action == 'importCSV') {
$importcsv = new ImportCsv($db, 'massstocklist');
$dir = $conf->stock->dir_temp;
$fullpath = $dir.'/'.$filetoimport;
$nblinesrecord = $importcsv->import_get_nb_of_lines($fullpath)-1;
$importcsv->import_open_file($fullpath);
$labelsrecord = $importcsv->import_read_record();
$i=0;
$data = array();
while ($i < $nblinesrecord) {
$data[] = $importcsv->import_read_record();
$id_product = $data[$i][0]['val'];
$id_sw = $data[$i][1]['val'];
$id_tw = $data[$i][2]['val'];
$qty = $data[$i][3]['val'];
$batch = $data[$i][4]['val'];
if ($action == 'importCSV' && !empty($user->rights->stock->mouvement->creer)) {
dol_mkdir($conf->stock->dir_temp);
$nowyearmonth = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
if (!($id_product > 0)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors');
}
if (!($id_sw > 0)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors');
}
if (!($id_tw > 0)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors');
}
if ($id_sw > 0 && $id_tw == $id_sw) {
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorWarehouseMustDiffers"), null, 'errors');
}
if (!$qty) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
}
$fullpath = $conf->stock->dir_temp."/".$user->id.'-csvfiletotimport.csv';
if (dol_move_uploaded_file($_FILES['userfile']['tmp_name'], $fullpath, 1) > 0) {
dol_syslog("File ".$fullpath." was added for import");
} else {
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
}
// Check a batch number is provided if product need it
if (!$error) {
$producttmp = new Product($db);
$producttmp->fetch($id_product);
if ($producttmp->hasbatch()) {
if (empty($batch)) {
if (!$error) {
$importcsv = new ImportCsv($db, 'massstocklist');
//print $importcsv->separator;
$nblinesrecord = $importcsv->import_get_nb_of_lines($fullpath)-1;
$importcsv->import_open_file($fullpath);
$labelsrecord = $importcsv->import_read_record();
if ($nblinesrecord <= 1) {
setEventMessages($langs->trans("BadNumberOfLinesMustHaveAtLeastOneLinePlusTitle"), null, 'errors');
} else {
$i=0;
$data = array();
while (($i < $nblinesrecord) && !$error) {
$data[] = $importcsv->import_read_record();
if (count($data[$i]) == 1) {
// Only 1 empty line
unset($data);
$i++;
continue;
}
//var_dump($data);
$id_sw = $data[$i][0]['val'];
$id_tw = $data[$i][1]['val'];
$id_product = $data[$i][2]['val'];
$qty = $data[$i][3]['val'];
$batch = $data[$i][4]['val'];
// TODO If product is a ref (not numeric or starts with "ref:..."), retreive the id of product from the ref
if (!($id_product > 0)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors');
}
// TODO If warehouse is a ref (not numeric or starts with "ref:..."), retreive the id of product from the ref
if (!($id_sw > 0)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseSource")), null, 'errors');
}
// TODO If warehouse is a ref (not numeric or starts with "ref:..."), retreive the id of product from the ref
if (!($id_tw > 0)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WarehouseTarget")), null, 'errors');
}
if ($id_sw > 0 && $id_tw == $id_sw) {
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $producttmp->ref), null, 'errors');
setEventMessages($langs->trans("ErrorWarehouseMustDiffers"), null, 'errors');
}
if (!$qty) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
}
// Check a batch number is provided if product need it
if (!$error) {
$producttmp = new Product($db);
$producttmp->fetch($id_product);
if ($producttmp->hasbatch()) {
if (empty($batch)) {
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $producttmp->ref), null, 'errors');
}
}
}
$i++;
}
if (!$error) {
foreach ($data as $key => $value) {
if (count(array_keys($listofdata)) > 0) {
$id = max(array_keys($listofdata)) + 1;
} else {
$id = 1;
}
$id_product = $data[$key][0]['val'];
$id_sw = $data[$key][1]['val'];
$id_tw = $data[$key][2]['val'];
$qty = $data[$key][3]['val'];
$batch = $data[$key][4]['val'];
$listofdata[$key] = array('id'=>$key, 'id_product'=>$id_product, 'qty'=>$qty, 'id_sw'=>$id_sw, 'id_tw'=>$id_tw, 'batch'=>$batch);
}
}
}
}
$i++;
}
if (!$error) {
foreach ($data as $key => $value) {
if (count(array_keys($listofdata)) > 0) {
$id = max(array_keys($listofdata)) + 1;
} else {
$id = 1;
}
$id_product = $data[$key][0]['val'];
$id_sw = $data[$key][1]['val'];
$id_tw = $data[$key][2]['val'];
$qty = $data[$key][3]['val'];
$batch = $data[$key][4]['val'];
$listofdata[$key] = array('id'=>$key, 'id_product'=>$id_product, 'qty'=>$qty, 'id_sw'=>$id_sw, 'id_tw'=>$id_tw, 'batch'=>$batch);
}
}
$_SESSION['massstockmove'] = json_encode($listofdata);
}
@ -401,6 +419,8 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes') {
Header('Location: '.$_SERVER["PHP_SELF"]);
exit;
}
/*
* View
*/
@ -426,119 +446,18 @@ $buttonrecord = $langs->trans("RecordMovement");
$titletoaddnoent = $langs->transnoentitiesnoconv("Select");
$buttonrecordnoent = $langs->transnoentitiesnoconv("RecordMovement");
print '<span class="opacitymedium">'.$langs->trans("SelectProductInAndOutWareHouse", $titletoaddnoent, $buttonrecordnoent).'</span><br>';
print '<br>'."\n";
// Form to add a line
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="addline">';
print '<div class="div-table-responsive-no-min">';
print '<table class="liste centpercent">';
//print '<div class="tagtable centpercent">';
$param = '';
print '<tr class="liste_titre">';
print getTitleFieldOfList($langs->trans('WarehouseSource'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
print getTitleFieldOfList($langs->trans('WarehouseTarget'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
if ($conf->productbatch->enabled) {
print getTitleFieldOfList($langs->trans('Batch'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
}
print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
print getTitleFieldOfList('', 0);
print '</tr>';
print '<tr class="oddeven">';
// From warehouse
print '<td>';
print img_picto($langs->trans("WarehouseSource"), 'stock', 'class="paddingright"').$formproduct->selectWarehouses($id_sw, 'id_sw', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200');
print '</td>';
// To warehouse
print '<td>';
print img_picto($langs->trans("WarehouseTarget"), 'stock', 'class="paddingright"').$formproduct->selectWarehouses($id_tw, 'id_tw', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200');
print '</td>';
// Product
print '<td>';
$filtertype = 0;
if (!empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
$filtertype = '';
}
if ($conf->global->PRODUIT_LIMIT_SIZE <= 0) {
$limit = '';
} else {
$limit = $conf->global->PRODUIT_LIMIT_SIZE;
}
print img_picto($langs->trans("Product"), 'product', 'class="paddingright"');
print $form->select_produits($id_product, 'productid', $filtertype, $limit, 0, -1, 2, '', 1, array(), 0, '1', 0, 'minwidth200imp maxwidth300', 1, '', null, 1);
print '</td>';
// Batch number
if ($conf->productbatch->enabled) {
print '<td>';
print img_picto($langs->trans("LotSerial"), 'lot', 'class="paddingright"');
print '<input type="text" name="batch" class="flat maxwidth50" value="'.$batch.'">';
print '</td>';
}
// Qty
print '<td class="center"><input type="text" class="flat maxwidth50" name="qty" value="'.$qty.'"></td>';
// Button to add line
print '<td class="right"><input type="submit" class="button" name="addline" value="'.dol_escape_htmltag($titletoadd).'"></td>';
print '</tr>';
foreach ($listofdata as $key => $val) {
$productstatic->fetch($val['id_product']);
$warehousestatics->fetch($val['id_sw']);
$warehousestatict->fetch($val['id_tw']);
print '<tr class="oddeven">';
print '<td>';
print $warehousestatics->getNomUrl(1);
print '</td>';
print '<td>';
print $warehousestatict->getNomUrl(1);
print '</td>';
print '<td>';
print $productstatic->getNomUrl(1).' - '.$productstatic->label;
print '</td>';
if ($conf->productbatch->enabled) {
print '<td>';
print $val['batch'];
print '</td>';
}
print '<td class="center">'.$val['qty'].'</td>';
print '<td class="right"><a href="'.$_SERVER["PHP_SELF"].'?action=delline&idline='.$val['id'].'">'.img_delete($langs->trans("Remove")).'</a></td>';
print '</tr>';
}
print '</table>';
print '</div>';
print '</form>';
print '<br>';
// Form to upload a file
print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" METHOD="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="importCSV">';
print '<input type="hidden" name="max_file_size" value="'.$conf->maxfilesize.'">';
print '<span class="opacitymedium">';
$s = $langs->trans("ChooseFileToImport", '{s1}');
$s = str_replace('{s1}', img_picto('', 'next'), $s);
print $s;
print '<br><br>';
print $langs->trans('InfoTemplateImport');
print '</span><br><br>';
print $form->textwithpicto($langs->trans('OrSelectAStockMovementFileToImport'), $langs->transnoentitiesnoconv("InfoTemplateImport", $importcsv->separator));
print '</span>';
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
print '<table class="noborder" width="100%" cellspacing="0" cellpadding="4">';
print '<tr class="oddeven nohover"><td colspan="6">';
print '<input type="file" name="userfile" size="20" maxlength="80"> &nbsp; &nbsp; ';
$out = (empty($conf->global->MAIN_UPLOAD_DOC) ? ' disabled' : '');
print '<input type="submit" class="button" value="'.$langs->trans("ImportFromCSV").'"'.$out.' name="sendit">';
@ -594,52 +513,94 @@ if (!empty($conf->global->MAIN_UPLOAD_DOC)) {
$out .= ' ('.$langs->trans("UploadDisabled").')';
}
print $out;
print '</form>';
print '<br><br>';
// Form to add a line
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="addline">';
print '<div class="div-table-responsive-no-min">';
print '<table class="liste centpercent">';
$param = '';
print '<tr class="liste_titre">';
print getTitleFieldOfList($langs->trans('WarehouseSource'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
print getTitleFieldOfList($langs->trans('WarehouseTarget'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
print getTitleFieldOfList($langs->trans('ProductRef'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
if ($conf->productbatch->enabled) {
print getTitleFieldOfList($langs->trans('Batch'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'tagtd maxwidthonsmartphone ');
}
print getTitleFieldOfList($langs->trans('Qty'), 0, $_SERVER["PHP_SELF"], '', $param, '', '', $sortfield, $sortorder, 'center tagtd maxwidthonsmartphone ');
print getTitleFieldOfList('', 0);
print '</tr>';
print '<tr class="oddeven">';
// From warehouse
print '<td>';
print img_picto($langs->trans("WarehouseSource"), 'stock', 'class="paddingright"').$formproduct->selectWarehouses($id_sw, 'id_sw', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200');
print '</td>';
print "</tr>\n";
// To warehouse
print '<td>';
print img_picto($langs->trans("WarehouseTarget"), 'stock', 'class="paddingright"').$formproduct->selectWarehouses($id_tw, 'id_tw', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, array(), 'minwidth200imp maxwidth200');
print '</td>';
// Product
print '<td>';
$filtertype = 0;
if (!empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
$filtertype = '';
}
if ($conf->global->PRODUIT_LIMIT_SIZE <= 0) {
$limit = '';
} else {
$limit = $conf->global->PRODUIT_LIMIT_SIZE;
}
// Search available imports
$filearray = dol_dir_list($conf->stock->dir_temp, 'files', 0, '', '', 'name', SORT_DESC);
if (count($filearray) > 0) {
$dir = $conf->stock->dir_temp;
print img_picto($langs->trans("Product"), 'product', 'class="paddingright"');
print $form->select_produits($id_product, 'productid', $filtertype, $limit, 0, -1, 2, '', 1, array(), 0, '1', 0, 'minwidth200imp maxwidth300', 1, '', null, 1);
print '</td>';
// Batch number
if ($conf->productbatch->enabled) {
print '<td>';
print img_picto($langs->trans("LotSerial"), 'lot', 'class="paddingright"');
print '<input type="text" name="batch" class="flat maxwidth50" value="'.$batch.'">';
print '</td>';
}
// Qty
print '<td class="center"><input type="text" class="flat maxwidth50" name="qty" value="'.$qty.'"></td>';
// Button to add line
print '<td class="right"><input type="submit" class="button" name="addline" value="'.dol_escape_htmltag($titletoadd).'"></td>';
// Search available files to import
$i = 0;
foreach ($filearray as $key => $val) {
$file = $val['name'];
print '</tr>';
// readdir return value in ISO and we want UTF8 in memory
if (!utf8_check($file)) {
$file = utf8_encode($file);
}
foreach ($listofdata as $key => $val) {
$productstatic->fetch($val['id_product']);
$warehousestatics->fetch($val['id_sw']);
$warehousestatict->fetch($val['id_tw']);
if (preg_match('/^\./', $file)) {
continue;
}
$modulepart = 'import';
$urlsource = $_SERVER["PHP_SELF"].'&filetoimport='.urlencode($filetoimport);
$relativepath = $file;
print '<tr class="oddeven">';
print '<td width="16">'.img_mime($file).'</td>';
print '<tr class="oddeven">';
print '<td>';
print $warehousestatics->getNomUrl(1);
print '</td>';
print '<td>';
print $warehousestatict->getNomUrl(1);
print '</td>';
print '<td>';
print $productstatic->getNomUrl(1).' - '.$productstatic->label;
print '</td>';
if ($conf->productbatch->enabled) {
print '<td>';
print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'" target="_blank">';
print $file;
print '</a>';
print $val['batch'];
print '</td>';
// Affiche taille fichier
print '<td style="text-align:right">'.dol_print_size(dol_filesize($dir.'/'.$file)).'</td>';
// Affiche date fichier
print '<td style="text-align:right">'.dol_print_date(dol_filemtime($dir.'/'.$file), 'dayhour').'</td>';
// Del button
print '<td style="text-align:right"><a href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&urlfile='.urlencode($relativepath);
print '">'.img_delete().'</a></td>';
// Action button
print '<td style="text-align:right">';
print '<a href="'.$_SERVER['PHP_SELF'].'?action=importCSV&filetoimport='.urlencode($relativepath).'">'.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15x"').'</a>';
print '</td>';
print '</tr>';
}
print '<td class="center">'.$val['qty'].'</td>';
print '<td class="right"><a href="'.$_SERVER["PHP_SELF"].'?action=delline&idline='.$val['id'].'">'.img_delete($langs->trans("Remove")).'</a></td>';
print '</tr>';
}
print '</table>';
@ -649,32 +610,36 @@ print '</form>';
print '<br>';
// Form to validate all movements
if (count($listofdata)) {
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire2" class="formconsumeproduce">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="createmovements">';
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire2" class="formconsumeproduce">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="createmovements">';
// Button to record mass movement
$codemove = (GETPOSTISSET("codemove") ? GETPOST("codemove", 'alpha') : dol_print_date(dol_now(), '%Y%m%d%H%M%S'));
$labelmovement = GETPOST("label") ? GETPOST('label') : $langs->trans("StockTransfer").' '.dol_print_date($now, '%Y-%m-%d %H:%M');
// Button to record mass movement
$codemove = (GETPOSTISSET("codemove") ? GETPOST("codemove", 'alpha') : dol_print_date(dol_now(), '%Y%m%d%H%M%S'));
$labelmovement = GETPOST("label") ? GETPOST('label') : $langs->trans("StockTransfer").' '.dol_print_date($now, '%Y-%m-%d %H:%M');
print '<div class="center">';
print '<span class="fieldrequired">'.$langs->trans("InventoryCode").':</span> ';
print '<input type="text" name="codemove" class="maxwidth300" value="'.dol_escape_htmltag($codemove).'"> &nbsp; ';
print '<span class="clearbothonsmartphone"></span>';
print $langs->trans("MovementLabel").': ';
print '<input type="text" name="label" class="minwidth300" value="'.dol_escape_htmltag($labelmovement).'"><br>';
print '<br>';
print '<div class="center">';
print '<span class="fieldrequired">'.$langs->trans("InventoryCode").':</span> ';
print '<input type="text" name="codemove" class="maxwidth300" value="'.dol_escape_htmltag($codemove).'"> &nbsp; ';
print '<span class="clearbothonsmartphone"></span>';
print $langs->trans("MovementLabel").': ';
print '<input type="text" name="label" class="minwidth300" value="'.dol_escape_htmltag($labelmovement).'"><br>';
print '<br>';
print '<div class="center"><input class="button" type="submit" name="valid" value="'.dol_escape_htmltag($buttonrecord).'"></div>';
print '<div class="center"><input class="button" type="submit" name="valid" value="'.dol_escape_htmltag($buttonrecord).'"></div>';
print '<br>';
print '</div>';
print '<br>';
print '</div>';
print '</form>';
}
print '</form>';
if ($action == 'delete') {
print $form->formconfirm($_SERVER["PHP_SELF"].'?urlfile='.urlencode(GETPOST('urlfile')).'&step=3'.$param, $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1);
}
// End of page
llxFooter();
$db->close();