diff --git a/htdocs/admin/project.php b/htdocs/admin/project.php index f2f216d7b52..8bb1baae575 100644 --- a/htdocs/admin/project.php +++ b/htdocs/admin/project.php @@ -3,6 +3,7 @@ * Copyright (C) 2011 Laurent Destailleur * Copyright (C) 2011-2012 Juanjo Menent * Copyright (C) 2011-2013 Philippe Grand + * Copyright (C) 2013 Florian Henry * * 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 @@ -16,13 +17,13 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - */ +*/ /** * \file htdocs/admin/project.php * \ingroup project * \brief Page to setup project module - */ +*/ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; @@ -45,7 +46,7 @@ $type='project'; /* * Actions - */ +*/ if ($action == 'updateMask') { @@ -56,14 +57,14 @@ if ($action == 'updateMask') if (! $res > 0) $error++; - if (! $error) - { - $mesg = "".$langs->trans("SetupSaved").""; - } - else - { - $mesg = "".$langs->trans("Error").""; - } + if (! $error) + { + $mesg = "".$langs->trans("SetupSaved").""; + } + else + { + $mesg = "".$langs->trans("Error").""; + } } else if ($action == 'specimen') @@ -78,7 +79,7 @@ else if ($action == 'specimen') $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); foreach($dirmodels as $reldir) { - $file=dol_buildpath($reldir."core/modules/project/pdf/pdf_".$modele.".modules.php",0); + $file=dol_buildpath($reldir."core/modules/project/pdf/pdf_".$modele.".modules.php",0); if (file_exists($file)) { $filefound=1; @@ -95,8 +96,8 @@ else if ($action == 'specimen') if ($module->write_file($project,$langs) > 0) { - header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project&file=SPECIMEN.pdf"); - return; + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project&file=SPECIMEN.pdf"); + return; } else { @@ -122,7 +123,7 @@ else if ($action == 'del') $ret = delDocumentModel($value, $type); if ($ret > 0) { - if ($conf->global->PROJECT_ADDON_PDF == "$value") dolibarr_del_const($db, 'PROJECT_ADDON_PDF',$conf->entity); + if ($conf->global->PROJECT_ADDON_PDF == "$value") dolibarr_del_const($db, 'PROJECT_ADDON_PDF',$conf->entity); } } @@ -154,7 +155,7 @@ else if ($action == 'setmod') /* * View - */ +*/ $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); @@ -179,8 +180,8 @@ dol_fiche_head($head, $hselected, $langs->trans("ModuleSetup")); /* * Projects Numbering model - */ - +*/ + print_titre($langs->trans("ProjectsNumberingModules")); print ''; @@ -284,7 +285,7 @@ print '

'; /* * Document templates generators - */ +*/ print_titre($langs->trans("ProjectsModelModule")); @@ -337,59 +338,80 @@ foreach ($dirmodels as $reldir) { while (($file = readdir($handle))!==false) { - if (substr($file, dol_strlen($file) -12) == '.modules.php' && substr($file,0,4) == 'pdf_') + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) { - $name = substr($file, 4, dol_strlen($file) -16); - $classname = substr($file, 0, dol_strlen($file) -12); - - $var=!$var; - print "\n $name"; - print "\n \n"; - require_once $dir.$file; - $module = new $classname($db); - print $module->description; - print "\n"; - - // Active - if (in_array($name, $def)) + if (file_exists($dir.'/'.$file)) { - print "\n"; - print 'scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("Enabled"),'switch_on'); - print ''; - print ""; - } - else - { - print "\n"; - print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; - print ""; - } + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); - // Default - print ""; - if ($conf->global->PROJECT_ADDON_PDF == "$name") - { - print img_picto($langs->trans("Default"),'on'); - } - else - { - print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; - } - print ''; + require_once $dir.'/'.$file; + $module = new $classname($db); - // Info - $htmltooltip = ''.$langs->trans("Name").': '.$module->name; - $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); - $htmltooltip.='
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; - $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; - $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); - print ''; - $link=''.img_object($langs->trans("Preview"),'project').''; - print $form->textwithpicto('     '.$link,$htmltooltip,-1,0); - print ''; + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; - print "\n"; + if ($modulequalified) + { + $var=!$var; + print ''; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print "\n"; + + // Active + if (in_array($name, $def)) + { + print "\n"; + print 'scandir.'&label='.urlencode($module->name).'">'; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print ""; + } + else + { + print "\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print ""; + } + + // Default + print ""; + if ($conf->global->PROJECT_ADDON_PDF == "$name") + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + $htmltooltip.='
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + + // Preview + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'bill').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print ''; + + print "\n"; + } + } } } closedir($handle); diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index 6c18da0e240..755ca681c73 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -162,10 +162,34 @@ if ($action == 'setdefaultduration') } } -/*if ($action == 'setusecustomercontactasrecipient') +// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) +if ($action == 'setModuleOptions') { - dolibarr_set_const($db, "PROPALE_USE_CUSTOMER_CONTACT_AS_RECIPIENT",$_POST["value"],'chaine',0,'',$conf->entity); -}*/ + $post_size=count($_POST); + + $db->begin(); + + for($i=0;$i < $post_size;$i++) + { + if (array_key_exists('param'.$i,$_POST)) + { + $param=GETPOST("param".$i,'alpha'); + $value=GETPOST("value".$i,'alpha'); + if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + } + } + if (! $error) + { + $db->commit(); + $mesg = "".$langs->trans("SetupSaved").""; + } + else + { + $db->rollback(); + $mesg = "".$langs->trans("Error").""; + } +} diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index de1a87ffe7e..e35c8d2940d 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -1,2250 +1,2250 @@ - - * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2010-2013 Juanjo Menent - * Copyright (C) 2010-2011 Philippe Grand - * Copyright (C) 2012 Christophe Battarel -* - * 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 . - */ - -/** - * \file htdocs/comm/propal.php - * \ingroup propale - * \brief Page of commercial proposals card and list - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formpropal.class.php'; -require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; -require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/propal.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; -if (! empty($conf->projet->enabled)) -{ - require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; -} - -$langs->load('companies'); -$langs->load('propal'); -$langs->load('compta'); -$langs->load('bills'); -$langs->load('orders'); -$langs->load('products'); -$langs->load("deliveries"); -if (! empty($conf->margin->enabled)) - $langs->load('margins'); - -$error=0; - -$id=GETPOST('id','int'); -$ref=GETPOST('ref','alpha'); -$socid=GETPOST('socid','int'); -$action=GETPOST('action','alpha'); -$origin=GETPOST('origin','alpha'); -$originid=GETPOST('originid','int'); -$confirm=GETPOST('confirm','alpha'); -$lineid=GETPOST('lineid','int'); - -//PDF -$hidedetails = (GETPOST('hidedetails','int') ? GETPOST('hidedetails','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); -$hidedesc = (GETPOST('hidedesc','int') ? GETPOST('hidedesc','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); -$hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); - -// Nombre de ligne pour choix de produit/service predefinis -$NBLINES=4; - -// Security check -if (! empty($user->societe_id)) $socid=$user->societe_id; -$result = restrictedArea($user, 'propal', $id); - -$object = new Propal($db); -$extrafields = new ExtraFields($db); - -// Load object -if ($id > 0 || ! empty($ref)) -{ - $ret=$object->fetch($id, $ref); - if ($ret > 0) $ret=$object->fetch_thirdparty(); - if ($ret < 0) dol_print_error('',$object->error); -} - -// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array -$hookmanager->initHooks(array('propalcard')); - - - -/* - * Actions - */ - -$parameters=array('socid'=>$socid); -$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - -// Action clone object -if ($action == 'confirm_clone' && $confirm == 'yes') -{ - if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) - { - setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); - } - else - { - if ($object->id > 0) - { - $result=$object->createFromClone($socid); - if ($result > 0) - { - header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); - exit; - } - else - { - setEventMessage($object->error, 'errors'); - $action=''; - } - } - } -} - -// Suppression de la propale -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->propal->supprimer) -{ - $result=$object->delete($user); - if ($result > 0) - { - header('Location: '.DOL_URL_ROOT.'/comm/propal/list.php'); - exit; - } - else - { - $langs->load("errors"); - setEventMessage($langs->trans($object->error), 'errors'); - } -} - -// Remove line -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->propal->creer) -{ - $result = $object->deleteline($lineid); - // reorder lines - if ($result) $object->line_order(true); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; -} - -// Validation -else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider) -{ - $result=$object->valid($user); - if ($result >= 0) - { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } - else - { - $langs->load("errors"); - setEventMessage($langs->trans($object->error), 'errors'); - } -} - -else if ($action == 'setdate' && $user->rights->propal->creer) -{ - $datep=dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - - if (empty($datep)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")), 'errors'); - } - - if (! $error) - { - $result=$object->set_date($user,$datep); - if ($result < 0) dol_print_error($db,$object->error); - } -} -else if ($action == 'setecheance' && $user->rights->propal->creer) -{ - $result=$object->set_echeance($user,dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear'])); - if ($result < 0) dol_print_error($db,$object->error); -} -else if ($action == 'setdate_livraison' && $user->rights->propal->creer) -{ - $result=$object->set_date_livraison($user,dol_mktime(12, 0, 0, $_POST['liv_month'], $_POST['liv_day'], $_POST['liv_year'])); - if ($result < 0) dol_print_error($db,$object->error); -} - -// Positionne ref client -else if ($action == 'set_ref_client' && $user->rights->propal->creer) -{ - $object->set_ref_client($user, $_POST['ref_client']); -} - -else if ($action == 'setnote_public' && $user->rights->propal->creer) -{ - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); - if ($result < 0) dol_print_error($db,$object->error); -} - -else if ($action == 'setnote' && $user->rights->propal->creer) -{ - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); - if ($result < 0) dol_print_error($db,$object->error); -} - -// Create proposal -else if ($action == 'add' && $user->rights->propal->creer) -{ - $object->socid=$socid; - $object->fetch_thirdparty(); - - $datep=dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); - $date_delivery=dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); - $duration=GETPOST('duree_validite'); - - if (empty($datep)) - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")), 'errors'); - $action='create'; - $error++; - } - if (empty($duration)) - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ValidityDuration")), 'errors'); - $action='create'; - $error++; - } - - if ($socid<1) - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); - $action='create'; - $error++; - } - - if (! $error) - { - $db->begin(); - - // Si on a selectionne une propal a copier, on realise la copie - if (GETPOST('createmode')=='copy' && GETPOST('copie_propal')) - { - if ($object->fetch(GETPOST('copie_propal')) > 0) - { - $object->ref = GETPOST('ref'); - $object->datep = $datep; - $object->date_livraison = $date_delivery; - $object->availability_id = GETPOST('availability_id'); - $object->demand_reason_id = GETPOST('demand_reason_id'); - $object->fk_delivery_address = GETPOST('fk_address'); - $object->duree_validite = $duration; - $object->cond_reglement_id = GETPOST('cond_reglement_id'); - $object->mode_reglement_id = GETPOST('mode_reglement_id'); - $object->remise_percent = GETPOST('remise_percent'); - $object->remise_absolue = GETPOST('remise_absolue'); - $object->socid = GETPOST('socid'); - $object->contactid = GETPOST('contactidp'); - $object->fk_project = GETPOST('projectid'); - $object->modelpdf = GETPOST('model'); - $object->author = $user->id; // deprecated - $object->note = GETPOST('note'); - $object->statut = 0; - - $id = $object->create_from($user); - } - else - { - setEventMessage($langs->trans("ErrorFailedToCopyProposal",GETPOST('copie_propal')), 'errors'); - } - } - else - { - $object->ref = GETPOST('ref'); - $object->ref_client = GETPOST('ref_client'); - $object->datep = $datep; - $object->date_livraison = $date_delivery; - $object->availability_id = GETPOST('availability_id'); - $object->demand_reason_id = GETPOST('demand_reason_id'); - $object->fk_delivery_address = GETPOST('fk_address'); - $object->duree_validite = GETPOST('duree_validite'); - $object->cond_reglement_id = GETPOST('cond_reglement_id'); - $object->mode_reglement_id = GETPOST('mode_reglement_id'); - - $object->contactid = GETPOST('contactidp'); - $object->fk_project = GETPOST('projectid'); - $object->modelpdf = GETPOST('model'); - $object->author = $user->id; // deprecated - $object->note = GETPOST('note'); - - $object->origin = GETPOST('origin'); - $object->origin_id = GETPOST('originid'); - - for ($i = 1 ; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i++) - { - if ($_POST['idprod'.$i]) - { - $xid = 'idprod'.$i; - $xqty = 'qty'.$i; - $xremise = 'remise'.$i; - $object->add_product($_POST[$xid],$_POST[$xqty],$_POST[$xremise]); - } - } - - // Get extra fields - foreach($_POST as $key => $value) - { - if (preg_match("/^options_/",$key)) - { - $object->array_options[$key]=GETPOST($key); - } - } - - $id = $object->create($user); - } - - if ($id > 0) - { - // Insertion contact par defaut si defini - if (GETPOST('contactidp')) - { - $result=$object->add_contact(GETPOST('contactidp'),'CUSTOMER','external'); - if ($result < 0) - { - $error++; - setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); - } - } - - if (! $error) - { - $db->commit(); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id); - exit; - } - else - { - $db->rollback(); - } - } - else - { - dol_print_error($db,$object->error); - $db->rollback(); - exit; - } - } -} - -// Classify billed -else if ($action == 'classifybilled' && $user->rights->propal->cloturer) -{ - $object->cloture($user, 4, ''); -} - -// Reopen proposal -else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) -{ - // prevent browser refresh from reopening proposal several times - if ($object->statut==2 || $object->statut==3) - { - $object->setStatut(1); - } -} - -// Close proposal -else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) -{ - if (! GETPOST('statut')) - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("CloseAs")), 'errors'); - $action='statut'; - } - else - { - // prevent browser refresh from closing proposal several times - if ($object->statut==1) - { - $object->cloture($user, GETPOST('statut'), GETPOST('note')); - } - } -} - -/* - * Add file in email form - */ -if (GETPOST('addfile')) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - // Set tmp user directory TODO Use a dedicated directory for temp mails files - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; - - dol_add_file_process($upload_dir_tmp,0,0); - $action='presend'; -} - -/* - * Remove file in email form - */ -if (GETPOST('removedfile')) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - // Set tmp user directory - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; - - // TODO Delete only files that was uploaded from email form - dol_remove_file_process($_POST['removedfile'],0); - $action='presend'; -} - -/* - * Send mail - */ -if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) -{ - $langs->load('mails'); - - if ($object->id > 0) - { - if ($_POST['sendto']) - { - // Le destinataire a ete fourni via le champ libre - $sendto = $_POST['sendto']; - $sendtoid = 0; - } - elseif ($_POST['receiver'] != '-1') - { - // Recipient was provided from combo list - if ($_POST['receiver'] == 'thirdparty') // Id of third party - { - $sendto = $object->client->email; - $sendtoid = 0; - } - else // Id du contact - { - $sendto = $object->client->contact_get_property($_POST['receiver'],'email'); - $sendtoid = $_POST['receiver']; - } - } - - if (dol_strlen($sendto)) - { - $langs->load("commercial"); - - $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>'; - $replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>'; - $message = $_POST['message']; - $sendtocc = $_POST['sendtocc']; - $deliveryreceipt = $_POST['deliveryreceipt']; - - if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; - else $subject = $langs->transnoentities('Propal').' '.$object->ref; - $actiontypecode='AC_PROP'; - $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; - if ($message) - { - $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; - $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; - $actionmsg.=$message; - } - $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - - // Create form object - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - - $attachedfiles=$formmail->get_attached_files(); - $filepath = $attachedfiles['paths']; - $filename = $attachedfiles['names']; - $mimetype = $attachedfiles['mimes']; - - // Envoi de la propal - require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); - if ($mailfile->error) - { - setEventMessage($mailfile->error, 'errors'); - } - else - { - $result=$mailfile->sendfile(); - if ($result) - { - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; - $object->actionmsg2 = $actionmsg2; - $object->fk_element = $object->id; - $object->elementtype = $object->element; - - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($db); - $result=$interface->run_triggers('PROPAL_SENTBYMAIL',$object,$user,$langs,$conf); - if ($result < 0) { - $error++; $this->errors=$interface->errors; - } - // Fin appel triggers - - if (! $error) - { - // Redirect here - // This avoid sending mail twice if going out and then back to page - $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); - setEventMessage($mesg); - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - else - { - dol_print_error($db); - } - } - else - { - $langs->load("other"); - if ($mailfile->error) - { - $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); - $mesg.='
'.$mailfile->error; - } - else - { - $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; - } - setEventMessage($mesg, 'errors'); - } - } - } - else - { - $langs->load("other"); - setEventMessage($langs->trans('ErrorMailRecipientIsEmpty').'!', 'errors'); - dol_syslog($langs->trans('ErrorMailRecipientIsEmpty')); - } - } - else - { - $langs->load("other"); - setEventMessage($langs->trans('ErrorFailedToReadEntity',$langs->trans("Proposal")), 'errors'); - dol_syslog($langs->trans('ErrorFailedToReadEntity',$langs->trans("Proposal"))); - } -} - -// Go back to draft -if ($action == 'modif' && $user->rights->propal->creer) -{ - $object->set_draft($user); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } -} - -else if ($action == "setabsolutediscount" && $user->rights->propal->creer) -{ - if ($_POST["remise_id"]) - { - if ($object->id > 0) - { - $result=$object->insert_discount($_POST["remise_id"]); - if ($result < 0) - { - setEventMessage($object->error, 'errors'); - } - } - } -} - -//Ajout d'une ligne produit dans la propale -else if ($action == "addline" && $user->rights->propal->creer) -{ - $idprod=GETPOST('idprod', 'int'); - $product_desc = (GETPOST('product_desc')?GETPOST('product_desc'):(GETPOST('np_desc')?GETPOST('np_desc'):(GETPOST('dp_desc')?GETPOST('dp_desc'):''))); - $price_ht = GETPOST('price_ht'); - $tva_tx = (GETPOST('tva_tx')?GETPOST('tva_tx'):0); - - if (empty($idprod) && GETPOST('type') < 0) - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); - $error++; - } - if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht != 0) || $price_ht == '')) // Unit price can be 0 but not ''. Also price can be negative for proposal. - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); - $error++; - } - if (empty($idprod) && empty($product_desc)) - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors'); - $error++; - } - - if (! $error && (GETPOST('qty') >= 0) && (! empty($product_desc) || ! empty($idprod))) - { - $pu_ht=0; - $pu_ttc=0; - $price_min=0; - $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); - - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - if (! empty($idprod)) - { - $prod = new Product($db); - $prod->fetch($idprod); - - $label = ((GETPOST('product_label') && GETPOST('product_label')!=$prod->label)?GETPOST('product_label'):''); - - // If prices fields are update - if (GETPOST('usenewaddlineform')) - { - $pu_ht=price2num($price_ht, 'MU'); - $pu_ttc=price2num(GETPOST('price_ttc'), 'MU'); - $tva_npr=(preg_match('/\*/', $tva_tx)?1:0); - $tva_tx=str_replace('*','', $tva_tx); - $desc = $product_desc; - } - else - { - $tva_tx = get_default_tva($mysoc,$object->client,$prod->id); - $tva_npr = get_default_npr($mysoc,$object->client,$prod->id); - - // On defini prix unitaire - if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->client->price_level) - { - $pu_ht = $prod->multiprices[$object->client->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; - $price_min = $prod->multiprices_min[$object->client->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; - } - else - { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - } - - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - if ($tva_tx != $prod->tva_tx) - { - if ($price_base_type != 'HT') - { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); - } - else - { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); - } - } - - $desc=''; - - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) - { - $outputlangs = $langs; - $newlang=''; - if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if (empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - - $desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description; - } - else - { - $desc = $prod->description; - } - - $desc=dol_concatdesc($desc,$product_desc); - - // Add custom code and origin country into description - if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) - { - $tmptxt='('; - if (! empty($prod->customcode)) $tmptxt.=$langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode; - if (! empty($prod->customcode) && ! empty($prod->country_code)) $tmptxt.=' - '; - if (! empty($prod->country_code)) $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code,0,$db,$langs,0); - $tmptxt.=')'; - $desc= dol_concatdesc($desc, $tmptxt); - } - } - - $type = $prod->type; - } - else - { - $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); - $tva_npr = (preg_match('/\*/', $tva_tx)?1:0); - $tva_tx = str_replace('*', '', $tva_tx); - $label = (GETPOST('product_label')?GETPOST('product_label'):''); - $desc = $product_desc; - $type = GETPOST('type'); - } - - // Margin - $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); - $buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):''); - - // Local Taxes - $localtax1_tx= get_localtax($tva_tx, 1, $object->client); - $localtax2_tx= get_localtax($tva_tx, 2, $object->client); - - $info_bits=0; - if ($tva_npr) $info_bits |= 0x01; - - if (! empty($price_min) && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) - { - $mesg = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').$langs->getCurrencySymbol($conf->currency)); - setEventMessage($mesg, 'errors'); - } - else - { - // Insert line - $result=$object->addline( - $id, - $desc, - $pu_ht, - GETPOST('qty'), - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $idprod, - GETPOST('remise_percent'), - $price_base_type, - $pu_ttc, - $info_bits, - $type, - -1, - 0, - GETPOST('fk_parent_line'), - $fournprice, - $buyingprice, - $label - ); - - if ($result > 0) - { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['idprod']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); - - // old method - unset($_POST['np_desc']); - unset($_POST['dp_desc']); - } - else - { - setEventMessage($object->error, 'errors'); - } - } - } -} - -// Mise a jour d'une ligne dans la propale -else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('save') == $langs->trans("Save")) -{ - // Define info_bits - $info_bits=0; - if (preg_match('/\*/', GETPOST('tva_tx'))) $info_bits |= 0x01; - - // Clean parameters - $description=dol_htmlcleanlastbr(GETPOST('product_desc')); - - // Define vat_rate - $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); - $vat_rate=str_replace('*','',$vat_rate); - $localtax1_rate=get_localtax($vat_rate,1,$object->client); - $localtax2_rate=get_localtax($vat_rate,2,$object->client); - $pu_ht=GETPOST('price_ht'); - - // Add buying price - $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); - $buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):''); - - // Define special_code for special lines - $special_code=0; - if (! GETPOST('qty')) $special_code=3; - - // Check minimum price - $productid = GETPOST('productid', 'int'); - if (! empty($productid)) - { - $product = new Product($db); - $res=$product->fetch($productid); - - $type=$product->type; - - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - $price_min = $product->multiprices_min[$object->client->price_level]; - - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label'):''); - - if ($price_min && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) - { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min,'MU')).$langs->getCurrencySymbol($conf->currency), 'errors'); - $error++; - } - } - else - { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label'):''); - - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); - $error++; - } - } - - if (! $error) - { - $result = $object->updateline( - GETPOST('lineid'), - $pu_ht, - GETPOST('qty'), - GETPOST('remise_percent'), - $vat_rate, - $localtax1_rate, - $localtax2_rate, - $description, - 'HT', - $info_bits, - $special_code, - GETPOST('fk_parent_line'), - 0, - $fournprice, - $buyingprice, - $label, - $type - ); - - if ($result >= 0) - { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['productid']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); - } - else - { - setEventMessage($object->error, 'errors'); - } - } -} - -else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('cancel') == $langs->trans('Cancel')) -{ - header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // Pour reaffichage de la fiche en cours d'edition - exit; -} - -// Generation doc (depuis lien ou depuis cartouche doc) -else if ($action == 'builddoc' && $user->rights->propal->creer) -{ - if (GETPOST('model')) - { - $object->setDocModel($user, GETPOST('model')); - } - - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - $result=propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - else - { - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); - exit; - } -} - -// Remove file in doc form -else if ($action == 'remove_file' && $user->rights->propal->creer) -{ - if ($object->id > 0) - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $langs->load("other"); - $upload_dir = $conf->propal->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret=dol_delete_file($file,0,0,0,$object); - if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); - else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); - } -} - -// Set project -else if ($action == 'classin' && $user->rights->propal->creer) -{ - $object->setProject($_POST['projectid']); -} - -// Delai de livraison -else if ($action == 'setavailability' && $user->rights->propal->creer) -{ - $result = $object->availability($_POST['availability_id']); -} - -// Origine de la propale -else if ($action == 'setdemandreason' && $user->rights->propal->creer) -{ - $result = $object->demand_reason($_POST['demand_reason_id']); -} - -// Conditions de reglement -else if ($action == 'setconditions' && $user->rights->propal->creer) -{ - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id','int')); -} - -else if ($action == 'setremisepercent' && $user->rights->propal->creer) -{ - $result = $object->set_remise_percent($user, $_POST['remise_percent']); -} - -else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) -{ - $result = $object->set_remise_absolue($user, $_POST['remise_absolue']); -} - -// Mode de reglement -else if ($action == 'setmode' && $user->rights->propal->creer) -{ - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int')); -} - -/* - * Ordonnancement des lignes - */ - -else if ($action == 'up' && $user->rights->propal->creer) -{ - $object->line_up(GETPOST('rowid')); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id.'#'.GETPOST('rowid')); - exit; -} - -else if ($action == 'down' && $user->rights->propal->creer) -{ - $object->line_down(GETPOST('rowid')); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret=$object->fetch($id); // Reload to get new records - propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id.'#'.GETPOST('rowid')); - exit; -} -else if ($action == 'update_extras') -{ - // Get extra fields - foreach($_POST as $key => $value) - { - if (preg_match("/^options_/",$key)) - { - $object->array_options[$key]=$_POST[$key]; - } - } - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('propaldao')); - $parameters=array('id'=>$object->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$object->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; - -} - -if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer) -{ - if ($action == 'addcontact') - { - if ($object->id > 0) - { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); - } - - if ($result >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else - { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') - { - $langs->load("errors"); - setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors'); - } - else - { - setEventMessage($object->error, 'errors'); - } - } - } - - // Bascule du statut d'un contact - else if ($action == 'swapstatut') - { - if ($object->fetch($id) > 0) - { - $result=$object->swapContactStatus(GETPOST('ligne')); - } - else - { - dol_print_error($db); - } - } - - // Efface un contact - else if ($action == 'deletecontact') - { - $object->fetch($id); - $result = $object->delete_contact($lineid); - - if ($result >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else - { - dol_print_error($db); - } - } -} - - -/* - * View - */ - -llxHeader('',$langs->trans('Proposal'),'EN:Commercial_Proposals|FR:Proposition_commerciale|ES:Presupuestos'); - -$form = new Form($db); -$formother = new FormOther($db); -$formfile = new FormFile($db); -$formpropal = new FormPropal($db); -$companystatic=new Societe($db); - -// fetch optionals attributes and labels -$extralabels=$extrafields->fetch_name_optionals_label('propal'); - -$now=dol_now(); - -// Add new proposal -if ($action == 'create') -{ - print_fiche_titre($langs->trans("NewProp")); - - $soc = new Societe($db); - if ($socid>0) $res=$soc->fetch($socid); - - $object = new Propal($db); - - print '
'; - print ''; - print ''; - - if ($origin != 'project' && $originid) - { - print ''; - print ''; - } - - print ''; - - // Reference - print ''; - - // Ref customer - print ''; - print ''; - - // Third party - print ''; - print ''; - if($socid>0) - { - print ''; - } - else - { - print ''; - } - print ''."\n"; - - // Contacts - if($socid>0) - { - print "'; - - // Ligne info remises tiers - print ''; - } - - // Date - print ''; - - // Validaty duration - print ''; - - // Terms of payment - print ''; - - // Mode of payment - print ''; - - // What trigger creation - print ''; - - // Delivery delay - print ''; - - // Delivery date (or manufacturing) - print ''; - print ''; - - // Model - print ''; - print ''; - print '"; - - // Project - if (! empty($conf->projet->enabled) && $socid>0) - { - $projectid = 0; - if ($origin == 'project') $projectid = ($originid?$originid:0); - - print ''; - print ''; - print ''; - } - - // Other attributes - $parameters=array('colspan' => ' colspan="3"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key=>$label) - { - $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); - - // Show separator only - if ($extrafields->attribute_type[$key] == 'separate') - { - print $extrafields->showSeparator($key); - } - else - { - print 'attribute_required[$key])) print ' class="fieldrequired"'; - print '>'.$label.''."\n"; - } - } - } - - print "
'.$langs->trans('Ref').''.$langs->trans("Draft").'
'.$langs->trans('RefCustomer').''; - print '
'.$langs->trans('Customer').''; - print $soc->getNomUrl(1); - print ''; - print ''; - print $form->select_company('','socid','s.client = 1 OR s.client = 2 OR s.client = 3',1); - print '
".$langs->trans("DefaultContact").''; - $form->select_contacts($soc->id,$setcontact,'contactidp',1,$srccontactslist); - print '
'.$langs->trans('Discounts').''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - $absolute_discount=$soc->getAvailableDiscounts(); - print '. '; - if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->trans("Currency".$conf->currency)); - else print $langs->trans("CompanyHasNoAbsoluteDiscount"); - print '.'; - print '
'.$langs->trans('Date').''; - $form->select_date('','','','','',"addprop"); - print '
'.$langs->trans("ValidityDuration").' '.$langs->trans("days").'
'.$langs->trans('PaymentConditionsShort').''; - $form->select_conditions_paiements($soc->cond_reglement,'cond_reglement_id'); - print '
'.$langs->trans('PaymentMode').''; - $form->select_types_paiements($soc->mode_reglement,'mode_reglement_id'); - print '
'.$langs->trans('Source').''; - $form->select_demand_reason('','demand_reason_id',"SRC_PROP",1); - print '
'.$langs->trans('AvailabilityPeriod').''; - $form->select_availability('','availability_id','',1); - print '
'.$langs->trans("DeliveryDate").''; - if ($conf->global->DATE_LIVRAISON_WEEK_DELAY != "") - { - $tmpdte = time() + ((7 * $conf->global->DATE_LIVRAISON_WEEK_DELAY) * 24 * 60 * 60); - $syear = date("Y", $tmpdte); - $smonth = date("m", $tmpdte); - $sday = date("d", $tmpdte); - $form->select_date($syear."-".$smonth."-".$sday,'liv_','','','',"addprop"); - } - else - { - $datepropal=empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; - $form->select_date($datepropal,'liv_','','','',"addprop"); - } - print '
'.$langs->trans("DefaultModel").''; - $liste=ModelePDFPropales::liste_modeles($db); - print $form->selectarray('model',$liste,$conf->global->PROPALE_ADDON_PDF); - print "
'.$langs->trans("Project").''; - - $numprojet=select_projects($soc->id,$projectid); - if ($numprojet==0) - { - print '   '.$langs->trans("AddProject").''; - } - print '
'; - print $extrafields->showInputField($key,$value); - print '
"; - print '
'; - - /* - * Combobox pour la fonction de copie - */ - - if (empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE)) - { - print ''; - } - - print ''; - if (! empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE)) - { - // For backward compatibility - print ''; - print ''; - print ''; - print ''; - - if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) print ''; - - print ''; - print ''; - } - - if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) - { - print ''; - } - print '
'.$langs->trans("CopyPropalFrom").' '; - $liste_propal = array(); - $liste_propal[0] = ''; - - $sql ="SELECT p.rowid as id, p.ref, s.nom"; - $sql.=" FROM ".MAIN_DB_PREFIX."propal p"; - $sql.= ", ".MAIN_DB_PREFIX."societe s"; - $sql.= " WHERE s.rowid = p.fk_soc"; - $sql.= " AND p.entity = ".$conf->entity; - $sql.= " AND p.fk_statut <> 0"; - $sql.= " ORDER BY Id"; - - $resql = $db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $row = $db->fetch_row($resql); - $propalRefAndSocName = $row[1]." - ".$row[2]; - $liste_propal[$row[0]]=$propalRefAndSocName; - $i++; - } - print $form->selectarray("copie_propal",$liste_propal, 0); - } - else - { - dol_print_error($db); - } - print '
 
'.$langs->trans("CreateEmptyPropal").'
'; - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) - { - $lib=$langs->trans("ProductsAndServices"); - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - for ($i = 1 ; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i++) - { - print ''; - print ''; - print ''; - print ''; - } - - print "
'.$lib.''.$langs->trans("Qty").''.$langs->trans("ReductionShort").'
'; - // multiprix - if($conf->global->PRODUIT_MULTIPRICES && $soc->price_level) - $form->select_produits('',"idprod".$i,'',$conf->product->limit_size,$soc->price_level); - else - $form->select_produits('',"idprod".$i,'',$conf->product->limit_size); - print '%
"; - - } - print '
'; - print '
'; - - $langs->load("bills"); - print '
'; - print ''; - print ' '; - print '
'; - - print "
"; -} -else -{ - /* - * Show object in view mode - */ - - $soc = new Societe($db); - $soc->fetch($object->socid); - - $head = propal_prepare_head($object); - dol_fiche_head($head, 'comm', $langs->trans('Proposal'), 0, 'propal'); - - $formconfirm=''; - - // Clone confirmation - if ($action == 'clone') - { - // Create an array for form - $formquestion=array( - //'text' => $langs->trans("ConfirmClone"), - //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid','int'),'socid','(s.client=1 OR s.client=2 OR s.client=3)')) - ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id,$langs->trans('ClonePropal'),$langs->trans('ConfirmClonePropal',$object->ref),'confirm_clone',$formquestion,'yes',1); - } - - // Confirm delete - else if ($action == 'delete') - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteProp'), $langs->trans('ConfirmDeleteProp',$object->ref), 'confirm_delete','',0,1); - } - - // Confirm reopen - else if ($action == 'reopen') - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenProp',$object->ref), 'confirm_reopen','',0,1); - } - - // Confirmation delete product/service line - else if ($action == 'ask_deleteline') - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline','',0,1); - } - - // Confirm validate proposal - else if ($action == 'validate') - { - $error=0; - - // on verifie si l'objet est en numerotation provisoire - $ref = substr($object->ref, 1, 4); - if ($ref == 'PROV') - { - $numref = $object->getNextNumRef($soc); - if (empty($numref)) - { - $error++; - dol_htmloutput_errors($object->error); - } - } - else - { - $numref = $object->ref; - } - - $text=$langs->trans('ConfirmValidateProp',$numref); - if (! empty($conf->notification->enabled)) - { - require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; - $notify=new Notify($db); - $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_PROPAL',$object->socid); - } - - if (! $error) $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProp'), $text, 'confirm_validate','',0,1); - } - - if (! $formconfirm) - { - $parameters=array('lineid'=>$lineid); - $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - } - - // Print form confirm - print $formconfirm; - - - print ''; - - $linkback = ''.$langs->trans("BackToList").''; - - // Ref - print ''; - - // Ref client - print ''; - print ''; - - // Company - print ''; - print ''; - - // Ligne info remises tiers - print ''; - - // Date of proposal - print ''; - print ''; - - // Date end proposal - print ''; - print ''; - print ''; - - // Payment term - print ''; - print ''; - - // Delivery date - $langs->load('deliveries'); - print ''; - print ''; - - // Delivery delay - print ''; - print ''; - - // Origin of demand - print ''; - print ''; - - // Payment mode - print ''; - print ''; - - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - print ''; - } - else - { - print '
'.$langs->trans('Ref').''; - print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); - print '
'; - print ''; - if ($action != 'refclient' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('RefCustomer').''; - print ''.img_edit($langs->trans('Modify')).'
'; - print '
'; - if ($user->rights->propal->creer && $action == 'refclient') - { - print '
'; - print ''; - print ''; - print ''; - print ' '; - print '
'; - } - else - { - print $object->ref_client; - } - print '
'.$langs->trans('Company').''.$soc->getNomUrl(1).'
'.$langs->trans('Discounts').''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - print '. '; - $absolute_discount=$soc->getAvailableDiscounts('','fk_facture_source IS NULL'); - $absolute_creditnote=$soc->getAvailableDiscounts('','fk_facture_source IS NOT NULL'); - $absolute_discount=price2num($absolute_discount,'MT'); - $absolute_creditnote=price2num($absolute_creditnote,'MT'); - if ($absolute_discount) - { - if ($object->statut > 0) - { - print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - } - else - { - // Remise dispo de type non avoir - $filter='fk_facture_source IS NULL'; - print '
'; - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?id='.$object->id,0,'remise_id',$soc->id,$absolute_discount,$filter); - } - } - if ($absolute_creditnote) - { - print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'. '; - } - if (! $absolute_discount && ! $absolute_creditnote) print $langs->trans("CompanyHasNoAbsoluteDiscount").'.'; - print '
'; - print ''; - if ($action != 'editdate' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('Date'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - if (! empty($object->brouillon) && $action == 'editdate') - { - print '
'; - print ''; - print ''; - $form->select_date($object->date,'re','','',0,"editdate"); - print ''; - print '
'; - } - else - { - if ($object->date) - { - print dol_print_date($object->date,'daytext'); - } - else - { - print ' '; - } - } - print '
'; - print ''; - if ($action != 'editecheance' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('DateEndPropal'); - print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; - print '
'; - if (! empty($object->brouillon) && $action == 'editecheance') - { - print '
'; - print ''; - print ''; - $form->select_date($object->fin_validite,'ech','','','',"editecheance"); - print ''; - print '
'; - } - else - { - if (! empty($object->fin_validite)) - { - print dol_print_date($object->fin_validite,'daytext'); - if ($object->statut == 1 && $object->fin_validite < ($now - $conf->propal->cloture->warning_delay)) print img_warning($langs->trans("Late")); - } - else - { - print ' '; - } - } - print '
'; - print ''; - if ($action != 'editconditions' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('PaymentConditionsShort'); - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetConditions'),1).'
'; - print '
'; - if ($action == 'editconditions') - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); - } - else - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'none'); - } - print '
'; - print ''; - if ($action != 'editdate_livraison' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('DeliveryDate'); - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetDeliveryDate'),1).'
'; - print '
'; - if ($action == 'editdate_livraison') - { - print '
'; - print ''; - print ''; - $form->select_date($object->date_livraison,'liv_','','','',"editdate_livraison"); - print ''; - print '
'; - } - else - { - print dol_print_date($object->date_livraison,'daytext'); - } - print '
'; - print ''; - if ($action != 'editavailability' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('AvailabilityPeriod'); - if (! empty($conf->commande->enabled)) print ' ('.$langs->trans('AfterOrder').')'; - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetAvailability'),1).'
'; - print '
'; - if ($action == 'editavailability') - { - $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id,$object->availability_id,'availability_id',1); - } - else - { - $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id,$object->availability_id,'none',1); - } - - print '
'; - print ''; - if ($action != 'editdemandreason' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('Source'); - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetDemandReason'),1).'
'; - print '
'; - //print $object->demand_reason_id; - if ($action == 'editdemandreason') - { - $form->form_demand_reason($_SERVER['PHP_SELF'].'?id='.$object->id,$object->demand_reason_id,'demand_reason_id',1); - } - else - { - $form->form_demand_reason($_SERVER['PHP_SELF'].'?id='.$object->id,$object->demand_reason_id,'none'); - } - - print '
'; - print ''; - if ($action != 'editmode' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('PaymentMode'); - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMode'),1).'
'; - print '
'; - if ($action == 'editmode') - { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); - } - else - { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'none'); - } - print '
'; - print ''; - if ($user->rights->propal->creer) - { - if ($action != 'classify') print ''; - print '
'; - print $langs->trans('Project').''.img_edit($langs->transnoentitiesnoconv('SetProject')).'
'; - print '
'; - if ($action == 'classify') - { - $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'projectid'); - } - else - { - $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none'); - } - print '
'; - if (! empty($object->fk_project)) - { - print ''; - $proj = new Project($db); - $proj->fetch($object->fk_project); - print ''; - print $proj->ref; - print ''; - print ''; - } - else { - print ' '; - } - } - print ''; - } - - // Other attributes - $res=$object->fetch_optionals($object->id,$extralabels); - $parameters=array('colspan' => ' colspan="3"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - - if ($action == 'edit_extras') - { - print '
'; - print ''; - print ''; - print ''; - } - - - foreach($extrafields->attribute_label as $key=>$label) - { - $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); - if ($extrafields->attribute_type[$key] == 'separate') - { - print $extrafields->showSeparator($key); - } - else - { - print 'attribute_required[$key])) print ' class="fieldrequired"'; - print '>'.$label.''; - if ($action == 'edit_extras' && $user->rights->propal->creer) - { - print $extrafields->showInputField($key,$value); - } - else - { - print $extrafields->showOutputField($key,$value); - } - print ''."\n"; - } - } - - if(count($extrafields->attribute_label) > 0) { - - if ($action == 'edit_extras' && $user->rights->propal->creer) - { - print ''; - print ''; - print ''; - print ''; - - } - else { - if ($object->statut == 0 && $user->rights->propal->creer) - { - print ''.img_picto('','edit').' '.$langs->trans('Modify').''; - } - } - } - } - - // Amount HT - print ''.$langs->trans('AmountHT').''; - print ''.price($object->total_ht).''; - print ''.$langs->trans("Currency".$conf->currency).''; - - // Margin Infos - if (! empty($conf->margin->enabled)) { - print ''; - $object->displayMarginInfos(); - print ''; - } - print ''; - - // Amount VAT - print ''.$langs->trans('AmountVAT').''; - print ''.price($object->total_tva).''; - print ''.$langs->trans("Currency".$conf->currency).''; - - // Amount Local Taxes - if ($mysoc->localtax1_assuj=="1") //Localtax1 - { - print ''.$langs->transcountry("AmountLT1",$mysoc->country_code).''; - print ''.price($object->total_localtax1).''; - print ''.$langs->trans("Currency".$conf->currency).''; - } - if ($mysoc->localtax2_assuj=="1") //Localtax2 - { - print ''.$langs->transcountry("AmountLT2",$mysoc->country_code).''; - print ''.price($object->total_localtax2).''; - print ''.$langs->trans("Currency".$conf->currency).''; - } - - - // Amount TTC - print ''.$langs->trans('AmountTTC').''; - print ''.price($object->total_ttc).''; - print ''.$langs->trans("Currency".$conf->currency).''; - - // Statut - print ''.$langs->trans('Status').''.$object->getLibStatut(4).''; - - print '
'; - - if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) - { - $blocname = 'contacts'; - $title = $langs->trans('ContactsAddresses'); - include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; - } - - if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) - { - $blocname = 'notes'; - $title = $langs->trans('Notes'); - include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; - } - - /* - * Lines - */ - - if (! empty($conf->use_javascript_ajax) && $object->statut == 0) - { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } - - print ''; - - // Show object lines - $result = $object->getLinesArray(); - if (! empty($object->lines)) - $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid); - - // Form to add new line - if ($object->statut == 0 && $user->rights->propal->creer) - { - if ($action != 'editline') - { - $var=true; - - if ($conf->global->MAIN_FEATURES_LEVEL > 1) - { - // Add free or predefined products/services - $object->formAddObjectLine(0,$mysoc,$soc); - } - else - { - // Add free products/services - $object->formAddFreeProduct(0,$mysoc,$soc); - - // Add predefined products/services - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) - { - $var=!$var; - $object->formAddPredefinedProduct(0,$mysoc,$soc); - } - } - - $parameters=array(); - $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - } - } - - print '
'; - - print ''; - print "\n"; - - if ($action == 'statut') - { - /* - * Formulaire cloture (signe ou non) - */ - $form_close = '
'; - $form_close.= ''; - $form_close.= ''; - $form_close.= ''; - $form_close.= ''; - $form_close.= ''; - $form_close.= '
'.$langs->trans("CloseAs").''; - $form_close.= ''; - $form_close.= ''; - $form_close.= '
'.$langs->trans('Note').'
'; - $form_close.= ''; - $form_close.= '   '; - $form_close.= ' '; - $form_close.= '
'; - - print $form_close; - } - - - /* - * Boutons Actions - */ - if ($action != 'presend') - { - print '
'; - - if ($action != 'statut' && $action <> 'editline') - { - // Validate - if ($object->statut == 0 && $object->total_ttc >= 0 && count($object->lines) > 0 && $user->rights->propal->valider) - { - if (count($object->lines) > 0) print ''.$langs->trans('Validate').''; - //else print ''.$langs->trans('Validate').''; - } - - // Edit - if ($object->statut == 1 && $user->rights->propal->creer) - { - print ''.$langs->trans('Modify').''; - } - - // ReOpen - if (($object->statut == 2 || $object->statut == 3) && $user->rights->propal->cloturer) - { - print 'global->MAIN_JUMP_TAG)?'':'#reopen').'"'; - print '>'.$langs->trans('ReOpen').''; - } - - // Send - if ($object->statut == 1 || $object->statut == 2) - { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->propal->propal_advance->send) - { - print ''.$langs->trans('SendByMail').''; - } - else print ''.$langs->trans('SendByMail').''; - } - - // Create an order - if (! empty($conf->commande->enabled) && $object->statut == 2 && $user->societe_id == 0) - { - if ($user->rights->commande->creer) - { - print ''.$langs->trans("AddOrder").''; - } - } - - // Create contract - if ($conf->contrat->enabled && $object->statut == 2 && $user->societe_id == 0) - { - $langs->load("contracts"); - - if ($user->rights->contrat->creer) - { - print ''.$langs->trans('AddContract').''; - } - } - - // Create an invoice and classify billed - if ($object->statut == 2 && $user->societe_id == 0) - { - if (! empty($conf->facture->enabled) && $user->rights->facture->creer) - { - print ''.$langs->trans("AddBill").''; - } - - $arraypropal=$object->getInvoiceArrayList(); - if (is_array($arraypropal) && count($arraypropal) > 0) - { - print 'socid.'">'.$langs->trans("ClassifyBilled").''; - } - } - - // Close - if ($object->statut == 1 && $user->rights->propal->cloturer) - { - print 'global->MAIN_JUMP_TAG)?'':'#close').'"'; - print '>'.$langs->trans('Close').''; - } - - // Clone - if ($user->rights->propal->creer) - { - print ''.$langs->trans("ToClone").''; - } - - // Delete - if ($user->rights->propal->supprimer) - { - print ''.$langs->trans('Delete').''; - } - - } - - print '
'; - print "
\n"; - } - - if ($action != 'presend') - { - print '
'; - print ''; // ancre - - - /* - * Documents generes - */ - $filename=dol_sanitizeFileName($object->ref); - $filedir=$conf->propal->dir_output . "/" . dol_sanitizeFileName($object->ref); - $urlsource=$_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed=$user->rights->propal->creer; - $delallowed=$user->rights->propal->supprimer; - - $var=true; - - $somethingshown=$formfile->show_documents('propal',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'',0,'',$soc->default_lang); - - - /* - * Linked object block - */ - $somethingshown=$object->showLinkedObjectBlock(); - - print ''; - - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions=new FormActions($db); - $somethingshown=$formactions->showactions($object,'propal',$socid); - - print '
'; - } - - - /* - * Action presend - * - */ - if ($action == 'presend') - { - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($object->ref,'/')); - $file=$fileparams['fullname']; - - // Build document if it not exists - if (! $file || ! is_readable($file)) - { - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - - $result=propale_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($object->ref,'/')); - $file=$fileparams['fullname']; - } - - print '
'; - print_titre($langs->trans('SendPropalByMail')); - - // Create form object - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->fromtype = 'user'; - $formmail->fromid = $user->id; - $formmail->fromname = $user->getFullName($langs); - $formmail->frommail = $user->email; - $formmail->withfrom=1; - $liste=array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; - $formmail->withto=GETPOST("sendto")?GETPOST("sendto"):$liste; - $formmail->withtocc=$liste; - $formmail->withtoccc=(! empty($conf->global->MAIN_EMAIL_USECCC)?$conf->global->MAIN_EMAIL_USECCC:false); - $formmail->withtopic=$langs->trans('SendPropalRef','__PROPREF__'); - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - - // Tableau des substitutions - $formmail->substit['__PROPREF__']=$object->ref; - $formmail->substit['__SIGNATURE__']=$user->signature; - $formmail->substit['__PERSONALIZED__']=''; - $formmail->substit['__CONTACTCIVNAME__']=''; - + + * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005 Marc Barilley / Ocebo + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2010-2013 Juanjo Menent + * Copyright (C) 2010-2011 Philippe Grand + * Copyright (C) 2012 Christophe Battarel +* + * 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 . + */ + +/** + * \file htdocs/comm/propal.php + * \ingroup propale + * \brief Page of commercial proposals card and list + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formpropal.class.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/propal.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +if (! empty($conf->projet->enabled)) +{ + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; +} + +$langs->load('companies'); +$langs->load('propal'); +$langs->load('compta'); +$langs->load('bills'); +$langs->load('orders'); +$langs->load('products'); +$langs->load("deliveries"); +if (! empty($conf->margin->enabled)) + $langs->load('margins'); + +$error=0; + +$id=GETPOST('id','int'); +$ref=GETPOST('ref','alpha'); +$socid=GETPOST('socid','int'); +$action=GETPOST('action','alpha'); +$origin=GETPOST('origin','alpha'); +$originid=GETPOST('originid','int'); +$confirm=GETPOST('confirm','alpha'); +$lineid=GETPOST('lineid','int'); + +//PDF +$hidedetails = (GETPOST('hidedetails','int') ? GETPOST('hidedetails','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); +$hidedesc = (GETPOST('hidedesc','int') ? GETPOST('hidedesc','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); +$hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); + +// Nombre de ligne pour choix de produit/service predefinis +$NBLINES=4; + +// Security check +if (! empty($user->societe_id)) $socid=$user->societe_id; +$result = restrictedArea($user, 'propal', $id); + +$object = new Propal($db); +$extrafields = new ExtraFields($db); + +// Load object +if ($id > 0 || ! empty($ref)) +{ + $ret=$object->fetch($id, $ref); + if ($ret > 0) $ret=$object->fetch_thirdparty(); + if ($ret < 0) dol_print_error('',$object->error); +} + +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +$hookmanager->initHooks(array('propalcard')); + + + +/* + * Actions + */ + +$parameters=array('socid'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + +// Action clone object +if ($action == 'confirm_clone' && $confirm == 'yes') +{ + if (1==0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) + { + setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); + } + else + { + if ($object->id > 0) + { + $result=$object->createFromClone($socid); + if ($result > 0) + { + header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); + exit; + } + else + { + setEventMessage($object->error, 'errors'); + $action=''; + } + } + } +} + +// Suppression de la propale +else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->propal->supprimer) +{ + $result=$object->delete($user); + if ($result > 0) + { + header('Location: '.DOL_URL_ROOT.'/comm/propal/list.php'); + exit; + } + else + { + $langs->load("errors"); + setEventMessage($langs->trans($object->error), 'errors'); + } +} + +// Remove line +else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->propal->creer) +{ + $result = $object->deleteline($lineid); + // reorder lines + if ($result) $object->line_order(true); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; +} + +// Validation +else if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->propal->valider) +{ + $result=$object->valid($user); + if ($result >= 0) + { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + else + { + $langs->load("errors"); + setEventMessage($langs->trans($object->error), 'errors'); + } +} + +else if ($action == 'setdate' && $user->rights->propal->creer) +{ + $datep=dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + + if (empty($datep)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")), 'errors'); + } + + if (! $error) + { + $result=$object->set_date($user,$datep); + if ($result < 0) dol_print_error($db,$object->error); + } +} +else if ($action == 'setecheance' && $user->rights->propal->creer) +{ + $result=$object->set_echeance($user,dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear'])); + if ($result < 0) dol_print_error($db,$object->error); +} +else if ($action == 'setdate_livraison' && $user->rights->propal->creer) +{ + $result=$object->set_date_livraison($user,dol_mktime(12, 0, 0, $_POST['liv_month'], $_POST['liv_day'], $_POST['liv_year'])); + if ($result < 0) dol_print_error($db,$object->error); +} + +// Positionne ref client +else if ($action == 'set_ref_client' && $user->rights->propal->creer) +{ + $object->set_ref_client($user, $_POST['ref_client']); +} + +else if ($action == 'setnote_public' && $user->rights->propal->creer) +{ + $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + if ($result < 0) dol_print_error($db,$object->error); +} + +else if ($action == 'setnote' && $user->rights->propal->creer) +{ + $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + if ($result < 0) dol_print_error($db,$object->error); +} + +// Create proposal +else if ($action == 'add' && $user->rights->propal->creer) +{ + $object->socid=$socid; + $object->fetch_thirdparty(); + + $datep=dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $date_delivery=dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + $duration=GETPOST('duree_validite'); + + if (empty($datep)) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")), 'errors'); + $action='create'; + $error++; + } + if (empty($duration)) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ValidityDuration")), 'errors'); + $action='create'; + $error++; + } + + if ($socid<1) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); + $action='create'; + $error++; + } + + if (! $error) + { + $db->begin(); + + // Si on a selectionne une propal a copier, on realise la copie + if (GETPOST('createmode')=='copy' && GETPOST('copie_propal')) + { + if ($object->fetch(GETPOST('copie_propal')) > 0) + { + $object->ref = GETPOST('ref'); + $object->datep = $datep; + $object->date_livraison = $date_delivery; + $object->availability_id = GETPOST('availability_id'); + $object->demand_reason_id = GETPOST('demand_reason_id'); + $object->fk_delivery_address = GETPOST('fk_address'); + $object->duree_validite = $duration; + $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->remise_percent = GETPOST('remise_percent'); + $object->remise_absolue = GETPOST('remise_absolue'); + $object->socid = GETPOST('socid'); + $object->contactid = GETPOST('contactidp'); + $object->fk_project = GETPOST('projectid'); + $object->modelpdf = GETPOST('model'); + $object->author = $user->id; // deprecated + $object->note = GETPOST('note'); + $object->statut = 0; + + $id = $object->create_from($user); + } + else + { + setEventMessage($langs->trans("ErrorFailedToCopyProposal",GETPOST('copie_propal')), 'errors'); + } + } + else + { + $object->ref = GETPOST('ref'); + $object->ref_client = GETPOST('ref_client'); + $object->datep = $datep; + $object->date_livraison = $date_delivery; + $object->availability_id = GETPOST('availability_id'); + $object->demand_reason_id = GETPOST('demand_reason_id'); + $object->fk_delivery_address = GETPOST('fk_address'); + $object->duree_validite = GETPOST('duree_validite'); + $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + + $object->contactid = GETPOST('contactidp'); + $object->fk_project = GETPOST('projectid'); + $object->modelpdf = GETPOST('model'); + $object->author = $user->id; // deprecated + $object->note = GETPOST('note'); + + $object->origin = GETPOST('origin'); + $object->origin_id = GETPOST('originid'); + + for ($i = 1 ; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i++) + { + if ($_POST['idprod'.$i]) + { + $xid = 'idprod'.$i; + $xqty = 'qty'.$i; + $xremise = 'remise'.$i; + $object->add_product($_POST[$xid],$_POST[$xqty],$_POST[$xremise]); + } + } + + // Get extra fields + foreach($_POST as $key => $value) + { + if (preg_match("/^options_/",$key)) + { + $object->array_options[$key]=GETPOST($key); + } + } + + $id = $object->create($user); + } + + if ($id > 0) + { + // Insertion contact par defaut si defini + if (GETPOST('contactidp')) + { + $result=$object->add_contact(GETPOST('contactidp'),'CUSTOMER','external'); + if ($result < 0) + { + $error++; + setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); + } + } + + if (! $error) + { + $db->commit(); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id); + exit; + } + else + { + $db->rollback(); + } + } + else + { + dol_print_error($db,$object->error); + $db->rollback(); + exit; + } + } +} + +// Classify billed +else if ($action == 'classifybilled' && $user->rights->propal->cloturer) +{ + $object->cloture($user, 4, ''); +} + +// Reopen proposal +else if ($action == 'confirm_reopen' && $user->rights->propal->cloturer && ! GETPOST('cancel')) +{ + // prevent browser refresh from reopening proposal several times + if ($object->statut==2 || $object->statut==3) + { + $object->setStatut(1); + } +} + +// Close proposal +else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST('cancel')) +{ + if (! GETPOST('statut')) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("CloseAs")), 'errors'); + $action='statut'; + } + else + { + // prevent browser refresh from closing proposal several times + if ($object->statut==1) + { + $object->cloture($user, GETPOST('statut'), GETPOST('note')); + } + } +} + +/* + * Add file in email form + */ +if (GETPOST('addfile')) +{ + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory TODO Use a dedicated directory for temp mails files + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; + + dol_add_file_process($upload_dir_tmp,0,0); + $action='presend'; +} + +/* + * Remove file in email form + */ +if (GETPOST('removedfile')) +{ + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; + + // TODO Delete only files that was uploaded from email form + dol_remove_file_process($_POST['removedfile'],0); + $action='presend'; +} + +/* + * Send mail + */ +if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! GETPOST('cancel')) +{ + $langs->load('mails'); + + if ($object->id > 0) + { + if ($_POST['sendto']) + { + // Le destinataire a ete fourni via le champ libre + $sendto = $_POST['sendto']; + $sendtoid = 0; + } + elseif ($_POST['receiver'] != '-1') + { + // Recipient was provided from combo list + if ($_POST['receiver'] == 'thirdparty') // Id of third party + { + $sendto = $object->client->email; + $sendtoid = 0; + } + else // Id du contact + { + $sendto = $object->client->contact_get_property($_POST['receiver'],'email'); + $sendtoid = $_POST['receiver']; + } + } + + if (dol_strlen($sendto)) + { + $langs->load("commercial"); + + $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>'; + $replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>'; + $message = $_POST['message']; + $sendtocc = $_POST['sendtocc']; + $deliveryreceipt = $_POST['deliveryreceipt']; + + if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; + else $subject = $langs->transnoentities('Propal').' '.$object->ref; + $actiontypecode='AC_PROP'; + $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; + if ($message) + { + $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; + $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; + $actionmsg.=$message; + } + $actionmsg2=$langs->transnoentities('Action'.$actiontypecode); + + // Create form object + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $attachedfiles=$formmail->get_attached_files(); + $filepath = $attachedfiles['paths']; + $filename = $attachedfiles['names']; + $mimetype = $attachedfiles['mimes']; + + // Envoi de la propal + require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); + if ($mailfile->error) + { + setEventMessage($mailfile->error, 'errors'); + } + else + { + $result=$mailfile->sendfile(); + if ($result) + { + // Initialisation donnees + $object->sendtoid = $sendtoid; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; + $object->actionmsg2 = $actionmsg2; + $object->fk_element = $object->id; + $object->elementtype = $object->element; + + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($db); + $result=$interface->run_triggers('PROPAL_SENTBYMAIL',$object,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + + if (! $error) + { + // Redirect here + // This avoid sending mail twice if going out and then back to page + $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); + setEventMessage($mesg); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; + } + else + { + dol_print_error($db); + } + } + else + { + $langs->load("other"); + if ($mailfile->error) + { + $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); + $mesg.='
'.$mailfile->error; + } + else + { + $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + setEventMessage($mesg, 'errors'); + } + } + } + else + { + $langs->load("other"); + setEventMessage($langs->trans('ErrorMailRecipientIsEmpty').'!', 'errors'); + dol_syslog($langs->trans('ErrorMailRecipientIsEmpty')); + } + } + else + { + $langs->load("other"); + setEventMessage($langs->trans('ErrorFailedToReadEntity',$langs->trans("Proposal")), 'errors'); + dol_syslog($langs->trans('ErrorFailedToReadEntity',$langs->trans("Proposal"))); + } +} + +// Go back to draft +if ($action == 'modif' && $user->rights->propal->creer) +{ + $object->set_draft($user); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } +} + +else if ($action == "setabsolutediscount" && $user->rights->propal->creer) +{ + if ($_POST["remise_id"]) + { + if ($object->id > 0) + { + $result=$object->insert_discount($_POST["remise_id"]); + if ($result < 0) + { + setEventMessage($object->error, 'errors'); + } + } + } +} + +//Ajout d'une ligne produit dans la propale +else if ($action == "addline" && $user->rights->propal->creer) +{ + $idprod=GETPOST('idprod', 'int'); + $product_desc = (GETPOST('product_desc')?GETPOST('product_desc'):(GETPOST('np_desc')?GETPOST('np_desc'):(GETPOST('dp_desc')?GETPOST('dp_desc'):''))); + $price_ht = GETPOST('price_ht'); + $tva_tx = (GETPOST('tva_tx')?GETPOST('tva_tx'):0); + + if (empty($idprod) && GETPOST('type') < 0) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); + $error++; + } + if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht != 0) || $price_ht == '')) // Unit price can be 0 but not ''. Also price can be negative for proposal. + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); + $error++; + } + if (empty($idprod) && empty($product_desc)) + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors'); + $error++; + } + + if (! $error && (GETPOST('qty') >= 0) && (! empty($product_desc) || ! empty($idprod))) + { + $pu_ht=0; + $pu_ttc=0; + $price_min=0; + $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); + + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + if (! empty($idprod)) + { + $prod = new Product($db); + $prod->fetch($idprod); + + $label = ((GETPOST('product_label') && GETPOST('product_label')!=$prod->label)?GETPOST('product_label'):''); + + // If prices fields are update + if (GETPOST('usenewaddlineform')) + { + $pu_ht=price2num($price_ht, 'MU'); + $pu_ttc=price2num(GETPOST('price_ttc'), 'MU'); + $tva_npr=(preg_match('/\*/', $tva_tx)?1:0); + $tva_tx=str_replace('*','', $tva_tx); + $desc = $product_desc; + } + else + { + $tva_tx = get_default_tva($mysoc,$object->client,$prod->id); + $tva_npr = get_default_npr($mysoc,$object->client,$prod->id); + + // On defini prix unitaire + if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->client->price_level) + { + $pu_ht = $prod->multiprices[$object->client->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; + $price_min = $prod->multiprices_min[$object->client->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; + } + else + { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } + + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + if ($tva_tx != $prod->tva_tx) + { + if ($price_base_type != 'HT') + { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); + } + else + { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); + } + } + + $desc=''; + + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) + { + $outputlangs = $langs; + $newlang=''; + if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if (empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description; + } + else + { + $desc = $prod->description; + } + + $desc=dol_concatdesc($desc,$product_desc); + + // Add custom code and origin country into description + if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) + { + $tmptxt='('; + if (! empty($prod->customcode)) $tmptxt.=$langs->transnoentitiesnoconv("CustomCode").': '.$prod->customcode; + if (! empty($prod->customcode) && ! empty($prod->country_code)) $tmptxt.=' - '; + if (! empty($prod->country_code)) $tmptxt.=$langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code,0,$db,$langs,0); + $tmptxt.=')'; + $desc= dol_concatdesc($desc, $tmptxt); + } + } + + $type = $prod->type; + } + else + { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $tva_npr = (preg_match('/\*/', $tva_tx)?1:0); + $tva_tx = str_replace('*', '', $tva_tx); + $label = (GETPOST('product_label')?GETPOST('product_label'):''); + $desc = $product_desc; + $type = GETPOST('type'); + } + + // Margin + $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); + $buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):''); + + // Local Taxes + $localtax1_tx= get_localtax($tva_tx, 1, $object->client); + $localtax2_tx= get_localtax($tva_tx, 2, $object->client); + + $info_bits=0; + if ($tva_npr) $info_bits |= 0x01; + + if (! empty($price_min) && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) + { + $mesg = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').$langs->getCurrencySymbol($conf->currency)); + setEventMessage($mesg, 'errors'); + } + else + { + // Insert line + $result=$object->addline( + $id, + $desc, + $pu_ht, + GETPOST('qty'), + $tva_tx, + $localtax1_tx, + $localtax2_tx, + $idprod, + GETPOST('remise_percent'), + $price_base_type, + $pu_ttc, + $info_bits, + $type, + -1, + 0, + GETPOST('fk_parent_line'), + $fournprice, + $buyingprice, + $label + ); + + if ($result > 0) + { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['idprod']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + + // old method + unset($_POST['np_desc']); + unset($_POST['dp_desc']); + } + else + { + setEventMessage($object->error, 'errors'); + } + } + } +} + +// Mise a jour d'une ligne dans la propale +else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('save') == $langs->trans("Save")) +{ + // Define info_bits + $info_bits=0; + if (preg_match('/\*/', GETPOST('tva_tx'))) $info_bits |= 0x01; + + // Clean parameters + $description=dol_htmlcleanlastbr(GETPOST('product_desc')); + + // Define vat_rate + $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); + $vat_rate=str_replace('*','',$vat_rate); + $localtax1_rate=get_localtax($vat_rate,1,$object->client); + $localtax2_rate=get_localtax($vat_rate,2,$object->client); + $pu_ht=GETPOST('price_ht'); + + // Add buying price + $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); + $buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):''); + + // Define special_code for special lines + $special_code=0; + if (! GETPOST('qty')) $special_code=3; + + // Check minimum price + $productid = GETPOST('productid', 'int'); + if (! empty($productid)) + { + $product = new Product($db); + $res=$product->fetch($productid); + + $type=$product->type; + + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + $price_min = $product->multiprices_min[$object->client->price_level]; + + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label'):''); + + if ($price_min && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) + { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min,'MU')).$langs->getCurrencySymbol($conf->currency), 'errors'); + $error++; + } + } + else + { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label'):''); + + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); + $error++; + } + } + + if (! $error) + { + $result = $object->updateline( + GETPOST('lineid'), + $pu_ht, + GETPOST('qty'), + GETPOST('remise_percent'), + $vat_rate, + $localtax1_rate, + $localtax2_rate, + $description, + 'HT', + $info_bits, + $special_code, + GETPOST('fk_parent_line'), + 0, + $fournprice, + $buyingprice, + $label, + $type + ); + + if ($result >= 0) + { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['productid']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + } + else + { + setEventMessage($object->error, 'errors'); + } + } +} + +else if ($action == 'updateligne' && $user->rights->propal->creer && GETPOST('cancel') == $langs->trans('Cancel')) +{ + header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // Pour reaffichage de la fiche en cours d'edition + exit; +} + +// Generation doc (depuis lien ou depuis cartouche doc) +else if ($action == 'builddoc' && $user->rights->propal->creer) +{ + if (GETPOST('model')) + { + $object->setDocModel($user, GETPOST('model')); + } + + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + $result=propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + else + { + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); + exit; + } +} + +// Remove file in doc form +else if ($action == 'remove_file' && $user->rights->propal->creer) +{ + if ($object->id > 0) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->propal->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); + } +} + +// Set project +else if ($action == 'classin' && $user->rights->propal->creer) +{ + $object->setProject($_POST['projectid']); +} + +// Delai de livraison +else if ($action == 'setavailability' && $user->rights->propal->creer) +{ + $result = $object->availability($_POST['availability_id']); +} + +// Origine de la propale +else if ($action == 'setdemandreason' && $user->rights->propal->creer) +{ + $result = $object->demand_reason($_POST['demand_reason_id']); +} + +// Conditions de reglement +else if ($action == 'setconditions' && $user->rights->propal->creer) +{ + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id','int')); +} + +else if ($action == 'setremisepercent' && $user->rights->propal->creer) +{ + $result = $object->set_remise_percent($user, $_POST['remise_percent']); +} + +else if ($action == 'setremiseabsolue' && $user->rights->propal->creer) +{ + $result = $object->set_remise_absolue($user, $_POST['remise_absolue']); +} + +// Mode de reglement +else if ($action == 'setmode' && $user->rights->propal->creer) +{ + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int')); +} + +/* + * Ordonnancement des lignes + */ + +else if ($action == 'up' && $user->rights->propal->creer) +{ + $object->line_up(GETPOST('rowid')); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id.'#'.GETPOST('rowid')); + exit; +} + +else if ($action == 'down' && $user->rights->propal->creer) +{ + $object->line_down(GETPOST('rowid')); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $object->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id.'#'.GETPOST('rowid')); + exit; +} +else if ($action == 'update_extras') +{ + // Get extra fields + foreach($_POST as $key => $value) + { + if (preg_match("/^options_/",$key)) + { + $object->array_options[$key]=$_POST[$key]; + } + } + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('propaldao')); + $parameters=array('id'=>$object->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$object->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + +} + +if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->propal->creer) +{ + if ($action == 'addcontact') + { + if ($object->id > 0) + { + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]); + } + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), 'errors'); + } + else + { + setEventMessage($object->error, 'errors'); + } + } + } + + // Bascule du statut d'un contact + else if ($action == 'swapstatut') + { + if ($object->fetch($id) > 0) + { + $result=$object->swapContactStatus(GETPOST('ligne')); + } + else + { + dol_print_error($db); + } + } + + // Efface un contact + else if ($action == 'deletecontact') + { + $object->fetch($id); + $result = $object->delete_contact($lineid); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + dol_print_error($db); + } + } +} + + +/* + * View + */ + +llxHeader('',$langs->trans('Proposal'),'EN:Commercial_Proposals|FR:Proposition_commerciale|ES:Presupuestos'); + +$form = new Form($db); +$formother = new FormOther($db); +$formfile = new FormFile($db); +$formpropal = new FormPropal($db); +$companystatic=new Societe($db); + +// fetch optionals attributes and labels +$extralabels=$extrafields->fetch_name_optionals_label('propal'); + +$now=dol_now(); + +// Add new proposal +if ($action == 'create') +{ + print_fiche_titre($langs->trans("NewProp")); + + $soc = new Societe($db); + if ($socid>0) $res=$soc->fetch($socid); + + $object = new Propal($db); + + print '
'; + print ''; + print ''; + + if ($origin != 'project' && $originid) + { + print ''; + print ''; + } + + print ''; + + // Reference + print ''; + + // Ref customer + print ''; + print ''; + + // Third party + print ''; + print ''; + if($socid>0) + { + print ''; + } + else + { + print ''; + } + print ''."\n"; + + // Contacts + if($socid>0) + { + print "'; + + // Ligne info remises tiers + print ''; + } + + // Date + print ''; + + // Validaty duration + print ''; + + // Terms of payment + print ''; + + // Mode of payment + print ''; + + // What trigger creation + print ''; + + // Delivery delay + print ''; + + // Delivery date (or manufacturing) + print ''; + print ''; + + // Model + print ''; + print ''; + print '"; + + // Project + if (! empty($conf->projet->enabled) && $socid>0) + { + $projectid = 0; + if ($origin == 'project') $projectid = ($originid?$originid:0); + + print ''; + print ''; + print ''; + } + + // Other attributes + $parameters=array('colspan' => ' colspan="3"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key=>$label) + { + $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); + + // Show separator only + if ($extrafields->attribute_type[$key] == 'separate') + { + print $extrafields->showSeparator($key); + } + else + { + print 'attribute_required[$key])) print ' class="fieldrequired"'; + print '>'.$label.''."\n"; + } + } + } + + print "
'.$langs->trans('Ref').''.$langs->trans("Draft").'
'.$langs->trans('RefCustomer').''; + print '
'.$langs->trans('Customer').''; + print $soc->getNomUrl(1); + print ''; + print ''; + print $form->select_company('','socid','s.client = 1 OR s.client = 2 OR s.client = 3',1); + print '
".$langs->trans("DefaultContact").''; + $form->select_contacts($soc->id,$setcontact,'contactidp',1,$srccontactslist); + print '
'.$langs->trans('Discounts').''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + $absolute_discount=$soc->getAvailableDiscounts(); + print '. '; + if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->trans("Currency".$conf->currency)); + else print $langs->trans("CompanyHasNoAbsoluteDiscount"); + print '.'; + print '
'.$langs->trans('Date').''; + $form->select_date('','','','','',"addprop"); + print '
'.$langs->trans("ValidityDuration").' '.$langs->trans("days").'
'.$langs->trans('PaymentConditionsShort').''; + $form->select_conditions_paiements($soc->cond_reglement,'cond_reglement_id'); + print '
'.$langs->trans('PaymentMode').''; + $form->select_types_paiements($soc->mode_reglement,'mode_reglement_id'); + print '
'.$langs->trans('Source').''; + $form->select_demand_reason('','demand_reason_id',"SRC_PROP",1); + print '
'.$langs->trans('AvailabilityPeriod').''; + $form->select_availability('','availability_id','',1); + print '
'.$langs->trans("DeliveryDate").''; + if ($conf->global->DATE_LIVRAISON_WEEK_DELAY != "") + { + $tmpdte = time() + ((7 * $conf->global->DATE_LIVRAISON_WEEK_DELAY) * 24 * 60 * 60); + $syear = date("Y", $tmpdte); + $smonth = date("m", $tmpdte); + $sday = date("d", $tmpdte); + $form->select_date($syear."-".$smonth."-".$sday,'liv_','','','',"addprop"); + } + else + { + $datepropal=empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; + $form->select_date($datepropal,'liv_','','','',"addprop"); + } + print '
'.$langs->trans("DefaultModel").''; + $liste=ModelePDFPropales::liste_modeles($db); + print $form->selectarray('model',$liste,($conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT?$conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT:$conf->global->PROPALE_ADDON_PDF)); + print "
'.$langs->trans("Project").''; + + $numprojet=select_projects($soc->id,$projectid); + if ($numprojet==0) + { + print '   '.$langs->trans("AddProject").''; + } + print '
'; + print $extrafields->showInputField($key,$value); + print '
"; + print '
'; + + /* + * Combobox pour la fonction de copie + */ + + if (empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE)) + { + print ''; + } + + print ''; + if (! empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE)) + { + // For backward compatibility + print ''; + print ''; + print ''; + print ''; + + if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) print ''; + + print ''; + print ''; + } + + if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) + { + print ''; + } + print '
'.$langs->trans("CopyPropalFrom").' '; + $liste_propal = array(); + $liste_propal[0] = ''; + + $sql ="SELECT p.rowid as id, p.ref, s.nom"; + $sql.=" FROM ".MAIN_DB_PREFIX."propal p"; + $sql.= ", ".MAIN_DB_PREFIX."societe s"; + $sql.= " WHERE s.rowid = p.fk_soc"; + $sql.= " AND p.entity = ".$conf->entity; + $sql.= " AND p.fk_statut <> 0"; + $sql.= " ORDER BY Id"; + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $row = $db->fetch_row($resql); + $propalRefAndSocName = $row[1]." - ".$row[2]; + $liste_propal[$row[0]]=$propalRefAndSocName; + $i++; + } + print $form->selectarray("copie_propal",$liste_propal, 0); + } + else + { + dol_print_error($db); + } + print '
 
'.$langs->trans("CreateEmptyPropal").'
'; + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) + { + $lib=$langs->trans("ProductsAndServices"); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + for ($i = 1 ; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i++) + { + print ''; + print ''; + print ''; + print ''; + } + + print "
'.$lib.''.$langs->trans("Qty").''.$langs->trans("ReductionShort").'
'; + // multiprix + if($conf->global->PRODUIT_MULTIPRICES && $soc->price_level) + $form->select_produits('',"idprod".$i,'',$conf->product->limit_size,$soc->price_level); + else + $form->select_produits('',"idprod".$i,'',$conf->product->limit_size); + print '%
"; + + } + print '
'; + print '
'; + + $langs->load("bills"); + print '
'; + print ''; + print ' '; + print '
'; + + print "
"; +} +else +{ + /* + * Show object in view mode + */ + + $soc = new Societe($db); + $soc->fetch($object->socid); + + $head = propal_prepare_head($object); + dol_fiche_head($head, 'comm', $langs->trans('Proposal'), 0, 'propal'); + + $formconfirm=''; + + // Clone confirmation + if ($action == 'clone') + { + // Create an array for form + $formquestion=array( + //'text' => $langs->trans("ConfirmClone"), + //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid','int'),'socid','(s.client=1 OR s.client=2 OR s.client=3)')) + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id,$langs->trans('ClonePropal'),$langs->trans('ConfirmClonePropal',$object->ref),'confirm_clone',$formquestion,'yes',1); + } + + // Confirm delete + else if ($action == 'delete') + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteProp'), $langs->trans('ConfirmDeleteProp',$object->ref), 'confirm_delete','',0,1); + } + + // Confirm reopen + else if ($action == 'reopen') + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenProp',$object->ref), 'confirm_reopen','',0,1); + } + + // Confirmation delete product/service line + else if ($action == 'ask_deleteline') + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline','',0,1); + } + + // Confirm validate proposal + else if ($action == 'validate') + { + $error=0; + + // on verifie si l'objet est en numerotation provisoire + $ref = substr($object->ref, 1, 4); + if ($ref == 'PROV') + { + $numref = $object->getNextNumRef($soc); + if (empty($numref)) + { + $error++; + dol_htmloutput_errors($object->error); + } + } + else + { + $numref = $object->ref; + } + + $text=$langs->trans('ConfirmValidateProp',$numref); + if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('NOTIFY_VAL_PROPAL',$object->socid); + } + + if (! $error) $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProp'), $text, 'confirm_validate','',0,1); + } + + if (! $formconfirm) + { + $parameters=array('lineid'=>$lineid); + $formconfirm=$hookmanager->executeHooks('formConfirm',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + + // Print form confirm + print $formconfirm; + + + print ''; + + $linkback = ''.$langs->trans("BackToList").''; + + // Ref + print ''; + + // Ref client + print ''; + print ''; + + // Company + print ''; + print ''; + + // Ligne info remises tiers + print ''; + + // Date of proposal + print ''; + print ''; + + // Date end proposal + print ''; + print ''; + print ''; + + // Payment term + print ''; + print ''; + + // Delivery date + $langs->load('deliveries'); + print ''; + print ''; + + // Delivery delay + print ''; + print ''; + + // Origin of demand + print ''; + print ''; + + // Payment mode + print ''; + print ''; + + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + print ''; + } + else + { + print '
'.$langs->trans('Ref').''; + print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); + print '
'; + print ''; + if ($action != 'refclient' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('RefCustomer').''; + print ''.img_edit($langs->trans('Modify')).'
'; + print '
'; + if ($user->rights->propal->creer && $action == 'refclient') + { + print '
'; + print ''; + print ''; + print ''; + print ' '; + print '
'; + } + else + { + print $object->ref_client; + } + print '
'.$langs->trans('Company').''.$soc->getNomUrl(1).'
'.$langs->trans('Discounts').''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + print '. '; + $absolute_discount=$soc->getAvailableDiscounts('','fk_facture_source IS NULL'); + $absolute_creditnote=$soc->getAvailableDiscounts('','fk_facture_source IS NOT NULL'); + $absolute_discount=price2num($absolute_discount,'MT'); + $absolute_creditnote=price2num($absolute_creditnote,'MT'); + if ($absolute_discount) + { + if ($object->statut > 0) + { + print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + } + else + { + // Remise dispo de type non avoir + $filter='fk_facture_source IS NULL'; + print '
'; + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?id='.$object->id,0,'remise_id',$soc->id,$absolute_discount,$filter); + } + } + if ($absolute_creditnote) + { + print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'. '; + } + if (! $absolute_discount && ! $absolute_creditnote) print $langs->trans("CompanyHasNoAbsoluteDiscount").'.'; + print '
'; + print ''; + if ($action != 'editdate' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('Date'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print '
'; + if (! empty($object->brouillon) && $action == 'editdate') + { + print '
'; + print ''; + print ''; + $form->select_date($object->date,'re','','',0,"editdate"); + print ''; + print '
'; + } + else + { + if ($object->date) + { + print dol_print_date($object->date,'daytext'); + } + else + { + print ' '; + } + } + print '
'; + print ''; + if ($action != 'editecheance' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('DateEndPropal'); + print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; + print '
'; + if (! empty($object->brouillon) && $action == 'editecheance') + { + print '
'; + print ''; + print ''; + $form->select_date($object->fin_validite,'ech','','','',"editecheance"); + print ''; + print '
'; + } + else + { + if (! empty($object->fin_validite)) + { + print dol_print_date($object->fin_validite,'daytext'); + if ($object->statut == 1 && $object->fin_validite < ($now - $conf->propal->cloture->warning_delay)) print img_warning($langs->trans("Late")); + } + else + { + print ' '; + } + } + print '
'; + print ''; + if ($action != 'editconditions' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('PaymentConditionsShort'); + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetConditions'),1).'
'; + print '
'; + if ($action == 'editconditions') + { + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); + } + else + { + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'none'); + } + print '
'; + print ''; + if ($action != 'editdate_livraison' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('DeliveryDate'); + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetDeliveryDate'),1).'
'; + print '
'; + if ($action == 'editdate_livraison') + { + print '
'; + print ''; + print ''; + $form->select_date($object->date_livraison,'liv_','','','',"editdate_livraison"); + print ''; + print '
'; + } + else + { + print dol_print_date($object->date_livraison,'daytext'); + } + print '
'; + print ''; + if ($action != 'editavailability' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('AvailabilityPeriod'); + if (! empty($conf->commande->enabled)) print ' ('.$langs->trans('AfterOrder').')'; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetAvailability'),1).'
'; + print '
'; + if ($action == 'editavailability') + { + $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id,$object->availability_id,'availability_id',1); + } + else + { + $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id,$object->availability_id,'none',1); + } + + print '
'; + print ''; + if ($action != 'editdemandreason' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('Source'); + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetDemandReason'),1).'
'; + print '
'; + //print $object->demand_reason_id; + if ($action == 'editdemandreason') + { + $form->form_demand_reason($_SERVER['PHP_SELF'].'?id='.$object->id,$object->demand_reason_id,'demand_reason_id',1); + } + else + { + $form->form_demand_reason($_SERVER['PHP_SELF'].'?id='.$object->id,$object->demand_reason_id,'none'); + } + + print '
'; + print ''; + if ($action != 'editmode' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('PaymentMode'); + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMode'),1).'
'; + print '
'; + if ($action == 'editmode') + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); + } + else + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'none'); + } + print '
'; + print ''; + if ($user->rights->propal->creer) + { + if ($action != 'classify') print ''; + print '
'; + print $langs->trans('Project').''.img_edit($langs->transnoentitiesnoconv('SetProject')).'
'; + print '
'; + if ($action == 'classify') + { + $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'projectid'); + } + else + { + $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none'); + } + print '
'; + if (! empty($object->fk_project)) + { + print ''; + $proj = new Project($db); + $proj->fetch($object->fk_project); + print ''; + print $proj->ref; + print ''; + print ''; + } + else { + print ' '; + } + } + print ''; + } + + // Other attributes + $res=$object->fetch_optionals($object->id,$extralabels); + $parameters=array('colspan' => ' colspan="3"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + + if ($action == 'edit_extras') + { + print '
'; + print ''; + print ''; + print ''; + } + + + foreach($extrafields->attribute_label as $key=>$label) + { + $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); + if ($extrafields->attribute_type[$key] == 'separate') + { + print $extrafields->showSeparator($key); + } + else + { + print 'attribute_required[$key])) print ' class="fieldrequired"'; + print '>'.$label.''; + if ($action == 'edit_extras' && $user->rights->propal->creer) + { + print $extrafields->showInputField($key,$value); + } + else + { + print $extrafields->showOutputField($key,$value); + } + print ''."\n"; + } + } + + if(count($extrafields->attribute_label) > 0) { + + if ($action == 'edit_extras' && $user->rights->propal->creer) + { + print ''; + print ''; + print ''; + print ''; + + } + else { + if ($object->statut == 0 && $user->rights->propal->creer) + { + print ''.img_picto('','edit').' '.$langs->trans('Modify').''; + } + } + } + } + + // Amount HT + print ''.$langs->trans('AmountHT').''; + print ''.price($object->total_ht).''; + print ''.$langs->trans("Currency".$conf->currency).''; + + // Margin Infos + if (! empty($conf->margin->enabled)) { + print ''; + $object->displayMarginInfos(); + print ''; + } + print ''; + + // Amount VAT + print ''.$langs->trans('AmountVAT').''; + print ''.price($object->total_tva).''; + print ''.$langs->trans("Currency".$conf->currency).''; + + // Amount Local Taxes + if ($mysoc->localtax1_assuj=="1") //Localtax1 + { + print ''.$langs->transcountry("AmountLT1",$mysoc->country_code).''; + print ''.price($object->total_localtax1).''; + print ''.$langs->trans("Currency".$conf->currency).''; + } + if ($mysoc->localtax2_assuj=="1") //Localtax2 + { + print ''.$langs->transcountry("AmountLT2",$mysoc->country_code).''; + print ''.price($object->total_localtax2).''; + print ''.$langs->trans("Currency".$conf->currency).''; + } + + + // Amount TTC + print ''.$langs->trans('AmountTTC').''; + print ''.price($object->total_ttc).''; + print ''.$langs->trans("Currency".$conf->currency).''; + + // Statut + print ''.$langs->trans('Status').''.$object->getLibStatut(4).''; + + print '
'; + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) + { + $blocname = 'contacts'; + $title = $langs->trans('ContactsAddresses'); + include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; + } + + if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) + { + $blocname = 'notes'; + $title = $langs->trans('Notes'); + include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; + } + + /* + * Lines + */ + + if (! empty($conf->use_javascript_ajax) && $object->statut == 0) + { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } + + print ''; + + // Show object lines + $result = $object->getLinesArray(); + if (! empty($object->lines)) + $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid); + + // Form to add new line + if ($object->statut == 0 && $user->rights->propal->creer) + { + if ($action != 'editline') + { + $var=true; + + if ($conf->global->MAIN_FEATURES_LEVEL > 1) + { + // Add free or predefined products/services + $object->formAddObjectLine(0,$mysoc,$soc); + } + else + { + // Add free products/services + $object->formAddFreeProduct(0,$mysoc,$soc); + + // Add predefined products/services + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) + { + $var=!$var; + $object->formAddPredefinedProduct(0,$mysoc,$soc); + } + } + + $parameters=array(); + $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + } + + print '
'; + + print ''; + print "\n"; + + if ($action == 'statut') + { + /* + * Formulaire cloture (signe ou non) + */ + $form_close = '
'; + $form_close.= ''; + $form_close.= ''; + $form_close.= ''; + $form_close.= ''; + $form_close.= ''; + $form_close.= '
'.$langs->trans("CloseAs").''; + $form_close.= ''; + $form_close.= ''; + $form_close.= '
'.$langs->trans('Note').'
'; + $form_close.= ''; + $form_close.= '   '; + $form_close.= ' '; + $form_close.= '
'; + + print $form_close; + } + + + /* + * Boutons Actions + */ + if ($action != 'presend') + { + print '
'; + + if ($action != 'statut' && $action <> 'editline') + { + // Validate + if ($object->statut == 0 && $object->total_ttc >= 0 && count($object->lines) > 0 && $user->rights->propal->valider) + { + if (count($object->lines) > 0) print ''.$langs->trans('Validate').''; + //else print ''.$langs->trans('Validate').''; + } + + // Edit + if ($object->statut == 1 && $user->rights->propal->creer) + { + print ''.$langs->trans('Modify').''; + } + + // ReOpen + if (($object->statut == 2 || $object->statut == 3) && $user->rights->propal->cloturer) + { + print 'global->MAIN_JUMP_TAG)?'':'#reopen').'"'; + print '>'.$langs->trans('ReOpen').''; + } + + // Send + if ($object->statut == 1 || $object->statut == 2) + { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->propal->propal_advance->send) + { + print ''.$langs->trans('SendByMail').''; + } + else print ''.$langs->trans('SendByMail').''; + } + + // Create an order + if (! empty($conf->commande->enabled) && $object->statut == 2 && $user->societe_id == 0) + { + if ($user->rights->commande->creer) + { + print ''.$langs->trans("AddOrder").''; + } + } + + // Create contract + if ($conf->contrat->enabled && $object->statut == 2 && $user->societe_id == 0) + { + $langs->load("contracts"); + + if ($user->rights->contrat->creer) + { + print ''.$langs->trans('AddContract').''; + } + } + + // Create an invoice and classify billed + if ($object->statut == 2 && $user->societe_id == 0) + { + if (! empty($conf->facture->enabled) && $user->rights->facture->creer) + { + print ''.$langs->trans("AddBill").''; + } + + $arraypropal=$object->getInvoiceArrayList(); + if (is_array($arraypropal) && count($arraypropal) > 0) + { + print 'socid.'">'.$langs->trans("ClassifyBilled").''; + } + } + + // Close + if ($object->statut == 1 && $user->rights->propal->cloturer) + { + print 'global->MAIN_JUMP_TAG)?'':'#close').'"'; + print '>'.$langs->trans('Close').''; + } + + // Clone + if ($user->rights->propal->creer) + { + print ''.$langs->trans("ToClone").''; + } + + // Delete + if ($user->rights->propal->supprimer) + { + print ''.$langs->trans('Delete').''; + } + + } + + print '
'; + print "
\n"; + } + + if ($action != 'presend') + { + print '
'; + print ''; // ancre + + + /* + * Documents generes + */ + $filename=dol_sanitizeFileName($object->ref); + $filedir=$conf->propal->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER["PHP_SELF"]."?id=".$object->id; + $genallowed=$user->rights->propal->creer; + $delallowed=$user->rights->propal->supprimer; + + $var=true; + + $somethingshown=$formfile->show_documents('propal',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'',0,'',$soc->default_lang); + + + /* + * Linked object block + */ + $somethingshown=$object->showLinkedObjectBlock(); + + print ''; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions=new FormActions($db); + $somethingshown=$formactions->showactions($object,'propal',$socid); + + print '
'; + } + + + /* + * Action presend + * + */ + if ($action == 'presend') + { + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($object->ref,'/')); + $file=$fileparams['fullname']; + + // Build document if it not exists + if (! $file || ! is_readable($file)) + { + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $result=propale_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($object->ref,'/')); + $file=$fileparams['fullname']; + } + + print '
'; + print_titre($langs->trans('SendPropalByMail')); + + // Create form object + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->fromtype = 'user'; + $formmail->fromid = $user->id; + $formmail->fromname = $user->getFullName($langs); + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $liste=array(); + foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; + $formmail->withto=GETPOST("sendto")?GETPOST("sendto"):$liste; + $formmail->withtocc=$liste; + $formmail->withtoccc=(! empty($conf->global->MAIN_EMAIL_USECCC)?$conf->global->MAIN_EMAIL_USECCC:false); + $formmail->withtopic=$langs->trans('SendPropalRef','__PROPREF__'); + $formmail->withfile=2; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + + // Tableau des substitutions + $formmail->substit['__PROPREF__']=$object->ref; + $formmail->substit['__SIGNATURE__']=$user->signature; + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; + //Find the good contact adress $custcontact=''; $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); - + $contactarr=$object->liste_contact(-1,'external'); + if (is_array($contactarr) && count($contactarr)>0) { foreach($contactarr as $contact) { if ($contact['libelle']==$langs->trans('TypeContact_propal_external_CUSTOMER')) { @@ -2257,29 +2257,29 @@ else if (!empty($custcontact)) { $formmail->substit['__CONTACTCIVNAME__']=$custcontact; } - } - - // Tableau des parametres complementaires - $formmail->param['action']='send'; - $formmail->param['models']='propal_send'; - $formmail->param['id']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - - - // Init list of files - if (GETPOST("mode")=='init') - { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); - } - - $formmail->show_form(); - - print '
'; - } -} - -// End of page -llxFooter(); -$db->close(); -?> + } + + // Tableau des parametres complementaires + $formmail->param['action']='send'; + $formmail->param['models']='propal_send'; + $formmail->param['id']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + } + + $formmail->show_form(); + + print '
'; + } +} + +// End of page +llxFooter(); +$db->close(); +?> diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 4545d4cd0ac..0288fa4f31f 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1634,6 +1634,20 @@ class Propal extends CommonObject $this->db->rollback(); return -2; } + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $this->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + //$ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($this->db, $this, $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL?$conf->global->PROPALE_ADDON_PDF_ODT_TOBILL:$this->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; @@ -1646,6 +1660,21 @@ class Propal extends CommonObject } else { + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id') ? GETPOST('lang_id') : $this->client->default_lang); + $outputlangs->setDefaultLang($newlang); + } + //$ret=$object->fetch($id); // Reload to get new records + propale_pdf_create($this->db, $this, $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED?$conf->global->PROPALE_ADDON_PDF_ODT_CLOSED:$this->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface=new Interfaces($this->db); diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index abf8e76f988..00741aad4d4 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -442,7 +442,7 @@ class Paiement extends CommonObject } // Add link 'company' in bank_url between invoice and bank transaction (for each invoice concerned by payment) - if (! $error) + if (! $error && $label != '(WithdrawalPayment)') { $linkaddedforthirdparty=array(); foreach ($this->amounts as $key => $value) // We should have always same third party but we loop in case of. diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 1977e41970a..87e555958e8 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -41,18 +41,9 @@ class box_activity extends ModeleBoxes var $info_box_head = array(); var $info_box_contents = array(); - /** - * Constructor - */ - function __construct($db) - { - $this->db = $db; - - $this->enabled = 1; - // FIXME: Use a cache to save data because this slow down too much main home page. This box slow down too seriously software. - // FIXME: Removed number_format (not compatible with all languages) - // FIXME: Pb into some status - } + // FIXME: Use a cache to save data because this slow down too much main home page. This box slow down too seriously software. + // FIXME: Removed number_format (not compatible with all languages) + // FIXME: Pb into some status /** * Charge les donnees en memoire pour affichage ulterieur @@ -66,6 +57,7 @@ class box_activity extends ModeleBoxes $totalMnt = 0; $totalnb = 0; + $i = 0; include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; @@ -99,7 +91,6 @@ class box_activity extends ModeleBoxes if ($result) { $num = $db->num_rows($result); - $i = 0; while ($i < $num) { $this->info_box_contents[$i][0] = array('td' => 'align="left" width="16"', 'logo' => 'bill'); @@ -140,7 +131,7 @@ class box_activity extends ModeleBoxes $result = $db->query($sql); if ($result) { - $num = $db->num_rows($result)+$i; + $num = $db->num_rows($result) + $i; $now=dol_now(); while ($i < $num) @@ -195,7 +186,7 @@ class box_activity extends ModeleBoxes if ($result) { - $num = $db->num_rows($result)+$i; + $num = $db->num_rows($result) + $i; while ($i < $num) { $this->info_box_contents[$i][0] = array('td' => 'align="left" width="16"','logo' => 'object_order'); @@ -246,7 +237,7 @@ class box_activity extends ModeleBoxes if ($result) { - $num = $db->num_rows($result)+$i; + $num = $db->num_rows($result) + $i; while ($i < $num) { $this->info_box_contents[$i][0] = array('td' => 'align="left" width="16"','logo' => 'object_propal'); diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index ad901b42ca9..7ca1b1dd4a2 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -33,7 +33,7 @@ class ModeleBoxes // Can't be abtract as it is instanciated to build "empty" var $error=''; var $max=5; var $enabled=1; - + var $rowid; var $id; var $position; diff --git a/htdocs/core/class/fileupload.class.php b/htdocs/core/class/fileupload.class.php index 8afb5f39f42..c5e83017940 100644 --- a/htdocs/core/class/fileupload.class.php +++ b/htdocs/core/class/fileupload.class.php @@ -436,7 +436,7 @@ class FileUpload { file_put_contents($file_path, fopen($uploaded_file, 'r'), FILE_APPEND); } else { - dol_move_uploaded_file($uploaded_file, $file_path, 1); + dol_move_uploaded_file($uploaded_file, $file_path, 1, 0, 0, 0, 'userfile'); } } else diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index 9154aaa2fdd..72b49af418e 100755 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -131,7 +131,7 @@ class HookManager // Define type of hook ('output', 'returnvalue' or 'addreplace') $hooktype='output'; if (preg_match('/^pdf_/',$method)) $hooktype='returnvalue'; // pdf_xxx except pdf_writelinedesc are returnvalue hooks. When there is 2 hooks of this type, only last one win. - if ($method == 'doActions' || $method == 'formObjectOptions' || $method == 'pdf_writelinedesc') $hooktype='addreplace'; + if (in_array($method,array('doActions','formObjectOptions','pdf_writelinedesc','paymentsupplierinvoices'))) $hooktype='addreplace'; // Loop on each hook to qualify modules that declared context $modulealreadyexecuted=array(); @@ -150,7 +150,7 @@ class HookManager // test to avoid to run twice a hook, when a module implements several active contexts if (in_array($module,$modulealreadyexecuted)) continue; $modulealreadyexecuted[$module]=$module; - // Hooks that return int + // Hooks that return int (doActions, formObjectOptions, pdf_writelinedesc, paymentsupplierinvoices) if ($hooktype == 'addreplace') { $resaction += $actionclassinstance->$method($parameters, $object, $action, $this); // $object and $action can be changed by method ($object->id during creation for example or $action to go back to other action for example) @@ -159,7 +159,7 @@ class HookManager $error++; $this->error=$actionclassinstance->error; $this->errors=array_merge($this->errors, (array) $actionclassinstance->errors); - // TODO remove this. Change must be inside the method if required + // TODO remove this. Change must be inside the method of hook if required if ($method == 'doActions') { if ($action=='add') $action='create'; @@ -170,7 +170,7 @@ class HookManager // Generic hooks that return a string (printSearchForm, printLeftBlock, printTopRightMenu, formAddObjectLine, formBuilddocOptions, ...) else { - // TODO. this should be done into the method by returning nothing + // TODO. this should be done into the method of hook by returning nothing if (is_array($parameters) && ! empty($parameters['special_code']) && $parameters['special_code'] > 3 && $parameters['special_code'] != $actionclassinstance->module_number) continue; $result = $actionclassinstance->$method($parameters, $object, $action, $this); // $object and $action can be changed by method ($object->id during creation for example or $action to go back to other action for example) diff --git a/htdocs/core/db/mysql.class.php b/htdocs/core/db/mysql.class.php index 386624132f7..1143372bb98 100644 --- a/htdocs/core/db/mysql.class.php +++ b/htdocs/core/db/mysql.class.php @@ -931,7 +931,7 @@ class DoliDBMysql $sql .= ",".implode(',',$sqluq); if($keys != "") $sql .= ",".implode(',',$sqlk); - $sql .=") type=".$type; + $sql .=") engine=".$type; dol_syslog($sql,LOG_DEBUG); if(! $this -> query($sql)) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 7d9d67f839c..2180546dc39 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -925,7 +925,7 @@ class DoliDBMysqli $sql .= ",".implode(',',$sqluq); if($keys != "") $sql .= ",".implode(',',$sqlk); - $sql .=") type=".$type; + $sql .=") engine=".$type; dol_syslog($sql,LOG_DEBUG); if(! $this -> query($sql)) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 351b3fed386..23bf990ae69 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -649,7 +649,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable $hookmanager->initHooks(array('fileslib')); - $parameters=array('filename' => $file_name, 'varfiles' => $varfiles, 'allowoverwrite' => $allowoverwrite); + $parameters=array('dest_file' => $dest_file, 'src_file' => $src_file, 'file_name' => $file_name, 'varfiles' => $varfiles, 'allowoverwrite' => $allowoverwrite); $reshook=$hookmanager->executeHooks('moveUploadedFile', $parameters, $object); } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 835e5a36ee1..edc39c6d164 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1640,10 +1640,11 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) * @param string $options Add more attribute on img tag (For example 'style="float: right"') * @param int $pictoisfullpath If 1, image path is a full path + * @param int $srconly Return only content of the src attribute of img. * @return string Return img tag * @see #img_object, #img_picto_common */ -function img_picto($alt, $picto, $options = '', $pictoisfullpath = false) +function img_picto($alt, $picto, $options = '', $pictoisfullpath = false, $srconly=0) { global $conf; @@ -1678,7 +1679,8 @@ function img_picto($alt, $picto, $options = '', $pictoisfullpath = false) $fullpathpicto = $url.'/'.$path.'/img/'.$picto; } - return ''.dol_escape_htmltag($alt).''; + if ($srconly) return $fullpathpicto; + else return ''.dol_escape_htmltag($alt).''; } /** diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index d02be9ebf06..89c92a14c69 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -159,6 +159,12 @@ class modAgenda extends DolibarrModules $this->rights[$r][5] = 'delete'; $r++; + $this->rights[$r][0] = 2414; + $this->rights[$r][1] = 'Export actions/tasks of others'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'export'; + // Main menu entries $this->menu = array(); // List of menus to add $r=0; @@ -355,12 +361,30 @@ class modAgenda extends DolibarrModules //-------- $r=0; - // $this->export_code[$r] Code unique identifiant l'export (tous modules confondus) - // $this->export_label[$r] Libelle par defaut si traduction de cle "ExportXXX" non trouvee (XXX = Code) - // $this->export_permission[$r] Liste des codes permissions requis pour faire l'export - // $this->export_fields_sql[$r] Liste des champs exportables en codif sql - // $this->export_fields_name[$r] Liste des champs exportables en codif traduction - // $this->export_sql[$r] Requete sql qui offre les donnees a l'export + $r++; + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]="Liste des action commerciales de l'agenda"; + $this->export_permission[$r]=array(array("agenda","export")); + $this->export_fields_array[$r]=array('a.id'=>'IdAgenda','a.label'=>'Actions','a.datep'=>'DateActionStart', + 'a.datea'=>'DateActionEnd','a.percent'=>'PercentDone','a.fk_user_author'=>'ActionAskedBy','a.fk_user_action'=>'ActionAffectedTo', + 'a.fk_user_done'=>"ActionDoneBy","a.priority"=>"Priority","a.fulldayevent"=>"EventOnFullDay","a.location"=>"Location", + "a.fk_soc"=>"Company","a.fk_contact"=>"contact","a.fk_action"=>"Action"); + + $this->export_TypeFields_array[$r]=array('a.id'=>'Numeric','a.label'=>'Text','a.datep'=>'Date','a.datep2'=>'Date', + 'a.datea'=>'Date','a.datea2'=>'Date','a.percent'=>'Numeric','a.fk_user_author'=>'List:user:name','a.fk_user_action'=>'List:user:name', + 'a.fk_user_done'=>"List:user:name","a.priority"=>"Numeric","a.fulldayevent"=>"Boolean","a.location"=>"Text", + "a.fk_soc"=>"List:Societe:nom","a.fk_contact"=>"List:socpeople:name","a.fk_action"=>"List:c_actioncomm:libelle:code"); + + $this->export_entities_array[$r]=array('a.id'=>'action','a.label'=>'action','a.datep'=>'action','a.datep2'=>'action', + 'a.datea'=>'action','a.datea2'=>'action','a.percent'=>'action','a.fk_user_author'=>'action','a.fk_user_action'=>'action', + 'a.fk_user_done'=>"action","a.priority"=>"action","a.fulldayevent"=>"action","a.location"=>"action", + "a.fk_soc"=>"action","a.fk_contact"=>"action","a.fk_action"=>"action"); + + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'actioncomm as a'; + $this->export_sql_end[$r] .=' Where a.entity = '.$conf->entity; + $this->export_sql_end[$r] .=' ORDER BY datep'; + } diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index 877bea83b22..a17835ddcc6 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -86,6 +86,13 @@ class modProjet extends DolibarrModules $this->const[$r][4] = 0; $r++; + $r++; + $this->const[$r][0] = "PROJECT_ADDON_PDF_ODT_PATH"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/project"; + $this->const[$r][3] = ""; + $this->const[$r][4] = 0; + // Boxes $this->boxes = array(); diff --git a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php new file mode 100644 index 00000000000..a1aa87366d9 --- /dev/null +++ b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php @@ -0,0 +1,790 @@ + + * Copyright (C) 2012 Juanjo Menent +* Copyright (C) 2013 Florian Henry +* +* 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 . +* or see http://www.gnu.org/ +*/ + +/** + * \file htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php + * \ingroup project + * \brief File of class to build ODT documents for third parties +*/ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; +require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; +if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; +if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; +if (! empty($conf->contrat->enabled)) require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; +if (! empty($conf->ficheinter->enabled)) require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; +if (! empty($conf->deplacement->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php'; +if (! empty($conf->agenda->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_project_odt extends ModelePDFProjects +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'PROJECT_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva COMMANDE_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 0; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2); // Par defaut, si n'etait pas defini + } + + + /** + * Define array with couple substitution key => substitution value + * + * @param Object $object Main object to use as data source + * @param Translate $outputlangs Lang object to use for output + * @return array Array of substitution + */ + function get_substitutionarray_object($object,$outputlangs) + { + global $conf; + + return array( + 'object_id'=>$object->id, + 'object_ref'=>$object->ref, + 'object_title'=>$object->title, + 'object_description'=>$object->description, + 'object_date_creation'=>dol_print_date($object->date_c,'day'), + 'object_date_modification'=>dol_print_date($object->date_m,'day'), + 'object_date_start'=>dol_print_date($object->date_start,'day'), + 'object_date_end'=>dol_print_date($object->date_end,'day'), + 'object_note_private'=>$object->note_private, + 'object_note_public'=>$object->note_public, + 'object_public'=>$object->public, + 'object_statut'=>html_entity_decode($object->getLibStatut()) + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $task Task Object + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_tasks($task,$outputlangs) + { + global $conf; + + return array( + 'task_ref'=>$task->ref, + 'task_fk_project'=>$task->fk_project, + 'task_projectref'=>$task->projectref, + 'task_projectlabel'=>$task->projectlabel, + 'task_label'=>$task->label, + 'task_description'=>$task->description, + 'task_fk_parent'=>$task->fk_parent, + 'task_duration'=>$task->duration, + 'task_progress'=>$task->progress, + 'task_public'=>$task->public, + 'task_date_start'=>dol_print_date($task->date_start,'day'), + 'task_date_end'=>dol_print_date($task->date_end,'day') + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $contact Contact array + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_project_contacts($contact,$outputlangs) + { + global $conf; + + return array( + 'projcontacts_id'=>$contact['id'], + 'projcontacts_rowid'=>$contact['rowid'], + 'projcontacts_role'=>$contact['libelle'], + 'projcontacts_lastname'=>$contact['lastname'], + 'projcontacts_firstname'=>$contact['firstname'], + 'projcontacts_fullcivname'=>$contact['fullname'], + 'projcontacts_socname'=>$contact['socname'], + 'projcontacts_email'=>$contact['email'] + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $file file array + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_project_file($file,$outputlangs) + { + global $conf; + + return array( + 'projfile_name'=>$file['name'], + 'projfile_date'=>dol_print_date($file['date'],'day'), + 'projfile_size'=>$file['size'] + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $refdetail Reference array + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_project_reference($refdetail,$outputlangs) + { + global $conf; + + return array( + 'projref_type'=>$refdetail['type'], + 'projref_ref'=>$refdetail['ref'], + 'projref_date'=>dol_print_date($refdetail['date'],'day'), + 'projref_socname'=>$refdetail['socname'], + 'projref_amountht'=>price($refdetail['amountht'],0,$outputlangs), + 'projref_amountttc'=>price($refdetail['amountttc'],0,$outputlangs), + 'projref_status'=>$refdetail['status'] + ); + } + + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".
\n"; + $texte.= '
'; + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= ''; + + // List of directories area + $texte.= ''; + + + $texte.= ''; + $texte.= ''; + + /*$texte.= ''; + $texte.= ''; + $texte.= '';*/ + + $texte.= '
'; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->PROJECT_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='
'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
'; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= '
'; + $texte.= ''; + $texte.= '  '; + $texte.= ''; + $texte.= '
'; + + // Scan directories + if (count($listofdir)) $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + + $texte.= '
'; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '
'; + $texte.= ''; + $texte.= '
'; + $texte.= '
'; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param Commande $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath) + { + global $user,$langs,$conf,$mysoc; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("projects"); + + if ($conf->projet->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new Project($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + + $dir = $conf->projet->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.odt/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + $newfiletmp=$objectref.'_'.$newfiletmp; + //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + $file=$dir.'/'.$newfiletmp.'.odt'; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + + dol_mkdir($conf->projet->dir_temp); + + $socobject=$object->thirdparty; + + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->nom, + '__FROM_EMAIL__' => $this->emetteur->email, + ); + complete_substitutions_array($substitutionarray, $langs, $object); + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->projet->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + + + // Make substitutions into odt of user info + $tmparray=$this->get_substitutionarray_user($user,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of mysoc + $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Make substitutions into odt of thirdparty + $tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Replace tags of object + external modules + $tmparray=$this->get_substitutionarray_object($object,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Replace tags of lines for tasks + try + { + $listlines = $odfHandler->setSegment('tasks'); + + $taskstatic = new Task($this->db); + + // Security check + $socid=0; + if (!empty($object->fk_soc)) $socid = $object->fk_soc; + + $tasksarray=$taskstatic->getTasksArray(0, 0, $object->id, $socid, 0); + + + + foreach ($tasksarray as $task) + { + $tmparray=$this->get_substitutionarray_tasks($task,$outputlangs); + //complete_substitutions_array($tmparray, $outputlangs, $object, $task, "completesubstitutionarray_lines"); + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace tags of project files + try + { + $listlines = $odfHandler->setSegment('projectfiles'); + + $upload_dir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($object->ref); + $filearray=dol_dir_list($upload_dir,"files",0,'','\.meta$','name',SORT_ASC,1); + + + foreach ($filearray as $filedetail) + { + //dol_syslog(get_class($this).'::ee $filedetail'.var_export($filedetail,true)); + $tmparray=$this->get_substitutionarray_project_file($filedetail,$outputlangs); + + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace tags of lines for contacts + $sourcearray=array('internal','external'); + $contact_arrray=array(); + foreach ($sourcearray as $source) { + $contact_temp=$object->liste_contact(-1,$source); + if ((is_array($contact_temp) && count($contact_temp) > 0)) + { + $contact_arrray=array_merge($contact_arrray,$contact_temp); + } + } + if ((is_array($contact_arrray) && count($contact_arrray) > 0)) + { + try + { + $listlines = $odfHandler->setSegment('projectcontacts'); + + foreach ($contact_arrray as $contact) + { + if ($contact['source']=='internal') { + $objectdetail=new User($this->db); + $objectdetail->fetch($contact['id']); + $contact['socname']=$mysoc->name; + } elseif ($contact['source']=='external') { + $objectdetail=new Contact($this->db); + $objectdetail->fetch($contact['id']); + + $soc=new Societe($this->db); + $soc->fetch($contact['socid']); + $contact['socname']=$soc->name; + } + $contact['fullname']=$objectdetail->getFullName($outputlangs,1); + + $tmparray=$this->get_substitutionarray_project_contacts($contact,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $contact, $contact, "completesubstitutionarray_lines"); + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + } + + //List of referent + + $listofreferent=array( + 'propal'=>array( + 'title'=>"ListProposalsAssociatedProject", + 'class'=>'Propal', + 'test'=>$conf->propal->enabled), + 'order'=>array( + 'title'=>"ListOrdersAssociatedProject", + 'class'=>'Commande', + 'test'=>$conf->commande->enabled), + 'invoice'=>array( + 'title'=>"ListInvoicesAssociatedProject", + 'class'=>'Facture', + 'test'=>$conf->facture->enabled), + 'invoice_predefined'=>array( + 'title'=>"ListPredefinedInvoicesAssociatedProject", + 'class'=>'FactureRec', + 'test'=>$conf->facture->enabled), + 'order_supplier'=>array( + 'title'=>"ListSupplierOrdersAssociatedProject", + 'class'=>'CommandeFournisseur', + 'test'=>$conf->fournisseur->enabled), + 'invoice_supplier'=>array( + 'title'=>"ListSupplierInvoicesAssociatedProject", + 'class'=>'FactureFournisseur', + 'test'=>$conf->fournisseur->enabled), + 'contract'=>array( + 'title'=>"ListContractAssociatedProject", + 'class'=>'Contrat', + 'test'=>$conf->contrat->enabled), + 'intervention'=>array( + 'title'=>"ListFichinterAssociatedProject", + 'class'=>'Fichinter', + 'disableamount'=>1, + 'test'=>$conf->ficheinter->enabled), + 'trip'=>array( + 'title'=>"ListTripAssociatedProject", + 'class'=>'Deplacement', + 'disableamount'=>1, + 'test'=>$conf->deplacement->enabled), + 'agenda'=>array( + 'title'=>"ListActionsAssociatedProject", + 'class'=>'ActionComm', + 'disableamount'=>1, + 'test'=>$conf->agenda->enabled) + ); + + //Inser refenrence + try + { + $listlines = $odfHandler->setSegment('projectrefs'); + + foreach ($listofreferent as $keyref => $valueref) + { + $title=$valueref['title']; + $classname=$valueref['class']; + $qualified=$valueref['test']; + if ($qualified) + { + $elementarray = $object->get_element_list($keyref); + if (count($elementarray)>0 && is_array($elementarray)) + { + $var=true; + $total_ht = 0; + $total_ttc = 0; + $num=count($elementarray); + for ($i = 0; $i < $num; $i++) + { + $ref_array=array(); + $ref_array['type']=$langs->trans($classname); + + $element = new $classname($this->db); + $element->fetch($elementarray[$i]); + $element->fetch_thirdparty(); + + //Ref object + $ref_array['ref']=$element->ref; + + //Date object + $dateref=$element->date; + if (empty($dateref)) $dateref=$element->datep; + if (empty($dateref)) $dateref=$element->date_contrat; + $ref_array['date']=$dateref; + + //Soc object + if (is_object($element->thirdparty)) { + $ref_array['socname']=$element->thirdparty->name; + } else { + $ref_array['socname']=''; + } + + //Amount object + if (empty($valueref['disableamount'])) { + if (!empty($element->total_ht)) { + $ref_array['amountht']=$element->total_ht; + $ref_array['amountttc']=$element->total_ttc; + }else { + $ref_array['amountht']=0; + $ref_array['amountttc']=0; + } + }else { + $ref_array['amountht']=''; + $ref_array['amountttc']=''; + } + + $ref_array['status']=html_entity_decode($element->getLibStatut(0)); + + $tmparray=$this->get_substitutionarray_project_reference($ref_array,$outputlangs); + + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + + } + } + $odfHandler->mergeSegment($listlines); + } + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Write new file + //$result=$odfHandler->exportAsAttachedFile('toto'); + $odfHandler->saveToDisk($file); + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + +} +?> \ No newline at end of file diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index 0f9e64c1fe2..0878e4da181 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -106,6 +106,12 @@ class doc_generic_proposal_odt extends ModelePDFPropales $texte.= ''; $texte.= ''; $texte.= ''; + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + $texte.= ''; + $texte.= ''; + $texte.= ''; + } $texte.= ''; // List of directories area @@ -143,8 +149,38 @@ class doc_generic_proposal_odt extends ModelePDFPropales $texte.= '
'; // Scan directories - if (count($listofdir)) $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + if (count($listofdir)) + { + $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + + if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) + { + // Model for creation + $liste=ModelePDFPropales::liste_modeles($this->db); + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= '"; + + $texte.= ''; + $texte.= ''; + $texte.= '"; + $texte.= ''; + + $texte.= ''; + $texte.= '"; + $texte.= '
'.$langs->trans("DefaultModelPropalCreate").''; + $texte.= $form->selectarray('value2',$liste,$conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT); + $texte.= "
'.$langs->trans("DefaultModelPropalToBill").''; + $texte.= $form->selectarray('value3',$liste,$conf->global->PROPALE_ADDON_PDF_ODT_TOBILL); + $texte.= "
'.$langs->trans("DefaultModelPropalClosed").''; + $texte.= $form->selectarray('value4',$liste,$conf->global->PROPALE_ADDON_PDF_ODT_CLOSED); + $texte.= "
'; + } + } + + $texte.= ''; diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index fb936b58f3f..6148ed5d5f7 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -82,6 +82,8 @@ if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->ex setEventMessage($object->error,'errors'); $action=''; }else { + if ($object->lastresult > 0) setEventMessage($langs->trans("JobFinished"),'warnings'); + else setEventMessage($langs->trans("JobFinished"),'mesgs'); $action=''; } @@ -123,9 +125,9 @@ if ($action=='add') { // Save parameters if ($action=='update') { $object->id=$id; - $object->jobtype=GETPOST('jobtype','alpha'); - $object->label=GETPOST('label','alpha'); - $object->command=GETPOST('command','alpha'); + $object->jobtype=GETPOST('jobtype'); + $object->label=GETPOST('label'); + $object->command=GETPOST('command'); $object->classesname=GETPOST('classesname','alpha'); $object->priority=GETPOST('priority','int'); $object->objectname=GETPOST('objectname','alpha'); @@ -194,10 +196,13 @@ if ($action=='inactive') { llxHeader('',$langs->trans("CronAdd")); -if ($action=='edit' || empty($action) || $action=='delete' || $action=='execute') { +if ($action=='edit' || empty($action) || $action=='delete' || $action=='execute') +{ $head=cron_prepare_head($object); dol_fiche_head($head, 'card', $langs->trans("CronTask"), 0, 'bill'); -} elseif ($action=='create') { +} +elseif ($action=='create') +{ print_fiche_titre($langs->trans("CronTask"),'','setup'); } @@ -251,8 +256,8 @@ if (empty($object->status) && $action != 'create') dol_htmloutput_mesg($langs->trans("CronTaskInactive"),'','warning',1); } -if (($action=="create") || ($action=="edit")) { - +if (($action=="create") || ($action=="edit")) +{ print '
'; print ''."\n"; if (!empty($object->id)) { @@ -565,6 +570,10 @@ if (($action=="create") || ($action=="edit")) { print ''; + + dol_fiche_end(); + + print "\n\n
\n"; if (! $user->rights->cron->create) { print ''.$langs->trans("Edit").''; @@ -585,9 +594,15 @@ if (($action=="create") || ($action=="edit")) { print ''.$langs->trans("CronStatusInactiveBtn").''; } } - if ((! $user->rights->cron->execute) || (empty($object->status))) { + if ((empty($user->rights->cron->execute))) + { print ''.$langs->trans("CronExecute").''; - } else { + } + else if (empty($object->status)) + { + print ''.$langs->trans("CronExecute").''; + } + else { print ''.$langs->trans("CronExecute").''; } print '

'; diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 078ee98ad8e..b43f4ed9bd4 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -834,9 +834,12 @@ class Cronjob extends CommonObject { global $langs, $conf; + $error=0; + $now=dol_now(); + $langs->load('cron'); - if (empty($userlogin)) { + if (empty($userlogin)) { $this->error="User login is mandatory"; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); return -1; @@ -845,27 +848,59 @@ class Cronjob extends CommonObject require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; $user=new User($this->db); $result=$user->fetch('',$userlogin); - if ($result<0) { + if ($result<0) + { $this->error="User Error:".$user->error; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); return -1; - }else { - if (empty($user->id)) { + } + else + { + if (empty($user->id)) + { $this->error=" User user login:".$userlogin." do not exists"; dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); return -1; } } - dol_syslog(get_class($this)."::run_jobs userlogin:$userlogin", LOG_DEBUG); + dol_syslog(get_class($this)."::run_jobs jobtype=".$this->jobtype." userlogin=".$userlogin, LOG_DEBUG); - $error=0; - $now=dol_now(); - if ($this->jobtype=='method') { + // Increase limit of time. Works only if we are not in safe mode + $ExecTimeLimit=600; + if (!empty($ExecTimeLimit)) + { + $err=error_reporting(); + error_reporting(0); // Disable all errors + //error_reporting(E_ALL); + @set_time_limit($ExecTimeLimit); // Need more than 240 on Windows 7/64 + error_reporting($err); + } + if (!empty($MemoryLimit)) + { + @ini_set('memory_limit', $MemoryLimit); + } + + + // Update last run date (to track launch) + $this->datelastrun=$now; + $this->lastoutput=''; + $this->lastresult=''; + $this->nbrun=$this->nbrun+1; + $result = $this->update($user); + if ($result<0) { + dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); + return -1; + } + + // Run a method + if ($this->jobtype=='method') + { // load classes $ret=dol_include_once("/".$this->module_name."/class/".$this->classesname,$this->objectname); - if ($ret===false) { + if ($ret===false) + { $this->error=$langs->trans('CronCannotLoadClass',$file,$this->objectname); dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); return -1; @@ -873,7 +908,8 @@ class Cronjob extends CommonObject // Load langs $result=$langs->load($this->module_name.'@'.$this->module_name); - if ($result<0) { + if ($result<0) + { dol_syslog(get_class($this)."::run_jobs Cannot load module langs".$langs->error, LOG_ERR); return -1; } @@ -883,66 +919,89 @@ class Cronjob extends CommonObject // Create Object for the call module $object = new $this->objectname($this->db); - - //Update launch start date - $this->datelastrun=$now; - $this->nbrun=$this->nbrun+1; - $result = $this->update($user); - if ($result<0) { - dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - return -1; - } - - $params_arr = array(); - $params_arr=explode(", ",$this->params); - if (!is_array($params_arr)) { + $params_arr = explode(", ",$this->params); + if (!is_array($params_arr)) + { $result = call_user_func(array($object, $this->methodename), $this->params); - }else { + } + else + { $result = call_user_func_array(array($object, $this->methodename), $params_arr); } - if ($result===false) { + if ($result===false) + { dol_syslog(get_class($this)."::run_jobs ".$object->error, LOG_ERR); return -1; - }else { + } + else + { $this->lastoutput=var_export($result,true); $this->lastresult=var_export($result,true); } - } elseif ($this->jobtype=='command') { - dol_syslog(get_class($this)."::run_jobs system:".$this->command, LOG_DEBUG); - $output_arr=array(); - - //Update launch start date - $this->datelastrun=$now; - $this->nbrun=$this->nbrun+1; - $result = $this->update($user); - if ($result<0) { - dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); - return -1; - } - - exec($this->command, $output_arr,$retval); - - dol_syslog(get_class($this)."::run_jobs output_arr:".var_export($output_arr,true), LOG_DEBUG); - - $this->lastoutput=''; - if (is_array($output_arr) && count($output_arr)>0) { - foreach($output_arr as $val) { - $this->lastoutput.=$val."\n"; - } - } - $this->lastresult=$retval; } - - //Update result date - $this->datelastresult=$now; + + // Run a command line + if ($this->jobtype=='command') + { + $command=escapeshellcmd($this->command); + $command.=" 2>&1"; + dol_mkdir($conf->cronjob->dir_temp); + $outputfile=$conf->cronjob->dir_temp.'/cronjob.'.$userlogin.'.out'; + + dol_syslog(get_class($this)."::run_jobs system:".$command, LOG_DEBUG); + $output_arr=array(); + + $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 + if ($execmethod == 1) + { + exec($command, $output_arr, $retval); + } + if ($execmethod == 2) + { + $ok=0; + $handle = fopen($outputfile, 'w'); + if ($handle) + { + dol_syslog("Run command ".$command); + $handlein = popen($command, 'r'); + while (!feof($handlein)) + { + $read = fgets($handlein); + fwrite($handle,$read); + $output_arr[]=$read; + } + pclose($handlein); + fclose($handle); + } + if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + } + + dol_syslog(get_class($this)."::run_jobs output_arr:".var_export($output_arr,true), LOG_DEBUG); + + + // Update with result + $this->lastoutput=''; + if (is_array($output_arr) && count($output_arr)>0) + { + foreach($output_arr as $val) + { + $this->lastoutput.=$val."\n"; + } + } + $this->lastresult=$retval; + $this->datelastresult=dol_now(); $result = $this->update($user); - if ($result<0) { + if ($result < 0) + { dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR); return -1; - }else { + } + else + { return 1; } diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index 5e972f0e55b..efed9579d1f 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -146,9 +146,9 @@ print $langs->trans('CronWaitingJobs'); print "

"; if (count($object->lines)>0) { - + print ''; - print ''; + print ''; $arg_url='&page='.$page.'&status='.$status.'&search_label='.$search_label; print_liste_field_titre($langs->trans("CronLabel"),$_SERVEUR['PHP_SELF'],"t.label","",$arg_url,'',$sortfield,$sortorder); print_liste_field_titre($langs->trans("CronTask"),'','',"",$arg_url,'',$sortfield,$sortorder); @@ -161,15 +161,15 @@ if (count($object->lines)>0) { print_liste_field_titre($langs->trans("CronLastResult"),$_SERVEUR['PHP_SELF'],"t.lastresult","",$arg_url,'',$sortfield,$sortorder); print_liste_field_titre($langs->trans("CronLastOutput"),$_SERVEUR['PHP_SELF'],"t.lastoutput","",$arg_url,'',$sortfield,$sortorder); print ''; - + print ''; - + print ''."\n"; print ''; print ''; - - - + + + print ''; @@ -186,30 +186,30 @@ if (count($object->lines)>0) { print '  '; print ''; print ''; - + print ''; print ''; - - - + + + // Boucler sur chaque job $style='impair'; foreach($object->lines as $line){ // title profil if ($style=='pair') {$style='impair';} else {$style='pair';} - + print ''; - + print ''; - + print ''; - + print ''; - + print ''; - + print ''; - + print ''; - + print ''; - + print ''; - + print ''; - + print ''; - - print ''; - + print ''; } print '
'; print ''; print '
'; if(!empty($line->label)) { - print ''.$line->label.''; - } + print ''.$line->label.''; + } else { print $langs->trans('CronNone'); } print ''; if ($line->jobtype=='method') { print $langs->trans('CronModule').':'.$line->module_name.'
'; @@ -219,7 +219,7 @@ if (count($object->lines)>0) { if(!empty($line->params)) { print '
'.$langs->trans('CronArgs').':'. $line->params; } - + }elseif ($line->jobtype=='command') { print $langs->trans('CronCommand').':'. dol_trunc($line->command); if(!empty($line->params)) { @@ -227,55 +227,55 @@ if (count($object->lines)>0) { } } print '
'; - if(!empty($line->datestart)) {print dol_print_date($line->datestart,'dayhourtext');} else {print $langs->trans('CronNone');} + if(!empty($line->datestart)) {print dol_print_date($line->datestart,'dayhour');} else {print $langs->trans('CronNone');} print ''; - if(!empty($line->dateend)) {print dol_print_date($line->dateend,'dayhourtext');} else {print $langs->trans('CronNone');} + if(!empty($line->dateend)) {print dol_print_date($line->dateend,'dayhour');} else {print $langs->trans('CronNone');} print ''; - if(!empty($line->datelastrun)) {print dol_print_date($line->datelastrun,'dayhourtext');} else {print $langs->trans('CronNone');} + if(!empty($line->datelastrun)) {print dol_print_date($line->datelastrun,'dayhour');} else {print $langs->trans('CronNone');} print ''; - if(!empty($line->datenextrun)) {print dol_print_date($line->datenextrun,'dayhourtext');} else {print $langs->trans('CronNone');} + if(!empty($line->datenextrun)) {print dol_print_date($line->datenextrun,'dayhour');} else {print $langs->trans('CronNone');} print ''; if($line->unitfrequency == "60") print $langs->trans('CronEach')." ".($line->frequency/$line->unitfrequency)." ".$langs->trans('Minutes'); if($line->unitfrequency == "3600") print $langs->trans('CronEach')." ".($line->frequency/$line->unitfrequency)." ".$langs->trans('Hours'); if($line->unitfrequency == "86400") print $langs->trans('CronEach')." ".($line->frequency/$line->unitfrequency)." ".$langs->trans('Days'); if($line->unitfrequency == "604800") print $langs->trans('CronEach')." ".($line->frequency/$line->unitfrequency)." ".$langs->trans('Weeks'); print ''; if(!empty($line->nbrun)) {print $line->nbrun;} else {print '0';} print ''; if(!empty($line->lastresult)) {print dol_trunc($line->lastresult);} else {print $langs->trans('CronNone');} print ''; if(!empty($line->lastoutput)) {print dol_trunc(nl2br($line->lastoutput),100);} else {print $langs->trans('CronNone');} print ''; + + print ''; if ($user->rights->cron->delete) { - print "id."&status=".$status."&action=delete\" title=\"".$langs->trans('CronDelete')."\">\"".$langs-trans('CronDelete')."\" />"; + print "id."&status=".$status."&action=delete\" title=\"".$langs->trans('CronDelete')."\">".img_delete()."  "; } else { - print "trans('NotEnoughPermissions')."\">\"".$langs-trans('NotEnoughPermissions')."\" />"; + print "trans('NotEnoughPermissions')."\">".img_delete()."   "; } if ($user->rights->cron->execute) { - print "id."&status=".$status."&action=execute\" title=\"".$langs->trans('CronExecute')."\">\"".$langs-trans('CronExecute')."\" />"; + print "id."&status=".$status."&action=execute\" title=\"".$langs->trans('CronExecute')."\">".img_picto('',"play").""; } else { - print "trans('NotEnoughPermissions')."\">\"".$langs-trans('NotEnoughPermissions')."\" />"; + print "trans('NotEnoughPermissions')."\">".img_picto('',"execute").""; } print '
'; @@ -283,13 +283,22 @@ if (count($object->lines)>0) { print $langs->trans('CronNoJobs'); } -print "\n\n
\n"; -if (! $user->rights->cron->create) { +print "\n
\n"; + +if (! $user->rights->cron->create) +{ print ''.$langs->trans("New").''; -} else { - print ''.$langs->trans("New").''; } -print '

'; +else +{ + print ''.$langs->trans("New").''; +} + +print '
'; + +print '
'; llxFooter(); -$db->close(); \ No newline at end of file + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 60bdf26a8ab..840c4cecb94 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1166,24 +1166,66 @@ class FactureFournisseur extends CommonInvoice } /** - * Delete a detail line from database + * Delete a detail line from database * - * @param int $rowid Id of line to delete - * @return void + * @param int $rowid Id of line to delete + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return void */ - function deleteline($rowid) + function deleteline($rowid, $notrigger=0) { - // Supprime ligne - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det '; - $sql .= ' WHERE rowid = '.$rowid.';'; - $resql = $this->db->query($sql); - if (! $resql) + global $user, $langs, $conf; + + if (! $rowid) $rowid=$this->id; + + dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); + + $error=0; + $this->db->begin(); + + if (! $error && ! $notrigger) { - dol_print_error($this->db); + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php"); + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('LINEBILL_SUPPLIER_DELETE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers } - // Mise a jour prix facture - $this->update_price(); - return 1; + + if (! $error) + { + // Supprime ligne + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det '; + $sql.= ' WHERE rowid = '.$rowid; + dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) + { + $error++; + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + } + } + + if (! $error) + { + // Mise a jour prix facture + $this->update_price(); + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } } @@ -1305,7 +1347,7 @@ class FactureFournisseur extends CommonInvoice $result.=$lien.($max?dol_trunc($this->ref,$max):$this->ref).$lienfin; return $result; } - + /** * Renvoie la reference de facture suivante non utilisee en fonction du modele * de numerotation actif defini dans INVOICE_SUPPLIER_ADDON_NUMBER diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 1a41324479c..4c5dc82bcec 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -90,12 +90,12 @@ if ($_POST["action"] == 'dispatch' && $user->rights->fournisseur->commande->rece global $conf, $langs, $user; // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result_trigger=$interface->run_triggers('ORDER_SUPPLIER_DISPATCH',$this,$user,$langs,$conf); - if ($result_trigger < 0) { $error++; $this->errors=$interface->errors; } + $interface=new Interfaces($db); + $result_trigger=$interface->run_triggers('ORDER_SUPPLIER_DISPATCH',$commande,$user,$langs,$conf); + if ($result_trigger < 0) { $error++; $commande->errors=$interface->errors; } // Fin appel triggers - $this->db->commit(); + $db->commit(); } if ($result > 0) diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php index b726d39231a..b8b4c209cb3 100644 --- a/htdocs/fourn/facture/fiche.php +++ b/htdocs/fourn/facture/fiche.php @@ -749,7 +749,7 @@ if ($action == 'send' && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_P { $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); // Must not contain " setEventMessage($mesg); - + $error=0; // Initialisation donnees @@ -1177,7 +1177,8 @@ if ($action == 'create') if (1==2 && ! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) { print ''; - print ' '.$langs->trans('Label').''; + print ' '; + print ''.$langs->trans('Label').''; print ''.$langs->trans('PriceUHT').''; print ''.$langs->trans('VAT').''; print ''.$langs->trans('Qty').''; @@ -1201,7 +1202,7 @@ if ($action == 'create') } // Other options - $parameters=array(); + $parameters=array('colspan' => ' colspan="6"'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook // Bouton "Create Draft" @@ -1571,7 +1572,7 @@ else } // Other options - $parameters=array('colspan' => ' colspan="3"'); + $parameters=array('colspan' => ' colspan="4"'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook print ''; @@ -1736,6 +1737,12 @@ else // Show range print_date_range($date_start,$date_end); } + + if (is_object($hookmanager)) + { + $parameters=array('fk_parent_line'=>$line->fk_parent_line, 'line'=>$object->lines[$i],'var'=>$var,'num'=>$num,'i'=>$i); + $reshook=$hookmanager->executeHooks('formViewProductSupplierOptions',$parameters,$object,$action); + } print ''; // VAT @@ -1808,7 +1815,7 @@ else if (is_object($hookmanager)) { $parameters=array(); - $reshook=$hookmanager->executeHooks('formCreateProductOptions',$parameters,$object,$action); + $reshook=$hookmanager->executeHooks('formCreateSupplierProductOptions',$parameters,$object,$action); } // Editor wysiwyg @@ -2036,7 +2043,7 @@ else * Show mail form */ if ($action == 'presend') - { + { $ref = dol_sanitizeFileName($object->ref); include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $fileparams = dol_most_recent_file($conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2).$ref, preg_quote($object->ref,'/')); @@ -2092,12 +2099,12 @@ else $formmail->substit['__SIGNATURE__']=$user->signature; $formmail->substit['__PERSONALIZED__']=''; $formmail->substit['__CONTACTCIVNAME__']=''; - + //Find the good contact adress $custcontact=''; $contactarr=array(); $contactarr=$object->liste_contact(-1,'external'); - + if (is_array($contactarr) && count($contactarr)>0) { foreach($contactarr as $contact) { if ($contact['libelle']==$langs->trans('TypeContact_invoice_supplier_external_BILLING')) { @@ -2107,12 +2114,12 @@ else $custcontact=$contactstatic->getFullName($langs,1); } } - + if (!empty($custcontact)) { $formmail->substit['__CONTACTCIVNAME__']=$custcontact; } } - + // Tableau des parametres complementaires $formmail->param['action']='send'; $formmail->param['models']='invoice_supplier_send'; diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index e9358624fe2..51b9972260e 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -185,8 +185,8 @@ $form=new Form($db); if ($action == 'create' || $action == 'add_paiement') { - $facture = new FactureFournisseur($db); - $facture->fetch($facid); + $object = new FactureFournisseur($db); + $object->fetch($facid); $datefacture=dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); $dateinvoice=($datefacture==''?(empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0):$datefacture); @@ -248,91 +248,98 @@ if ($action == 'create' || $action == 'add_paiement') } print ''; - /* - * Autres factures impayees - */ - $sql = 'SELECT f.rowid as facid, f.rowid as ref, f.facnumber, f.total_ht, f.total_ttc, f.datef as df'; - $sql.= ', SUM(pf.amount) as am'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as f'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid'; - $sql.= " WHERE f.entity = ".$conf->entity; - $sql.= ' AND f.fk_soc = '.$facture->socid; - $sql.= ' AND f.paye = 0'; - $sql.= ' AND f.fk_statut = 1'; // Statut=0 => non validee, Statut=2 => annulee - $sql.= ' GROUP BY f.rowid, f.facnumber, f.total_ht, f.total_ttc, f.datef'; - $resql = $db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - if ($num > 0) - { - $i = 0; - print '
'; - print $langs->trans('Invoices').'
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + $parameters=array('facid'=>$facid, 'ref'=>$ref, 'objcanvas'=>$objcanvas); + $reshook=$hookmanager->executeHooks('paymentsupplierinvoices',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + $error=$hookmanager->error; $errors=$hookmanager->errors; + if (empty($reshook)) + { + /* + * Autres factures impayees + */ + $sql = 'SELECT f.rowid as facid, f.rowid as ref, f.facnumber, f.total_ht, f.total_ttc, f.datef as df'; + $sql.= ', SUM(pf.amount) as am'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as f'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid'; + $sql.= " WHERE f.entity = ".$conf->entity; + $sql.= ' AND f.fk_soc = '.$object->socid; + $sql.= ' AND f.paye = 0'; + $sql.= ' AND f.fk_statut = 1'; // Statut=0 => non validee, Statut=2 => annulee + $sql.= ' GROUP BY f.rowid, f.facnumber, f.total_ht, f.total_ttc, f.datef'; + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + if ($num > 0) + { + $i = 0; + print '
'; - $var=True; - $total=0; - $total_ttc=0; - $totalrecu=0; - while ($i < $num) - { - $objp = $db->fetch_object($resql); - $var=!$var; - print ''; - print ''; - print ''; - if ($objp->df > 0 ) - { - print ''; - } - else - { - print ''; - } - print ''; - print ''; - print ''; - print '\n"; - $total+=$objp->total_ht; - $total_ttc+=$objp->total_ttc; - $totalrecu+=$objp->am; - $i++; - } - if ($i > 1) - { - // Print total - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - } - print "
'.$langs->trans('Ref').''.$langs->trans('RefSupplier').''.$langs->trans('Date').''.$langs->trans('AmountTTC').''.$langs->trans('AlreadyPaid').''.$langs->trans('RemainderToPay').''.$langs->trans('Amount').'
'.img_object($langs->trans('ShowBill'),'bill').' '.$objp->ref; - print ''.$objp->facnumber.''; - print dol_print_date($db->jdate($objp->df)).'!!!'.price($objp->total_ttc).''.price($objp->am).''.price($objp->total_ttc - $objp->am).''; - $namef = 'amount_'.$objp->facid; - print ''; - print "
'.$langs->trans('TotalTTC').':'.price($total_ttc).''.price($totalrecu).''.price($total_ttc - $totalrecu).' 
\n"; - } - $db->free($resql); - } - else - { - dol_print_error($db); - } + print $langs->trans('Invoices').'
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $var=True; + $total=0; + $total_ttc=0; + $totalrecu=0; + while ($i < $num) + { + $objp = $db->fetch_object($resql); + $var=!$var; + print ''; + print ''; + print ''; + if ($objp->df > 0 ) + { + print ''; + } + else + { + print ''; + } + print ''; + print ''; + print ''; + print '\n"; + $total+=$objp->total_ht; + $total_ttc+=$objp->total_ttc; + $totalrecu+=$objp->am; + $i++; + } + if ($i > 1) + { + // Print total + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + } + print "
'.$langs->trans('Ref').''.$langs->trans('RefSupplier').''.$langs->trans('Date').''.$langs->trans('AmountTTC').''.$langs->trans('AlreadyPaid').''.$langs->trans('RemainderToPay').''.$langs->trans('Amount').'
'.img_object($langs->trans('ShowBill'),'bill').' '.$objp->ref; + print ''.$objp->facnumber.''; + print dol_print_date($db->jdate($objp->df)).'!!!'.price($objp->total_ttc).''.price($objp->am).''.price($objp->total_ttc - $objp->am).''; + $namef = 'amount_'.$objp->facid; + print ''; + print "
'.$langs->trans('TotalTTC').':'.price($total_ttc).''.price($totalrecu).''.price($total_ttc - $totalrecu).' 
\n"; + } + $db->free($resql); + } + else + { + dol_print_error($db); + } + } // print ''; print '

'.$langs->trans("ClosePaidInvoicesAutomatically"); diff --git a/htdocs/install/doctemplates/project/template_project.odt b/htdocs/install/doctemplates/project/template_project.odt new file mode 100755 index 00000000000..ff34277a48c Binary files /dev/null and b/htdocs/install/doctemplates/project/template_project.odt differ diff --git a/htdocs/install/doctemplates/project/template_task_summary.odt b/htdocs/install/doctemplates/project/template_task_summary.odt new file mode 100755 index 00000000000..67c43a785d2 Binary files /dev/null and b/htdocs/install/doctemplates/project/template_task_summary.odt differ diff --git a/htdocs/install/etape1.php b/htdocs/install/etape1.php index 009d953e73d..1f48bf8efc0 100644 --- a/htdocs/install/etape1.php +++ b/htdocs/install/etape1.php @@ -400,7 +400,7 @@ if (! $error && $db->connected && $action == "set") require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $srcroot=$main_dir.'/install/doctemplates'; $destroot=$main_data_dir.'/doctemplates'; - $docs=array('thirdparties' => 'thirdparty', 'proposals' => 'proposal', 'orders' => 'order', 'invoices' => 'invoice'); + $docs=array('thirdparties' => 'thirdparty', 'proposals' => 'proposal', 'orders' => 'order', 'invoices' => 'invoice', 'projects' => 'project'); foreach($docs as $cursordir => $cursorfile) { $src=$srcroot.'/'.$cursordir.'/template_'.$cursorfile.'.odt'; diff --git a/htdocs/install/etape5.php b/htdocs/install/etape5.php index 1fb4f45e80f..0ae7303bf38 100644 --- a/htdocs/install/etape5.php +++ b/htdocs/install/etape5.php @@ -237,7 +237,7 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i',$action)) dolibarr_install_syslog('install/etape5.php Activate module file='.$file); $res=dol_include_once("/core/modules/".$file); - $res=Activate($modtoactivatenew,1); + $res=activateModule($modtoactivatenew,1); if (! $result) print 'ERROR in activating module file='.$file; } } @@ -421,4 +421,4 @@ clearstatcache(); dolibarr_install_syslog("--- install/etape5.php Dolibarr setup finished", LOG_INFO); pFooter(1,$setuplang); -?> \ No newline at end of file +?> diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang index c64c74f1f58..e6930cd0b08 100644 --- a/htdocs/langs/en_US/cron.lang +++ b/htdocs/langs/en_US/cron.lang @@ -1,5 +1,22 @@ # Dolibarr language file - en_US - cron CHARSET=UTF-8 +Module2310Name=Cron +Module2310Desc=Scheduled task management + +# +# About page +# +About = About +CronAbout = About Cron +CronAboutPage = Cron about page + +# +# Right +# +Permission23101 = Read Scheduled task +Permission23102 = Create/update Scheduled task +Permission23103 = Delete Scheduled task +Permission23104 = Execute Scheduled task # # Admin @@ -12,6 +29,14 @@ FileToLaunchCronJobs=Command to launch cron jobs CronExplainHowToRunUnix=On Unix environement you should use crontab to run Command line each minutes CronExplainHowToRunWin=On Microsoft(tm) Windows environement you can use Scheduled task tools to run Command line each minutes + +# +# Menu +# +CronListActive= List of active jobs +CronListInactive= List of disabled jobs + + # # Page list # diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index 197a9f52146..a5f01c3e884 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -96,3 +96,6 @@ TypeContact_propal_external_CUSTOMER=Customer contact following-up proposal # Document models DocModelAzurDescription=A complete proposal model (logo...) DocModelJauneDescription=Jaune proposal model +DefaultModelPropalCreate=Default model creation +DefaultModelPropalToBill=Default template when closing a business proposal (to be invoiced) +DefaultModelPropalClosed=Default template when closing a business proposal (unbilled) diff --git a/htdocs/langs/fr_FR/propal.lang b/htdocs/langs/fr_FR/propal.lang index 5a4c05f0d6d..5a52f3b442b 100644 --- a/htdocs/langs/fr_FR/propal.lang +++ b/htdocs/langs/fr_FR/propal.lang @@ -97,4 +97,7 @@ TypeContact_propal_external_CUSTOMER=Contact client suivi propale DocModelAzurDescription=Modèle de propositions commerciales complet (logo...) DocModelJauneDescription=Modèle de proposition Jaune Numbershort=N° +DefaultModelPropalCreate=Modèle par défaut à la création +DefaultModelPropalToBill=Modèle par défaut lors de la cloture d'une proposition commerciale (à facturer) +DefaultModelPropalClosed=Modèle par défaut lors de la cloture d'une proposition commerciale (non facturée) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index dd6ac430fee..88efcfd76b5 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1075,6 +1075,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; } // jQuery File Upload + /* if (! empty($conf->global->MAIN_USE_JQUERY_FILEUPLOAD) || (defined('REQUIRE_JQUERY_FILEUPLOAD') && constant('REQUIRE_JQUERY_FILEUPLOAD'))) { print ''."\n"; @@ -1086,6 +1087,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; print ''."\n"; } + */ // jQuery DataTables if (! empty($conf->global->MAIN_USE_JQUERY_DATATABLES) || (defined('REQUIRE_JQUERY_DATATABLES') && constant('REQUIRE_JQUERY_DATATABLES'))) { diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 97eb27745a8..d2864b08c11 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -3,6 +3,7 @@ /* Copyright (C) 2002-2005 Rodolphe Quiedeville * Copyright (C) 2005-2012 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -260,7 +261,7 @@ class Project extends CommonObject if (empty($id) && empty($ref)) return -1; $sql = "SELECT rowid, ref, title, description, public, datec"; - $sql.= ", tms, dateo, datee, fk_soc, fk_user_creat, fk_statut, note_private, note_public"; + $sql.= ", tms, dateo, datee, fk_soc, fk_user_creat, fk_statut, note_private, note_public,model_pdf"; $sql.= " FROM " . MAIN_DB_PREFIX . "projet"; if (! empty($id)) { @@ -298,6 +299,7 @@ class Project extends CommonObject $this->user_author_id = $obj->fk_user_creat; $this->public = $obj->public; $this->statut = $obj->fk_statut; + $this->modelpdf = $obj->model_pdf; $this->db->free($resql); diff --git a/htdocs/theme/amarok/img/play.png b/htdocs/theme/amarok/img/play.png new file mode 100644 index 00000000000..6de3e256ba6 Binary files /dev/null and b/htdocs/theme/amarok/img/play.png differ diff --git a/htdocs/theme/auguria/img/play.png b/htdocs/theme/auguria/img/play.png new file mode 100644 index 00000000000..6de3e256ba6 Binary files /dev/null and b/htdocs/theme/auguria/img/play.png differ diff --git a/htdocs/theme/bureau2crea/img/play.png b/htdocs/theme/bureau2crea/img/play.png new file mode 100644 index 00000000000..6de3e256ba6 Binary files /dev/null and b/htdocs/theme/bureau2crea/img/play.png differ diff --git a/htdocs/theme/cameleo/img/play.png b/htdocs/theme/cameleo/img/play.png new file mode 100644 index 00000000000..6de3e256ba6 Binary files /dev/null and b/htdocs/theme/cameleo/img/play.png differ diff --git a/htdocs/theme/eldy/img/play.png b/htdocs/theme/eldy/img/play.png new file mode 100644 index 00000000000..6de3e256ba6 Binary files /dev/null and b/htdocs/theme/eldy/img/play.png differ