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 '";
-}
-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 '| '.$langs->trans('Ref').' | ';
- print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', '');
- print ' |
';
-
- // Ref client
- print '| ';
- print '';
- print ' | ';
- if ($user->rights->propal->creer && $action == 'refclient')
- {
- print '';
- }
- else
- {
- print $object->ref_client;
- }
- print ' | ';
- print '
';
-
- // Company
- print '| '.$langs->trans('Company').' | '.$soc->getNomUrl(1).' | ';
- print '
';
-
- // Ligne info remises tiers
- print '| '.$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 ' |
';
-
- // Date of proposal
- print '';
- print '| ';
- print '';
- print ' | ';
- if (! empty($object->brouillon) && $action == 'editdate')
- {
- print '';
- }
- else
- {
- if ($object->date)
- {
- print dol_print_date($object->date,'daytext');
- }
- else
- {
- print ' ';
- }
- }
- print ' | ';
-
- // Date end proposal
- print '
';
- print '| ';
- print '';
- print ' | ';
- if (! empty($object->brouillon) && $action == 'editecheance')
- {
- 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 '
';
-
- // Payment term
- print '| ';
- print '';
- 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 '
';
-
- // Delivery date
- $langs->load('deliveries');
- print '| ';
- print '';
- print ' | ';
- if ($action == 'editdate_livraison')
- {
- print '';
- }
- else
- {
- print dol_print_date($object->date_livraison,'daytext');
- }
- print ' | ';
- print '
';
-
- // Delivery delay
- print '| ';
- print '';
- 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 '
';
-
- // Origin of demand
- print '| ';
- print '';
- 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 '
';
-
- // Payment mode
- print '';
- print '| ';
- print '';
- 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 ' |
';
-
- // Project
- if (! empty($conf->projet->enabled))
- {
- $langs->load("projects");
- print '| ';
- print '';
- 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 ' |
';
- }
- else
- {
- 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 $form_close;
- }
-
-
- /*
- * Boutons Actions
- */
- if ($action != 'presend')
- {
- 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 '";
+}
+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 '| '.$langs->trans('Ref').' | ';
+ print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', '');
+ print ' |
';
+
+ // Ref client
+ print '| ';
+ print '';
+ print ' | ';
+ if ($user->rights->propal->creer && $action == 'refclient')
+ {
+ print '';
+ }
+ else
+ {
+ print $object->ref_client;
+ }
+ print ' | ';
+ print '
';
+
+ // Company
+ print '| '.$langs->trans('Company').' | '.$soc->getNomUrl(1).' | ';
+ print '
';
+
+ // Ligne info remises tiers
+ print '| '.$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 ' |
';
+
+ // Date of proposal
+ print '';
+ print '| ';
+ print '';
+ print ' | ';
+ if (! empty($object->brouillon) && $action == 'editdate')
+ {
+ print '';
+ }
+ else
+ {
+ if ($object->date)
+ {
+ print dol_print_date($object->date,'daytext');
+ }
+ else
+ {
+ print ' ';
+ }
+ }
+ print ' | ';
+
+ // Date end proposal
+ print '
';
+ print '| ';
+ print '';
+ print ' | ';
+ if (! empty($object->brouillon) && $action == 'editecheance')
+ {
+ 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 '
';
+
+ // Payment term
+ print '| ';
+ print '';
+ 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 '
';
+
+ // Delivery date
+ $langs->load('deliveries');
+ print '| ';
+ print '';
+ print ' | ';
+ if ($action == 'editdate_livraison')
+ {
+ print '';
+ }
+ else
+ {
+ print dol_print_date($object->date_livraison,'daytext');
+ }
+ print ' | ';
+ print '
';
+
+ // Delivery delay
+ print '| ';
+ print '';
+ 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 '
';
+
+ // Origin of demand
+ print '| ';
+ print '';
+ 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 '
';
+
+ // Payment mode
+ print '';
+ print '| ';
+ print '';
+ 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 ' |
';
+
+ // Project
+ if (! empty($conf->projet->enabled))
+ {
+ $langs->load("projects");
+ print '| ';
+ print '';
+ 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 ' |
';
+ }
+ else
+ {
+ 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 $form_close;
+ }
+
+
+ /*
+ * Boutons Actions
+ */
+ if ($action != 'presend')
+ {
+ 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 '
';
+ if ($srconly) return $fullpathpicto;
+ else return '
';
}
/**
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.= '';
+
+ 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.= '| '.$langs->trans("DefaultModelPropalCreate").' | ';
+ $texte.= '';
+ $texte.= $form->selectarray('value2',$liste,$conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT);
+ $texte.= " |
";
+
+ $texte.= '';
+ $texte.= '| '.$langs->trans("DefaultModelPropalToBill").' | ';
+ $texte.= '';
+ $texte.= $form->selectarray('value3',$liste,$conf->global->PROPALE_ADDON_PDF_ODT_TOBILL);
+ $texte.= " |
";
+ $texte.= '';
+
+ $texte.= '| '.$langs->trans("DefaultModelPropalClosed").' | ';
+ $texte.= '';
+ $texte.= $form->selectarray('value4',$liste,$conf->global->PROPALE_ADDON_PDF_ODT_CLOSED);
+ $texte.= " |
";
+ $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 '
";
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 '
';
@@ -283,13 +283,22 @@ if (count($object->lines)>0) {
print $langs->trans('CronNoJobs');
}
-print "\n\n';
+
+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 '| '.$langs->trans('Ref').' | ';
- print ''.$langs->trans('RefSupplier').' | ';
- print ''.$langs->trans('Date').' | ';
- print ''.$langs->trans('AmountTTC').' | ';
- print ''.$langs->trans('AlreadyPaid').' | ';
- print ''.$langs->trans('RemainderToPay').' | ';
- print ''.$langs->trans('Amount').' | ';
- 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 '| '.img_object($langs->trans('ShowBill'),'bill').' '.$objp->ref;
- print ' | ';
- print ''.$objp->facnumber.' | ';
- if ($objp->df > 0 )
- {
- print '';
- print dol_print_date($db->jdate($objp->df)).' | ';
- }
- else
- {
- print '!!! | ';
- }
- print ''.price($objp->total_ttc).' | ';
- print ''.price($objp->am).' | ';
- print ''.price($objp->total_ttc - $objp->am).' | ';
- print '';
- $namef = 'amount_'.$objp->facid;
- print '';
- print " |
\n";
- $total+=$objp->total_ht;
- $total_ttc+=$objp->total_ttc;
- $totalrecu+=$objp->am;
- $i++;
- }
- if ($i > 1)
- {
- // Print total
- print '';
- print '| '.$langs->trans('TotalTTC').': | ';
- print ''.price($total_ttc).' | ';
- print ''.price($totalrecu).' | ';
- print ''.price($total_ttc - $totalrecu).' | ';
- print ' | ';
- print "
\n";
- }
- print "
\n";
- }
- $db->free($resql);
- }
- else
- {
- dol_print_error($db);
- }
+ print $langs->trans('Invoices').'
';
+ print '\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
|