diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 79f509225f60573c8892b42544494cbdbeb56831..6d464cceb29ea4d73917ee9924f3a682cd306975 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1656,6 +1656,10 @@ abstract class CommonObject $fieldtva='tva'; $fieldup='pu_ht'; } + if ($this->element == 'expensereport') + { + $fieldup='value_unit'; + } $sql = 'SELECT rowid, qty, '.$fieldup.' as up, remise_percent, total_ht, '.$fieldtva.' as total_tva, total_ttc, '.$fieldlocaltax1.' as total_localtax1, '.$fieldlocaltax2.' as total_localtax2,'; $sql.= ' tva_tx as vatrate, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, info_bits, product_type'; @@ -1770,6 +1774,7 @@ abstract class CommonObject if ($this->element == 'facture' || $this->element == 'facturerec') $fieldht='total'; if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') $fieldtva='total_tva'; if ($this->element == 'propal') $fieldttc='total'; + if ($this->element == 'expensereport') $fieldtva='total_tva'; if (empty($nodatabaseupdate)) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0d247cdb1815274b9575793ddb6c018ab8292c15..10acc6a8c10ed6b2e66a479ee6a7cc1435b1403c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4172,13 +4172,14 @@ function print_date_range($date_start,$date_end,$format = '',$outputlangs='') /** * Format output for start and end date * - * @param timestamp $date_start Start date - * @param timestamp $date_end End date - * @param string $format Output format - * @param Translate $outputlangs Output language - * @return string String + * @param timestamp $date_start Start date + * @param timestamp $date_end End date + * @param string $format Output format + * @param Translate $outputlangs Output language + * @param string $withparenthesis 1=Add parenthesis, 0=non parenthesis + * @return string String */ -function get_date_range($date_start,$date_end,$format = '',$outputlangs='') +function get_date_range($date_start,$date_end,$format = '',$outputlangs='', $withparenthesis=1) { global $langs; @@ -4188,15 +4189,15 @@ function get_date_range($date_start,$date_end,$format = '',$outputlangs='') if ($date_start && $date_end) { - $out.= ' ('.$outputlangs->trans('DateFromTo',dol_print_date($date_start, $format, false, $outputlangs),dol_print_date($date_end, $format, false, $outputlangs)).')'; + $out.= ($withparenthesis?' (':'').$outputlangs->trans('DateFromTo',dol_print_date($date_start, $format, false, $outputlangs),dol_print_date($date_end, $format, false, $outputlangs)).($withparenthesis?')':''); } if ($date_start && ! $date_end) { - $out.= ' ('.$outputlangs->trans('DateFrom',dol_print_date($date_start, $format, false, $outputlangs)).')'; + $out.= ($withparenthesis?' (':'').$outputlangs->trans('DateFrom',dol_print_date($date_start, $format, false, $outputlangs)).($withparenthesis?')':''); } if (! $date_start && $date_end) { - $out.= ' ('.$outputlangs->trans('DateUntil',dol_print_date($date_end, $format, false, $outputlangs)).')'; + $out.= ($withparenthesis?' (':'').$outputlangs->trans('DateUntil',dol_print_date($date_end, $format, false, $outputlangs)).($withparenthesis?')':''); } return $out; diff --git a/htdocs/core/modules/expensereport/modules_deplacement.php b/htdocs/core/modules/expensereport/modules_deplacement.php new file mode 100755 index 0000000000000000000000000000000000000000..707eaad54b8f5e5c20a1e7fbb85f979fb652b653 --- /dev/null +++ b/htdocs/core/modules/expensereport/modules_deplacement.php @@ -0,0 +1,93 @@ +<?php +require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; + + +/** + * Parent class for trips and expenses templates + */ +class ModeleExpenseReport extends CommonDocGenerator +{ + var $error=''; + + + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param string $maxfilenamelength Max length of value to show + * @return array List of templates + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + global $conf; + + $type='expensereport'; + $liste=array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $liste=getListOfModels($db,$type,$maxfilenamelength); + + return $liste; + } + +} + +function expensereport_pdf_create($db, $id, $message, $modele, $outputlangs) +{ + global $conf,$langs; + $langs->load("trips"); + + // Increase limit for PDF build + $err=error_reporting(); + error_reporting(0); + @set_time_limit(120); + error_reporting($err); + + $dir = dol_buildpath('/expensereport/core/modules/expensereport/'); + + // Positionne modele sur le nom du modele a utiliser + if (! strlen($modele)) + { + if ($conf->global->DEPLACEMENT_ADDON_PDF) + { + $modele = $conf->global->DEPLACEMENT_ADDON_PDF; + } + else + { + print $langs->trans("Error")." ".$langs->trans("Error_DEPLACEMENT_ADDON_PDF_NotDefined"); + return 0; + } + } + + // Charge le modele + $file = "pdf_".$modele.".modules.php"; + if (file_exists($dir.$file)) + { + $classname = "pdf_".$modele; + require_once($dir.$file); + + $obj = new $classname($db); + $obj->message = $message; + + // We save charset_output to restore it because write_file can change it if needed for + // output format that does not support UTF8. + $sav_charset_output=$outputlangs->charset_output; + if ($obj->write_file($id, $outputlangs) > 0) + { + $outputlangs->charset_output=$sav_charset_output; + return 1; + } + else + { + $outputlangs->charset_output=$sav_charset_output; + dol_print_error($db,"expensereport_pdf_create Error: ".$obj->error); + return -1; + } + + } + else + { + dol_print_error('',$langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$dir.$file)); + return -1; + } +} diff --git a/htdocs/core/modules/expensereport/pdf_teclib.modules.php b/htdocs/core/modules/expensereport/pdf_teclib.modules.php new file mode 100755 index 0000000000000000000000000000000000000000..6b3b59639e51dece40439d05d6380e490fd64fad --- /dev/null +++ b/htdocs/core/modules/expensereport/pdf_teclib.modules.php @@ -0,0 +1,759 @@ +<?php +/* Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2005-2010 Regis Houssin <regis@dolibarr.fr> + * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr> + * Copyright (C) 2010 Juanjo Menent <jmenent@2byte.es> + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/expensereport/core/modules/expensereport/pdf_.modules.php + * \ingroup facture + * \brief File of class to generate invoices from crab model + * \author Laurent Destailleur + */ + +dol_include_once("/expensereport/core/modules/expensereport/modules_expensereport.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php"); +require_once(DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'); +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + + + +/** + * Classe permettant de generer les factures au modele Crabe + */ +class pdf_ extends ModeleExpenseReport +{ + var $emetteur; // Objet societe qui emet + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("trips"); + $langs->load("project"); + $langs->load("expensereport@expensereport"); + + $this->db = $db; + $this->name = ""; + $this->description = $langs->trans('PDFDescription'); + + // Dimension page pour format A4 + $this->type = 'pdf'; + $formatarray=pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; + $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; + $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; + $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION + $this->option_modereg = 1; // Affiche mode reglement + $this->option_condreg = 1; // Affiche conditions reglement + $this->option_codeproduitservice = 1; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 1; // Affiche si il y a eu escompte + $this->option_credit_note = 1; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 1; // Support add of a watermark on drafts + + $this->franchise=!$mysoc->tva_assuj; + + // Get source company + $this->emetteur=$mysoc; + if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined + + // Defini position des colonnes + // Defini position des colonnes + $this->posxpiece=$this->marge_gauche+1; + $this->posxdesc=20; + $this->posxdate=85; + $this->posxtype=105; + $this->posxprojet=125; + $this->posxtva=145; + $this->posxup=158; + $this->posxqty=170; + $this->postotalttc=176; + if ($this->page_largeur < 210) // To work with US executive format + { + $this->posxdate-=20; + $this->posxtype-=20; + $this->posxprojet-=20; + $this->posxtva-=20; + $this->posxup-=20; + $this->posxqty-=20; + $this->postotalttc-=20; + } + + $this->tva=array(); + $this->localtax1=array(); + $this->localtax2=array(); + $this->atleastoneratenotnull=0; + $this->atleastonediscount=0; + } + + + /** + * Function to build pdf onto disk + * + * @param Object $object Object to generate + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + */ + function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $user,$langs,$conf,$mysoc,$db,$hookmanager; + + if (! is_object($outputlangs)) $outputlangs=$langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; + + + // Hack to use expensereport dir + $rootfordata = DOL_DATA_ROOT; + $rootforuser = DOL_DATA_ROOT; + // If multicompany module is enabled, we redefine the root of data + //if (! empty($this->multicompany->enabled) && ! empty($this->entity) && $this->entity > 1) + //{ + // $rootfordata.='/'.$this->entity; + //} + $conf->expensereport->dir_output = $rootfordata.'/expensereport'; + $conf->expensereport_->dir_output = $rootfordata.'/expensereport'; + + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("trips"); + $outputlangs->load("project"); + $outputlangs->load("expensereport@expensereport"); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + if ($conf->expensereport_->dir_output) + { + // Definition de l'objet $object (pour compatibilite ascendante) + if (! is_object($object)) + { + $id = $object; + $object = new ExpenseReport($db); + $ret=$object->fetch($id,$user); + } + + $objectref = dol_sanitizeFileName($object->ref_number); + $dir = $conf->expensereport_->dir_output . "/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + + if (isset($object->lignes) && ! isset($object->lines)) $object->lines=$object->lignes; + + if (file_exists($dir)) + { + $nblignes = count($object->lines); + + // Create pdf instance + $pdf=pdf_getInstance($this->format); + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + // Set path to the background PDF File + if (empty($conf->global->MAIN_DISABLE_FPDI) && ! empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb=0; + $pdf->SetDrawColor(128,128,128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref_number)); + $pdf->SetSubject($outputlangs->transnoentities("Trips")); + $pdf->SetCreator(""); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref_number)." ".$outputlangs->transnoentities("Trips")); + if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + $pdf->SetAutoPageBreak(1,0); + + // Positionne $this->atleastonediscount si on a au moins une remise + for ($i = 0 ; $i < $nblignes ; $i++) + { + if ($object->lines[$i]->remise_percent) + { + $this->atleastonediscount++; + } + } + + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + $tab_top = 95; + $tab_top_newpage = 95; + $tab_height = 110; + $tab_height_newpage = 110; + + // Affiche notes + if (! empty($object->note)) + { + $tab_top = 93; + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($object->note), 0, 1); + $nexY = $pdf->GetY(); + $height_note=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1); + + $tab_height = $tab_height - $height_note; + $tab_top = $nexY+6; + } + else + { + $height_note=0; + } + + $iniY = $tab_top + 7; + $curY = $tab_top + 7; + $nexY = $tab_top + 7; + + // Loop on each lines + for ($i = 0 ; $i < $nblignes ; $i++) + { + $curY = $nexY; + $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0,0,0); + + $piece_comptable = $i +1; + + // Piece comptable + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell($this->posxcomment-$this->posxpiece-1, 3, $this->posxpiece-1, $curY, $piece_comptable, 0, 1); + + // Comments + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY ($this->posxcomment, $curY); + $pdf->writeHTMLCell($this->posxdate-$this->posxdesc-1, 3, $this->posxdesc-1, $curY, $object->lignes[$i]->comments, 0, 1); + + //nexY + $nexY = $pdf->GetY(); + + // Date + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY ($this->posxdate, $curY); + $pdf->MultiCell($this->posxtype-$this->posxdate-1, 3,dol_print_date($object->lignes[$i]->date,"day",false,$outpulangs), 0, 'C'); + + // Type + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY ($this->posxtype, $curY); + $pdf->MultiCell($this->posxprojet-$this->posxtype-1, 3,$outputlangs->transnoentities($object->lignes[$i]->type_fees_code), 0, 'C'); + + // Projet + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY ($this->posxprojet, $curY); + $pdf->MultiCell($this->posxtva-$this->posxprojet-1, 3,$object->lignes[$i]->projet_ref, 0, 'C'); + + // TVA + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY ($this->posxtva, $curY); + $pdf->MultiCell($this->posxup-$this->posxtva-1, 3,vatrate($object->lignes[$i]->tva_taux,true), 0, 'R'); + + // UP + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY ($this->posxup, $curY); + $pdf->MultiCell($this->posxqty-$this->posxup-1, 3,price($object->lignes[$i]->value_unit), 0, 'R'); + + // QTY + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY ($this->posxqty, $curY); + $pdf->MultiCell($this->postotalttc-$this->posxqty, 3,$object->lignes[$i]->qty, 0, 'C'); + + // TotalTTC + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY ($this->postotalttc-2, $curY); + $pdf->MultiCell(26, 3,price($object->lignes[$i]->total_ttc), 0, 'R'); + + $nexY+=5; + + // Cherche nombre de lignes a venir pour savoir si place suffisante + if ($i < ($nblignes - 1)) // If it's not last line + { + //on recupere la description du produit suivant + $follow_descproduitservice = $object->lines[$i+1]->desc; + //on compte le nombre de ligne afin de verifier la place disponible (largeur de ligne 52 caracteres) + $nblineFollowDesc = dol_nboflines_bis($follow_descproduitservice,52,$outputlangs->charset_output)*4; + // Et si on affiche dates de validite, on ajoute encore une ligne + if ($object->lines[$i]->date_start && $object->lines[$i]->date_end) + { + $nblineFollowDesc += 4; + } + } + else // If it's last line + { + $nblineFollowDesc = 0; + } + + // Test if a new page is required + if ($pagenb == 1) + { + $tab_top_in_current_page=$tab_top; + $tab_height_in_current_page=$tab_height; + } + else + { + $tab_top_in_current_page=$tab_top_newpage; + $tab_height_in_current_page=$tab_height_newpage; + } + if (($nexY+$nblineFollowDesc) > ($tab_top_in_current_page+$tab_height_in_current_page) && $i < ($nblignes - 1)) + { + if ($pagenb == 1): + $this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs); + $nexY=$tab_top + $tab_height + 1; + else: + $this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs); + $nexY=$tab_top_newpage + $tab_height_newpage + 1; + endif; + + $this->_pagefoot($pdf,$object,$outputlangs); + + // New page + $pdf->AddPage(); + $pagenb++; + $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + $nexY = $tab_top_newpage + 7; + } + + } + + // Show square + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $tab_height, $nexY, $outputlangs); + $bottomlasttab=$tab_top + $tab_height + 1; + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $tab_height_newpage, $nexY, $outputlangs); + $bottomlasttab=$tab_top_newpage + $tab_height_newpage + 1; + } + + // Affiche zone totaux + $posy=$bottomlasttab+5;//$nexY+95; + $pdf->SetXY(120, $posy); + $pdf->MultiCell(50, 5, $outputlangs->transnoentities("TotalHT"), 1, 'L'); + $pdf->SetXY (170, $posy); + $pdf->MultiCell(30, 5, price($object->total_ht), 1, 'R'); + $pdf->SetFillColor(248,248,248); + + $posy+=5; + $pdf->SetXY (120, $posy); + $pdf->SetFont('','B', 10); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(50, 5, $outputlangs->transnoentities("TotalTTC"), 1,'L'); + $pdf->SetXY (170, $posy); + $pdf->MultiCell(30, 5, price($object->total_ttc),1, 'R'); + + // Pied de page + $this->_pagefoot($pdf,$object,$outputlangs); + if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file,'F'); + + // Add pdfgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + return 1; // Pas d'erreur + } + else + { + $this->error=$langs->trans("ErrorCanNotCreateDir",$dir); + return 0; + } + } + else + { + $this->error=$langs->trans("ErrorConstantNotDefined","DEPLACEMENT_OUTPUTDIR"); + return 0; + } + $this->error=$langs->trans("ErrorUnknown"); + return 0; // Erreur par defaut + } + + /** + * Show top header of page. + * + * @param PDF &$pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @return void + */ + function _pagehead(&$pdf, $object, $showaddress, $outputlangs) + { + global $conf,$langs,$hookmanager; + + $outputlangs->load("main"); + $outputlangs->load("trips"); + $outputlangs->load("companies"); + $default_font_size = pdf_getPDFFontSize($outputlangs); + + /* + // ajout du fondu vert en bas de page à droite + $image_fondue = $conf->mycompany->dir_output.'/fondu_vert_.jpg'; + $pdf->Image($image_fondue,20,107,200,190); + + pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); + */ + + // Filligrane brouillon + if($object->fk_c_expensereport_statuts==1) + { + pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',"' - PREVIEW ONLY"); + } + + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('','B', $default_font_size + 3); + + $posy=$this->marge_haute; + $posx=$this->page_largeur-$this->marge_droite-100; + + $pdf->SetXY($this->marge_gauche,$posy); + + // Logo + $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) + { + if (is_readable($logo)) + { + $height=pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } + else + { + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size -2); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } + else + { + $text=$this->emetteur->name; + $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + + $pdf->SetFont('','B', $default_font_size + 6); + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(255,255,255); + $pdf->SetFillColor(193,219,62); + $ref_text = explode($conf->global->NDF_EXPLODE_CHAR,$object->ref_number); + $ref_text = substr($ref_text[1],3,$conf->global->NDF_NUM_CAR_REF); + $pdf->MultiCell(110,6,"Note de frais ".$ref_text, 0, 'L', 1); + + $pdf->SetFont('','', $default_font_size -1); + + // Réf complète + $posy+=8; + $pdf->SetXY(100,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Ref")." : " . $object->ref_number, '', 'L'); + + // Date début période + $posy+=5; + $pdf->SetXY(100,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DateStart")." : " . ($object->date_debut>0?$object->date_debut:dol_print_date($object->date_debut,"day",false,$outpulangs)), '', 'L'); + + // Date fin période + $posy+=5; + $pdf->SetXY(100,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DateEnd")." : " . ($object->date_fin>0?dol_print_date($object->date_fin,"day",false,$outpulangs):''), '', 'L'); + + // Statut NDF + $posy+=7; + $pdf->SetXY(100,$posy); + $pdf->SetFont('','B',20); + $pdf->SetTextColor(111,81,124); + if(preg_match("#Pay#",$object->libelle_statut) && !preg_match("#A P#",$object->libelle_statut)): + $pdf->MultiCell(100, 3,$outputlangs->convToOutputCharset("Payée"), '', 'L'); + elseif(preg_match("#Annul#",$object->libelle_statut)): + $pdf->MultiCell(100, 3,$outputlangs->convToOutputCharset("Annulée"), '', 'L'); + elseif(preg_match("#Refus#",$object->libelle_statut)): + $pdf->MultiCell(100, 3,$outputlangs->convToOutputCharset("Refusée"), '', 'L'); + else: + $pdf->MultiCell(100, 3,$object->libelle_statut, '', 'L'); + endif; + + // Sender properties + $carac_emetteur = ''; + $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->convToOutputCharset($this->emetteur->address); + $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->convToOutputCharset($this->emetteur->zip).' '.$outputlangs->convToOutputCharset($this->emetteur->town); + $carac_emetteur .= "\n"; + // Tel + if ($this->emetteur->phone) $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->transnoentities("Phone")." : ".$outputlangs->convToOutputCharset($this->emetteur->phone); + // Fax + if ($this->emetteur->fax) $carac_emetteur .= ($carac_emetteur ? ($this->emetteur->tel ? " - " : "\n") : '' ).$outputlangs->transnoentities("Fax")." : ".$outputlangs->convToOutputCharset($this->emetteur->fax); + // EMail + if ($this->emetteur->email) $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->transnoentities("Email")." : ".$outputlangs->convToOutputCharset($this->emetteur->email); + // Web + if ($this->emetteur->url) $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->transnoentities("Web")." : ".$outputlangs->convToOutputCharset($this->emetteur->url); + + // Show sender + $posy=50; + $posx=$this->marge_gauche; + $hautcadre=40; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=118; + + // Show sender frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(66,5, $outputlangs->transnoentities("TripSociete")." :",'','L'); + $pdf->SetXY($posx,$posy); + $pdf->SetFillColor(224,224,224); + $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0,0,60); + + // Show sender name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + + // Show sender information + $pdf->SetXY($posx+2,$posy+8); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); + + // Show recipient + $posy=50; + $posx=100; + + // Show recipient frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','B',8); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(80,5, $outputlangs->transnoentities("TripNDF")." :", 0, 'L'); + $pdf->rect($posx, $posy, 100, $hautcadre); + + // Informations for trip (dates and users workflow) + $userfee=new User($this->db); + $userfee->fetch($object->fk_user_author); $posy+=3; + $pdf->SetXY($posx+2,$posy); + $pdf->SetFont('','',10); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("AUTHOR")." : ".$outputlangs->convToOutputCharset($userfee->firstname)." ".$outputlangs->convToOutputCharset($userfee->lastname),0,'L'); + $posy+=5; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("DATE_SAVE")." : ".dol_print_date($object->date_create,"day",false,$outpulangs),0,'L'); + + if($object->fk_c_expensereport_statuts<3): + $userfee=new User($this->db); + $userfee->fetch($object->fk_user_validator); $posy+=6; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("VALIDATOR")." : ".$outputlangs->convToOutputCharset($userfee->firstname)." ".$outputlangs->convToOutputCharset($userfee->lastname),0,'L'); + elseif($object->fk_c_expensereport_statuts==99): + $userfee=new User($this->db); + $userfee->fetch($object->fk_user_refuse); $posy+=6; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("REFUSEUR")." : ".$outputlangs->convToOutputCharset($userfee->firstname)." ".$outputlangs->convToOutputCharset($userfee->lastname),0,'L'); + $posy+=5; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("MOTIF_REFUS")." : ".$outputlangs->convToOutputCharset($object->detail_refuse),0,'L'); + $posy+=5; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("DATE_REFUS")." : ".dol_print_date($object->date_refuse,"day",false,$outpulangs),0,'L'); + elseif($object->fk_c_expensereport_statuts==4): + $userfee=new User($this->db); + $userfee->fetch($object->fk_user_cancel); $posy+=6; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("CANCEL_USER")." : ".$outputlangs->convToOutputCharset($userfee->firstname)." ".$outputlangs->convToOutputCharset($userfee->lastname),0,'L'); + $posy+=5; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("MOTIF_CANCEL")." : ".$outputlangs->convToOutputCharset($object->detail_cancel),0,'L'); + $posy+=5; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("DATE_CANCEL")." : ".dol_print_date($object->date_cancel,"day",false,$outpulangs),0,'L'); + else: + $userfee=new User($this->db); + $userfee->fetch($object->fk_user_validator); $posy+=6; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("VALIDOR")." : ".$outputlangs->convToOutputCharset($userfee->firstname)." ".$outputlangs->convToOutputCharset($userfee->lastname),0,'L'); + $posy+=5; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("DATE_VALIDE")." : ".dol_print_date($object->date_valide,"day",false,$outpulangs),0,'L'); + endif; + + if($object->fk_c_expensereport_statuts==6): + $userfee=new User($this->db); + $userfee->fetch($object->fk_user_paid); $posy+=6; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("AUTHORPAIEMENT")." : ".$outputlangs->convToOutputCharset($userfee->firstname)." ".$outputlangs->convToOutputCharset($userfee->lastname),0,'L'); + $posy+=5; + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell(96,4,$outputlangs->transnoentities("DATE_PAIEMENT")." : ".dol_print_date($object->date_paiement,"day",false,$outpulangs),0,'L'); + endif; + + } + + /** + * Affiche la grille des lignes de factures + * + * @param $pdf Objet PDF + * @param $tab_top Tab top + * @param $tab_height Tab height + * @param $nexY next y + * @param $outputlangs Output langs + * @return void + */ + function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs) + { + global $conf; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$conf->currency)); + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 4), $tab_top -4); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + $pdf->SetDrawColor(128,128,128); + + // Rect prend une longueur en 3eme param + $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height); + // line prend une position y en 3eme param + $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); + + $pdf->SetFont('','',8); + + //Piece comptable + $pdf->SetXY ($this->posxpiece-1, $tab_top+1); + $pdf->MultiCell($this->posxpiece-$this->posxpiece-1,1,$outputlangs->transnoentities("Piece"),'','L'); + + //Comments + $pdf->line($this->posxdesc-1, $tab_top, $this->posxdesc-1, $tab_top + $tab_height); + $pdf->SetXY ($this->posxdesc-1, $tab_top+1); + $pdf->MultiCell($this->posxdate-$this->posxdesc-1,1,$outputlangs->transnoentities("Description"),'','L'); + + //Date + $pdf->line($this->posxdate-1, $tab_top, $this->posxdate-1, $tab_top + $tab_height); + $pdf->SetXY ($this->posxdate-1, $tab_top+1); + $pdf->MultiCell($this->posxtype-$this->posxdate-1,2, $outputlangs->transnoentities("Date"),'','C'); + + //Type + $pdf->line($this->posxtype-1, $tab_top, $this->posxtype-1, $tab_top + $tab_height); + $pdf->SetXY ($this->posxtype-1, $tab_top+1); + $pdf->MultiCell($this->posxprojet-$this->posxtype-1,2, $outputlangs->transnoentities("Type"),'','C'); + + // Projet + $pdf->line($this->posxprojet-1, $tab_top, $this->posxprojet-1, $tab_top + $tab_height); + $pdf->SetXY ($this->posxprojet-1, $tab_top+1); + $pdf->MultiCell($this->posxtva-$this->posxprojet-1,2, $outputlangs->transnoentities("Project"),'','C'); + + //TVA + $pdf->line($this->posxtva-1, $tab_top, $this->posxtva-1, $tab_top + $tab_height); + $pdf->SetXY ($this->posxtva-1, $tab_top+1); + $pdf->MultiCell($this->posxup-$this->posxtva-1,2, $outputlangs->transnoentities("VAT"),'','C'); + + //PU + $pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height); + $pdf->SetXY ($this->posxup-1, $tab_top+1); + $pdf->MultiCell($this->posxqty-$this->posxup-1,2, $outputlangs->transnoentities("PU"),'','C'); + + //QTY + $pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height); + $pdf->SetXY ($this->posxqty-1, $tab_top+1); + $pdf->MultiCell($this->postotalttc-$this->posxqty,2, $outputlangs->transnoentities("Q"),'','R'); + + //TOTALTTC + $pdf->line($this->postotalttc, $tab_top, $this->postotalttc, $tab_top + $tab_height); + $pdf->SetXY ($this->postotalttc-4, $tab_top+1); + $pdf->MultiCell(28,2, $outputlangs->transnoentities("TotalTTC"),'','R'); + + $pdf->SetTextColor(0,0,0); + } + + /** + * Show footer of page. Need this->emetteur object + * + * @param PDF &$pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) + { + return pdf_pagefoot($pdf,$outputlangs,'DEPLACEMENT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,0,$hidefreetext); + } + +} + diff --git a/htdocs/core/modules/modDeplacement.class.php b/htdocs/core/modules/modDeplacement.class.php index c536553ac4bcd2893912f3cbcd25a431a1826d6d..f08a346577af4cc1c59378339f00125d4ca943f1 100644 --- a/htdocs/core/modules/modDeplacement.class.php +++ b/htdocs/core/modules/modDeplacement.class.php @@ -50,7 +50,7 @@ class modDeplacement extends DolibarrModules $this->description = "Gestion des notes de frais et deplacements"; // Si traduction Module75Desc non trouvee // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'dolibarr'; + $this->version = 'dolibarr_deprecated'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); $this->special = 0; diff --git a/htdocs/core/modules/modExpenseReport.class.php b/htdocs/core/modules/modExpenseReport.class.php new file mode 100755 index 0000000000000000000000000000000000000000..54d0496a4dd4d017ecce573c7951ecd255cdee5d --- /dev/null +++ b/htdocs/core/modules/modExpenseReport.class.php @@ -0,0 +1,347 @@ +<?php +/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2004-2009 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2005-2010 Regis Houssin <regis@dolibarr.fr> + * Copyright (C) 2011 Dimitri Mouillard <dmouillard@teclib.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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \defgroup Indicateurs + * \brief Module indicateurs + * Such a file must be copied into htdocs/includes/module directory. + */ + +/** + * \file htdocs/indicateurs/core/modules/modExpenseReport.class.php + * \ingroup indicateur + * \brief Description and activation file for module ExpenseReport + */ +include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php"); + + +/** + * Description and activation class for module ExpenseReport + */ +class modExpenseReport extends DolibarrModules +{ + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param Database $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db = $db; + + // Id for module (must be unique). + // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id). + $this->numero = 770; + // Key text used to identify module (for permissions, menus, etc...) + $this->rights_class = 'deplacement'; + + // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' + // It is used to group modules in module setup page + $this->family = "hr"; + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) + $this->description = "Manage and claim expense reports (transportation, meal, ...)"; + // Possible values for version are: 'development', 'experimental', 'dolibarr' or version + $this->version = 'dolibarr'; + // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) + $this->special = 0; + // Name of image file used for this module. + // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' + // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' + $this->picto='trip'; + + // Defined if the directory /mymodule/inc/triggers/ contains triggers or not + $this->triggers = 0; + + // Data directories to create when module is enabled. + // Example: this->dirs = array("/mymodule/temp"); + $this->dirs = array(); + $r=0; + + // Relative path to module style sheet if exists. Example: '/mymodule/css/mycss.css'. + //$this->style_sheet = '/mymodule/mymodule.css.php'; + + // Config pages. Put here list of php page names stored in admmin directory used to setup module. + $this->config_page_url = array(); + + // Dependencies + $this->depends = array(); // List of modules id that must be enabled if this module is enabled +// $this->conflictwith = array("modDeplacement"); + $this->requiredby = array(); // List of modules id to disable if this one is disabled + $this->phpmin = array(4,3); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(3,0); // Minimum version of Dolibarr required by module + $this->langfiles = array("companies","trips","deplacement@deplacement"); + + // Constants + // Example: $this->const=array(0=>array('MYMODULE_MYNEWCONST1','chaine','myvalue','This is a constant to add',0), + // 1=>array('MYMODULE_MYNEWCONST2','chaine','myvalue','This is another constant to add',0) ); + // 2=>array('MAIN_MODULE_MYMODULE_NEEDSMARTY','chaine',1,'Constant to say module need smarty',0) + $this->const = array(); // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 0 or 'allentities') + + // Array to add new pages in new tabs + $this->tabs = array(); + // where entity can be + // 'thirdparty' to add a tab in third party view + // 'intervention' to add a tab in intervention view + // 'order_supplier' to add a tab in supplier order view + // 'invoice_supplier' to add a tab in supplier invoice view + // 'invoice' to add a tab in customer invoice view + // 'order' to add a tab in customer order view + // 'product' to add a tab in product view + // 'stock' to add a tab in stock view + // 'propal' to add a tab in propal view + // 'member' to add a tab in fundation member view + // 'contract' to add a tab in contract view + // 'user' to add a tab in user view + // 'group' to add a tab in group view + // 'contact' to add a tab in contact view + + + // Boxes + $this->boxes = array(); // List of boxes + $r=0; + + // Add here list of php file(s) stored in includes/boxes that contains class to show a box. + // Example: + //$this->boxes[$r][1] = "myboxa.php"; + //$r++; + //$this->boxes[$r][1] = "myboxb.php"; + //$r++; + + + // Permissions + $this->rights = array(); // Permission array used by this module + $this->rights_class = 'expensereport'; + + $this->rights[1][0] = 771; + $this->rights[1][1] = 'Read expense reports (own and his subordinates)'; + $this->rights[1][2] = 'r'; + $this->rights[1][3] = 1; + $this->rights[1][4] = 'lire'; + + $this->rights[3][0] = 772; + $this->rights[3][1] = 'Create/modify expense reports'; + $this->rights[3][2] = 'w'; + $this->rights[3][3] = 0; + $this->rights[3][4] = 'creer'; + + $this->rights[4][0] = 773; + $this->rights[4][1] = 'Delete expense reports'; + $this->rights[4][2] = 'd'; + $this->rights[4][3] = 0; + $this->rights[4][4] = 'supprimer'; + + $this->rights[2][0] = 774; + $this->rights[2][1] = 'Read all expense reports'; + $this->rights[2][2] = 'r'; + $this->rights[2][3] = 1; + $this->rights[2][4] = 'readall'; + + $this->rights[6][0] = 775; + $this->rights[6][1] = 'Approve expense reports'; + $this->rights[6][2] = 'w'; + $this->rights[6][3] = 0; + $this->rights[6][4] = 'to_validate'; + + $this->rights[7][0] = 776; + $this->rights[7][1] = 'Pay expense reports'; + $this->rights[7][2] = 'w'; + $this->rights[7][3] = 0; + $this->rights[7][4] = 'to_paid'; + + if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) + { + $this->rights[8][0] = 777; + $this->rights[8][1] = 'Synchroniser les NDF avec un compte courant'; + $this->rights[8][2] = 'w'; + $this->rights[8][3] = 0; + $this->rights[8][4] = 'synchro'; + + $this->rights[9][0] = 778; + $this->rights[9][1] = 'Exporter les NDF au format CSV'; + $this->rights[9][2] = 'r'; + $this->rights[9][3] = 0; + $this->rights[9][4] = 'export_csv'; + } + + $this->rights[5][0] = 779; + $this->rights[5][1] = 'Export expense reports'; + $this->rights[5][2] = 'r'; + $this->rights[5][3] = 0; + $this->rights[5][4] = 'export'; + + // Exports + $r=0; + + $r++; + $this->export_code[$r]='trips_'.$r; + $this->export_label[$r]='ListTripsAndExpenses'; + $this->export_permission[$r]=array(array("expensereport","export")); + $this->export_fields_array[$r]=array('d.rowid'=>"TripId",'d.type'=>"Type",'d.km'=>"FeesKilometersOrAmout",'d.note'=>'NotePrivate','d.note_public'=>'NotePublic','s.nom'=>'ThirdParty','u.lastname'=>'Lastname','u.firstname'=>'Firstname','d.dated'=>"Date"); + $this->export_entities_array[$r]=array('d.rowid'=>"Trip",'d.type'=>"Trip",'d.km'=>"Trip",'d.note'=>'Trip','d.note_public'=>'Trip','s.nom'=>'company','u.lastname'=>'user','u.firstname'=>'user','d.dated'=>"Date"); + $this->export_alias_array[$r]=array('d.rowid'=>"idtrip",'d.type'=>"type",'d.km'=>"km",'d.note'=>'note','d.note_public'=>'note_public','s.nom'=>'companyname','u.lastname'=>'name','u.firstname'=>'firstname','d.dated'=>'date'); + + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'user as u'; + $this->export_sql_end[$r] .=', '.MAIN_DB_PREFIX.'expensereport as d'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON d.fk_soc = s.rowid'; + $this->export_sql_end[$r] .=' WHERE d.fk_user = u.rowid'; + $this->export_sql_end[$r] .=' AND d.entity = '.$conf->entity; + + + + // Main menu entries + $this->menu = array(); // List of menus to add + $r=0; + + // Example to declare a Left Menu entry: fk_mainmenu=home,fk_leftmenu=modulesadmintools + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=accountancy', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry) + 'type'=>'left', // This is a Left menu entry + 'titre'=>'TripsAndExpenses', + 'mainmenu'=>'accountancy', + 'leftmenu'=>'expensereport', + 'url'=>'/expensereport/index.php', + 'langs'=>'trips', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>100, + 'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + $r++; + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=accountancy,fk_leftmenu=expensereport', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry) + 'type'=>'left', // This is a Left menu entry + 'titre'=>'New', + 'mainmenu'=>'accountancy', + 'leftmenu'=>'expensereport_detail', + 'url'=>'/expensereport/card.php?action=create', + 'langs'=>'trips', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>100, + 'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + $r++; + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=accountancy,fk_leftmenu=expensereport', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry) + 'type'=>'left', // This is a Left menu entry + 'titre'=>'List', + 'mainmenu'=>'accountancy', + 'leftmenu'=>'expensereport_detail', + 'url'=>'/expensereport/list.php', + 'langs'=>'trips', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>100, + 'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + $r++; + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=accountancy,fk_leftmenu=expensereport', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry) + 'type'=>'left', // This is a Left menu entry + 'titre'=>'Statistics', + 'mainmenu'=>'accountancy', + 'leftmenu'=>'expensereport_detail', + 'url'=>'/expensereport/stats/index.php', + 'langs'=>'trips', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>100, + 'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + $r++; + + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=accountancy,fk_leftmenu=expensereport', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry) + 'type'=>'left', // This is a Left menu entry + 'titre'=>'ExportTripCSV', + 'mainmenu'=>'accountancy', + 'leftmenu'=>'expensereport_detail', + 'url'=>'/expensereport/export_csv.php', + 'langs'=>'expensereport', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>100, + 'enabled'=>'$conf->global->DEPLACEMENT_TO_CLEAN', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + $r++; + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=accountancy,fk_leftmenu=expensereport', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry) + 'type'=>'left', // This is a Left menu entry + 'titre'=>'Synchro_Compta', + 'mainmenu'=>'accountancy', + 'leftmenu'=>'expensereport_detail', + 'url'=>'/expensereport/synchro_compta.php', + 'langs'=>'expensereport', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. + 'position'=>100, + 'enabled'=>'$conf->global->DEPLACEMENT_TO_CLEAN', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. + 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules + 'target'=>'', + 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both + $r++; + } + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories. + * + * @param string $options Options + * @return int 1 if OK, 0 if KO + */ + function init($options='') + { + global $conf; + + $this->remove($options); + + $result=$this->_load_tables('/deplacement/sql/'); + + $sql = array( + "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'teclib' AND entity = ".$conf->entity, + "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('teclib','deplacement',".$conf->entity.")" + ); + + return $this->_init($sql,$options); + } + + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted. + * + * @param string Options + * @return int 1 if OK, 0 if KO + */ + function remove($options='') + { + $sql = array(); + + return $this->_remove($sql,$options); + } + +} + diff --git a/htdocs/expensereport/ajax/ajaxprojet.php b/htdocs/expensereport/ajax/ajaxprojet.php new file mode 100755 index 0000000000000000000000000000000000000000..0ab755433095ad3fdec8e3e94e90e71feb0196ad --- /dev/null +++ b/htdocs/expensereport/ajax/ajaxprojet.php @@ -0,0 +1,88 @@ +<?php +/* Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr> + * Copyright (C) 2005-2009 Regis Houssin <regis@dolibarr.fr> + * Copyright (C) 2007-2010 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2010 Cyrille de Lambert <info@auguria.net> + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file htdocs/expensereport/ajax/ajaxprojet.php + * \brief File to return Ajax response on third parties request + */ + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); + +$res=0; +require '../../main.inc.php'; + + +/* + * View + */ + +// Ajout directives pour resoudre bug IE +//header('Cache-Control: Public, must-revalidate'); +//header('Pragma: public'); + +//top_htmlhead("", "", 1); // Replaced with top_httphead. An ajax page does not need html header. +top_httphead(); + +//print '<!-- Ajax page called with url '.$_SERVER["PHP_SELF"].'?'.$_SERVER["QUERY_STRING"].' -->'."\n"; + +dol_syslog(join(',',$_GET)); + + +// Generation liste des projets +if (GETPOST('fk_projet') != '') +{ + $return_arr = array(); + + $sql = "SELECT p.rowid, p.ref, p.title, s.nom"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; + if (! empty($_GET["fk_projet"])) $sql.= " WHERE p.ref LIKE '%".$db->escape($_GET["fk_projet"])."%' OR p.title LIKE '%".$db->escape($_GET["fk_projet"])."%' OR s.nom LIKE '%".$db->escape($_GET["fk_projet"])."%'"; // Add other filters + $sql.= " ORDER BY p.ref ASC"; + + $resql=$db->query($sql); + if ($resql) + { + while ($row = $db->fetch_array($resql)) + { + $label=$row['ref'].' - '.$row['title']; + $row_array['label'] = $label; + $row_array['value'] = $label; + $row_array['key'] = $row['rowid']; + + array_push($return_arr,$row_array); + } + + echo json_encode($return_arr); + } + else + { + echo json_encode(array('nom'=>'Error','label'=>'Error','key'=>'Error','value'=>'Error')); + } +} +else +{ + echo json_encode(array('nom'=>'ErrorBadParameter','label'=>'ErrorBadParameter','key'=>'ErrorBadParameter','value'=>'ErrorBadParameter')); +} diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php new file mode 100755 index 0000000000000000000000000000000000000000..7d52ac5b538e0ef490fb5ad1f88a56ab51d50e87 --- /dev/null +++ b/htdocs/expensereport/card.php @@ -0,0 +1,1776 @@ +<?php +/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2005-2009 Regis Houssin <regis@dolibarr.fr> + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file htdocs/expensereport/card.php + * \brief Page for trip and expense card + */ + +$res=0; +require '../main.inc.php'; +require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php"); +require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'); +require_once(DOL_DOCUMENT_ROOT."/core/class/html.formmail.class.php"); +require_once(DOL_DOCUMENT_ROOT."/core/class/html.formprojet.class.php"); +require_once(DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/trip.lib.php"); +dol_include_once('/expensereport/core/modules/expensereport/modules_expensereport.php'); +dol_include_once("/expensereport/class/expensereport.class.php"); + +$langs->load("trips"); + +$action=GETPOST('action'); +$date_start = dol_mktime(0, 0, 0, GETPOST('date_debutmonth'), GETPOST('date_debutday'), GETPOST('date_debutyear')); +$date_end = dol_mktime(0, 0, 0, GETPOST('date_finmonth'), GETPOST('date_finday'), GETPOST('date_finyear')); + + +// If socid provided by ajax company selector +if (! empty($_REQUEST['socid_id'])) +{ + $_GET['socid'] = $_GET['socid_id']; + $_POST['socid'] = $_POST['socid_id']; + $_REQUEST['socid'] = $_REQUEST['socid_id']; +} + +// Security check +$id=GETPOST("id",'int'); +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expensereport', 0, 'expensereport'); + +$mesg=""; + + +// Hack to use expensereport dir +$rootfordata = DOL_DATA_ROOT; +$rootforuser = DOL_DATA_ROOT; +// If multicompany module is enabled, we redefine the root of data +if (! empty($conf->multicompany->enabled) && ! empty($conf->entity) && $conf->entity > 1) +{ + $rootfordata.='/'.$conf->entity; +} +$conf->expensereport->dir_output = $rootfordata.'/expensereport'; +$conf->expensereport->dir_output = $rootfordata.'/expensereport'; + + + +/* + * Actions + */ + +if ($action == 'confirm_delete' && $_GET["confirm"] == "yes" && $id > 0 && $user->rights->expensereport->supprimer) +{ + $object = new ExpenseReport($db); + $result=$object->delete($id); + if ($result >= 0) + { + header("Location: index.php"); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +if ($action == 'add' && $user->rights->expensereport->creer) +{ + $object = new ExpenseReport($db); + + $object->date_debut = $date_start; + $object->date_fin = $date_end; + + $object->fk_user_validator = GETPOST('fk_user_validator','int'); + $object->fk_c_expensereport_statuts = 1; + $object->fk_c_paiement = GETPOST('fk_c_paiement','int'); + $object->note = GETPOST('note'); + + if ($object->periode_existe($user,dol_print_date($object->date_debut, 'dayrfc'),dol_print_date($object->date_fin, 'dayrfc'))) + { + setEventMessage($langs->trans("ErrorDoubleDeclaration"),'errors'); + $action='create'; + } + else + { + $db->begin(); + + $id = $object->create($user); + + if ($id > 0) + { + $db->commit(); + Header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + $db->rollback(); + $action='create'; + } + } +} + +if ($action == 'update' && $user->rights->expensereport->creer) +{ + $object = new ExpenseReport($db); + $object->fetch($_POST['id'],$user); + + $object->date_debut = $date_start; + $object->date_fin = $date_end; + + if($object->fk_c_expensereport_statuts < 3) + { + $object->fk_user_validator = GETPOST('fk_user_validator','int'); + } + + $object->fk_c_paiement = GETPOST('fk_c_paiement','int'); + $object->note = GETPOST('note'); + + $result = $object->update($user); + if ($result > 0) + { + header("Location: ".$_SEVER["PHP_SELF"]."?id=".$_POST['id']); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +if ($action == "confirm_save" && GETPOST("confirm") == "yes" && $id > 0 && $user->rights->expensereport->creer) +{ + $object = new ExpenseReport($db); + $object->fetch($id,$user); + $result = $object->set_save($user); + if ($result > 0) + { + // Send mail + if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) + { + // Send mail + + // TO + $destinataire = new User($db); + $destinataire->fetch($object->fk_user_validator); + $emailTo = $destinataire->email; + + // FROM + $expediteur = new User($db); + $expediteur->fetch($object->fk_user_author); + $emailFrom = $expediteur->email; + + // SUBJECT + $subject = "' ERP - Note de frais à valider"; + + // CONTENT + $message = "Bonjour {$destinataire->firstname},\n\n"; + $message.= "Veuillez trouver en pièce jointe une nouvelle note de frais à valider.\n"; + $message.= "- Déclarant : {$expediteur->firstname} {$expediteur->lastname}\n"; + $message.= "- Période : du {$object->date_debut} au {$object->date_fin}\n"; + $message.= "- Lien : {$dolibarr_main_url_root}/expensereport/card.php?id={$object->id}\n\n"; + $message.= "Bien cordialement,\n' SI"; + + // Génération du pdf avant attachement + $object->setDocModel($user,""); + $resultPDF = expensereport_pdf_create($db,$id,'',"",$langs); + + if($resultPDF): + // ATTACHMENT + $filename=array(); $filedir=array(); $mimetype=array(); + array_push($filename,dol_sanitizeFileName($object->ref_number).".pdf"); + array_push($filedir,$conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref_number) . "/" . dol_sanitizeFileName($object->ref_number).".pdf"); + array_push($mimetype,"application/pdf"); + + // PREPARE SEND + $mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename); + + if(!$mailfile->error): + + // SEND + $result=$mailfile->sendfile(); + if ($result): + Header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + exit; + endif; + + else: + + $mesg="Impossible d'envoyer l'email."; + + endif; + // END - Send mail + else: + dol_print_error($db,$resultPDF); + exit; + endif; + } + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +if ($action == "confirm_save_from_refuse" && $_GET["confirm"] == "yes" && $id > 0 && $user->rights->expensereport->creer) +{ + $object = new ExpenseReport($db); + $object->fetch($id,$user); + $result = $object->set_save_from_refuse($user); + if ($result > 0) + { + // Send mail + if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) + { + // TO + $destinataire = new User($db); + $destinataire->fetch($object->fk_user_validator); + $emailTo = $destinataire->email; + + // FROM + $expediteur = new User($db); + $expediteur->fetch($object->fk_user_author); + $emailFrom = $expediteur->email; + + // SUBJECT + $subject = "' ERP - Note de frais à re-approuver"; + + // CONTENT + $dateRefusEx = explode(" ",$object->date_refuse); + + $message = "Bonjour {$destinataire->firstname},\n\n"; + $message.= "Le {$dateRefusEx[0]} à {$dateRefusEx[1]} vous avez refusé d'approuver la note de frais \"{$object->ref_number}\". Vous aviez émis le motif suivant : {$object->detail_refuse}\n\n"; + $message.= "L'auteur vient de modifier la note de frais, veuillez trouver la nouvelle version en pièce jointe.\n"; + $message.= "- Déclarant : {$expediteur->firstname} {$expediteur->lastname}\n"; + $message.= "- Période : du {$object->date_debut} au {$object->date_fin}\n"; + $message.= "- Lien : {$dolibarr_main_url_root}/expensereport/card.php?id={$object->id}\n\n"; + $message.= "Bien cordialement,\n' SI"; + + // Génération du pdf avant attachement + $object->setDocModel($user,""); + $resultPDF = expensereport_pdf_create($db,$id,'',"",$langs); + + if($resultPDF): + // ATTACHMENT + $filename=array(); $filedir=array(); $mimetype=array(); + array_push($filename,dol_sanitizeFileName($object->ref_number).".pdf"); + array_push($filedir,$conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref_number) . "/" . dol_sanitizeFileName($object->ref_number).".pdf"); + array_push($mimetype,"application/pdf"); + + // PREPARE SEND + $mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename); + + if(!$mailfile->error): + + // SEND + $result=$mailfile->sendfile(); + if ($result): + Header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + exit; + endif; + + else: + + $mesg="Impossible d'envoyer l'email."; + + endif; + // END - Send mail + else: + dol_print_error($db,$resultPDF); + exit; + endif; + } + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +// Approve +if ($action == "confirm_validate" && GETPOST("confirm") == "yes" && $id > 0 && $user->rights->expensereport->to_validate) +{ + $object = new ExpenseReport($db); + $object->fetch($id,$user); + + $result = $object->set_valide($user); + if ($result > 0) + { + if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) + { + $object = new ExpenseReport($db); + $object->fetch($id,$user); + + // Send mail + + // TO + $destinataire = new User($db); + $destinataire->fetch($object->fk_user_author); + $emailTo = $destinataire->email; + + // CC + $emailCC = $conf->global->NDF_CC_EMAILS; + + // FROM + $expediteur = new User($db); + $expediteur->fetch($object->fk_user_valid); + $emailFrom = $expediteur->email; + + // SUBJECT + $subject = "' ERP - Note de frais validée"; + + // CONTENT + $message = "Bonjour {$destinataire->firstname},\n\n"; + $message.= "Votre note de frais \"{$object->ref_number}\" vient d'être approuvé!\n"; + $message.= "- Approbateur : {$expediteur->firstname} {$expediteur->lastname}\n"; + $message.= "- Lien : {$dolibarr_main_url_root}/expensereport/card.php?id={$object->id}\n\n"; + $message.= "Bien cordialement,\n' SI"; + + // Génération du pdf avant attachement + $object->setDocModel($user,""); + $resultPDF = expensereport_pdf_create($db,$id,'',"",$langs); + + if($resultPDF): + // ATTACHMENT + $filename=array(); $filedir=array(); $mimetype=array(); + array_push($filename,dol_sanitizeFileName($object->ref_number).".pdf"); + array_push($filedir, $conf->expensereport->dir_output. + "/". + dol_sanitizeFileName($object->ref_number) . + "/". + dol_sanitizeFileName($object->ref_number). + ".pdf" + ); + array_push($mimetype,"application/pdf"); + + // PREPARE SEND + $mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename,$emailCC); + + if(!$mailfile->error): + + // SEND + $result=$mailfile->sendfile(); + if ($result): + setEventMessage($langs->trans("MailSuccessfulySent",$emailFrom,$emailTo)); + Header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + exit; + else: + setEventMessage($langs->trans("ErrorFailedToSendMail",$emailFrom,$emailTo),'errors'); + endif; + + else: + setEventMessage($langs->trans("ErrorFailedToSendMail",$emailFrom,$emailTo),'errors'); + endif; + // END - Send mail + else : // if ($resultPDF) + dol_print_error($db,$resultPDF); + exit; + endif; + } + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +if ($action == "confirm_refuse" && $_POST['confirm']=="yes" && !empty($_POST['detail_refuse']) && $id > 0 && $user->rights->expensereport->to_validate) +{ + $object = new ExpenseReport($db); + $object->fetch($id,$user); + + $result = $object->set_refuse($user,$_POST['detail_refuse']); + if ($result > 0) + { + if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) + { + $object = new ExpenseReport($db); + $object->fetch($id,$user); + + // Send mail + + // TO + $destinataire = new User($db); + $destinataire->fetch($object->fk_user_author); + $emailTo = $destinataire->email; + + // FROM + $expediteur = new User($db); + $expediteur->fetch($object->fk_user_refuse); + $emailFrom = $expediteur->email; + + // SUBJECT + $subject = "' ERP - Note de frais refusée"; + + // CONTENT + $message = "Bonjour {$destinataire->firstname},\n\n"; + $message.= "Votre note de frais \"{$object->ref_number}\" vient d'être refusée.\n"; + $message.= "- Refuseur : {$expediteur->firstname} {$expediteur->lastname}\n"; + $message.= "- Motif de refus : {$_POST['detail_refuse']}\n"; + $message.= "- Lien : {$dolibarr_main_url_root}/expensereport/card.php?id={$object->id}\n\n"; + $message.= "Bien cordialement,\n' SI"; + + // PREPARE SEND + $mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message); + + if(!$mailfile->error) + { + // SEND + $result=$mailfile->sendfile(); + if ($result) + { + setEventMessage($langs->trans("MailSuccessfulySent",$emailFrom,$emailTo)); + Header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + exit; + } + else + { + setEventMessage($langs->trans("ErrorFailedToSendMail",$emailFrom,$emailTo),'errors'); + $mesg="Impossible d'envoyer l'email."; + } + // END - Send mail + } + } + } + else + { + setEventMessage($object->error, $object->errors); + } +} + +if ($action == "confirm_cancel" && GETPOST('confirm')=="yes" && !empty($_POST['detail_cancel']) && $id > 0 && $user->rights->expensereport->to_validate) +{ + $object = new ExpenseReport($db); + $object->fetch($id,$user); + if($user->id == $object->fk_user_validator) + { + $result = $object->set_cancel($user,$_POST['detail_cancel']); + + if ($result > 0) + { + if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) + { + $object = new ExpenseReport($db); + $object->fetch($id,$user); + + // Send mail + + // TO + $destinataire = new User($db); + $destinataire->fetch($object->fk_user_author); + $emailTo = $destinataire->email; + + // FROM + $expediteur = new User($db); + $expediteur->fetch($object->fk_user_cancel); + $emailFrom = $expediteur->email; + + // SUBJECT + $subject = "' ERP - Note de frais annulée"; + + // CONTENT + $message = "Bonjour {$destinataire->firstname},\n\n"; + $message.= "Votre note de frais \"{$object->ref_number}\" vient d'être annulée.\n"; + $message.= "- Annuleur : {$expediteur->firstname} {$expediteur->lastname}\n"; + $message.= "- Motif d'annulation : {$_POST['detail_cancel']}\n"; + $message.= "- Lien : {$dolibarr_main_url_root}/expensereport/card.php?id={$object->id}\n\n"; + $message.= "Bien cordialement,\n' SI"; + + // PREPARE SEND + $mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message); + + if(!$mailfile->error) + { + // SEND + $result=$mailfile->sendfile(); + if ($result) + { + header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + exit; + } + else + { + $mesg="Impossible d'envoyer l'email."; + } + // END - Send mail + } + else + { + setEventMessages($mail->error, $mail->errors, 'errors'); + } + } + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + else + { + setEventMessages($langs->transnoentitiesnoconv("NOT_VALIDATOR"), '', 'errors'); + } +} + +if ($action == "confirm_paid" && $_GET['confirm']=="yes" && $id > 0 && $user->rights->expensereport->to_paid) +{ + $object = new ExpenseReport($db); + $object->fetch($id,$user); + $result = $object->set_paid($user); + if ($result > 0) + { + if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) + { + $object = new ExpenseReport($db); + $object->fetch($id,$user); + + // Send mail + + // TO + $destinataire = new User($db); + $destinataire->fetch($object->fk_user_author); + $emailTo = $destinataire->email; + + // FROM + $expediteur = new User($db); + $expediteur->fetch($object->fk_user_paid); + $emailFrom = $expediteur->email; + + // SUBJECT + $subject = "' ERP - Note de frais payée"; + + // CONTENT + $message = "Bonjour {$destinataire->firstname},\n\n"; + $message.= "Votre note de frais \"{$object->ref_number}\" vient d'être payée.\n"; + $message.= "- Payeur : {$expediteur->firstname} {$expediteur->lastname}\n"; + $message.= "- Lien : {$dolibarr_main_url_root}/expensereport/card.php?id={$object->id}\n\n"; + $message.= "Bien cordialement,\n' SI"; + + // Génération du pdf avant attachement + $object->setDocModel($user,""); + $resultPDF = expensereport_pdf_create($db,$id,'',"",$langs); + + // PREPARE SEND + $mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message); + + if(!$mailfile->error): + + // SEND + $result=$mailfile->sendfile(); + if ($result): + // Insert écriture dans le compte courant + $idTrip = $id; + $idAccount = 1; + + $object = new ExpenseReport($db); + $object->fetch($idTrip,$user); + + $datePaiement = explode("-",$object->date_paiement); + + $dateop = dol_mktime(12,0,0,$datePaiement[1],$datePaiement[2],$datePaiement[0]); + $operation = $object->code_paiement; + $label = "Règlement ".$object->ref_number; + $amount = - price2num($object->total_ttc); + $num_chq = ''; + $cat1 = ''; + + $user = new User($db); + $user->fetch($object->fk_user_paid); + + $acct=new Account($db,$idAccount); + $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, $cat1, $user); + + if ($insertid > 0): + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql.= " SET integration_compta = 1, fk_bank_account = $idAccount"; + $sql.= " WHERE rowid = $idTrip"; + $resql=$db->query($sql); + if($result): + Header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + exit; + else: + dol_print_error($db); + endif; + else: + dol_print_error($db,$acct->error); + endif; + endif; + + else: + + $mesg="Impossible d'envoyer l'email."; + + endif; + // END - Send mail + } + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +if ($action == "confirm_brouillonner" && $_GET['confirm']=="yes" && $id > 0 && $user->rights->expensereport->creer) +{ + $object = new ExpenseReport($db); + $object->fetch($id,$user); + if($user->id == $object->fk_user_author OR $user->id == $object->fk_user_validator) + { + $result = $object->set_draft($user); + if ($result > 0) + { + header("Location: ".$_SEVER["PHP_SELF"]."?id=".$id); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + else + { + setEventMessages($langs->transnoentitiesnoconv("NOT_AUTHOR"), '', 'errors'); + } +} + +if ($action == "addline") +{ + $db->begin(); + + $object_ligne = new ExpenseReportLigne($db); + + $object_ligne->comments = empty($_POST['comments'])?"Aucun commentaire.":$_POST['comments']; + $object_ligne->qty = empty($_POST['qty'])?1:$_POST['qty']; + + // Convertion de "," en "." dans le nombre entré dans le champ + if(preg_match("#,#",$_POST['value_unit'])) + { + $object_ligne->value_unit = preg_replace("#,#",".",$_POST['value_unit']); + } + else + { + $object_ligne->value_unit = $_POST['value_unit']; + } + + $object_ligne->value_unit = number_format($object_ligne->value_unit,3,'.',''); + + $date = explode("/",$_POST['date']); + $object_ligne->date = $date[2]."-".$date[1]."-".$date[0]; + + $object_ligne->fk_c_type_fees = empty($_POST['fk_c_type_fees'])?1:$_POST['fk_c_type_fees']; + + // Get tax id from rate + $tva_tx=GETPOST('fk_c_tva'); + $sql = "SELECT t.rowid, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; + $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as p"; + $sql .= " WHERE t.fk_pays = p.rowid AND p.code = '".$mysoc->country_code."'"; + $sql .= " AND t.taux = ".$db->escape($tva_tx)." AND t.active = 1"; + + dol_syslog("get_localtax sql=".$sql); + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + $tva=$obj->rowid; + } + else dol_print_error($db); + + // Force la TVA à 0% lorsque c'est du transport + if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) + { + if ($object_ligne->fk_c_type_fees==10) + { + $tva = 15; // TODO A virer le hardcoding + } + } + + $object_ligne->fk_c_tva = $tva; + + $object_ligne->fk_projet = $_POST['fk_projet']; + + // Tests des données rentrées + $error = false; + + // Si aucun projet n'est défini + if (empty($object_ligne->fk_projet) || $object_ligne->fk_projet==-1) + { + $error = true; + $text_error[] = "NO_PROJECT"; + } + + // Si aucune date n'est rentrée + if($object_ligne->date=="--"): + $error = true; + $text_error[] = "NO_DATE"; + endif; + + // Si aucun prix n'est rentré + if($object_ligne->value_unit==0): + $error = true; + $text_error[] = "NO_PRICE"; + endif; + + // S'il y'a eu au moins une erreur + if($error) + { + $mesg = implode(",",$text_error); + Header("Location: ".$_SERVER["PHP_SELF"]."?id=".$_POST['fk_expensereport']."&mesg=$mesg"); + exit; + } + else + { + $object_ligne->fk_expensereport = $_POST['fk_expensereport']; + + $object_ligne->fetch_taux($object_ligne->fk_c_tva); + + // Calculs des totos + $object_ligne->total_ttc = $object_ligne->value_unit * $object_ligne->qty; + $object_ligne->total_ttc = number_format($object_ligne->total_ttc,2,'.',''); + + $tx_tva = $object_ligne->tva_taux/100; + $tx_tva = $tx_tva + 1; + + $object_ligne->total_ht = $object_ligne->total_ttc / $tx_tva; + $object_ligne->total_ht = number_format($object_ligne->total_ht,2,'.',''); + + $object_ligne->total_tva = $object_ligne->total_ttc - $object_ligne->total_ht; + // Fin calculs des totos + + $result = $object_ligne->insert(); + if ($result > 0) + { + $object = new ExpenseReport($db); + $object->fetch($_POST['fk_expensereport'],$user); + $object->update_totaux_add($object_ligne->total_ht,$object_ligne->total_tva); + + $db->commit(); + Header("Location: ".$_SERVER["PHP_SELF"]."?id=".$_POST['fk_expensereport']); + exit; + } + else + { + dol_print_error($db,$object->error); + $db->rollback(); + exit; + } + } +} + +if ($action == 'confirm_delete_line' && $_POST["confirm"] == "yes") +{ + $object = new ExpenseReport($db); + $object->fetch($_GET["id"],$user); + + $object_ligne = new ExpenseReportLigne($db); + $object_ligne->fetch($_GET["rowid"]); + $total_ht = $object_ligne->total_ht; + $total_tva = $object_ligne->total_tva; + + $result=$object->deleteline($_GET["rowid"]); + if ($result >= 0) + { + $object->update_totaux_del($object_ligne->total_ht,$object_ligne->total_tva); + header("Location: ".$_SERVER["PHP_SELF"]."?id=".$_GET['id']); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +if ($action == "updateligne" ) +{ + $object = new ExpenseReport($db); + + $object_id = GETPOST('id','int'); + $object->fetch($object_id,$user); + + $rowid = $_POST['rowid']; + $type_fees_id = empty($_POST['fk_c_type_fees'])?1:$_POST['fk_c_type_fees']; + + // Get tax id from rate + $tva_tx=GETPOST('fk_c_tva'); + $sql = "SELECT t.rowid, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; + $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as p"; + $sql .= " WHERE t.fk_pays = p.rowid AND p.code = '".$mysoc->country_code."'"; + $sql .= " AND t.taux = ".$db->escape($tva_tx)." AND t.active = 1"; + + dol_syslog("get_localtax sql=".$sql); + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + $c_tva=$obj->rowid; + } + else dol_print_error($db); + + // Force la TVA à 0% lorsque c'est du transport + if ($type_fees_id==10) + { + $c_tva = 15; + } + + $object_ligne->fk_c_tva = $c_tva; + $projet_id = $_POST['fk_projet']; + $comments = $_POST['comments']; + $qty = $_POST['qty']; + + // Convertion de "," en "." dans le nombre entré dans le champ + if(preg_match("#,#",$_POST['value_unit'])): + $value_unit = preg_replace("#,#",".",$_POST['value_unit']); + else: + $value_unit = $_POST['value_unit']; + endif; + + $date = explode("/",$_POST['date']); + $date = $date[2]."-".$date[1]."-".$date[0]; + + $result = $object->updateline($rowid, $type_fees_id, $projet_id, $c_tva, $comments, $qty, $value_unit, $date, $object_id); + if ($result >= 0) + { + $object->recalculer($object_id); + header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object_id); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +if ($action == "recalc" && $id > 0) +{ + $object = new ExpenseReport($db); + $object->fetch($id); + if($object->recalculer($id) > 0) + { + header("Location: ".$_SERVER["PHP_SELF"]."?id=".$_GET['id']); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } +} + +/* + * Generer ou regenerer le document PDF + */ +if ($action == 'builddoc') // En get ou en post +{ + $depl = new ExpenseReport($db, 0, $_GET['id']); + $depl->fetch($_GET['id'],$user); + + if ($_REQUEST['model']) + { + $depl->setDocModel($user, $_REQUEST['model']); + } + + $outputlangs = $langs; + if (! empty($_REQUEST['lang_id'])) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + $result=expensereport_pdf_create($db, $depl->id, '', $depl->modelpdf, $outputlangs); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + else + { + Header('Location: '.$_SERVER["PHP_SELF"].'?id='.$depl->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); + exit; + } +} + +// Remove file in doc form +else if ($action == 'remove_file') +{ + $object = new ExpenseReport($db, 0, $_GET['id']); + if ($object->fetch($id)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $object->fetch_thirdparty(); + + $langs->load("other"); + $upload_dir = $conf->expensereport->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + $action=''; + } +} + + +/* + * View + */ + +llxHeader(); + +$html = new Form($db); +$formfile = new FormFile($db); +$form = new Form($db); +$formproject = new FormProjets($db); + +if (! empty($conf->global->DEPLACEMENT_TO_CLEAN)) +{ + if(!empty($_GET['mesg'])) + { + $text_mesg = explode(",",$_GET['mesg']); + + foreach($text_mesg as $text) + { + $mesg.= "- ".$langs->trans($text)."<br />"; + } + + print "<div class=\"error\" style=\"font-size:15px;background-color:#FFB3B3;\">"; + print $langs->trans("LINE_NOT_ADDED")."<br />"; + print $mesg; + print "</div>"; + } + else + { + if ($mesg) print "<div class=\"error\" style=\"font-size:16px;background-color:red;\">".$mesg."</div>"; + } +} + + +/* + * Create + */ + +if ($action == 'create') +{ + print print_fiche_titre($langs->trans("NewTrip")); + + print '<form action="'.$_SERVER['PHP_SELF'].'" method="post" name="create">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="add">'; + + dol_fiche_head(''); + + print '<table class="border" width="100%">'; + print '<tbody>'; + print '<tr>'; + print '<td>'.$langs->trans("DateStart").'</td>'; + print '<td>'; + $html->select_date($date_start?$date_start:-1,'date_debut',0,0,0,'',1,1); + print '</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'.$langs->trans("DateEnd").'</td>'; + print '<td>'; + $html->select_date($date_end?$date_end:-1,'date_fin',0,0,0,'',1,1); + print '</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'.$langs->trans("VALIDATOR").'</td>'; + print '<td>'; + $object = new ExpenseReport($db); + $include_users = $object->fetch_users_approver_expensereport(); + $s=$html->select_dolusers((GETPOST('fk_user_validator')?GETPOST('fk_user_validator'):$conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR), "fk_user_validator", 1, "", 0, $include_users); + print $html->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate")); + print '</td>'; + print '</tr>'; + if (! empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) + { + print '<tr>'; + print '<td>'.$langs->trans("ModePaiement").'</td>'; + print '<td>'; + $html->select_types_paiements(2,'fk_c_paiement'); + print '</td>'; + print '</tr>'; + } + print '<tr>'; + print '<td>'.$langs->trans("Note").'</td>'; + print '<td>'; + print '<textarea name="note" class="flat" rows="'.ROWS_3.'" cols="100">'.GETPOST('note').'</textarea>'; + print '</td>'; + print '</tr>'; + print '<tbody>'; + print '</table>'; + + dol_fiche_end(); + + print '<center>'; + print '<input type="submit" value="'.$langs->trans("AddTrip").'" name="bouton" class="button" />'; + print ' <input type="button" value="'.$langs->trans("Cancel").'" class="button" onclick="history.go(-1)" />'; + print '</center>'; + + print '</form>'; +} +else +{ + if($id > 0) + { + $object = new ExpenseReport($db); + $result = $object->fetch($id,$user); + + if($result) + { + if ($object->fk_user_author != $user->id) + { + if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)) + { + print_fiche_titre($langs->trans('TripCard')); + + print '<div class="tabBar">'; + print $langs->trans('NotUserRightToView'); + print '</div>'; + + $db->close(); + + llxFooter(); + + exit; + } + } + + //$head = trip_prepare_head($object); + + $head[0][0] = $_SERVER['PHP_SELF'].'?id='.$object->id; + $head[0][1] = $langs->trans('Card'); + $head[0][2] = 'card'; + $h++; + + dol_fiche_head($head, 'card', $langs->trans("TripCard"), 0, 'trip'); + + if ($action == 'edit' && ($object->fk_c_expensereport_statuts < 3 || $object->fk_c_expensereport_statuts==99)) + { + print "<form name='update' action=\"".$_SERVER['PHP_SELF']."\" method=\"post\">\n"; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + + if($object->fk_c_expensereport_statuts==99) + { + print '<input type="hidden" name="action" value="updateFromRefuse">'; + } + else + { + print '<input type="hidden" name="action" value="update">'; + } + + print '<input type="hidden" name="id" value="'.$id.'">'; + + + print '<table class="border" style="width:100%;">'; + + $linkback = '<a href="'.DOL_URL_ROOT.'/expensereport/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>'; + + // Ref + print '<tr><td width="25%">'.$langs->trans("Ref").'</td><td>'; + print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'ref', ''); + print '</td></tr>'; + + print '<tr>'; + print '<td>'.$langs->trans("DateStart").'</td>'; + print '<td>'; + $html->select_date($object->date_debut,'date_debut'); + print '</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'.$langs->trans("DateEnd").'</td>'; + print '<td>'; + $html->select_date($object->date_fin,'date_fin'); + print '</td>'; + print '</tr>'; + + if (! empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) + { + print '<tr>'; + print '<td>'.$langs->trans("ModePaiement").'</td>'; + print '<td>'; + $html->select_types_paiements($object->fk_c_paiement,'fk_c_paiement'); + print '</td>'; + print '</tr>'; + } + + if($object->fk_c_expensereport_statuts<3) + { + print '<tr>'; + print '<td>'.$langs->trans("VALIDATOR").'</td>'; + print '<td>'; + $include_users = $object->fetch_users_approver_expensereport(); + $s=$html->select_dolusers($object->fk_user_validator,"fk_user_validator",0,"",0,$include_users); + print $html->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate")); + print '</td>'; + print '</tr>'; + } + else + { + print '<tr>'; + print '<td>'.$langs->trans("VALIDOR").'</td>'; + print '<td>'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_valid); + print $userfee->getNomUrl(1); + print '</td></tr>'; + } + + print '<tr>'; + print '<td>'.$langs->trans("AUTHOR").'</td>'; + print '<td>'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_author); + print $userfee->getNomUrl(1); + print '</td></tr>'; + if ($object->fk_c_expensereport_statuts==6) + { + print '<tr>'; + print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>'; + print '<td>'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_paid); + print $userfee->getNomUrl(1); + print '</td></tr>'; + + } + print '<tr>'; + print '<td>'.$langs->trans("Note").'</td>'; + print '<td>'; + print '<textarea name="note" class="flat" rows="1" cols="70">'.$object->note.'</textarea>'; + print '</td>'; + print '</tr>'; + print '</table>'; + + print '<br><div class="center">'; + print '<input type="submit" value="'.$langs->trans("Modify").'" name="bouton" class="button"> '; + print '<input type="button" value="'.$langs->trans("CancelAddTrip").'" class="button" onclick="history.go(-1)" />'; + print '</div>'; + + print '</form>'; + + } + else + { + + if ($action == 'save'): + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_save","","",1); + if ($ret == 'html') print '<br>'; + endif; + + if ($action == 'save_from_refuse'): + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_save_from_refuse","","",1); + if ($ret == 'html') print '<br>'; + endif; + + if ($action == 'delete'): + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteTrip"),$langs->trans("ConfirmDeleteTrip"),"confirm_delete","","",1); + if ($ret == 'html') print '<br>'; + endif; + + if ($action == 'validate'): + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("ValideTrip"),$langs->trans("ConfirmValideTrip"),"confirm_validate","","",1); + if ($ret == 'html') print '<br>'; + endif; + + if ($action == 'paid'): + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("PaidTrip"),$langs->trans("ConfirmPaidTrip"),"confirm_paid","","",1); + if ($ret == 'html') print '<br>'; + endif; + + if ($action == 'cancel'): + $array_input = array(array('type'=>"text",'label'=>"Entrez ci-dessous un motif d'annulation :",'name'=>"detail_cancel",'size'=>"50",'value'=>"")); + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("ConfirmCancelTrip"),"","confirm_cancel",$array_input,"",0); + if ($ret == 'html') print '<br>'; + endif; + + if ($action == 'brouillonner'): + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("BrouillonnerTrip"),$langs->trans("ConfirmBrouillonnerTrip"),"confirm_brouillonner","","",1); + if ($ret == 'html') print '<br>'; + endif; + + if ($action == 'refuse'): + $array_input = array(array('type'=>"text",'label'=>"Entrez ci-dessous un motif de refus :",'name'=>"detail_refuse",'size'=>"50",'value'=>"")); + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("ConfirmRefuseTrip"),"","confirm_refuse",$array_input,"yes",0); + if ($ret == 'html') print '<br>'; + endif; + + if ($action == 'delete_line') + { + $ret=$html->form_confirm($_SEVER["PHP_SELF"]."?id=".$_GET['id']."&rowid=".$_GET['rowid'],$langs->trans("DeleteLine"),$langs->trans("ConfirmDeleteLine"),"confirm_delete_line"); + if ($ret == 'html') print '<br>'; + } + + print '<table class="border centpercent">'; + + $linkback = '<a href="'.DOL_URL_ROOT.'/expensereport/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>'; + + // Ref + print '<tr><td width="25%">'.$langs->trans("Ref").'</td><td>'; + print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'ref', ''); + print '</td></tr>'; + + print '<tr>'; + print '<td>'.$langs->trans("Periode").'</td>'; + print '<td>'; + print get_date_range($object->date_debut,$object->date_fin,'',$langs,0); + print '</td>'; + print '</tr>'; + if (! empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) + { + print '<tr>'; + print '<td>'.$langs->trans("ModePaiement").'</td>'; + print '<td>'.$object->libelle_paiement.'</td>'; + print '</tr>'; + } + print '<tr>'; + print '<td>'.$langs->trans("Statut").'</td>'; + print '<td style="font-weight:bold;">'.$object->libelle_statut.'</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'.$langs->trans("Note").'</td>'; + print '<td>'.$object->note.'</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'.$langs->trans("AmountHT").'</td>'; + print '<td>'.price($object->total_ht).'</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'.$langs->trans("AmountVAT").'</td>'; + print '<td>'.price($object->total_tva).'</td>'; + print '</tr>'; + print '<tr>'; + print '<td>'.$langs->trans("AmountTTC").'</td>'; + print '<td>'.price($object->total_ttc).'</td>'; + print '</tr>'; + + if($object->fk_c_expensereport_statuts<3) + { + print '<tr>'; + print '<td>'.$langs->trans("VALIDATOR").'</td>'; + print '<td>'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_validator); + print $userfee->getNomUrl(1); + print '</td></tr>'; + } + elseif($object->fk_c_expensereport_statuts==4) + { + print '<tr>'; + print '<td><span style="font-weight:bold;color:red;">'.$langs->trans("CANCEL_USER").'</span></td>'; + print '<td><span style="font-weight:bold;color:red;">'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_cancel); + print $userfee->getNomUrl(1); + print '</span></td></tr>'; + print '<tr>'; + print '<td><span style="font-weight:bold;color:red;">'.$langs->trans("MOTIF_CANCEL").'</span></td>'; + print '<td><span style="font-weight:bold;color:red;">'.$object->detail_cancel.'</span></td></tr>'; + print '</tr>'; + print '<tr>'; + print '<td><span style="font-weight:bold;color:red;">'.$langs->trans("DATE_CANCEL").'</span></td>'; + print '<td><span style="font-weight:bold;color:red;">'.$object->date_cancel.'</span></td></tr>'; + print '</tr>'; + } + else + { + print '<tr>'; + print '<td>'.$langs->trans("VALIDOR").'</td>'; + print '<td>'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_valid); + print $userfee->getNomUrl(1); + print '</td></tr>'; + print '<tr>'; + print '<td>'.$langs->trans("DATE_VALIDE").'</td>'; + print '<td>'.$object->date_valide.'</td></tr>'; + print '</tr>'; + } + + print '<tr>'; + print '<td>'.$langs->trans("AUTHOR").'</td>'; + print '<td>'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_author); + print $userfee->getNomUrl(1); + print '</td></tr>'; + + print '<tr>'; + print '<td>'.$langs->trans("DATE_SAVE").'</td>'; + print '<td>'.$object->date_create.'</td></tr>'; + print '</tr>'; + if($object->fk_c_expensereport_statuts==6) + { + print '<tr>'; + print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>'; + print '<td>'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_paid); + print $userfee->getNomUrl(1); + print '</td></tr>'; + print '<tr>'; + print '<td>'.$langs->trans("DATE_PAIEMENT").'</td>'; + print '<td>'.$object->date_paiement.'</td></tr>'; + print '</tr>'; + } + if($object->fk_c_expensereport_statuts==99 || !empty($object->detail_refuse)) + { + print '<tr>'; + print '<td><span style="font-weight:bold;color:red;">'.$langs->trans("REFUSEUR").'</span></td>'; + print '<td><span style="font-weight:bold;color:red;">'; + $userfee=new User($db); + $userfee->fetch($object->fk_user_refuse); + print $userfee->getNomUrl(1); + print '</span></td></tr>'; + print '<tr>'; + print '<td><span style="font-weight:bold;color:red;">'.$langs->trans("MOTIF_REFUS").'</span></td>'; + print '<td><span style="font-weight:bold;color:red;">'.$object->detail_refuse.'</span></td></tr>'; + print '</tr>'; + print '<tr>'; + print '<td><span style="font-weight:bold;color:red;">'.$langs->trans("DATE_REFUS").'</span></td>'; + print '<td><span style="font-weight:bold;color:red;">'.$object->date_refuse.'</span></td></tr>'; + print '</tr>'; + } + print '</table>'; + + print '<br>'; + + // Fetch Lines of current ndf + $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,'; + $sql.= ' fde.fk_c_tva, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; + $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; + $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref,'; + $sql.= ' tva.rowid as tva_id, tva.taux as tva_taux'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det fde'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON fde.fk_c_type_fees=ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet pjt ON fde.fk_projet=pjt.rowid'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_tva tva ON fde.fk_c_tva=tva.rowid'; + $sql.= ' WHERE fde.fk_expensereport = '.$id; + + $resql = $db->query($sql); + if ($resql) + { + $num_lignes = $db->num_rows($resql); + $i = 0;$total = 0; + + if ($num_lignes) + { + print '<div style="clear: both;">'; + + print '<form name="updateligne" action="'.$_SERVER["PHP_SELF"].'" method="post">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="updateligne">'; + print '<input type="hidden" name="id" value="'.$object->id.'">'; + + print '<table class="noborder" width="100%">'; + + print '<tr class="liste_titre">'; + if ($action != 'editline') print '<td style="text-align:center;width:9%;">'.$langs->trans('Piece').'</td>'; + print '<td style="text-align:center;">'.$langs->trans('Date').'</td>'; + print '<td style="text-align:center;">'.$langs->trans('Project').'</td>'; + print '<td style="text-align:center;">'.$langs->trans('Type').'</td>'; + print '<td style="text-align:left;">'.$langs->trans('Description').'</td>'; + print '<td style="text-align:right;">'.$langs->trans('VAT').'</td>'; + print '<td style="text-align:right;">'.$langs->trans('UnitPriceTTC').'</td>'; + print '<td style="text-align:right;">'.$langs->trans('Qty').'</td>'; + if ($action != 'editline') + { + print '<td style="text-align:right;">'.$langs->trans('AmountHT').'</td>'; + print '<td style="text-align:right;">'.$langs->trans('AmountTTC').'</td>'; + } + // Ajout des boutons de modification/suppression + if ($object->fk_c_expensereport_statuts<2 OR $object->fk_c_expensereport_statuts==99) + { + print '<td style="text-align:right;"></td>'; + } + + print '</tr>'; + + $var=true; + while ($i < $num_lignes) + { + $piece_comptable = $i + 1; + $objp = $db->fetch_object($resql); + $var=!$var; + if ($action != 'editline') + { + print '<tr '.$bc[$var].'>'; + print '<td style="text-align:center;width:9%;">'; + print img_picto("Document", "generic"); + print ' <span style="color:red;font-weight:bold;font-size:14px;">'.$piece_comptable.'</span></td>'; + print '<td style="text-align:center;">'.$objp->date.'</td>'; + print '<td style="text-align:center;">'.$objp->projet_ref.'</td>'; + print '<td style="text-align:center;">'.$langs->trans("TF_".strtoupper($objp->type_fees_libelle)).'</td>'; + print '<td style="text-align:left;">'.$objp->comments.'</td>'; + print '<td style="text-align:right;">'.vatrate($objp->tva_taux,true).'</td>'; + print '<td style="text-align:right;">'.price($objp->value_unit).'</td>'; + print '<td style="text-align:right;">'.$objp->qty.'</td>'; + print '<td style="text-align:right;">'.$objp->total_ht.'</td>'; + print '<td style="text-align:right;">'.$objp->total_ttc.'</td>'; + + // Ajout des boutons de modification/suppression + if($object->fk_c_expensereport_statuts<2 OR $object->fk_c_expensereport_statuts==99) + { + print '<td style="text-align:right;" class="nowrap">'; + print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&rowid='.$objp->rowid.'#'.$objp->rowid.'">'; + print img_edit(); + print '</a> '; + print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete_line&rowid='.$objp->rowid.'">'; + print img_delete(); + print '</a>'; + print '</td>'; + } + print '</tr>'; + } + else + { + if($objp->rowid==$_GET['rowid']) + { + //modif ligne!!!!! + print '<tr '.$bc[$var].'>'; + // Sélection date + print '<td style="text-align:center;width:10%;">'; + $html->select_date($objp->date,'date'); + print '</td>'; + + // Sélection projet + print '<td style="text-align:center;width:10%;">'; + print select_projet($objp->fk_projet,'','fk_projet'); + print '</td>'; + + // Sélection type + print '<td style="text-align:center;width:10%;">'; + select_type_fees_id($objp->type_fees_code,'fk_c_type_fees'); + print '</td>'; + + // Add comments + print '<td style="text-align:left;width:35%;">'; + print '<textarea class="flat_ndf" name="comments" class="centpercent">'.$objp->comments.'</textarea>'; + print '</td>'; + + // Sélection TVA + print '<td style="text-align:right;width:10%;">'; + print $form->load_tva('fk_c_tva', (isset($_POST["fk_c_tva"])?$_POST["fk_c_tva"]:$objp->tva_taux), $mysoc, ''); + print '</td>'; + + // Prix unitaire + print '<td style="text-align:right;width:10%;">'; + print '<input type="text" size="10" name="value_unit" value="'.$objp->value_unit.'" />'; + print '</td>'; + + // Quantité + print '<td style="text-align:right;width:10%;">'; + print '<input type="text" size="10" name="qty" value="'.$objp->qty.'" />'; + print '</td>'; + + print '<td style="text-align:center;">'; + print '<input type="hidden" name="rowid" value="'.$objp->rowid.'">'; + print '<input type="submit" class="button" name="save" value="'.$langs->trans('Save').'">'; + print '<br /><input type="submit" class="button" name="cancel" value="'.$langs->trans('Cancel').'">'; + print '</td>'; + } + } + + $i++; + } + + $db->free($resql); + + print '</table>'; + + print '</form>'; + + print '</div>'; + } + else + { + /* print '<table width="100%">'; + print '<tr><td><div class="error" style="display:block;">'.$langs->trans("AucuneLigne").'</div></td></tr>'; + print '</table>';*/ + } + //print '</div>'; + + // Ajouter une ligne + if (($object->fk_c_expensereport_statuts==1 || $object->fk_c_expensereport_statuts==99) && $action != 'editline') + { + print_fiche_titre($langs->trans("AddLine"),'',''); + + print '<form method="post" action="'.$_SERVER['PHP_SELF'].'" name="addline">'; + print '<input type="hidden" name="fk_expensereport" value="'.$id.'" />'; + print '<input type="hidden" name="action" value="addline" />'; + + print '<table class="noborder" width="100%">'; + print '<tr class="liste_titre">'; + print '<td style="text-align:center;">'.$langs->trans('Date').'</td>'; + print '<td>'.$langs->trans('Project').'</td>'; + print '<td>'.$langs->trans('Type').'</td>'; + print '<td>'.$langs->trans('Description').'</td>'; + print '<td style="text-align:right;">'.$langs->trans('VAT').'</td>'; + print '<td style="text-align:right;">'.$langs->trans('UnitPriceTTC').'</td>'; + print '<td style="text-align:right;">'.$langs->trans('Qty').'</td>'; + print '<td style="text-align:center;"></td>'; + print '</tr>'; + + print '<tr>'; + + // Sélection date + print '<td style="text-align:center;">'; + $html->select_date(-1,'date'); + print '</td>'; + + // Sélection projet + print '<td>'; + print select_projet('','','fk_projet'); + //$formproject->select_projects('','','fk_projet'); + print '</td>'; + + // Sélection type + print '<td>'; + select_type_fees_id('TF_TRAIN','fk_c_type_fees'); + print '</td>'; + + // Add comments + print '<td style="text-align:left;">'; + print '<textarea class="flat_ndf centpercent" name="comments"></textarea>'; + print '</td>'; + + // Sélection TVA + print '<td style="text-align:right;">'; + print $form->load_tva('fk_c_tva', (isset($_POST["fk_c_tva"])?$_POST["fk_c_tva"]:-1), $mysoc, ''); + print '</td>'; + + // Prix unitaire + print '<td style="text-align:right;">'; + print '<input type="text" size="10" name="value_unit" />'; + print '</td>'; + + // Quantité + print '<td style="text-align:right;">'; + print '<input type="text" size="4" name="qty" />'; + print '</td>'; + + print '<td style="text-align:center;"><input type="submit" value="'.$langs->trans("Add").'" name="bouton" class="button"></td>'; + print '</tr>'; + + print '</table>'; + + print '</form>'; + } // Fin si c'est payé/validé + + } + } // end edit or not edit + + dol_fiche_end(); + + } // end of if result + else + { + dol_print_error($db); + } + + } //fin si id > 0 + +} + + + +/* + * Barre d'actions + */ + +print '<div class="tabsAction">'; + +if ($action != 'create' && $action != 'edit') +{ + $object = new ExpenseReport($db); + $object->fetch($id,$user); + + /* Si l'état est "Brouillon" + * ET user à droit "creer/supprimer" + * ET fk_user_author == user courant + * Afficher : "Enregistrer" / "Modifier" / "Supprimer" + */ + if($user->rights->expensereport->creer AND $object->fk_c_expensereport_statuts==1) + { + if($object->fk_user_author==$user->id) + { + // Modifier + print '<a class="butAction" href="'.$_SEVER["PHP_SELF"].'?action=edit&id='.$id.'">'.$langs->trans('ModifyInfoGen').'</a>'; + + // Enregistrer + print '<a class="butAction" href="'.$_SEVER["PHP_SELF"].'?action=save&id='.$id.'">'.$langs->trans('Validate').'</a>'; + + if ($user->rights->expensereport->supprimer) + { + // Supprimer + print '<a class="butActionDelete" href="'.$_SEVER["PHP_SELF"].'?action=delete&id='.$id.'">'.$langs->trans('Delete').'</a>'; + } + } + } + + /* Si l'état est "Refusée" + * ET user à droit "creer/supprimer" + * ET fk_user_author == user courant + * Afficher : "Enregistrer" / "Modifier" / "Supprimer" + */ + if($user->rights->expensereport->creer && $object->fk_c_expensereport_statuts==99) + { + if ($object->fk_user_author == $user->id) + { + // Modifier + print '<a class="butAction" href="'.$_SEVER["PHP_SELF"].'?action=edit&id='.$id.'">'.$langs->trans('ModifyInfoGen').'</a>'; + + // Brouillonner (le statut refusée est identique à brouillon) + //print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$id.'">'.$langs->trans('BROUILLONNER').'</a>'; + // Enregistrer depuis le statut "Refusée" + print '<a class="butAction" href="'.$_SEVER["PHP_SELF"].'?action=save_from_refuse&id='.$id.'">'.$langs->trans('Validate').'</a>'; + + if ($user->rights->expensereport->supprimer) + { + // Supprimer + print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&id='.$id.'">'.$langs->trans('Delete').'</a>'; + } + } + } + + if ($user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts==5) + { + if ($object->fk_user_author == $user->id || $object->fk_user_valid == $user->id) + { + // Brouillonner + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$id.'">'.$langs->trans('BROUILLONNER').'</a>'; + } + } + + /* Si l'état est "En attente d'approbation" + * ET user à droit de "to_validate" + * ET fk_user_validator == user courant + * Afficher : "Valider" / "Refuser" / "Supprimer" + */ + if ($object->fk_c_expensereport_statuts == 2) + { + if ($object->fk_user_author == $user->id) + { + // Brouillonner + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$id.'">'.$langs->trans('BROUILLONNER').'</a>'; + } + } + + if ($user->rights->expensereport->to_validate && $object->fk_c_expensereport_statuts == 2) + { + //if($object->fk_user_validator==$user->id) + //{ + // Valider + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=validate&id='.$id.'">'.$langs->trans('Approve').'</a>'; + // Refuser + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$id.'">'.$langs->trans('REFUSE').'</a>'; + //} + + if ($object->fk_user_author==$user->id) + { + // Annuler + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$id.'">'.$langs->trans('CANCEL').'</a>'; + } + + if($user->rights->expensereport->supprimer) + { + // Supprimer + print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&id='.$id.'">'.$langs->trans('Delete').'</a>'; + } + } + + /* Si l'état est "A payer" + * ET user à droit de "to_paid" + * Afficher : "Annuler" / "Payer" / "Supprimer" + */ + if ($user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts==5) + { + // Payer + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=paid&id='.$id.'">'.$langs->trans('TO_PAID').'</a>'; + + // Annuler + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$id.'">'.$langs->trans('CANCEL').'</a>'; + + if($user->rights->expensereport->supprimer) + { + // Supprimer + print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&id='.$id.'">'.$langs->trans('Delete').'</a>'; + } + } + + /* Si l'état est "Payée" + * ET user à droit "to_validate" + * ET user à droit "to_paid" + * Afficher : "Annuler" + */ + if ($user->rights->expensereport->to_validate && $user->rights->expensereport->to_paid && $object->fk_c_expensereport_statuts==6) + { + // Annuler + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$id.'">'.$langs->trans('Cancel').'</a>'; + if($user->rights->expensereport->supprimer) + { + // Supprimer + print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&id='.$id.'">'.$langs->trans('Delete').'</a>'; + } + } + + /* Si l'état est "Annulée" + * ET user à droit "supprimer" + * Afficher : "Supprimer" + */ + if ($user->rights->expensereport->supprimer && $object->fk_c_expensereport_statuts==4) + { + + if ($object->fk_user_validator==$user->id) + { + // Brouillonner + print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$id.'">'.$langs->trans('BROUILLONNER').'</a>'; + } + + // Supprimer + print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&id='.$id.'">'.$langs->trans('Delete').'</a>'; + + } +} + +print '</div>'; + + +$conf->global->DOL_URL_ROOT_DOCUMENT_PHP=dol_buildpath('/expensereport/documentwrapper.php',1); + + +print '<div style="width:50%">'; + +/* + * Documents generes + */ +if($user->rights->expensereport->export && $object->fk_c_expensereport_statuts>0 && $action != 'edit') +{ + $filename = dol_sanitizeFileName($object->ref_number); + $filedir = $conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref_number); + $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; + $genallowed = 1; + $delallowed = 1; + $var = true; + print $formfile->showdocuments('expensereport',$filename,$filedir,$urlsource,$genallowed,$delallowed); + $somethingshown = $formfile->numoffiles; +} + +print '</div>'; + + +llxFooter(); + +$db->close(); diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php new file mode 100755 index 0000000000000000000000000000000000000000..c54090dfe2fae9d51b6b7fea028104ce69b6c073 --- /dev/null +++ b/htdocs/expensereport/class/expensereport.class.php @@ -0,0 +1,1496 @@ +<?php +require_once(DOL_DOCUMENT_ROOT ."/core/class/commonobject.class.php"); + +/** + * Class to manage Trips and Expenses + */ +class ExpenseReport extends CommonObject +{ + var $db; + var $error; + var $element='expensereport'; + var $table_element='expensereport'; + var $table_element_line = 'expensereport_det'; + var $fk_element = 'fk_expensereport'; + + var $id; + var $ref_number; + var $lignes=array(); + var $total_ht; + var $total_tva; + var $total_ttc; + var $note; + var $date_debut; + var $date_fin; + + var $fk_user_validator; + var $fk_c_expensereport_statuts; // -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé + var $fk_c_paiement; + + var $user_author_infos; + var $user_validator_infos; + + var $libelle_paiement; + var $libelle_statut; + var $code_paiement; + var $code_statut; + + /* + ACTIONS + */ + + // Enregistrement + var $date_create; + var $fk_user_author; + + // Refus + var $date_refuse; + var $detail_refuse; + var $fk_user_refuse; + + // Annulation + var $date_cancel; + var $detail_cancel; + var $fk_user_cancel; + + // Validation + var $date_valide; + var $fk_user_valid; + var $user_valid_infos; + + // Paiement + var $date_paiement; + var $fk_user_paid; + var $user_paid_infos; + + /* + END ACTIONS + */ + + + /** + * Constructor + * + * @param DoliDB $db Handler acces base de donnees + */ + function __construct($db) + { + $this->db = $db; + $this->total_ht = 0; + $this->total_ttc = 0; + $this->total_tva = 0; + + // List of language codes for status + $this->statuts[0]='Draft'; + $this->statuts[2]='Validated'; + $this->statuts[4]='Canceled'; + $this->statuts[5]='Approved'; + $this->statuts[6]='Paid'; + $this->statuts[99]='Refused'; + $this->statuts_short[0]='Draft'; + $this->statuts_short[2]='Validated'; + $this->statuts_short[4]='Canceled'; + $this->statuts_short[5]='Approved'; + $this->statuts_short[6]='Paid'; + $this->statuts_short[99]='Refused'; + $this->statuts_logo[0]='statut0'; + $this->statuts_logo[2]='statut4'; + $this->statuts_logo[4]='statut3'; + $this->statuts_logo[5]='statut5'; + $this->statuts_logo[6]='statut6'; + $this->statuts_logo[99]='statutx'; + + return 1; + } + + /** + * Create object in database + * + * @param User $user User that create + * @return int <0 if KO, >0 if OK + */ + function create($user) + { + global $conf; + + $now = dol_now(); + + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." ("; + $sql.= "ref_number"; + $sql.= ",total_ht"; + $sql.= ",total_ttc"; + $sql.= ",total_tva"; + $sql.= ",date_debut"; + $sql.= ",date_fin"; + $sql.= ",date_create"; + $sql.= ",fk_user_author"; + $sql.= ",fk_user_validator"; + $sql.= ",fk_c_expensereport_statuts"; + $sql.= ",fk_c_paiement"; + $sql.= ",note"; + $sql.= ") VALUES("; + $sql.= "'(PROV)'"; + $sql.= ", ".$this->total_ht; + $sql.= ", ".$this->total_ttc; + $sql.= ", ".$this->total_tva; + $sql.= ", '".$this->db->idate($this->date_debut)."'"; + $sql.= ", '".$this->db->idate($this->date_fin)."'"; + $sql.= ", '".$this->db->idate($now)."'"; + $sql.= ", ".($user->id > 0 ? $user->id:"null"); + $sql.= ", ".($this->fk_user_validator > 0 ? $this->fk_user_validator:2); + $sql.= ", ".($this->fk_c_expensereport_statuts > 1 ? $this->fk_c_expensereport_statuts:1); + $sql.= ", ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement:2); + $sql.= ", ".($this->note?"'".$this->note."'":"null"); + $sql.= ")"; + + dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element); + $this->ref_number='(PROV'.$this->id.')'; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element." SET ref_number='".$this->ref_number."' WHERE rowid=".$this->id; + dol_syslog(get_class($this)."::create sql=".$sql); + $resql=$this->db->query($sql); + if (!$resql) $error++; + + foreach ($this->lignes as $i => $val) + { + $newndfline=new ExpenseReportLigne($this->db); + $newndfline=$this->lignes[$i]; + $newndfline->fk_expensereport=$this->id; + if ($result >= 0) + { + $result=$newndfline->insert(); + } + if ($result < 0) + { + $error++; + break; + } + } + + if (! $error) + { + $result=$this->update_price(); + if ($result > 0) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -3; + } + } + else + { + dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -1; + } + + } + + /** + * update + * + * @param User $user User making change + * @return int <0 if KO, >0 if OK + */ + function update($user) + { + global $langs; + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql.= " total_ht = ".$this->total_ht; + $sql.= " , total_ttc = ".$this->total_ttc; + $sql.= " , total_tva = ".$this->total_tva; + $sql.= " , date_debut = '".$this->date_debut."'"; + $sql.= " , date_fin = '".$this->date_fin."'"; + $sql.= " , fk_user_author = ".($user->id > 0 ? "'".$user->id."'":"null"); + $sql.= " , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null"); + $sql.= " , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid:"null"); + $sql.= " , fk_user_paid = ".($this->fk_user_paid > 0 ? $this->fk_user_paid:"null"); + $sql.= " , fk_c_expensereport_statuts = ".($this->fk_c_expensereport_statuts > 0 ? $this->fk_c_expensereport_statuts:"null"); + $sql.= " , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement:"null"); + $sql.= " , note = ".(!empty($this->note)?"'".$this->db->escape($this->note)."'":"''"); + $sql.= " , detail_refuse = ".(!empty($this->detail_refuse)?"'".$this->db->escape($this->detail_refuse)."'":"''"); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + /** + * Load an object from database + */ + function fetch($id,$user='') + { + global $conf,$db; + + if(!$user->rights->expensereport->lire): + $restrict = " AND fk_user_author = ".$user->id; + else: + $restrict = ""; + endif; + + $sql = "SELECT d.rowid, d.ref_number, d.note,"; // DEFAULT + $sql.= " d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,"; // ACTIONS + $sql.= " d.date_refuse, d.date_cancel,"; // ACTIONS + $sql.= " d.total_ht, d.total_ttc, d.total_tva,"; // TOTAUX (int) + $sql.= " d.date_debut, d.date_fin, d.date_create, d.date_valide, d.date_paiement,"; // DATES (datetime) + $sql.= " d.fk_user_author, d.fk_user_validator, d.fk_c_expensereport_statuts, d.fk_c_paiement,"; // FOREING KEY (int) + $sql.= " d.fk_user_valid, d.fk_user_paid,"; // FOREING KEY 2 (int) + $sql.= " dp.libelle as libelle_paiement, dp.code as code_paiement"; // INNER JOIN paiement + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." d"; + $sql.= " INNER JOIN ".MAIN_DB_PREFIX."c_paiement dp ON d.fk_c_paiement = dp.id"; + $sql.= " WHERE d.rowid = ".$id; + $sql.= $restrict; + + dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); + $result = $db->query($sql) ; + if ($result) + { + $obj = $db->fetch_object($result); + + $this->id = $obj->rowid; + $this->ref = $obj->ref_number; + $this->ref_number = $obj->ref_number; + $this->total_ht = $obj->total_ht; + $this->total_tva = $obj->total_tva; + $this->total_ttc = $obj->total_ttc; + $this->note = $obj->note; + $this->detail_refuse = $obj->detail_refuse; + $this->detail_cancel = $obj->detail_cancel; + + $this->date_debut = $obj->date_debut; + $this->date_fin = $obj->date_fin; + $this->date_paiement = $obj->date_paiement; + $this->date_valide = $obj->date_valide; + $this->date_create = $obj->date_create; + $this->date_refuse = $obj->date_refuse; + $this->date_cancel = $obj->date_cancel; + + $this->fk_user_author = $obj->fk_user_author; + $this->fk_user_validator = $obj->fk_user_validator; + $this->fk_user_valid = $obj->fk_user_valid; + $this->fk_user_paid = $obj->fk_user_paid; + $this->fk_user_refuse = $obj->fk_user_refuse; + $this->fk_user_cancel = $obj->fk_user_cancel; + + $this->user_author_infos = $this->fetch_names($this->fk_user_author); + $this->user_validator_infos = $this->fetch_names($this->fk_user_validator); + + $this->fk_c_expensereport_statuts = $obj->fk_c_expensereport_statuts; + $this->fk_c_paiement = $obj->fk_c_paiement; + + if($this->fk_c_expensereport_statuts==5 || $this->fk_c_expensereport_statuts==6){ + $this->user_valid_infos = $this->fetch_names($this->fk_user_valid); + } + + if($this->fk_c_expensereport_statuts==6){ + $this->user_paid_infos = $this->fetch_names($this->fk_user_paid); + } + + $this->libelle_statut = $obj->libelle_statut; + $this->libelle_paiement = $obj->libelle_paiement; + $this->code_statut = $obj->code_statut; + $this->code_paiement = $obj->code_paiement; + + $this->lignes = array(); + + $result=$this->fetch_lines(); + + return 1; + } + else + { + $this->error=$db->error(); + return -1; + } + } + + + /** + * Returns the label status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @return string Label + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Returns the label of a statut + * + * @param int $status id statut + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @return string Label + */ + function LibStatut($status,$mode=0) + { + global $langs; + + if ($mode == 0) + return $langs->trans($this->statuts[$status]); + + if ($mode == 1) + return $langs->trans($this->statuts_short[$status]); + + if ($mode == 2) + return img_picto($langs->trans($this->statuts_short[$status]), $this->statuts_logo[$status]).' '.$langs->trans($this->statuts_short[$status]); + + if ($mode == 3) + return img_picto($langs->trans($this->statuts_short[$status]), $this->statuts_logo[$status]); + + if ($mode == 4) + return img_picto($langs->trans($this->statuts_short[$status]),$this->statuts_logo[$status]).' '.$langs->trans($this->statuts[$status]); + + if ($mode == 5) + return '<span class="hideonsmartphone">'.$langs->trans($this->statuts_short[$status]).' </span>'.img_picto($langs->trans($this->statuts_short[$status]),$this->statuts_logo[$status]); + + } + + + /** + * + * @param unknown_type $id + * @return unknown + */ + function fetch_names($id) + { + global $db; + + $sql = "SELECT lastname, firstname, email, user_mobile, office_phone "; + $sql.= "FROM ".MAIN_DB_PREFIX."user "; + $sql.= "WHERE rowid = ".$id; + $result = $db->query($sql); + $obj = $db->fetch_object($result); + return $obj; + } + + /** + * + * @param unknown_type $projectid + * @param unknown_type $user + */ + function fetch_line_by_project($projectid,$user='') + { + global $conf,$db,$langs; + + $langs->load('trips'); + + if($user->rights->expensereport->lire) { + + $sql = "SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc"; + $sql.= " FROM ".MAIN_DB_PREFIX."expensereport_det as de"; + $sql.= " WHERE de.fk_projet = ".$projectid; + + dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); + $result = $db->query($sql) ; + if ($result) + { + $num = $db->num_rows($result); + $i = 0; + $total_HT = 0; + $total_TTC = 0; + + while ($i < $num) + { + + $objp = $db->fetch_object($result); + + $sql2 = "SELECT d.rowid, d.fk_user_author, d.ref_number, d.fk_c_expensereport_statuts"; + $sql2.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; + $sql2.= " WHERE d.rowid = '".$objp->fk_expensereport."'"; + + $result2 = $db->query($sql2); + $obj = $db->fetch_object($result2); + + $objp->fk_user_author = $obj->fk_user_author; + $objp->ref_num = $obj->ref_number; + $objp->fk_c_expensereport_status = $obj->fk_c_expensereport_statuts; + $objp->rowid = $obj->rowid; + + $total_HT = $total_HT + $objp->total_ht; + $total_TTC = $total_TTC + $objp->total_ttc; + $author = new User($db); + $author->fetch($objp->fk_user_author); + + print '<tr>'; + print '<td><a href="'.DOL_URL_ROOT.'/expensereport/card.php?id='.$objp->rowid.'">'.$objp->ref_num.'</a></td>'; + print '<td align="center">'.dol_print_date($objp->date,'day').'</td>'; + print '<td>'.$author->getNomUrl().'</td>'; + print '<td>'.$objp->comments.'</td>'; + print '<td align="right">'.price($objp->total_ht).'</td>'; + print '<td align="right">'.price($objp->total_ttc).'</td>'; + print '<td align="right">'; + + switch($objp->fk_c_expensereport_status) { + case 4: + print img_picto($langs->trans('StatusOrderCanceled'),'statut5'); + break; + case 1: + print $langs->trans('Draft').' '.img_picto($langs->trans('Draft'),'statut0'); + break; + case 2: + print $langs->trans('TripForValid').' '.img_picto($langs->trans('TripForValid'),'statut3');; + break; + case 5: + print $langs->trans('TripForPaid').' '.img_picto($langs->trans('TripForPaid'),'statut3'); + break; + case 6: + print $langs->trans('TripPaid').' '.img_picto($langs->trans('TripPaid'),'statut4'); + break; + } + /* + if ($status==4) return img_picto($langs->trans('StatusOrderCanceled'),'statut5'); + if ($status==1) return img_picto($langs->trans('StatusOrderDraft'),'statut0'); + if ($status==2) return img_picto($langs->trans('StatusOrderValidated'),'statut1'); + if ($status==2) return img_picto($langs->trans('StatusOrderOnProcess'),'statut3'); + if ($status==5) return img_picto($langs->trans('StatusOrderToBill'),'statut4'); + if ($status==6) return img_picto($langs->trans('StatusOrderOnProcess'),'statut6'); + */ + print '</td>'; + print '</tr>'; + + $i++; + } + + print '<tr class="liste_total"><td colspan="4">'.$langs->trans("Number").': '.$i.'</td>'; + print '<td align="right" width="100">'.$langs->trans("TotalHT").' : '.price($total_HT).'</td>'; + print '<td align="right" width="100">'.$langs->trans("TotalTTC").' : '.price($total_TTC).'</td>'; + print '<td> </td>'; + print '</tr>'; + + } + else + { + $this->error=$db->error(); + return -1; + } + } + + } + + function recalculer($id){ + $sql = 'SELECT tt.total_ht, tt.total_ttc, tt.total_tva'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as tt'; + $sql.= ' WHERE tt.'.$this->fk_element.' = '.$id; + + $total_ht = 0; $total_tva = 0; $total_ttc = 0; + + dol_syslog('ExpenseReport::recalculer sql='.$sql,LOG_DEBUG); + + $result = $this->db->query($sql); + if($result): + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num): + $objp = $this->db->fetch_object($result); + $total_ht+=$objp->total_ht; + $total_tva+=$objp->total_tva; + $i++; + endwhile; + + $total_ttc = $total_ht + $total_tva; + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql.= " total_ht = ".$total_ht; + $sql.= " , total_ttc = ".$total_ttc; + $sql.= " , total_tva = ".$total_tva; + $sql.= " WHERE rowid = ".$id; + $result = $this->db->query($sql); + if($result): + $this->db->free($result); + return 1; + else: + $this->error=$this->db->error(); + dol_syslog('ExpenseReport::recalculer: Error '.$this->error,LOG_ERR); + return -3; + endif; + else: + $this->error=$this->db->error(); + dol_syslog('ExpenseReport::recalculer: Error '.$this->error,LOG_ERR); + return -3; + endif; + } + + function fetch_lines() + { + $sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date,'; + $sql.= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_projet, de.fk_c_tva,'; + $sql.= ' de.total_ht, de.total_tva, de.total_ttc,'; + $sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,'; + $sql.= ' ctv.taux as taux_tva,'; + $sql.= ' p.ref as ref_projet, p.title as title_projet'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as de'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON de.fk_c_type_fees = ctf.id'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_tva ctv ON de.fk_c_tva = ctv.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet p ON de.fk_projet = p.rowid'; + $sql.= ' WHERE de.'.$this->fk_element.' = '.$this->id; + + dol_syslog('ExpenseReport::fetch_lines sql='.$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $this->db->fetch_object($result); + $deplig = new ExpenseReportLigne($this->db); + + $deplig->rowid = $objp->rowid; + $deplig->comments = $objp->comments; + $deplig->qty = $objp->qty; + $deplig->value_unit = $objp->value_unit; + $deplig->date = $objp->date; + + $deplig->fk_expensereport = $objp->fk_expensereport; + $deplig->fk_c_type_fees = $objp->fk_c_type_fees; + $deplig->fk_projet = $objp->fk_projet; + $deplig->fk_c_tva = $objp->fk_c_tva; + + $deplig->total_ht = $objp->total_ht; + $deplig->total_tva = $objp->total_tva; + $deplig->total_ttc = $objp->total_ttc; + + $deplig->type_fees_code = $objp->code_type_fees; + $deplig->type_fees_libelle = $objp->libelle_type_fees; + $deplig->tva_taux = $objp->taux_tva; + $deplig->projet_ref = $objp->ref_projet; + $deplig->projet_title = $objp->title_projet; + + $this->lignes[$i] = $deplig; + $i++; + } + $this->db->free($result); + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog('ExpenseReport::fetch_lines: Error '.$this->error,LOG_ERR); + return -3; + } + } + + function delete($rowid=0) + { + global $user,$langs,$conf; + + if (!$rowid) $rowid=$this->id; + + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line.' WHERE '.$this->fk_element.' = '.$rowid; + if ($this->db->query($sql)) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE rowid = '.$rowid; + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + dol_syslog("ExpenseReport.class::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -6; + } + } + else + { + $this->error=$this->db->error()." sql=".$sql; + dol_syslog("ExpenseReport.class::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -4; + } + } + + function set_save($user){ + global $conf,$langs; + + $expld_car = (empty($conf->global->NDF_EXPLODE_CHAR))?"-":$conf->global->NDF_EXPLODE_CHAR; + + // Sélection du numéro de ref suivant + $ref_next = $this->getNextNumRef(); + $ref_number_int = ($this->ref_number+1)-1; + + // Sélection de la date de début de la NDF + $sql = 'SELECT date_debut'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element; + $sql.= ' WHERE rowid = '.$this->id; + $result = $this->db->query($sql); + $objp = $this->db->fetch_object($result); + $this->date_debut = $objp->date_debut; + $expld_date_debut = explode("-",$this->date_debut); + $this->date_debut = $expld_date_debut[0].$expld_date_debut[1].$expld_date_debut[2]; + + // Création du ref_number suivant + if($ref_next): + $this->ref_number = strtoupper($user->login).$expld_car."NDF".$this->ref_number.$expld_car.$this->date_debut; + endif; + + if ($this->fk_c_expensereport_statuts != 2): + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET ref_number = '".$this->ref_number."', fk_c_expensereport_statuts = 2"; + $sql.= " ,ref_number_int = $ref_number_int"; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_save sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + + else: + + dol_syslog(get_class($this)."::set_save expensereport already with save status", LOG_WARNING); + + endif; + } + + function set_save_from_refuse($user){ + global $conf,$langs; + + // Sélection de la date de début de la NDF + $sql = 'SELECT date_debut'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element; + $sql.= ' WHERE rowid = '.$this->id; + + $result = $this->db->query($sql); + + $objp = $this->db->fetch_object($result); + + $this->date_debut = $objp->date_debut; + $expld_date_debut = explode("-",$this->date_debut); + $this->date_debut = $expld_date_debut[0].$expld_date_debut[1].$expld_date_debut[2]; + + if ($this->fk_c_expensereport_statuts != 2): + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_c_expensereport_statuts = 2"; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_save_from_refuse sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + + else: + + dol_syslog(get_class($this)."::set_save_from_refuse expensereport already with save status", LOG_WARNING); + + endif; + } + + function set_valide($user){ + // date de validation + $this->date_valide = $this->db->idate(gmmktime()); + if ($this->fk_c_expensereport_statuts != 5): + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET ref_number = '".$this->ref_number."', fk_c_expensereport_statuts = 5, fk_user_valid = ".$user->id; + $sql.= ', date_valide='.$this->date_valide; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_valide sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + else: + dol_syslog(get_class($this)."::set_valide expensereport already with valide status", LOG_WARNING); + endif; + } + + /** + * Refuse + * + * @param User $user User + * @param Details $details Details + */ + function set_refuse($user,$details) + { + // date de refus + $this->date_refuse = $this->db->idate(gmmktime()); + if ($this->fk_c_expensereport_statuts != 99): + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET ref_number = '".$this->ref_number."', fk_c_expensereport_statuts = 99, fk_user_refuse = ".$user->id; + $sql.= ', date_refuse='.$this->date_refuse; + $sql.= ", detail_refuse='".addslashes($details)."'"; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_refuse sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + else: + dol_syslog(get_class($this)."::set_refuse expensereport already with refuse status", LOG_WARNING); + endif; + } + + function set_paid($user){ + $this->date_paiement = $this->db->idate(gmmktime()); + if ($this->fk_c_expensereport_statuts != 6): + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_c_expensereport_statuts = 6, fk_user_paid = ".$user->id; + $sql.= ', date_paiement='.$this->date_paiement; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_paid sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + else: + dol_syslog(get_class($this)."::set_paid expensereport already with paid status", LOG_WARNING); + endif; + } + + function set_unpaid($user) + { + if ($this->fk_c_expensereport_statuts != 5) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_c_expensereport_statuts = 5"; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_unpaid sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + } + else + { + dol_syslog(get_class($this)."::set_unpaid expensereport already with unpaid status", LOG_WARNING); + } + } + + function set_draft($user) + { + if ($this->fk_c_expensereport_statuts != 1) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_c_expensereport_statuts = 1,"; + //$sql.= " , ref_number = '(PROV".$this->id.")', ref_number_int = 0"; + $sql.= " ref_number_int = 0"; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_draft sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)) return 1; + else + { + $this->error=$this->db->error(); + return -1; + } + } + else + { + dol_syslog(get_class($this)."::set_draft expensereport already with draft status", LOG_WARNING); + } + } + + function set_to_valide($user) + { + if ($this->fk_c_expensereport_statuts != 2): + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_c_expensereport_statuts = 2, fk_user_validator = ".$this->fk_user_validator; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_to_valide sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + else: + dol_syslog(get_class($this)."::set_to_valide expensereport already with to-valide status", LOG_WARNING); + endif; + } + + function set_cancel($user,$detail){ + $this->date_cancel = $this->db->idate(gmmktime()); + if ($this->fk_c_expensereport_statuts != 4): + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET fk_c_expensereport_statuts = 4, fk_user_cancel = ".$user->id; + $sql.= ', date_cancel='.$this->date_cancel; + $sql.= " ,detail_cancel='".addslashes($detail)."'"; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_cancel sql=".$sql, LOG_DEBUG); + + if ($this->db->query($sql)): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + else: + dol_syslog(get_class($this)."::set_cancel expensereport already with cancel status", LOG_WARNING); + endif; + } + + function getNextNumRef(){ + global $conf; + + $expld_car = (empty($conf->global->NDF_EXPLODE_CHAR))?"-":$conf->global->NDF_EXPLODE_CHAR; + $num_car = (empty($conf->global->NDF_NUM_CAR_REF))?"5":$conf->global->NDF_NUM_CAR_REF; + + $sql = 'SELECT de.ref_number_int'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' de'; + $sql.= ' ORDER BY de.ref_number_int DESC'; + + $result = $this->db->query($sql); + + if($this->db->num_rows($result) > 0): + $objp = $this->db->fetch_object($result); + $this->ref_number = $objp->ref_number_int; + $this->ref_number++; + while(strlen($this->ref_number) < $num_car): + $this->ref_number = "0".$this->ref_number; + endwhile; + else: + $this->ref_number = 1; + while(strlen($this->ref_number) < $num_car): + $this->ref_number = "0".$this->ref_number; + endwhile; + endif; + + if ($result): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + } + + + /** + * Return clicable name (with picto eventually) + * + * @param int $withpicto 0=Pas de picto, 1=Inclut le picto dans le lien, 2=Picto seul + * @return string Chaine avec URL + */ + function getNomUrl($withpicto=0) + { + global $langs; + + $result=''; + + $lien = '<a href="'.DOL_URL_ROOT.'/expensereport/card.php?id='.$this->id.'">'; + $lienfin='</a>'; + + $picto='trip'; + + $label=$langs->trans("Show").': '.$this->ref; + + if ($withpicto) $result.=($lien.img_object($label,$picto).$lienfin); + if ($withpicto && $withpicto != 2) $result.=' '; + if ($withpicto != 2) $result.=$lien.$this->ref.$lienfin; + return $result; + } + + + function update_totaux_add($ligne_total_ht,$ligne_total_tva){ + $this->total_ht = $this->total_ht + $ligne_total_ht; + $this->total_tva = $this->total_tva + $ligne_total_tva; + $this->total_ttc = $this->total_ht + $this->total_tva; + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql.= " total_ht = ".$this->total_ht; + $sql.= " , total_ttc = ".$this->total_ttc; + $sql.= " , total_tva = ".$this->total_tva; + $sql.= " WHERE rowid = ".$this->id; + + $result = $this->db->query($sql); + if ($result): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + } + + function update_totaux_del($ligne_total_ht,$ligne_total_tva){ + $this->total_ht = $this->total_ht - $ligne_total_ht; + $this->total_tva = $this->total_tva - $ligne_total_tva; + $this->total_ttc = $this->total_ht + $this->total_tva; + + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql.= " total_ht = ".$this->total_ht; + $sql.= " , total_ttc = ".$this->total_ttc; + $sql.= " , total_tva = ".$this->total_tva; + $sql.= " WHERE rowid = ".$this->id; + + $result = $this->db->query($sql); + if ($result): + return 1; + else: + $this->error=$this->db->error(); + return -1; + endif; + } + + + + function updateline($rowid, $type_fees_id, $projet_id, $c_tva, $comments, $qty, $value_unit, $date, $expensereport_id) + { + if ($this->fk_c_expensereport_statuts==1 || $this->fk_c_expensereport_statuts==99) + { + $this->db->begin(); + + // Select du taux de tva par rapport au code + $sql = "SELECT t.taux as taux_tva"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_tva t"; + $sql.= " WHERE t.rowid = ".$c_tva; + $result = $this->db->query($sql); + $objp_tva = $this->db->fetch_object($result); + + // calcul de tous les totaux de la ligne + $total_ttc = $qty*$value_unit; + $total_ttc = number_format($total_ttc,2,'.',''); + + $tx_tva = $objp_tva->taux_tva/100; + $tx_tva = $tx_tva + 1; + $total_ht = $total_ttc/$tx_tva; + $total_ht = number_format($total_ht,2,'.',''); + + $total_tva = $total_ttc - $total_ht; + // fin calculs + + $ligne = new ExpenseReportLigne($this->db); + $ligne->comments = $comments; + $ligne->qty = $qty; + $ligne->value_unit = $value_unit; + $ligne->date = $date; + + $ligne->fk_expensereport = $expensereport_id; + $ligne->fk_c_type_fees = $type_fees_id; + $ligne->fk_projet = $projet_id; + $ligne->fk_c_tva = $c_tva; + + $ligne->total_ht = $total_ht; + $ligne->total_tva = $total_tva; + $ligne->total_ttc = $total_ttc; + $ligne->tva_taux = $objp_tva->taux_tva; + $ligne->rowid = $rowid; + + // Select des infos sur le type fees + $sql = "SELECT c.code as code_type_fees, c.label as libelle_type_fees"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees c"; + $sql.= " WHERE c.id = ".$type_fees_id; + $result = $this->db->query($sql); + $objp_fees = $this->db->fetch_object($result); + $ligne->type_fees_code = $objp_fees->code_type_fees; + $ligne->type_fees_libelle = $objp_fees->libelle_type_fees; + + // Select des informations du projet + $sql = "SELECT p.ref as ref_projet, p.title as title_projet"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet p"; + $sql.= " WHERE p.rowid = ".$projet_id; + $result = $this->db->query($sql); + $objp_projet = $this->db->fetch_object($result); + $ligne->projet_ref = $objp_projet->ref_projet; + $ligne->projet_title = $objp_projet->title_projet; + + $result = $ligne->update(); + if ($result > 0): + $this->db->commit(); + return 1; + else: + $this->error=$ligne->error; + $this->db->rollback(); + return -2; + endif; + + } + } + + /** + * deleteline + * + * @param unknown_type $rowid + * @param unknown_type $user + * @return number + */ + function deleteline($rowid, $user='') + { + $this->db->begin(); + + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql.= ' WHERE rowid = '.$rowid; + + dol_syslog(get_class($this)."::deleteline sql=".$sql); + $result = $this->db->query($sql); + if (!$result) + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -1; + } + + $this->db->commit(); + + return 1; + } + + /** + * dumpp + * + * @param unknown_type $value + */ + function dumpp($value) + { + echo '<div style="margin-top:10px;width:50%;font-size:8px;background:#CCC;">'; + var_dump("<pre>",$value,"</pre>"); + echo '</div>'; + } + + /** + * periode_existe + * + * @param unknown_type $user + * @param unknown_type $date_debut + * @param unknown_type $date_fin + */ + function periode_existe($user,$date_debut,$date_fin) + { + $sql = "SELECT rowid,date_debut,date_fin"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " WHERE fk_user_author = '{$user->id}'"; + + dol_syslog(get_class($this)."::periode_existe sql=".$sql); + $result = $this->db->query($sql); + if($result): + $num_lignes = $this->db->num_rows($result); $i = 0; + + if($num_lignes>0): + $date_d_form = explode("-",$date_debut); // 1 + $date_f_form = explode("-",$date_fin); // 2 + $date_d_form = mktime(12,0,0,$date_d_form[1],$date_d_form[2],$date_d_form[0]); + $date_f_form = mktime(12,0,0,$date_f_form[1],$date_f_form[2],$date_f_form[0]); + + $existe = false; + + while ($i < $num_lignes): + $objp = $this->db->fetch_object($result); + + $date_d_req = explode("-",$objp->date_debut); // 3 + $date_f_req = explode("-",$objp->date_fin); // 4 + $date_d_req = mktime(12,0,0,$date_d_req[1],$date_d_req[2],$date_d_req[0]); + $date_f_req = mktime(12,0,0,$date_f_req[1],$date_f_req[2],$date_f_req[0]); + + if(!($date_f_form < $date_d_req OR $date_d_form > $date_f_req)) $existe = true; + + $i++; + endwhile; + + if($existe) return 1; + else return 0; + + else: + return 0; + endif; + else: + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::periode_existe Error ".$this->error, LOG_ERR); + return -1; + endif; + } + + + /** + * Return list of people with permission to validate trips and expenses + * + * @return array Array of user ids + */ + function fetch_users_approver_expensereport() + { + $users_validator=array(); + + $sql = "SELECT fk_user"; + $sql.= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd"; + $sql.= " WHERE ur.fk_id = rd.id and module = 'expensereport' AND perms = 'to_validate'"; // Permission 'Approve'; + + dol_syslog(get_class($this)."::fetch_users_approver_expensereport sql=".$sql); + $result = $this->db->query($sql); + if($result) + { + $num_lignes = $this->db->num_rows($result); $i = 0; + while ($i < $num_lignes) + { + $objp = $this->db->fetch_object($result); + array_push($users_validator,$objp->fk_user); + $i++; + } + return $users_validator; + } + else + { + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this)."::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR); + return -1; + } + } +} + + +/** + * Class of expense report details lines + */ +class ExpenseReportLigne +{ + var $db; + var $error; + + var $rowid; + var $comments; + var $qty; + var $value_unit; + var $date; + + var $fk_c_tva; + var $fk_c_type_fees; + var $fk_projet; + var $fk_expensereport; + + var $type_fees_code; + var $type_fees_libelle; + + var $projet_ref; + var $projet_title; + + var $tva_taux; + + var $total_ht; + var $total_tva; + var $total_ttc; + + + function ExpenseReportLigne($DB) + { + $this->db= $DB ; + } + + function fetch($rowid) + { + $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,'; + $sql.= ' fde.fk_c_tva, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; + $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; + $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref,'; + $sql.= ' tva.rowid as tva_id, tva.taux as tva_taux'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det fde'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees ctf ON fde.fk_c_type_fees=ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet pjt ON fde.fk_projet=pjt.rowid'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_tva tva ON fde.fk_c_tva=tva.rowid'; + $sql.= ' WHERE fde.rowid = '.$rowid; + + $result = $this->db->query($sql); + + if($result) { + $objp = $this->db->fetch_object($result); + + $this->rowid = $objp->rowid; + $this->fk_expensereport = $objp->fk_expensereport; + $this->comments = $objp->comments; + $this->qty = $objp->qty; + $this->date = $objp->date; + $this->value_unit = $objp->value_unit; + $this->fk_c_tva = $objp->fk_c_tva; + $this->fk_c_type_fees = $objp->fk_c_type_fees; + $this->fk_projet = $objp->fk_projet; + $this->type_fees_code = $objp->type_fees_code; + $this->type_fees_libelle = $objp->type_fees_libelle; + $this->projet_ref = $objp->projet_ref; + $this->projet_title = $objp->projet_title; + $this->tva_taux = $objp->tva_taux; + $this->total_ht = $objp->total_ht; + $this->total_tva = $objp->total_tva; + $this->total_ttc = $objp->total_ttc; + + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + function insert($notrigger=0) + { + global $langs,$user,$conf; + + dol_syslog("ExpenseReportLigne::Insert rang=".$this->rang, LOG_DEBUG); + + // Clean parameters + $this->comments=trim($this->comments); + if (!$this->value_unit_HT) $this->value_unit_HT=0; + $this->qty = price2num($this->qty); + + $this->db->begin(); + + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'expensereport_det'; + $sql.= ' (fk_expensereport, fk_c_type_fees, fk_projet,'; + $sql.= ' fk_c_tva, comments, qty, value_unit, total_ht, total_tva, total_ttc, date)'; + $sql.= " VALUES (".$this->fk_expensereport.","; + $sql.= " ".$this->fk_c_type_fees.","; + $sql.= " ".($this->fk_projet>0?$this->fk_projet:'null').","; + $sql.= " ".$this->fk_c_tva.","; + $sql.= " '".$this->db->escape($this->comments)."',"; + $sql.= " ".$this->qty.","; + $sql.= " ".$this->value_unit.","; + $sql.= " ".$this->total_ht.","; + $sql.= " ".$this->total_tva.","; + $sql.= " ".$this->total_ttc.","; + $sql.= "'".$this->date."'"; + $sql.= ")"; + + dol_syslog("ExpenseReportLigne::insert sql=".$sql); + + $resql=$this->db->query($sql); + + if ($resql): + $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'expensereport_det'); + $this->db->commit(); + return $this->rowid; + else: + $this->error=$this->db->error(); + dol_syslog("ExpenseReportLigne::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + endif; + } + + function update() + { + global $user,$langs,$conf; + + // Clean parameters + $this->comments=trim($this->comments); + + $this->db->begin(); + + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."expensereport_det SET"; + $sql.= " comments='".addslashes($this->comments)."'"; + $sql.= ",value_unit=".$this->value_unit.""; + $sql.= ",qty=".$this->qty.""; + if ($this->date) { $sql.= ",date='".$this->date."'"; } + else { $sql.=',date=null'; } + $sql.= ",total_ht=".$this->total_ht.""; + $sql.= ",total_tva=".$this->total_tva.""; + $sql.= ",total_ttc=".$this->total_ttc.""; + if ($this->fk_c_type_fees) $sql.= ",fk_c_type_fees=".$this->fk_c_type_fees; + else $sql.= ",fk_c_type_fees=null"; + if ($this->fk_projet) $sql.= ",fk_projet=".$this->fk_projet; + else $sql.= ",fk_projet=null"; + if ($this->fk_c_tva) $sql.= ",fk_c_tva=".$this->fk_c_tva; + else $sql.= ",fk_c_tva=null"; + $sql.= " WHERE rowid = ".$this->rowid; + + dol_syslog("ExpenseReportLigne::update sql=".$sql); + + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog("ExpenseReportLigne::update Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + + function fetch_taux($id){ + $sql = "SELECT taux"; + $sql .= " FROM ".MAIN_DB_PREFIX ."c_tva"; + $sql .= " WHERE rowid = ".$id; + $resql=$this->db->query($sql); + $objp = $this->db->fetch_object($result); + $this->tva_taux = $objp->taux; + } +} + +/** + * Retourne la liste deroulante des differents etats d'une note de frais. + * Les valeurs de la liste sont les id de la table c_expensereport_statuts + * + * @param int $selected etat pre-selectionne + * @param string $htmlname Name of HTML select + * @param int $useempty 1=Add empty line + * @return string HTML select with sattus + */ +function select_expensereport_statut($selected='',$htmlname='fk_c_expensereport_statuts',$useempty=1) +{ + global $db; + + $tmpep=new ExpenseReport($db); + + print '<select class="flat" name="'.$htmlname.'">'; + if ($useempty) print '<option value="-1"> </option>'; + foreach ($tmpep->statuts as $key => $val) + { + if ($selected == $key) + { + print '<option value="'.$key.'" selected="true">'; + } + else + { + print '<option value="'.$key.'">'; + } + print $val; + print '</option>'; + } + print '</select>'; +} + +/** + * + * @param unknown_type $selected + * @param unknown_type $filter + * @param unknown_type $htmlname + * + * TODO Utiliser le select project officiel + */ +function select_projet($selected='',$filter='', $htmlname='fk_projet') +{ + global $conf,$user,$langs,$db; + + $out=''; + + $sql = "SELECT p.rowid, p.ref, p.title"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= " WHERE p.entity = ".$conf->entity; + if (is_numeric($selected)) $sql.= " AND p.rowid = ".$selected; + + dol_syslog("Form::select_projet sql=".$sql); + $resql=$db->query($sql); + if ($resql) + { + if ($conf->use_javascript_ajax && ! $forcecombo) + { + $minLength = (is_numeric($conf->global->COMPANY_USE_SEARCH_TO_SELECT)?$conf->global->COMPANY_USE_SEARCH_TO_SELECT:2); + + $projetid = 0; + + if ($selected) + { + $obj = $db->fetch_object($resql); + $projetid = $obj->rowid?$obj->rowid:''; + } + + $out.= "\n".'<!-- Input text for third party with Ajax.Autocompleter (select_techno_ajax) -->'."\n"; + $out.= '<table class="nobordernopadding"><tr class="nocellnopadd">'; + $out.= '<td class="nobordernopadding">'; + if ($projetid == 0) { + $out.= '<input type="text" size="30" id="search_'.$htmlname.'" name="search_'.$htmlname.'" value="" />'; + } else { + $out.= '<input type="text" size="30" id="search_'.$htmlname.'" name="search_'.$htmlname.'" value="'.$obj->ref.' - '.$obj->title.'" />'; + } + $out.= ajax_autocompleter(($projetid?$projetid:-1),$htmlname,dol_buildpath('/expensereport/ajax/ajaxprojet.php',1).'?filter='.urlencode($filter), '', $minLength); + $out.= '</td>'; + $out.= '</tr>'; + $out.= '</table>'; + } + + } + else + { + dol_print_error($db); + } + + return $out; +} + +/** + * Return list of types of notes with select value = id + * + * @param selected Preselected type + * @param htmlname Name of field in form + * @param showempty Add an empty field + * @return string Select html + */ +function select_type_fees_id($selected='',$htmlname='type',$showempty=0) +{ + global $db,$langs,$user; + $langs->load("trips"); + + print '<select class="flat" name="'.$htmlname.'">'; + if ($showempty) + { + print '<option value="-1"'; + if ($selected == -1) print ' selected="true"'; + print '> </option>'; + } + + $sql = "SELECT c.code, c.label as type,c.id FROM ".MAIN_DB_PREFIX."c_type_fees as c"; + $sql.= " ORDER BY c.label ASC"; + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + while ($i < $num) + { + $obj = $db->fetch_object($resql); + print '<option value="'.$obj->id.'"'; + if ($obj->code == $selected) print ' selected="true"'; + print '>'; + if ($obj->code != $langs->trans($obj->code)) print $langs->trans($obj->code); + else print $langs->trans($obj->type); + $i++; + } + } + print '</select>'; +} diff --git a/htdocs/expensereport/class/expensereportstats.class.php b/htdocs/expensereport/class/expensereportstats.class.php new file mode 100644 index 0000000000000000000000000000000000000000..64d0aaf01ed43c3f96044db8de8854c1c90023f1 --- /dev/null +++ b/htdocs/expensereport/class/expensereportstats.class.php @@ -0,0 +1,163 @@ +<?php +/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (c) 2005-2008 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@capnetworks.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 <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/expensereport/class/expensereportstats.class.php + * \ingroup factures + * \brief Fichier de la classe de gestion des stats des expensereport et notes de frais + */ +include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php'; +dol_include_once('/expensereport/class/expensereport.class.php'); + +/** + * Classe permettant la gestion des stats des expensereports et notes de frais + */ +class ExpenseReportStats extends Stats +{ + public $table_element; + + var $socid; + var $userid; + + var $from; + var $field; + var $where; + + /** + * Constructor + * + * @param DoliDB $db Database handler + * @param int $socid Id third party + * @param int $userid Id user for filter + * @return void + */ + function __construct($db, $socid=0, $userid=0) + { + global $conf; + + $this->db = $db; + $this->socid = $socid; + $this->userid = $userid; + + $object=new ExpenseReport($this->db); + $this->from = MAIN_DB_PREFIX.$object->table_element; + $this->field='total_ht'; + + $this->where = " fk_c_expensereport_statuts > 0 and date_valide > '2000-01-01'"; + //$this->where.= " AND entity = ".$conf->entity; + if ($this->socid) + { + $this->where.=" AND fk_soc = ".$this->socid; + } + if ($this->userid > 0) $this->where.=' AND fk_user_author = '.$this->userid; + } + + + /** + * Renvoie le nombre de facture par annee + * + * @return array Array of values + */ + function getNbByYear() + { + $sql = "SELECT YEAR(date_valide) as dm, count(*)"; + $sql.= " FROM ".$this->from; + $sql.= " GROUP BY dm DESC"; + $sql.= " WHERE ".$this->where; + + return $this->_getNbByYear($sql); + } + + + /** + * Renvoie le nombre de facture par mois pour une annee donnee + * + * @param string $year Year to scan + * @return array Array of values + */ + function getNbByMonth($year) + { + $sql = "SELECT MONTH(date_valide) as dm, count(*)"; + $sql.= " FROM ".$this->from; + $sql.= " WHERE YEAR(date_valide) = ".$year; + $sql.= " AND ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + $res=$this->_getNbByMonth($year, $sql); + //var_dump($res);print '<br>'; + return $res; + } + + + /** + * Renvoie le montant de facture par mois pour une annee donnee + * + * @param int $year Year to scan + * @return array Array of values + */ + function getAmountByMonth($year) + { + $sql = "SELECT date_format(date_valide,'%m') as dm, sum(".$this->field.")"; + $sql.= " FROM ".$this->from; + $sql.= " WHERE date_format(date_valide,'%Y') = '".$year."'"; + $sql.= " AND ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + $res=$this->_getAmountByMonth($year, $sql); + //var_dump($res);print '<br>'; + return $res; + } + + /** + * Return average amount + * + * @param int $year Year to scan + * @return array Array of values + */ + function getAverageByMonth($year) + { + $sql = "SELECT date_format(date_valide,'%m') as dm, avg(".$this->field.")"; + $sql.= " FROM ".$this->from; + $sql.= " WHERE date_format(date_valide,'%Y') = '".$year."'"; + $sql.= " AND ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + return $this->_getAverageByMonth($year, $sql); + } + + /** + * Return nb, total and average + * + * @return array Array of values + */ + function getAllByYear() + { + $sql = "SELECT date_format(date_valide,'%Y') as year, count(*) as nb, sum(".$this->field.") as total, avg(".$this->field.") as avg"; + $sql.= " FROM ".$this->from; + $sql.= " WHERE ".$this->where; + $sql.= " GROUP BY year"; + $sql.= $this->db->order('year','DESC'); + + return $this->_getAllByYear($sql); + } +} + diff --git a/htdocs/expensereport/document.php b/htdocs/expensereport/document.php new file mode 100644 index 0000000000000000000000000000000000000000..65ee2a1bbaad9e1d1b036c2c1f1f63dc444eca2e --- /dev/null +++ b/htdocs/expensereport/document.php @@ -0,0 +1,131 @@ +<?php +/* Copyright (C) 2003-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com> + * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@capnetworks.com> + * Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com> + * Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es> + * Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/compta/expensereport/document.php + * \ingroup expensereport + * \brief Page of linked files onto trip and expenses + */ + +require '../main.inc.php'; + +$langs->load("other"); +$langs->load("trips"); +$langs->load("companies"); +$langs->load("interventions"); + +$id = GETPOST('id','int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action','alpha'); +$confirm = GETPOST('confirm','alpha'); + +// Security check +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expensereport', $id, ''); + + +// Get parameters +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortorder) $sortorder="ASC"; +if (! $sortfield) $sortfield="name"; + + +$object = new ExpenseReport($db); +$object->fetch($id, $ref); + +$upload_dir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($object->ref); +$modulepart='trip'; + + +/* + * Actions + */ + +include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php'; + + +/* + * View + */ + +$form = new Form($db); + +llxHeader("","",$langs->trans("TripCard")); + + +if ($object->id) +{ + $object->fetch_thirdparty(); + + $head=trip_prepare_head($object); + + dol_fiche_head($head, 'documents', $langs->trans("TripCard"), 0, 'trip'); + + + // Construit liste des fichiers + $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); + $totalsize=0; + foreach($filearray as $key => $file) + { + $totalsize+=$file['size']; + } + + + print '<table class="border" width="100%">'; + + $linkback = '<a href="'.DOL_URL_ROOT.'/compta/expensereport/list.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>'; + + // Ref + print '<tr><td width="30%">'.$langs->trans("Ref").'</td><td>'; + print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'ref', ''); + print '</td></tr>'; + + // Societe + //print "<tr><td>".$langs->trans("Company")."</td><td>".$object->client->getNomUrl(1)."</td></tr>"; + + print '<tr><td>'.$langs->trans("NbOfAttachedFiles").'</td><td colspan="3">'.count($filearray).'</td></tr>'; + print '<tr><td>'.$langs->trans("TotalSizeOfAttachedFiles").'</td><td colspan="3">'.$totalsize.' '.$langs->trans("bytes").'</td></tr>'; + print '</table>'; + + print '</div>'; + + $modulepart = 'expensereport'; + $permission = $user->rights->expensereport->creer; + $param = '&id=' . $object->id; + include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php'; + +} +else +{ + print $langs->trans("ErrorUnknown"); +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/expensereport/export_csv.php b/htdocs/expensereport/export_csv.php new file mode 100755 index 0000000000000000000000000000000000000000..07f4167b724d607fe685ec1ebcd74d583f419eda --- /dev/null +++ b/htdocs/expensereport/export_csv.php @@ -0,0 +1,199 @@ +<?php +/* Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/expensereport/index.php + * \brief Page list of expenses + */ + +require '../main.inc.php'; +require_once(DOL_DOCUMENT_ROOT."/core/class/html.formfile.class.php"); +dol_include_once("/expensereport/class/expensereport.class.php"); + +$langs->load("users"); +$langs->load("trips"); + +if(!$user->rights->expensereport->export_csv) { + accessforbidden(); + exit(); +} + +// Security check +$socid = $_GET["socid"]?$_GET["socid"]:''; +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expensereport','',''); + +$req = "SELECT * FROM ".MAIN_DB_PREFIX."rights_def WHERE id = '178'"; +$result = $db->query($req); +$num = $db->num_rows($result); + +if($num < 1) { + + $insert = "INSERT INTO ".MAIN_DB_PREFIX."rights_def ("; + $insert.= "`id` ,"; + $insert.= "`libelle` ,"; + $insert.= "`module` ,"; + $insert.= "`entity` ,"; + $insert.= "`perms` ,"; + $insert.= "`subperms` ,"; + $insert.= "`type` ,"; + $insert.= "`bydefault`"; + $insert.= ")"; + $insert.= "VALUES ("; + $insert.= "'178', 'Exporter les notes de frais au format CSV', 'expensereport', '1', 'export_csv', NULL , 'r', '0'"; + $insert.= ")"; + + $req = $db->query($insert); + +} + + +/* + * View + */ + +llxHeader(); + +print_fiche_titre($langs->trans("ExportTripCSV")); + +print '<div class="tabBar">'; + +print '<form method="post" action="'.$_SERVER['PHP_SELF'].'">'; +print '<input type="hidden" name="action" value="export"/>'; +print '<p>Choisir le mois à exporter : '; + +$year = date('Y', time()); +$month = date('m', time()); + +print '<select name="mois">'; + +for($i=1;$i<13;$i++) { + $mois = str_pad($i, 2, "0", STR_PAD_LEFT); + if($month == $mois) { + print '<option value="'.$mois.'" selected="selected">'.$mois.'</option>'; + } else { + print '<option value="'.$mois.'">'.$mois.'</option>'; + } +} + +print '</select> '; + +print '<select name="annee">'; + +for($i=2009;$i<$year+1;$i++) { + if($year == $i) { + print '<option value="'.$i.'" selected="selected">'.$i.'</option>'; + } else { + print '<option value="'.$i.'">'.$i.'</option>'; + } +} + +print '</select> '; + +print '<input type="submit" class="button" value="Exporter" />'; +print '</p>'; +print '</form>'."\n"; + +// Si c'est une action +if (isset($_POST['action'])) +{ + if($_POST['action'] == 'export') + { + $select_date = $_POST['annee'].'-'.$_POST['mois']; + + //var_dump($conf->expensereport->dir_output.'/export/'); + if (!file_exists($conf->expensereport->dir_output.'/export/')) + { + dol_mkdir($conf->expensereport->dir_output.'/export/'); + } + + $dir = $conf->expensereport->dir_output.'/export/expensereport-'.$select_date.'.csv'; + $outputlangs = $langs; + $outputlangs->charset_output = 'UTF-8'; + + $sql = "SELECT d.rowid, d.ref_number, d.date_paiement, d.total_ht, d.total_tva, d.total_ttc"; + $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d"; + $sql.= " WHERE date_paiement LIKE '".$select_date."%'"; + $sql.= " ORDER BY d.rowid"; + + $result = $db->query($sql); + $num = $db->num_rows($result); + if ($num) + { + $open = fopen($dir,"w+"); + + $ligne = "ID, Référence, ----, Date paiement, Montant HT, TVA, Montant TTC\n"; + for ($i = 0; $i < $num; $i++) + { + $ligne.= "----, ----, ----, ----, ----, ----, ----\n"; + $objet = $db->fetch_object($result); + $objet->total_ht = number_format($objet->total_ht,2); + $objet->total_tva = number_format($objet->total_tva,2); + $objet->total_ttc = number_format($objet->total_ttc,2); + $objet->ref_number = trim($objet->ref_number); + $ligne.= "{$objet->rowid}, {$objet->ref_number}, ----, {$objet->date_paiement}, {$objet->total_ht}, {$objet->total_tva}, {$objet->total_ttc}\n"; + + $ligne.= "--->, Ligne, Type, Description, ----, ----, ----\n"; + + + $sql2 = "SELECT de.rowid, t.label as libelle, de.comments, de.total_ht, de.total_tva, de.total_ttc"; + $sql2.= " FROM ".MAIN_DB_PREFIX."expensereport_det as de,"; + $sql2.= " ".MAIN_DB_PREFIX."c_type_fees as t"; + $sql2.= " WHERE de.fk_c_type_fees = t.id"; + $sql2.= " AND de.fk_expensereport = '".$objet->rowid."'"; + $sql2.= " ORDER BY de.date"; + + $result2 = $db->query($sql2); + $num2 = $db->num_rows($result2); + + if($num2) { + for ($a = 0; $a < $num2; $a++) + { + $objet2 = $db->fetch_object($result2); + $objet2->total_ht = number_format($objet2->total_ht,2); + $objet2->total_tva = number_format($objet2->total_tva,2); + $objet2->total_ttc = number_format($objet2->total_ttc,2); + $objet2->comments = str_replace(',',';',$objet2->comments); + $objet2->comments = str_replace("\r\n",' ',$objet2->comments); + $objet2->comments = str_replace("\n",' ',$objet2->comments); + + $ligne.= "--->, {$objet2->rowid}, {$objet2->libelle}, {$objet2->comments}, {$objet2->total_ht}, {$objet2->total_tva}, {$objet2->total_ttc}\n"; + } + } + + } + + $ligne = $outputlangs->convToOutputCharset($ligne); + + fwrite($open,$ligne); + fclose($open); + + print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart=expensereport&file=export%2Fexpensereport-'.$select_date.'.csv" target="_blank">Télécharger le fichier expensereport-'.$select_date.'.csv</a>'; + + } else { + + print '<b>'.$langs->trans('NoTripsToExportCSV').'</b>'; + + } + } +} + +print '</div>'; + +llxFooter(); + +$db->close(); diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php new file mode 100644 index 0000000000000000000000000000000000000000..aae513618db2083737299a12972485e92becb016 --- /dev/null +++ b/htdocs/expensereport/index.php @@ -0,0 +1,208 @@ +<?php +/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com> + * Copyright (C) 2005-2011 Regis Houssin <regis.houssin@capnetworks.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 <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/expensereport/index.php + * \brief Page list of expenses + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php'; +dol_include_once("/expensereport/class/expensereport.class.php"); + +$langs->load("companies"); +$langs->load("users"); +$langs->load("trips"); + +// Security check +$socid = GETPOST('socid','int'); +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expensereport','',''); + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortorder) $sortorder="DESC"; +if (! $sortfield) $sortfield="d.date_create"; +$limit = $conf->liste_limit; + + +/* + * View + */ + +$tripandexpense_static=new ExpenseReport($db); + +$childids = $user->getAllChildIds(); +$childids[]=$user->id; + +//$help_url='EN:Module_Donations|FR:Module_Dons|ES:Módulo_Donaciones'; +$help_url=''; +llxHeader('',$langs->trans("ListOfFees"),$help_url); + + +$label=$somme=$nb=array(); + +$totalnb=$totalsum=0; +$sql = "SELECT tf.code, tf.label, count(de.rowid) as nb, sum(de.total_ht) as km"; +$sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d, ".MAIN_DB_PREFIX."expensereport_det as de, ".MAIN_DB_PREFIX."c_type_fees as tf"; +$sql.= " WHERE de.fk_expensereport = d.rowid AND de.fk_c_type_fees = tf.id"; +if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)) $sql.=' AND d.fk_user_author IN ('.join(',',$childids).')'; +$sql.= " GROUP BY tf.code, tf.label"; + +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $db->fetch_object($result); + + $somme[$objp->code] = $objp->km; + $nb[$objp->code] = $objp->nb; + $label[$objp->code] = $objp->label; + $totalnb += $objp->nb; + $totalsum += $objp->km; + $i++; + } + $db->free($result); +} else { + dol_print_error($db); +} + + +print_fiche_titre($langs->trans("ExpensesArea")); + + +print '<div class="fichecenter"><div class="fichethirdleft">'; + + +print '<table class="noborder" width="100%">'; +print '<tr class="liste_titre">'; +print '<td colspan="4">'.$langs->trans("Statistics").'</td>'; +print "</tr>\n"; + +//$listoftype=$tripandexpense_static->listOfTypes(); +$listoftype=$label; +foreach ($listoftype as $code => $label) +{ + $dataseries[]=array('label'=>$label,'data'=>(isset($somme[$code])?(int) $somme[$code]:0)); +} + +if ($conf->use_javascript_ajax) +{ + print '<tr '.$bc[0].'><td align="center" colspan="4">'; + $data=array('series'=>$dataseries); + dol_print_graph('stats',320,180,$data,1,'pie',0); + print '</td></tr>'; +} + +print '<tr class="liste_total">'; +print '<td>'.$langs->trans("Total").'</td>'; +print '<td align="right" colspan="3">'.price($totalsum,1,$langs,0,0,0,$conf->currency).'</td>'; +print '</tr>'; + +print '</table>'; + + + +// Right area +print '</div><div class="fichetwothirdright"><div class="ficheaddleft">'; + + +$max=10; + +$langs->load("boxes"); + +$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, d.rowid, d.date_debut as dated, d.date_fin as datef, d.date_create as dm, d.total_ht, d.total_ttc, d.fk_c_expensereport_statuts as fk_status"; +$sql.= " FROM ".MAIN_DB_PREFIX."expensereport as d, ".MAIN_DB_PREFIX."user as u"; +if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +$sql.= " WHERE u.rowid = d.fk_user_author"; +if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)) $sql.=' AND d.fk_user_author IN ('.join(',',$childids).')'; +//$sql.= " AND d.entity = ".$conf->entity; +if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND d.fk_user_author = s.rowid AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; +if ($socid) $sql.= " AND d.fk_user_author = ".$socid; +$sql.= $db->order($sortfield,$sortorder); +$sql.= $db->plimit($max, 0); + +$result = $db->query($sql); +if ($result) +{ + $var=false; + $num = $db->num_rows($result); + + $i = 0; + + print '<table class="noborder" width="100%">'; + print '<tr class="liste_titre">'; + print '<td colspan="2">'.$langs->trans("BoxTitleLastModifiedExpenses",min($max,$num)).'</td>'; + print '<td align="right">'.$langs->trans("AmountHT").'</td>'; + print '<td align="right">'.$langs->trans("AmountTTC").'</td>'; + print '<td align="right">'.$langs->trans("DateModificationShort").'</td>'; + print '<td> </td>'; + print '</tr>'; + if ($num) + { + $total_ttc = $totalam = $total = 0; + + $expensereportstatic=new ExpenseReport($db); + $userstatic=new User($db); + while ($i < $num && $i < $max) + { + $obj = $db->fetch_object($result); + $expensereportstatic->ref=$obj->rowid; + $expensereportstatic->id=$obj->rowid; + $userstatic->id=$obj->uid; + $userstatic->lastname=$obj->lastname; + $userstatic->firstname=$obj->firstname; + print '<tr '.$bc[$var].'>'; + print '<td>'.$expensereportstatic->getNomUrl(1).'</td>'; + print '<td>'.$userstatic->getNomUrl(1).'</td>'; + print '<td align="right">'.$obj->total_ht.'</td>'; + print '<td align="right">'.$obj->total_ttc.'</td>'; + print '<td align="right">'.dol_print_date($db->jdate($obj->dm),'day').'</td>'; + print '<td align="right">'; + //print $obj->libelle; + print $expensereportstatic->LibStatut($obj->fk_status,3); + print '</td>'; + print '</tr>'; + $var=!$var; + $i++; + } + + } + else + { + print '<tr '.$bc[$var].'><td colspan="2">'.$langs->trans("None").'</td></tr>'; + } + print '</table><br>'; +} +else dol_print_error($db); + +print '</div></div></div>'; + +llxFooter(); + +$db->close(); diff --git a/htdocs/expensereport/info.php b/htdocs/expensereport/info.php new file mode 100644 index 0000000000000000000000000000000000000000..866e67ec04bfccc121023b0c16cbc198f526c26e --- /dev/null +++ b/htdocs/expensereport/info.php @@ -0,0 +1,63 @@ +<?php +/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2004-2005 Laurent Destailleur <eldy@users.sourceforge.net> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/expensereport/info.php + * \ingroup trip + * \brief Page to show a trip information + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/trip.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/expensereport/class/expensereport.class.php'; + +$langs->load("trips"); + +// Security check +$id = GETPOST('id','int'); +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expensereport', $id, ''); + + +/* + * View + */ + +llxHeader(); + +if ($id) +{ + $object = new ExpenseReport($db); + $object->fetch($id); + $object->info($id); + + $head = trip_prepare_head($object); + + dol_fiche_head($head, 'info', $langs->trans("TripCard"), 0, 'trip'); + + print '<table width="100%"><tr><td>'; + dol_print_object_info($object); + print '</td></tr></table>'; + + print '</div>'; +} + +$db->close(); + +llxFooter(); diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php new file mode 100755 index 0000000000000000000000000000000000000000..c9a965b55878371a554c757608ddfe0072dd90b2 --- /dev/null +++ b/htdocs/expensereport/list.php @@ -0,0 +1,316 @@ +<?php +/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com> + * Copyright (C) 2005-2009 Regis Houssin <regis@dolibarr.fr> + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file htdocs/expensereport/index.php + * \brief Page liste des expensereports + */ + +require "../main.inc.php"; +dol_include_once("/expensereport/class/expensereport.class.php"); +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + +$langs->load("companies"); +$langs->load("users"); +$langs->load("trips"); + +// Security check +$socid = $_GET["socid"]?$_GET["socid"]:''; +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expensereport','',''); + +$search_ref=GETPOST('search_ref'); + + +/* + * View + */ + +$html = new Form($db); +$formother = new FormOther($db); +$expensereporttmp=new ExpenseReport($db); + +llxHeader(); + +$max_year = 5; +$min_year = 5; + +$sortorder = $_GET["sortorder"]; +$sortfield = $_GET["sortfield"]; +$page = $_GET["page"]; + +$search_ref = $_GET['search_ref']; + +$month_start = $_GET['month_start']; +$year_start = $_GET['year_start']; +$month_end = $_GET['month_end']; +$year_end = $_GET['year_end']; + +$search_user = $_GET['search_user']; + +$search_state = $_GET['search_state']; + + +if (!$sortorder) $sortorder="DESC"; +if (!$sortfield) $sortfield="d.date_debut"; + +if ($page == -1) { + $page = 0 ; +} + +$limit = $conf->liste_limit; +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +$sql = "SELECT d.rowid, d.ref_number, d.total_ht, d.total_tva, d.total_ttc, d.fk_c_expensereport_statuts,"; +$sql.= " d.date_debut, d.date_fin,"; +$sql.= " u.rowid as id_user, u.firstname, u.lastname"; +$sql.= " FROM ".MAIN_DB_PREFIX."expensereport d\n"; +$sql.= " INNER JOIN ".MAIN_DB_PREFIX."user u ON d.fk_user_author = u.rowid\n"; + +// WHERE +if(!empty($search_ref)){ + $sql.= " WHERE d.ref_number LIKE '%".$db->escape($search_ref)."%'\n"; +}else{ + $sql.= " WHERE 1 = 1\n"; +} + +// DATE START +if ($month_start > 0) { + if ($year_start > 0) { + if($month_end > 0) { + if($year_end > 0) { + $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; + $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; + } else { + $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; + $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; + } + } else { + if($year_end > 0) { + $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; + $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; + } else { + $sql.= " AND date_format(d.date_debut, '%Y-%m') >= '$year_start-$month_start'"; + } + } + } else { + $sql.= " AND date_format(d.date_debut, '%m') >= '$month_start'"; + } +} else { + if ($year_start > 0) { + if($month_end > 0) { + if($year_end > 0) { + $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; + $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; + } else { + $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; + $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; + } + } else { + if($year_end > 0) { + $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; + $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; + } else { + $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; + } + } + } else { + if($month_end > 0) { + if($year_end > 0) { + $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; + $sql.= " AND date_format(d.date_fin, '%Y-%m') <= '$year_end-$month_end'"; + } else { + $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; + $sql.= " AND date_format(d.date_fin, '%m') <= '$month_end'"; + } + } else { + if($year_end > 0) { + $sql.= " AND date_format(d.date_debut, '%Y') >= '$year_start'"; + $sql.= " AND date_format(d.date_fin, '%Y') <= '$year_end'"; + } + } + } +} + +if(!empty($search_user) && $search_user != -1) { + $sql.= " AND d.fk_user_author = '$search_user'\n"; +} + +if(!empty($search_state)) { + $sql.= " AND d.fk_c_expensereport_statuts = '$search_state'\n"; +} + +// RESTRICT RIGHTS +if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)){ + $sql.= " AND d.fk_user_author = '{$user->id}'\n"; +} + +// ORDER +$sql.= " ORDER BY $sortfield $sortorder " . $db->plimit( $limit + 1 ,$offset); + +if($_GET['debug']=='ok'){ + var_dump("<pre>",$sql,"</pre>"); exit(); +} + +//print $sql; +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + + $i = 0; + print_barre_liste($langs->trans("ListTripsAndExpenses"), $page, $_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords); + + print '<form method="GET" action="'.$_SERVER["PHP_SELF"].'">'."\n"; + print '<table class="noborder" width="100%">'; + print "<tr class=\"liste_titre\">"; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"d.rowid","",$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"d.date_debut","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"d.date_fin","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Person"),$_SERVER["PHP_SELF"],"u.lastname","",$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("TotalHT"),$_SERVER["PHP_SELF"],"d.total_ht","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("TotalVAT"),$_SERVER["PHP_SELF"],"d.total_tva","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("TotalTTC"),$_SERVER["PHP_SELF"],"d.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Statut"),$_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre(); + print "</tr>\n"; + + // FILTRES + print '<tr class="liste_titre">'; + print '<td class="liste_titre" align="left">'; + print '<input class="flat" size="15" type="text" name="search_ref" value="'.$search_ref.'">'; + + // Date start + print '<td class="liste_titre" align="center">'; + print '<input class="flat" type="text" size="1" maxlength="2" name="month_start" value="'.$month_start.'">'; + $formother->select_year($year_start,'year_start',1, $min_year, $max_year); + print '</td>'; + + // Date end + print '<td class="liste_titre" align="center">'; + print '<input class="flat" type="text" size="1" maxlength="2" name="month_end" value="'.$month_end.'">'; + $formother->select_year($year_end,'year_end',1, $min_year, $max_year); + print '</td>'; + + // User + if ($user->rights->expensereport->readall || $user->rights->expensereport->lire_tous){ + print '<td class="liste_titre" align="left">'; + $html->select_users($search_user,"search_user",1,"",0,''); + print '</td>'; + } else { + print '<td class="liste_titre"> </td>'; + } + + + print '<td class="liste_titre"> </td>'; + + print '<td class="liste_titre"> </td>'; + + print '<td class="liste_titre" align="right">'; + print "</td>"; + + // Status + print '<td class="liste_titre" align="right">'; + select_expensereport_statut($search_state,'search_state'); + print '</td>'; + print '<td class="liste_titre" align="right" width="20px">'; + print ' <input type="image" class="liste_titre" name="button_search" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png" alt="'.$langs->trans('Search').'">'; + print "</td>"; + + print "</tr>\n"; + + $var=true; + + $total_total_ht = 0; + $total_total_ttc = 0; + $total_total_tva = 0; + + if($num>0) + { + while ($i < $num) + { + $objp = $db->fetch_object($resql); + + $var=!$var; + print "<tr ".$bc[$var].">"; + print '<td><a href="card.php?id='.$objp->rowid.'">'.img_object($langs->trans("ShowTrip"),"trip").' '.$objp->ref_number.'</a></td>'; + print '<td align="center">'.($objp->date_debut > 0 ? dol_print_date($objp->date_debut, 'day') : '').'</td>'; + print '<td align="center">'.($objp->date_fin > 0 ? dol_print_date($objp->date_fin, 'day') : '').'</td>'; + print '<td align="left"><a href="'.DOL_URL_ROOT.'/user/card.php?id='.$objp->id_user.'">'.img_object($langs->trans("ShowUser"),"user").' '.dolGetFirstLastname($objp->firstname, $objp->lastname).'</a></td>'; + /*print '<td align="right">'.price($objp->total_tva, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; + print '<td align="right">'.price($objp->total_ht, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; + print '<td align="right">'.price($objp->total_ttc, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; + */ + print '<td align="right">'.price($objp->total_ht).'</td>'; + print '<td align="right">'.price($objp->total_tva).'</td>'; + print '<td align="right">'.price($objp->total_ttc).'</td>'; + + $expensereporttmp->status=$objp->statut; + print '<td align="right" colspan="2">'.$expensereporttmp->getLibStatut(5).'</td>'; + print "</tr>\n"; + + $total_total_ht = $total_total_ht + $objp->total_ht; + $total_total_tva = $total_total_tva + $objp->total_tva; + $total_total_ttc = $total_total_ttc + $objp->total_ttc; + + $i++; + } + + print '<tr class="liste_total">'; + print '<td colspan="4">'.$langs->trans("Total").'</td>'; + /* + print '<td style="text-align:right;">'.price($total_total_tva, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; + print '<td style="text-align:right;">'.price($total_total_ht, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; + print '<td style="text-align:right;">'.price($total_total_ttc, '', $langs, 0, 'MT', 0, $conf->currency).'</td>'; + */ + print '<td style="text-align:right;">'.$total_total_ht.'</td>'; + print '<td style="text-align:right;">'.$total_total_tva.'</td>'; + print '<td style="text-align:right;">'.$total_total_ttc.'</td>'; + print '<td></td>'; + print '<td></td>'; + print '</tr>'; + + } + else + { + print '<td colspan="9">'.$langs->trans("NoRecordFound").'</td>'; + } + print "</table>"; + + print "</form>"; + + print '<div class="tabsAction">'; + print '<a href="'.dol_buildpath('/expensereport/card.php',1).'?action=create" class="butAction">Ajouter une note de frais</a>'; + print '</div>'; + + $db->free($resql); +} +else +{ + dol_print_error($db); +} + + +llxFooter(); + +$db->close(); diff --git a/htdocs/expensereport/stats/index.php b/htdocs/expensereport/stats/index.php new file mode 100755 index 0000000000000000000000000000000000000000..07843985b007abf097ce5e76c0385ff1adec6a9c --- /dev/null +++ b/htdocs/expensereport/stats/index.php @@ -0,0 +1,297 @@ +<?php +/* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (c) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2012 Marcos García <marcosgdf@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 <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/expensereport/stats/index.php + * \ingroup expensereport + * \brief Page for statistics of module trips and expenses + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereportstats.class.php'; + +$langs->load("trips"); + +$WIDTH=DolGraph::getDefaultGraphSizeForStats('width'); +$HEIGHT=DolGraph::getDefaultGraphSizeForStats('height'); + +$userid=GETPOST('userid','int'); +$socid=GETPOST('socid','int'); if ($socid < 0) $socid=0; +$id = GETPOST('id','int'); + +// Security check +if ($user->societe_id > 0) +{ + $action = ''; + $socid = $user->societe_id; +} +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expensereport', $id,''); + +$nowyear=strftime("%Y", dol_now()); +$year = GETPOST('year')>0?GETPOST('year'):$nowyear; +//$startyear=$year-2; +$startyear=$year-1; +$endyear=$year; + +$mode=GETPOST("mode")?GETPOST("mode"):'customer'; + + +/* + * View + */ + +$form=new Form($db); + +llxHeader(); + +$title=$langs->trans("TripsAndExpensesStatistics"); +$dir=$conf->expensereport->dir_temp; + +print_fiche_titre($title, $mesg); + +dol_mkdir($dir); + +$stats = new ExpenseReportStats($db, $socid, $userid); + + +// Build graphic number of object +// $data = array(array('Lib',val1,val2,val3),...) +//print "$endyear, $startyear"; +$data = $stats->getNbByMonthWithPrevYear($endyear,$startyear); +//var_dump($data); + +$filenamenb = $dir."/tripsexpensesnbinyear-".$year.".png"; +$fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=tripsexpensesstats&file=tripsexpensesnbinyear-'.$year.'.png'; + +$px1 = new DolGraph(); +$mesg = $px1->isGraphKo(); +if (! $mesg) +{ + $px1->SetData($data); + $px1->SetPrecisionY(0); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px1->SetLegend($legend); + $px1->SetMaxValue($px1->GetCeilMaxValue()); + $px1->SetWidth($WIDTH); + $px1->SetHeight($HEIGHT); + $px1->SetYLabel($langs->trans("Number")); + $px1->SetShading(3); + $px1->SetHorizTickIncrement(1); + $px1->SetPrecisionY(0); + $px1->mode='depth'; + $px1->SetTitle($langs->trans("NumberByMonth")); + + $px1->draw($filenamenb,$fileurlnb); +} + +// Build graphic amount of object +$data = $stats->getAmountByMonthWithPrevYear($endyear,$startyear); +//var_dump($data); +// $data = array(array('Lib',val1,val2,val3),...) + +$filenameamount = $dir."/tripsexpensesamountinyear-".$year.".png"; +$fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=tripsexpensesstats&file=tripsexpensesamountinyear-'.$year.'.png'; + +$px2 = new DolGraph(); +$mesg = $px2->isGraphKo(); +if (! $mesg) +{ + $px2->SetData($data); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px2->SetLegend($legend); + $px2->SetMaxValue($px2->GetCeilMaxValue()); + $px2->SetMinValue(min(0,$px2->GetFloorMinValue())); + $px2->SetWidth($WIDTH); + $px2->SetHeight($HEIGHT); + $px2->SetYLabel($langs->trans("Amount")); + $px2->SetShading(3); + $px2->SetHorizTickIncrement(1); + $px2->SetPrecisionY(0); + $px2->mode='depth'; + $px2->SetTitle($langs->trans("AmountTotal")); + + $px2->draw($filenameamount,$fileurlamount); +} + + +$data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); + +if (!$user->rights->societe->client->voir || $user->societe_id) +{ + $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png'; + if ($mode == 'customer') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png'; + if ($mode == 'supplier') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$user->id.'-'.$year.'.png'; +} +else +{ + $filename_avg = $dir.'/ordersaverage-'.$year.'.png'; + if ($mode == 'customer') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$year.'.png'; + if ($mode == 'supplier') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$year.'.png'; +} + +$px3 = new DolGraph(); +$mesg = $px3->isGraphKo(); +if (! $mesg) +{ + $px3->SetData($data); + $i = $startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px3->SetLegend($legend); + $px3->SetYLabel($langs->trans("AmountAverage")); + $px3->SetMaxValue($px3->GetCeilMaxValue()); + $px3->SetMinValue($px3->GetFloorMinValue()); + $px3->SetWidth($WIDTH); + $px3->SetHeight($HEIGHT); + $px3->SetShading(3); + $px3->SetHorizTickIncrement(1); + $px3->SetPrecisionY(0); + $px3->mode='depth'; + $px3->SetTitle($langs->trans("AmountAverage")); + + $px3->draw($filename_avg,$fileurl_avg); +} + + +// Show array +$data = $stats->getAllByYear(); +$arrayyears=array(); +foreach($data as $val) { + $arrayyears[$val['year']]=$val['year']; +} +if (! count($arrayyears)) $arrayyears[$nowyear]=$nowyear; + + +$h=0; +$head = array(); +$head[$h][0] = DOL_URL_ROOT . '/compta/expensereport/stats/index.php'; +$head[$h][1] = $langs->trans("ByMonthYear"); +$head[$h][2] = 'byyear'; +$h++; + +complete_head_from_modules($conf,$langs,null,$head,$h,'trip_stats'); + +dol_fiche_head($head,'byyear',$langs->trans("Statistics")); + + +print '<div class="fichecenter"><div class="fichethirdleft">'; + + +// Show filter box +print '<form name="stats" method="POST" action="'.$_SERVER["PHP_SELF"].'">'; +print '<input type="hidden" name="mode" value="'.$mode.'">'; +print '<table class="border" width="100%">'; +print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>'; +// Company +/* +print '<tr><td>'.$langs->trans("ThirdParty").'</td><td>'; +$filter=''; +print $form->select_company($socid,'socid',$filter,1,1); +print '</td></tr>'; +*/ +// User +print '<tr><td>'.$langs->trans("User").'</td><td>'; +print $form->select_dolusers($userid,'userid',1); +print '</td></tr>'; +// Year +print '<tr><td>'.$langs->trans("Year").'</td><td>'; +if (! in_array($year,$arrayyears)) $arrayyears[$year]=$year; +arsort($arrayyears); +print $form->selectarray('year',$arrayyears,$year,0); +print '</td></tr>'; +print '<tr><td align="center" colspan="2"><input type="submit" name="submit" class="button" value="'.$langs->trans("Refresh").'"></td></tr>'; +print '</table>'; +print '</form>'; +print '<br><br>'; + +print '<table class="border" width="100%">'; +print '<tr height="24">'; +print '<td align="center">'.$langs->trans("Year").'</td>'; +print '<td align="center">'.$langs->trans("Number").'</td>'; +print '<td align="center">'.$langs->trans("AmountTotal").'</td>'; +print '<td align="center">'.$langs->trans("AmountAverage").'</td>'; +print '</tr>'; + +$oldyear=0; +foreach ($data as $val) +{ + $year = $val['year']; + while ($year && $oldyear > $year+1) + { // If we have empty year + $oldyear--; + print '<tr height="24">'; + print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$oldyear.'&mode='.$mode.'">'.$oldyear.'</a></td>'; + print '<td align="right">0</td>'; + print '<td align="right">0</td>'; + print '<td align="right">0</td>'; + print '</tr>'; + } + print '<tr height="24">'; + print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&mode='.$mode.'">'.$year.'</a></td>'; + print '<td align="right">'.$val['nb'].'</td>'; + print '<td align="right">'.price(price2num($val['total'],'MT'),1).'</td>'; + print '<td align="right">'.price(price2num($val['avg'],'MT'),1).'</td>'; + print '</tr>'; + $oldyear=$year; +} + +print '</table>'; + + +print '</div><div class="fichetwothirdright"><div class="ficheaddleft">'; + + +// Show graphs +print '<table class="border" width="100%"><tr valign="top"><td align="center">'; +if ($mesg) { print $mesg; } +else { + print $px1->show(); + print "<br>\n"; + print $px2->show(); + print "<br>\n"; + print $px3->show(); +} +print '</td></tr></table>'; + + +print '</div></div></div>'; +print '<div style="clear:both"></div>'; + + +dol_fiche_end(); + + +llxFooter(); + +$db->close(); diff --git a/htdocs/expensereport/synchro_compta.php b/htdocs/expensereport/synchro_compta.php new file mode 100755 index 0000000000000000000000000000000000000000..3f94da6eb1be418a1726f8c167e8213b12370bec --- /dev/null +++ b/htdocs/expensereport/synchro_compta.php @@ -0,0 +1,196 @@ +<?php + +require '../main.inc.php'; +require_once(DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'); +dol_include_once("/expensereport/class/expensereport.class.php"); + +$langs->load("companies"); +$langs->load("users"); +$langs->load("trips"); +$langs->load("banks"); + +$idAccount=isset($_GET["account"])?$_GET["account"]:$_POST["account"]; + +if ($_GET["action"] == 'confirm_ndf_to_account' && $_GET["confirm"] == "yes"): + + $idTrip = $_GET['idTrip']; + + $expensereport = new ExpenseReport($db); + $expensereport->fetch($idTrip,$user); + + $datePaiement = explode("-",$expensereport->date_paiement); + + $dateop = dol_mktime(12,0,0,$datePaiement[1],$datePaiement[2],$datePaiement[0]); + $operation = $expensereport->code_paiement; + $label = "Règlement ".$expensereport->ref_number; + $amount = - price2num($expensereport->total_ttc); + $num_chq = ''; + $cat1 = ''; + + $user = new User($db); + $user->fetch($expensereport->fk_user_paid); + + $acct=new Account($db,$idAccount); + $insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, $cat1, $user); + + if ($insertid > 0): + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql.= " SET integration_compta = 1, fk_bank_account = $idAccount"; + $sql.= " WHERE rowid = $idTrip"; + $resql=$db->query($sql); + if($result): + Header("Location: synchro_compta.php?account=".$idAccount); + exit; + else: + dol_print_error($db); + endif; + else: + dol_print_error($db,$acct->error); + endif; +endif; + +if ($_GET["action"] == 'confirm_account_to_ndf' && $_GET["confirm"] == "yes"): + + $idTrip = $_GET['idTrip']; + + $expensereport = new ExpenseReport($db); + $expensereport->fetch($idTrip,$user); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank"; + $sql.= " WHERE label LIKE '%".$expensereport->ref_number."%'"; + $resql=$db->query($sql); + if ($resql > 0): + $sql = " UPDATE ".MAIN_DB_PREFIX."expensereport d"; + $sql.= " SET integration_compta = 0, fk_bank_account = 0"; + $sql.= " WHERE rowid = $idTrip"; + $resql=$db->query($sql); + if($result): + Header("Location: synchro_compta.php?account=".$idAccount); + exit; + else: + dol_print_error($db); + endif; + else: + dol_print_error($db); + endif; +endif; + + +/* + * Actions + */ + +llxHeader(); + +$html = new Form($db); + +$submit = isset($_POST['submit'])?true:false; +$idAccount=isset($_GET["account"])?$_GET["account"]:$_POST["account"]; + +print_fiche_titre($langs->trans("TripSynch")); + + +dol_fiche_head(''); + + +if ($_GET["action"] == 'ndfTOaccount'): + $idTrip = $_GET['idTrip']; + $ret=$html->form_confirm("synchro_compta.php?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("ndfToAccount"),$langs->trans("ConfirmNdfToAccount"),"confirm_ndf_to_account","","",1); + if ($ret == 'html') print '<br />'; +endif; + +if ($_GET["action"] == 'accountTOndf'): + $idTrip = $_GET['idTrip']; + $ret=$html->form_confirm("synchro_compta.php?idTrip=".$idTrip."&account=".$idAccount,$langs->trans("AccountToNdf"),$langs->trans("ConfirmAccountToNdf"),"confirm_account_to_ndf","","",1); + if ($ret == 'html') print '<br />'; +endif; + +if(empty($submit) && empty($idAccount)): + + print "<form name='add' method=\"post\" action=\"synchro_compta.php\">"; + print 'Choix du compte '; + print $html->select_comptes($_POST['account'],'account',0,'',1); + print ' <input type="submit" name="submit" class="button" value="'.$langs->trans("ViewAccountSynch").'">'; + print "</form>"; + +else: + + print "<form name='add' method=\"post\" action=\"synchro_compta.php\">"; + print 'Choix du compte '; + print $html->select_comptes($idAccount,'account',0,'',1); + print ' <input type="submit" class="button" value="'.$langs->trans("ViewAccountSynch").'">'; + print "</form>"; + + $sql = "SELECT d.fk_bank_account, d.ref_number, d.rowid, d.date_valide, d.fk_user_author, d.total_ttc, d.integration_compta, d.fk_c_expensereport_statuts"; + $sql.= " ,CONCAT(u.firstname,' ',u.lastname) as declarant_NDF"; + $sql.= " FROM ".MAIN_DB_PREFIX."expensereport d"; + $sql.= " INNER JOIN ".MAIN_DB_PREFIX."user u ON d.fk_user_author = u.rowid"; + $sql.= " WHERE d.fk_c_expensereport_statuts = 6"; + $sql.= " ORDER BY d.date_valide DESC"; + + $resql=$db->query($sql); + if ($resql): + $num = $db->num_rows($resql); $i = 0; + if($num>0): + + $account=new Account($db); + $account->fetch($idAccount); + + print '<br>'; + + print "<table class='noborder' width='80%'>"; + print '<tr class="liste_titre">'; + print '<td>'.$langs->trans("Ref").'</td>'; + print '<td>'.$langs->trans("DateValidation").'</td>'; + print '<td>'.$langs->trans("USER_AUTHOR").'</td>'; + print '<td align="center">'.$langs->trans("TotalTTC").'</td>'; + print '<td align="center">Actions</td>'; + print '<td>Compte</td>'; + print '<td align="center">Int.</td>'; + print '</tr>'; + + while($i<$num): + $objp = $db->fetch_object($resql); + $var=!$var; + print "<tr $bc[$var]>"; + print '<td>'.$objp->ref_number.'</td>'; + print '<td>'.dol_print_date($db->jdate($objp->date_valide),'day').'</td>'; + print '<td><a href="'.DOL_URL_ROOT.'/user/card.php?id='.$objp->fk_user_author.'">'.img_object($langs->trans("ShowUser"),"user").' '.$objp->declarant_NDF.'</a></td>'; + print '<td align="center">'.$objp->total_ttc.' '.$langs->trans("EURO").'</td>'; + + if($objp->integration_compta): + print '<td align="center"><a href="synchro_compta.php?action=accountTOndf&idTrip='.$objp->rowid.'&account='.$idAccount.'"><img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1leftarrow.png" style="border:0px;" alt="Compte vers NDF" title="Compte vers NDF"/></a></td>'; + else: + print '<td align="center"><a href="synchro_compta.php?action=ndfTOaccount&idTrip='.$objp->rowid.'&account='.$idAccount.'"><img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1rightarrow.png" style="border:0px;" alt="NDF vers Compte" title="NDF vers Compte"/></a></td>'; + endif; + + print '<td>'.$account->label.'</td>'; + + if($objp->integration_compta): + print '<td align="center"><img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/tick.png" style="border:0px;" alt="Intégration OK" /></td>'; + else: + print '<td align="center"><img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/off.png" style="border:0px;" alt="Intégration Non OK" /></td>'; + endif; + + print "</tr>"; + $i++; + endwhile; + + print "</table>"; + + else: + print '<div class="error">'.$langs->trans("AucuneTripToSynch").'</div>'; + endif; + + $db->free($resql); + else: + dol_print_error($db); + endif; + +endif; + +dol_fiche_end(); + +llxFooter(); + +$db->close(); \ No newline at end of file diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index 1f61a1a5a9bd115ddd8a8980a8f8246755a0d4ff..0acea91984b88e4fdb1fd6ed44bdb32e5e3b1d83 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -111,3 +111,77 @@ ALTER TABLE llx_commande_fournisseur_dispatch ADD COLUMN sellby date DEFAULT NUL ALTER TABLE llx_stock_mouvement ADD COLUMN batch varchar(30) DEFAULT NULL; ALTER TABLE llx_stock_mouvement ADD COLUMN eatby date DEFAULT NULL; ALTER TABLE llx_stock_mouvement ADD COLUMN sellby date DEFAULT NULL; + + + + +CREATE TABLE llx_expensereport ( + rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY, + ref_number varchar(50) NOT NULL, + entity integer DEFAULT 1 NOT NULL, -- multi company id + ref_number_int integer DEFAULT NULL, + ref_ext integer, + total_ht double(24,8) DEFAULT 0, + total_tva double(24,8) DEFAULT 0, + localtax1 double(24,8) DEFAULT 0, -- amount total localtax1 + localtax2 double(24,8) DEFAULT 0, -- amount total localtax2 + total_ttc double(24,8) DEFAULT 0, + date_debut date NOT NULL, + date_fin date NOT NULL, + date_paiement datetime, + date_valide datetime, + date_create datetime NOT NULL, + fk_user_author integer NOT NULL, + fk_user_modif integer DEFAULT NULL, + fk_user_validator integer DEFAULT NULL, + fk_c_expensereport_statuts integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé + fk_c_paiement integer DEFAULT NULL, + note text, + note_private text, + fk_user_valid integer DEFAULT NULL, + fk_user_paid integer DEFAULT NULL, + detail_refuse varchar(255) DEFAULT NULL, + date_cancel datetime, + date_refuse datetime, + detail_cancel varchar(255) DEFAULT NULL, + fk_user_cancel integer DEFAULT NULL, + fk_user_refuse integer DEFAULT NULL, + integration_compta integer DEFAULT NULL, + fk_bank_account integer DEFAULT NULL, + model_pdf varchar(50) DEFAULT NULL +) ENGINE=innodb; + + + + +CREATE TABLE llx_expensereport_det +( + rowid integer PRIMARY KEY NOT NULL, + fk_expensereport integer NOT NULL, + fk_c_type_fees integer NOT NULL, + fk_projet integer NOT NULL, + fk_c_tva integer NOT NULL, + comments text NOT NULL, + product_type integer DEFAULT -1, + qty real NOT NULL, + value_unit real NOT NULL, + remise_percent real, + tva_tx double(6,3), -- Vat rat + localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + localtax1_type varchar(10) NULL, -- localtax1 type + localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_type varchar(10) NULL, -- localtax2 type + total_ht double(24,8) DEFAULT 0 NOT NULL, + total_tva double(24,8) DEFAULT 0 NOT NULL, + total_localtax1 double(24,8) DEFAULT 0, -- Total LocalTax1 for total quantity of line + total_localtax2 double(24,8) DEFAULT 0, -- total LocalTax2 for total quantity of line + total_ttc double(24,8) DEFAULT 0 NOT NULL, + date date NOT NULL, + info_bits integer DEFAULT 0, -- TVA NPR ou non + special_code integer DEFAULT 0, -- code pour les lignes speciales + rang integer DEFAULT 0, -- position of line + import_key varchar(14) +) ENGINE=innodb; + + + diff --git a/htdocs/install/mysql/tables/llx_expensereport.sql b/htdocs/install/mysql/tables/llx_expensereport.sql new file mode 100755 index 0000000000000000000000000000000000000000..6fcdfa92291e2f27d58479150233302f63cd8d07 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_expensereport.sql @@ -0,0 +1,54 @@ +-- ============================================================================ +-- Copyright (C) 2015 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- 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 <http://www.gnu.org/licenses/>. +-- +-- ============================================================================ + +CREATE TABLE llx_expensereport ( + rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY, + ref_number varchar(50) NOT NULL, + entity integer DEFAULT 1 NOT NULL, -- multi company id + ref_number_int integer DEFAULT NULL, + ref_ext integer, + total_ht double(24,8) DEFAULT 0, + total_tva double(24,8) DEFAULT 0, + localtax1 double(24,8) DEFAULT 0, -- amount total localtax1 + localtax2 double(24,8) DEFAULT 0, -- amount total localtax2 + total_ttc double(24,8) DEFAULT 0, + date_debut date NOT NULL, + date_fin date NOT NULL, + date_paiement datetime, + date_valide datetime, + date_create datetime NOT NULL, + fk_user_author integer NOT NULL, + fk_user_modif integer DEFAULT NULL, + fk_user_validator integer DEFAULT NULL, + fk_c_expensereport_statuts integer NOT NULL, -- 1=brouillon, 2=validé (attente approb), 4=annulé, 5=approuvé, 6=payed, 99=refusé + fk_c_paiement integer DEFAULT NULL, + note text, + note_private text, + fk_user_valid integer DEFAULT NULL, + fk_user_paid integer DEFAULT NULL, + detail_refuse varchar(255) DEFAULT NULL, + date_cancel datetime, + date_refuse datetime, + detail_cancel varchar(255) DEFAULT NULL, + fk_user_cancel integer DEFAULT NULL, + fk_user_refuse integer DEFAULT NULL, + integration_compta integer DEFAULT NULL, + fk_bank_account integer DEFAULT NULL, + model_pdf varchar(50) DEFAULT NULL +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_expensereport_det.sql b/htdocs/install/mysql/tables/llx_expensereport_det.sql new file mode 100644 index 0000000000000000000000000000000000000000..644668f5713a8f104c6fe05914a891d7827763e0 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_expensereport_det.sql @@ -0,0 +1,46 @@ +-- ============================================================================ +-- Copyright (C) 2015 Laurent Destailleur <eldy@users.sourceforge.net> +-- +-- 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 <http://www.gnu.org/licenses/>. +-- +-- ============================================================================ + +CREATE TABLE llx_expensereport_det +( + rowid integer PRIMARY KEY NOT NULL, + fk_expensereport integer NOT NULL, + fk_c_type_fees integer NOT NULL, + fk_projet integer NOT NULL, + fk_c_tva integer NOT NULL, + comments text NOT NULL, + product_type integer DEFAULT -1, + qty real NOT NULL, + value_unit real NOT NULL, + remise_percent real, + tva_tx double(6,3), -- Vat rat + localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + localtax1_type varchar(10) NULL, -- localtax1 type + localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_type varchar(10) NULL, -- localtax2 type + total_ht double(24,8) DEFAULT 0 NOT NULL, + total_tva double(24,8) DEFAULT 0 NOT NULL, + total_localtax1 double(24,8) DEFAULT 0, -- Total LocalTax1 for total quantity of line + total_localtax2 double(24,8) DEFAULT 0, -- total LocalTax2 for total quantity of line + total_ttc double(24,8) DEFAULT 0 NOT NULL, + date date NOT NULL, + info_bits integer DEFAULT 0, -- TVA NPR ou non + special_code integer DEFAULT 0, -- code pour les lignes speciales + rang integer DEFAULT 0, -- position of line + import_key varchar(14) +) ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_facturedet.sql b/htdocs/install/mysql/tables/llx_facturedet.sql index 2c01234f4b943eb394f22d47a882552a4b53e99b..d663adf4e1cbf96982aa5f2d4c2f54b9f3444ef4 100644 --- a/htdocs/install/mysql/tables/llx_facturedet.sql +++ b/htdocs/install/mysql/tables/llx_facturedet.sql @@ -30,7 +30,7 @@ create table llx_facturedet fk_product integer NULL, -- Doit pouvoir etre nul pour ligne detail sans produits label varchar(255) DEFAULT NULL, description text, - tva_tx double(6,3), -- Taux tva produit/service (exemple 19.6) + tva_tx double(6,3), -- Vat rate (example 20%) localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate localtax1_type varchar(10) NULL, -- localtax1 type localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate @@ -43,8 +43,8 @@ create table llx_facturedet price double(24,8), -- Deprecated (Do not use) total_ht double(24,8), -- Total HT de la ligne toute quantite et incluant remise ligne et globale total_tva double(24,8), -- Total TVA de la ligne toute quantite et incluant remise ligne et globale - total_localtax1 double(24,8) DEFAULT 0, -- Total LocalTax1 for total quantity of line - total_localtax2 double(24,8) DEFAULT 0, -- total LocalTax2 for total quantity of line + total_localtax1 double(24,8) DEFAULT 0, -- Total LocalTax1 for total quantity of line + total_localtax2 double(24,8) DEFAULT 0, -- total LocalTax2 for total quantity of line total_ttc double(24,8), -- Total TTC de la ligne toute quantite et incluant remise ligne et globale product_type integer DEFAULT 0, date_start datetime DEFAULT NULL, -- date debut si service @@ -55,8 +55,8 @@ create table llx_facturedet fk_product_fournisseur_price integer DEFAULT NULL, -- reference of supplier price when line was added (may be used to update buy_price_ht current price when future invoice will be created) fk_code_ventilation integer DEFAULT 0 NOT NULL, - special_code integer UNSIGNED DEFAULT 0, -- code pour les lignes speciales - rang integer DEFAULT 0, -- ordre d'affichage + special_code integer DEFAULT 0, -- code pour les lignes speciales + rang integer DEFAULT 0, -- position of line import_key varchar(14), situation_percent real, -- % progression of lines invoicing diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index ed39be9426c9eb0aef3925c45f39572df53589f3..345f2342244e9983cd3388953977fec21fb2cc2a 100755 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -493,10 +493,14 @@ Module600Name=Notifications Module600Desc=Send EMail notifications on some Dolibarr business events to third-party contacts (setup defined on each thirdparty) Module700Name=Donations Module700Desc=Donation management +Module770Name=Expense Report +Module770Desc=Management and claim expense reports (transportation, meal, ...) Module1200Name=Mantis Module1200Desc=Mantis integration Module1400Name=Accounting Module1400Desc=Accounting management (double parties) +Module1520Name=Document Generation +Module1520Desc=Mass mail document generation Module1780Name=Categories Module1780Desc=Category management (products, suppliers and customers) Module2000Name=WYSIWYG editor @@ -711,6 +715,13 @@ Permission538=Export services Permission701=Read donations Permission702=Create/modify donations Permission703=Delete donations +Permission771=Read expense reports (own and his subordinates) +Permission772=Create/modify expense reports +Permission773=Delete expense reports +Permission774=Read all expense reports (even for user not subordinates) +Permission775=Approve expense reports +Permission776=Pay expense reports +Permission779=Export expense reports Permission1001=Read stocks Permission1002=Create/modify warehouses Permission1003=Delete warehouses diff --git a/htdocs/langs/en_US/trips.lang b/htdocs/langs/en_US/trips.lang index 64adbeb0dd6060902b80a24ccdd96f1bb538932a..e34f58715d844b6e8ece11c55fe11eea3749ce00 100644 --- a/htdocs/langs/en_US/trips.lang +++ b/htdocs/langs/en_US/trips.lang @@ -1,22 +1,127 @@ # Dolibarr language file - Source file is en_US - trips -Trip=Trip -Trips=Trips -TripsAndExpenses=Trips and expenses -TripsAndExpensesStatistics=Trips and expenses statistics -TripCard=Trip card -AddTrip=Create trip -ListOfTrips=List of trips +Trip=Expense report +Trips=Expense reports +TripsAndExpenses=Expenses reports +TripsAndExpensesStatistics=Expense reports statistics +TripCard=Expense report card +AddTrip=Create expense report +ListOfTrips=List of expense report ListOfFees=List of fees -NewTrip=New trip +NewTrip=New expense report CompanyVisited=Company/foundation visited Kilometers=Kilometers FeesKilometersOrAmout=Amount or kilometers -DeleteTrip=Delete trip -ConfirmDeleteTrip=Are you sure you want to delete this trip ? +DeleteTrip=Delete expense report +ConfirmDeleteTrip=Are you sure you want to delete this expense report ? +ListTripsAndExpenses=List of expense reports +ExpensesArea=Expense reports area +SearchATripAndExpense=Search an expense report +ClassifyRefunded=Classify 'Refunded' + +TripId=Id expense report +AnyOtherInThisListCanValidate=Person to inform for validation. +TripSociete=Information company +TripSalarie=Informations user +TripNDF=Informations expense report + +DeleteLine=Delete a ligne of the expense report +ConfirmDeleteLine=Are you sure you want to delete this line ? + TF_OTHER=Other TF_LUNCH=Lunch -TF_TRIP=Trip -ListTripsAndExpenses=List of trips and expenses -ExpensesArea=Trips and expenses area -SearchATripAndExpense=Search a trip and expense -ClassifyRefunded=Classify 'Refunded' \ No newline at end of file +TF_METRO=Metro +TF_TRAIN=Train +TF_BUS=Bus +TF_PEAGE=Toll +TF_ESSENCE=Fuel +TF_HOTEL=Hostel +TF_TAXI=Taxi + +ErrorDoubleDeclaration=ERREUR : Vous avez déclaré au moins une note de frais dans le même intervalle. +ListTripsAndExpenses=Liste des notes de frais +AucuneNDF=Il n'y a aucune note de frais déclarée correspondante à votre recherche! +AucuneLigne=Il n'y a aucune ligne de déclarée dans cette note de frais! +AddLine=Ajouter une ligne +AddLineMini=Ajouter +TotalHT=Montant HT +TotalTTC=Montant TTC +TotalTVA=Total TVA + +Date_DEBUT=Date de début période +Date_FIN=Date de fin période +ModePaiement=Mode de paiement +Note=Note +Project=Projet + +VALIDATOR=Utilisateur informé pour validation +VALIDOR=Validée par +AUTHOR=Enregistrée par +AUTHORPAIEMENT=Payée par +REFUSEUR=Refusée par +CANCEL_USER=Annulée par + +MOTIF_REFUS=Motif de refus +MOTIF_CANCEL=Motif d'annulation + +DATE_REFUS=Date du refus +DATE_CANCEL=Date annulation +DATE_VALIDE=Date de validation +DATE_PAIEMENT=Date de paiement +DATE_SAVE=Date d'enregistrement + +REFUSE=Refuse +TO_PAID=Pay +BROUILLONNER=Reopen +SendToValid=Sent to approve +ModifyInfoGen=Edit + +NOT_VALIDATOR=Vous n'êtes pas la personne habilitée à valider cette note de frais! +NOT_AUTHOR=Vous n'êtes pas l'auteur de cette note de frais, impossible de réaliser l'opération voulue! +NOT_VALIDOR=Vous n'êtes pas le valideur de cette note de frais, vous ne pouvez donc pas réaliser cette opération! +NotUserRightToView=Vous n'avez pas le droit d'afficher cette note de frais. + +RefuseTrip=Refuser une note de frais +ConfirmRefuseTrip=Êtes vous sûr de vouloir refuser cette note de frais ? + +ValideTrip=Valider une note de frais +ConfirmValideTrip=Êtes vous sûr de vouloir valider cette note de frais ? + +PaidTrip=Payer une note de frais +ConfirmPaidTrip=Êtes vous sûr de vouloir payer cette note de frais ? + +CancelTrip=Annuler une note de frais +ConfirmCancelTrip=Êtes vous sûr de vouloir annuler cette note de frais ? + +BrouillonnerTrip=Remettre une note de frais en brouillon +ConfirmBrouillonnerTrip=Êtes vous sûr de vouloir remettre cette note de frais en brouillon ? + +SaveTrip=Enregistrement de votre note de frais +ConfirmSaveTrip=Êtes vous sûr de vouloir enregistrer cette note de frais? (elle sera transmise par mail pour validation) + +INFOS_DATES=Infos Workflow +INFOS_NDF=Infos générales note de frais + +StatsTrip=Statistiques +Synchro_Compta=NDF <-> Compte + +TripSynch=Synchronisation : Notes de frais <-> Compte courant +TripToSynch=Notes de frais à intégrer dans la compta +AucuneTripToSynch=Aucune note de frais n'est en statut "Payée". +ViewAccountSynch=Voir le compte + +ConfirmNdfToAccount=Êtes-vous sûr de vouloir intégrer cette note de frais dans le compte courant? +ndfToAccount=Note de frais - Intégration + +ConfirmAccountToNdf=Êtes-vous sûr de vouloir retirer cette note de frais du compte courant? +AccountToNdf=Note de frais - Retrait + +LINE_NOT_ADDED=Ligne non ajoutée : +NO_PROJECT=Aucun projet sélectionné. +NO_DATE=Aucune date sélectionnée. +NO_PRICE=Aucun prix indiqué. + +TripForValid=à Valider +TripForPaid=à Payer +TripPaid=Payée + +NoTripsToExportCSV=No expense report to export for this period. diff --git a/htdocs/langs/fr_FR/expensereport.lang b/htdocs/langs/fr_FR/expensereport.lang new file mode 100755 index 0000000000000000000000000000000000000000..6af74164f2dfc876cd35a14f51b5b9306600c08d --- /dev/null +++ b/htdocs/langs/fr_FR/expensereport.lang @@ -0,0 +1,137 @@ +# Dolibarr language file - fr_FR - trips +CHARSET=UTF-8 +Trip=Note de frais +Trips=Notes de frais +TripsAndExpenses=Notes de frais +TripId=Id note de frais +TripCard=Fiche note de frais +AddTrip=Ajouter note de frais +ListOfTrips=Liste des notes de frais +ListOfFees=Liste des notes de frais +NewTrip=Nouvelle note de frais +CancelAddTrip=Annuler +ExportTripCSV=Exporter en CSV +AnyOtherInThisListCanValidate=Toute personne dans la liste pourra valider. Le choix détermine qui sera informé. +TripSociete=Informations société +TripSalarie=Informations salarié +TripNDF=Informations note de frais + +DeleteTrip=Supprimer note de frais +ConfirmDeleteTrip=Êtes vous sûr de vouloir supprimer cette note de frais ? + +DeleteLine=Supprimer une ligne de la note de frais +ConfirmDeleteLine=Êtes vous sûr de vouloir supprimer cette ligne ? + +TF_OTHER=Autre +TF_LUNCH=Repas +TF_METRO=Métro +TF_TRAIN=Train +TF_RATP=Ratp +TF_BUS=Bus +TF_PEAGE=Péage +TF_ESSENCE=Essence +TF_SNCF=SNCF (Autre) +TF_HOTEL=Hôtel +TF_TRANSPORT=SNCF (Train) +TF_TAXI=Taxi + +ErrorDoubleDeclaration=ERREUR : Vous avez déclaré au moins une note de frais dans le même intervalle. +ListTripsAndExpenses=Liste des notes de frais +AucuneNDF=Il n'y a aucune note de frais déclarée correspondante à votre recherche! +AucuneLigne=Il n'y a aucune ligne de déclarée dans cette note de frais! +AddLine=Ajouter une ligne +AddLineMini=Ajouter +TotalHT=Montant HT +TotalTTC=Montant TTC +TotalTVA=Total TVA + +Date_DEBUT=Date de début période +Date_FIN=Date de fin période +ModePaiement=Mode de paiement +Note=Note +Project=Projet + +VALIDATOR=Utilisateur informé pour validation +VALIDOR=Validée par +AUTHOR=Enregistrée par +AUTHORPAIEMENT=Payée par +REFUSEUR=Refusée par +CANCEL_USER=Annulée par + +MOTIF_REFUS=Motif de refus +MOTIF_CANCEL=Motif d'annulation + +DATE_REFUS=Date du refus +DATE_CANCEL=Date annulation +DATE_VALIDE=Date de validation +DATE_PAIEMENT=Date de paiement +DATE_SAVE=Date d'enregistrement + +VALIDATE=Valider +REFUSE=Refuser +CANCEL=Annuler +TO_PAID=Payer +BROUILLONNER=Remettre en brouillon +SendToValid=Envoyer en validation +ModifyInfoGen=Modifier les infos générales + +Module20130304Name=Notes de frais +Module20130304Desc=Gestion des notes de frais et déplacement (par ') + +NOT_VALIDATOR=Vous n'êtes pas la personne habilitée à valider cette note de frais! +NOT_AUTHOR=Vous n'êtes pas l'auteur de cette note de frais, impossible de réaliser l'opération voulue! +NOT_VALIDOR=Vous n'êtes pas le valideur de cette note de frais, vous ne pouvez donc pas réaliser cette opération! +NotUserRightToView=Vous n'avez pas le droit d'afficher cette note de frais. + +RefuseTrip=Refuser une note de frais +ConfirmRefuseTrip=Êtes vous sûr de vouloir refuser cette note de frais ? + +ValideTrip=Valider une note de frais +ConfirmValideTrip=Êtes vous sûr de vouloir valider cette note de frais ? + +PaidTrip=Payer une note de frais +ConfirmPaidTrip=Êtes vous sûr de vouloir payer cette note de frais ? + +CancelTrip=Annuler une note de frais +ConfirmCancelTrip=Êtes vous sûr de vouloir annuler cette note de frais ? + +BrouillonnerTrip=Remettre une note de frais en brouillon +ConfirmBrouillonnerTrip=Êtes vous sûr de vouloir remettre cette note de frais en brouillon ? + +SaveTrip=Enregistrement de votre note de frais +ConfirmSaveTrip=Êtes vous sûr de vouloir enregistrer cette note de frais? (elle sera transmise par mail pour validation) + +INFOS_DATES=Infos Workflow +INFOS_NDF=Infos générales note de frais + +EURO=€ +PriceUNITAIRE=Prix U. (TTC) + +StatsTrip=Statistiques +Synchro_Compta=NDF <-> Compte + +TripSynch=Synchronisation : Notes de frais <-> Compte courant +TripToSynch=Notes de frais à intégrer dans la compta +AucuneTripToSynch=Aucune note de frais n'est en statut "Payée". +ViewAccountSynch=Voir le compte + +ConfirmNdfToAccount=Êtes-vous sûr de vouloir intégrer cette note de frais dans le compte courant? +ndfToAccount=Note de frais - Intégration + +ConfirmAccountToNdf=Êtes-vous sûr de vouloir retirer cette note de frais du compte courant? +AccountToNdf=Note de frais - Retrait + +USER_AUTHOR=Auteur +PU=P.U. +Q=Q + +LINE_NOT_ADDED=Ligne non ajoutée : +NO_PROJECT=Aucun projet sélectionné. +NO_DATE=Aucune date sélectionnée. +NO_PRICE=Aucun prix indiqué. + +TripForValid=à Valider +TripForPaid=à Payer +TripPaid=Payée + +NoTripsToExportCSV=Il n'y a pas de notes de frais à exporter pour cette période. \ No newline at end of file